From 9b13ca5260b671904942fccaf25b5ed892a0860f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 6 Jun 2013 14:50:01 +0100 Subject: [PATCH 001/507] Added first FPA API functions. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_project.py | 2 +- src/api/api_fpa.cpp | 107 ++++++++++++++++++++++++++++++++++++++++++ src/api/z3.h | 1 + src/api/z3_fpa.h | 82 ++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 src/api/api_fpa.cpp create mode 100644 src/api/z3_fpa.h diff --git a/scripts/mk_project.py b/scripts/mk_project.py index e6e7d5dc8..e2bbd20ca 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -59,7 +59,7 @@ def init_project_def(): add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv') add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa', 'aig_tactic', 'muz_qe', 'sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') add_lib('smtparser', ['portfolio'], 'parsers/smt') - API_files = ['z3_api.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h'] + API_files = ['z3_api.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fpa.h'] add_lib('api', ['portfolio', 'user_plugin', 'smtparser', 'realclosure'], includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files) add_exe('shell', ['api', 'sat', 'extra_cmds'], exe_name='z3') diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp new file mode 100644 index 000000000..8e8493d63 --- /dev/null +++ b/src/api/api_fpa.cpp @@ -0,0 +1,107 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + api_fpa.cpp + +Abstract: + + +Author: + + Christoph M. Wintersteiger (cwinter) 2013-06-05 + +Notes: + +--*/ +#include +#include"z3.h" +#include"api_log_macros.h" +#include"api_context.h" +#include"float_decl_plugin.h" + +extern "C" { + + Z3_sort Z3_API Z3_mk_fpa_rounding_mode_sort(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_fpa_rounding_mode_sort(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_sort r = of_sort(float_util(ctx->m()).mk_rm_sort()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(__in Z3_context c) + { + Z3_TRY; + LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_round_nearest_ties_to_even()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(__in Z3_context c) + { + Z3_TRY; + LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_round_nearest_ties_to_away()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(__in Z3_context c) + { + Z3_TRY; + LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_round_toward_positive()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(__in Z3_context c) + { + Z3_TRY; + LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_round_toward_negative()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(__in Z3_context c) + { + Z3_TRY; + LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_round_toward_zero()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_sort Z3_API Z3_mk_fpa_sort(Z3_context c, unsigned ebits, unsigned sbits) { + Z3_TRY; + LOG_Z3_mk_fpa_sort(c, ebits, sbits); + RESET_ERROR_CODE(); + if (ebits < 2 || sbits < 3) { + SET_ERROR_CODE(Z3_INVALID_ARG); + } + api::context * ctx = mk_c(c); + float_util fu(ctx->m()); + Z3_sort r = of_sort(fu.mk_float_sort(ebits, sbits)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + + +}; diff --git a/src/api/z3.h b/src/api/z3.h index db8becafd..2a56fa9a7 100644 --- a/src/api/z3.h +++ b/src/api/z3.h @@ -27,6 +27,7 @@ Notes: #include"z3_algebraic.h" #include"z3_polynomial.h" #include"z3_rcf.h" +#include"z3_fpa.h" #undef __in #undef __out diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h new file mode 100644 index 000000000..a3e61931b --- /dev/null +++ b/src/api/z3_fpa.h @@ -0,0 +1,82 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + z3_fpa.h + +Abstract: + + Additional APIs for floating-point arithmetic (FPA). + +Author: + + Christoph M. Wintersteiger (cwinter) 2013-06-05 + +Notes: + +--*/ +#ifndef _Z3_FPA_H_ +#define _Z3_FPA_H_ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + + /** + \brief Create a rounding mode sort. + + def_API('Z3_mk_fpa_rounding_mode_sort', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_rounding_mode_sort(__in Z3_context c); + + /** + \brief Create a numeral of rounding mode sort which represents the NearestTiesToEven rounding mode. + + def_API('Z3_mk_fpa_round_nearest_ties_to_even', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(__in Z3_context c); + + /** + \brief Create a numeral of rounding mode sort which represents the NearestTiesToAway rounding mode. + + def_API('Z3_mk_fpa_round_nearest_ties_to_away', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(__in Z3_context c); + + /** + \brief Create a numeral of rounding mode sort which represents the TowardPositive rounding mode. + + def_API('Z3_mk_fpa_round_toward_positive', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(__in Z3_context c); + + /** + \brief Create a numeral of rounding mode sort which represents the TowardNegative rounding mode. + + def_API('Z3_mk_fpa_round_toward_negative', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(__in Z3_context c); + + /** + \brief Create a numeral of rounding mode sort which represents the TowardZero rounding mode. + + def_API('Z3_mk_fpa_round_toward_zero', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(__in Z3_context c); + + + /** + \brief Create a floating point sort. + + def_API('Z3_mk_fpa_sort', SORT, (_in(CONTEXT), _in(UINT), _in(UINT))) + + \remark ebits must be larger than 1 and sbits must be larger than 2. + */ + Z3_sort Z3_API Z3_mk_fpa_sort(__in Z3_context c, __in unsigned ebits, __in unsigned sbits); + +#ifdef __cplusplus +}; +#endif // __cplusplus + +#endif From 573ec293dc0fc6d9dc9408c832b62f55b4bfd909 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 7 Jun 2013 19:09:41 +0100 Subject: [PATCH 002/507] FPA: Added core C API. Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 253 +++++++++++++++++++++++++++++++++++- src/api/z3_fpa.h | 220 ++++++++++++++++++++++++++++++- src/ast/float_decl_plugin.h | 3 +- 3 files changed, 469 insertions(+), 7 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 8e8493d63..74030a0b0 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -33,7 +33,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(__in Z3_context c) + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); @@ -44,7 +44,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(__in Z3_context c) + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); @@ -55,7 +55,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(__in Z3_context c) + Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); @@ -66,7 +66,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(__in Z3_context c) + Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); @@ -77,7 +77,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(__in Z3_context c) + Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); @@ -102,6 +102,249 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_nan(Z3_context c, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_nan(c, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_nan(to_sort(s))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_inf(Z3_context c, Z3_sort s, Z3_bool negative) { + Z3_TRY; + LOG_Z3_mk_fpa_inf(c, s, negative); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util fu(ctx->m()); + Z3_ast r = of_ast(negative != 0 ? fu.mk_minus_inf(to_sort(s)) : fu.mk_plus_inf(to_sort(s))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_abs(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_abs(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_abs(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_neg(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_neg(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_uminus(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_add(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_add(c, rm, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_sub(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_add(c, rm, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_mul(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_add(c, rm, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_div(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_add(c, rm, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_fma(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2, Z3_ast t3) { + Z3_TRY; + LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_fused_ma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_sqrt(Z3_context c, Z3_ast rm, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_sqrt(c, rm, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_sqrt(to_expr(rm), to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_rem(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_rem(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_rem(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_eq(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_eq(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_float_eq(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_leq(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_leq(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_le(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_lt(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_lt(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_lt(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_geq(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_geq(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_ge(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_gt(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_gt(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_gt(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_is_normal(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_is_normal(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_is_normal(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_is_subnormal(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_is_subnormal(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_is_subnormal(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_is_zero(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_is_zero(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_is_zero(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_is_inf(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_is_inf(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_is_inf(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_is_nan(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_is_nan(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_is_nan(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_min(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_min(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_min(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_max(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_max(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_max(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_convert(Z3_context c, Z3_sort s, Z3_ast rm, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_convert(c, s, rm, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util fu(ctx->m()); + expr * args [2] = { to_expr(rm), to_expr(t) }; + Z3_ast r = of_ast(ctx->m().mk_app(fu.get_family_id(), OP_TO_FLOAT, + to_sort(s)->get_num_parameters(), to_sort(s)->get_parameters(), + 2, args)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } }; diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index a3e61931b..c9feb0778 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -65,7 +65,6 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(__in Z3_context c); - /** \brief Create a floating point sort. @@ -74,7 +73,226 @@ extern "C" { \remark ebits must be larger than 1 and sbits must be larger than 2. */ Z3_sort Z3_API Z3_mk_fpa_sort(__in Z3_context c, __in unsigned ebits, __in unsigned sbits); + + /** + \brief Create a NaN of sort s. + + def_API('Z3_mk_fpa_nan', AST, (_in(CONTEXT),_in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_nan(__in Z3_context c, __in Z3_sort s); + + /** + \brief Create a floating point infinity of sort s. + + When \c negative is true, -Inf will be generated instead of +Inf. + + def_API('Z3_mk_fpa_inf', AST, (_in(CONTEXT),_in(SORT),_in(BOOL))) + */ + Z3_ast Z3_API Z3_mk_fpa_inf(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); + /** + \brief Floating-point absolute value + + t must have floating point sort. + + def_API('Z3_mk_fpa_abs', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_abs(__in Z3_context c, __in Z3_ast t); + + /** + \brief Floating-point negation + + t must have floating point sort. + + def_API('Z3_mk_fpa_neg', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_neg(__in Z3_context c, __in Z3_ast t); + + /** + \brief Floating-point addition + + rm must be of FPA rounding mode sort, t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_add', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_add(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point subtraction + + rm must be of FPA rounding mode sort, t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_sub', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_sub(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point multiplication + + rm must be of FPA rounding mode sort, t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_mul', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_mul(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point division + + The nodes rm must be of FPA rounding mode sort t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_div', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_div(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point fused multiply-add. + + The result is round((t1 * t2) + t3) + + rm must be of FPA rounding mode sort, t1, t2, and t3 must have floating point sort. + + def_API('Z3_mk_fpa_fma', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_fma(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t1, __in Z3_ast t2, __in Z3_ast t3); + + /** + \brief Floating-point square root + + rm must be of FPA rounding mode sort, t must have floating point sort. + + def_API('Z3_mk_fpa_sqrt', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_sqrt(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t); + + /** + \brief Floating-point remainder + + t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_rem', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_rem(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point equality + + Note that this is IEEE 754 equality (as opposed to SMT-LIB =). + + t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_eq', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_eq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point less-than or equal + + t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_leq', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_leq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point less-than + + t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_lt', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_lt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + + /** + \brief Floating-point greater-than or equal + + t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_geq', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_geq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Floating-point greater-than + + t1 and t2 must have floating point sort. + + def_API('Z3_mk_fpa_gt', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_gt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Predicate indicating whether t is a normal floating point number + + t must have floating point sort. + + def_API('Z3_mk_fpa_is_normal', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_normal(__in Z3_context c, __in Z3_ast t); + + /** + \brief Predicate indicating whether t is a subnormal floating point number + + t must have floating point sort. + + def_API('Z3_mk_fpa_is_subnormal', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_subnormal(__in Z3_context c, __in Z3_ast t); + + /** + \brief Predicate indicating whether t is a floating point number with zero value, i.e., +0 or -0. + + t must have floating point sort. + + def_API('Z3_mk_fpa_is_zero', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_zero(__in Z3_context c, __in Z3_ast t); + + /** + \brief Predicate indicating whether t is a floating point number representing +Inf or -Inf + + t must have floating point sort. + + def_API('Z3_mk_fpa_is_inf', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_inf(__in Z3_context c, __in Z3_ast t); + + /** + \brief Predicate indicating whether t is a NaN + + t must have floating point sort. + + def_API('Z3_mk_fpa_is_nan', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_nan(__in Z3_context c, __in Z3_ast t); + + /** + \brief Minimum of floating point numbers + + t1, t2 must have floating point sort. + + def_API('Z3_mk_fpa_min', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_min(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Maximum of floating point numbers + + t1, t2 must have floating point sort. + + def_API('Z3_mk_fpa_max', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_max(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Conversion of a floating point number to sort s. + + s must be a floating point sort, rm must have rounding mode sort, and t must have floating point sort. + + def_API('Z3_mk_fpa_convert', AST, (_in(CONTEXT),_in(SORT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_convert(__in Z3_context c, __in Z3_sort s, __in Z3_ast rm, __in Z3_ast t); + #ifdef __cplusplus }; #endif // __cplusplus diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index f1b60a91b..deda7e045 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -178,6 +178,7 @@ public: family_id get_fid() const { return m_fid; } family_id get_family_id() const { return m_fid; } arith_util & au() { return m_a_util; } + float_decl_plugin & plugin() { return *m_plugin; } sort * mk_float_sort(unsigned ebits, unsigned sbits); sort * mk_rm_sort() { return m().mk_sort(m_fid, ROUNDING_MODE_SORT); } @@ -211,7 +212,7 @@ public: bool is_nan(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nan(v); } bool is_plus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pinf(v); } - bool is_minus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); } + bool is_minus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); } bool is_zero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_zero(v); } bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } From ebbdff87577473d14c990e580118a42bc2c937fa Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 10 Jun 2013 15:53:24 +0100 Subject: [PATCH 003/507] doc bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/IntExpr.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/dotnet/IntExpr.cs b/src/api/dotnet/IntExpr.cs index 4c52ec79f..58bf1b973 100644 --- a/src/api/dotnet/IntExpr.cs +++ b/src/api/dotnet/IntExpr.cs @@ -1,5 +1,5 @@ /*++ -Copyright () 2012 Microsoft Corporation +Copyright (c) 2012 Microsoft Corporation Module Name: From a36a09e08171e7e0d0c00f1bab508a780b5bbae2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 10 Jun 2013 15:53:41 +0100 Subject: [PATCH 004/507] FPA API: minor fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 30 ++++++- src/api/z3_fpa.h | 191 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 194 insertions(+), 27 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 74030a0b0..cfb5a2624 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -122,6 +122,19 @@ extern "C" { RETURN_Z3(r); Z3_CATCH_RETURN(0); } + + Z3_ast Z3_API Z3_mk_double(Z3_context c, double v, Z3_sort ty) { + Z3_TRY; + LOG_Z3_mk_double(c, v, ty); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util fu(ctx->m()); + mpf tmp; + fu.fm().set(tmp, fu.get_ebits(to_sort(ty)), fu.get_sbits(to_sort(ty)), v); + Z3_ast r = of_ast(fu.mk_value(tmp)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } Z3_ast Z3_API Z3_mk_fpa_abs(Z3_context c, Z3_ast t) { Z3_TRY; @@ -223,9 +236,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_leq(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_ast Z3_API Z3_mk_fpa_le(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; - LOG_Z3_mk_fpa_leq(c, t1, t2); + LOG_Z3_mk_fpa_le(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(float_util(ctx->m()).mk_le(to_expr(t1), to_expr(t2))); @@ -243,9 +256,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_geq(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_ast Z3_API Z3_mk_fpa_ge(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; - LOG_Z3_mk_fpa_geq(c, t1, t2); + LOG_Z3_mk_fpa_ge(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(float_util(ctx->m()).mk_ge(to_expr(t1), to_expr(t2))); @@ -347,4 +360,13 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_to_ieee_bv(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(float_util(ctx->m()).mk_to_ieee_bv(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } }; diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index c9feb0778..93268b821 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -25,6 +25,8 @@ extern "C" { /** \brief Create a rounding mode sort. + + \param c logical context. def_API('Z3_mk_fpa_rounding_mode_sort', SORT, (_in(CONTEXT),)) */ @@ -32,6 +34,8 @@ extern "C" { /** \brief Create a numeral of rounding mode sort which represents the NearestTiesToEven rounding mode. + + \param c logical context. def_API('Z3_mk_fpa_round_nearest_ties_to_even', AST, (_in(CONTEXT),)) */ @@ -39,6 +43,8 @@ extern "C" { /** \brief Create a numeral of rounding mode sort which represents the NearestTiesToAway rounding mode. + + \param c logical context. def_API('Z3_mk_fpa_round_nearest_ties_to_away', AST, (_in(CONTEXT),)) */ @@ -46,6 +52,8 @@ extern "C" { /** \brief Create a numeral of rounding mode sort which represents the TowardPositive rounding mode. + + \param c logical context. def_API('Z3_mk_fpa_round_toward_positive', AST, (_in(CONTEXT),)) */ @@ -54,28 +62,41 @@ extern "C" { /** \brief Create a numeral of rounding mode sort which represents the TowardNegative rounding mode. + \param c logical context. + def_API('Z3_mk_fpa_round_toward_negative', AST, (_in(CONTEXT),)) */ Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(__in Z3_context c); /** \brief Create a numeral of rounding mode sort which represents the TowardZero rounding mode. + + \param c logical context. def_API('Z3_mk_fpa_round_toward_zero', AST, (_in(CONTEXT),)) */ Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(__in Z3_context c); + + /** \brief Create a floating point sort. - - def_API('Z3_mk_fpa_sort', SORT, (_in(CONTEXT), _in(UINT), _in(UINT))) + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort', SORT, (_in(CONTEXT), _in(UINT), _in(UINT))) */ Z3_sort Z3_API Z3_mk_fpa_sort(__in Z3_context c, __in unsigned ebits, __in unsigned sbits); /** \brief Create a NaN of sort s. + + \param c logical context. + \param s target sort def_API('Z3_mk_fpa_nan', AST, (_in(CONTEXT),_in(SORT))) */ @@ -83,16 +104,41 @@ extern "C" { /** \brief Create a floating point infinity of sort s. + + \param c logical context. + \param s target sort + \param negative indicates whether the result should be negative When \c negative is true, -Inf will be generated instead of +Inf. def_API('Z3_mk_fpa_inf', AST, (_in(CONTEXT),_in(SORT),_in(BOOL))) */ Z3_ast Z3_API Z3_mk_fpa_inf(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); - + + /** + \brief Create a numeral of floating point sort. + + This function can be use to create numerals that fit in a double value. + It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. + + \params c logical context. + \params v value. + \params ty sort. + + ty must be a floating point sort + + \sa Z3_mk_numeral + + def_API('Z3_mk_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) + */ + Z3_ast Z3_API Z3_mk_double(__in Z3_context c, __in double v, __in Z3_sort ty); + /** \brief Floating-point absolute value + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_abs', AST, (_in(CONTEXT),_in(AST))) @@ -102,6 +148,9 @@ extern "C" { /** \brief Floating-point negation + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_neg', AST, (_in(CONTEXT),_in(AST))) @@ -111,7 +160,12 @@ extern "C" { /** \brief Floating-point addition - rm must be of FPA rounding mode sort, t1 and t2 must have floating point sort. + \param c logical context. + \param rm rounding mode + \param t1 floating-point term. + \param t2 floating-point term. + + rm must be of FPA rounding mode sort, t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_add', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -120,7 +174,12 @@ extern "C" { /** \brief Floating-point subtraction - rm must be of FPA rounding mode sort, t1 and t2 must have floating point sort. + \param c logical context. + \param rm rounding mode + \param t1 floating-point term. + \param t2 floating-point term. + + rm must be of FPA rounding mode sort, t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_sub', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -129,7 +188,12 @@ extern "C" { /** \brief Floating-point multiplication - rm must be of FPA rounding mode sort, t1 and t2 must have floating point sort. + \param c logical context. + \param rm rounding mode + \param t1 floating-point term. + \param t2 floating-point term. + + rm must be of FPA rounding mode sort, t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_mul', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -138,7 +202,12 @@ extern "C" { /** \brief Floating-point division - The nodes rm must be of FPA rounding mode sort t1 and t2 must have floating point sort. + \param c logical context. + \param rm rounding mode + \param t1 floating-point term. + \param t2 floating-point term. + + The nodes rm must be of FPA rounding mode sort t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_div', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -147,9 +216,14 @@ extern "C" { /** \brief Floating-point fused multiply-add. + \param c logical context. + \param rm rounding mode + \param t1 floating-point term. + \param t2 floating-point term. + The result is round((t1 * t2) + t3) - rm must be of FPA rounding mode sort, t1, t2, and t3 must have floating point sort. + rm must be of FPA rounding mode sort, t1, t2, and t3 must have the same floating point sort. def_API('Z3_mk_fpa_fma', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST),_in(AST))) */ @@ -158,6 +232,10 @@ extern "C" { /** \brief Floating-point square root + \param c logical context. + \param rm rounding mode + \param t floating-point term. + rm must be of FPA rounding mode sort, t must have floating point sort. def_API('Z3_mk_fpa_sqrt', AST, (_in(CONTEXT),_in(AST),_in(AST))) @@ -167,7 +245,11 @@ extern "C" { /** \brief Floating-point remainder - t1 and t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_rem', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ @@ -176,27 +258,39 @@ extern "C" { /** \brief Floating-point equality + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + Note that this is IEEE 754 equality (as opposed to SMT-LIB =). - t1 and t2 must have floating point sort. + t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_eq', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_eq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Floating-point less-than or equal + \brief Floating-point less than or equal - t1 and t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1 and t2 must have the same floating point sort. - def_API('Z3_mk_fpa_leq', AST, (_in(CONTEXT),_in(AST),_in(AST))) + def_API('Z3_mk_fpa_le', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_leq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + Z3_ast Z3_API Z3_mk_fpa_le(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** \brief Floating-point less-than - t1 and t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_lt', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ @@ -204,18 +298,26 @@ extern "C" { /** - \brief Floating-point greater-than or equal + \brief Floating-point greater than or equal - t1 and t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1 and t2 must have the same floating point sort. - def_API('Z3_mk_fpa_geq', AST, (_in(CONTEXT),_in(AST),_in(AST))) + def_API('Z3_mk_fpa_ge', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_geq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + Z3_ast Z3_API Z3_mk_fpa_ge(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** \brief Floating-point greater-than - t1 and t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1 and t2 must have the same floating point sort. def_API('Z3_mk_fpa_gt', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ @@ -224,6 +326,9 @@ extern "C" { /** \brief Predicate indicating whether t is a normal floating point number + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_is_normal', AST, (_in(CONTEXT),_in(AST))) @@ -233,6 +338,9 @@ extern "C" { /** \brief Predicate indicating whether t is a subnormal floating point number + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_is_subnormal', AST, (_in(CONTEXT),_in(AST))) @@ -242,6 +350,9 @@ extern "C" { /** \brief Predicate indicating whether t is a floating point number with zero value, i.e., +0 or -0. + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_is_zero', AST, (_in(CONTEXT),_in(AST))) @@ -251,6 +362,9 @@ extern "C" { /** \brief Predicate indicating whether t is a floating point number representing +Inf or -Inf + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_is_inf', AST, (_in(CONTEXT),_in(AST))) @@ -260,6 +374,9 @@ extern "C" { /** \brief Predicate indicating whether t is a NaN + \param c logical context. + \param t floating-point term. + t must have floating point sort. def_API('Z3_mk_fpa_is_nan', AST, (_in(CONTEXT),_in(AST))) @@ -269,7 +386,11 @@ extern "C" { /** \brief Minimum of floating point numbers - t1, t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1, t2 must have the same floating point sort. def_API('Z3_mk_fpa_min', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ @@ -278,20 +399,44 @@ extern "C" { /** \brief Maximum of floating point numbers - t1, t2 must have floating point sort. + \param c logical context. + \param t1 floating-point term. + \param t2 floating-point term. + + t1, t2 must have the same floating point sort. def_API('Z3_mk_fpa_max', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_max(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Conversion of a floating point number to sort s. + \brief Conversion of a floating point number to another floating-point sort s. + + Produces a term that represents the conversion of a floating-point term t to a different + floating point sort s. If necessary, rounding according to rm is applied. + + \param c logical context. + \param s floating-point sort. + \param rm rounding mode. + \param t floating-point term. s must be a floating point sort, rm must have rounding mode sort, and t must have floating point sort. def_API('Z3_mk_fpa_convert', AST, (_in(CONTEXT),_in(SORT),_in(AST),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_convert(__in Z3_context c, __in Z3_sort s, __in Z3_ast rm, __in Z3_ast t); + + /** + \brief Conversion of a floating point term to a bit-vector term in IEEE754 format. + + \param c logical context. + \param t floating-point term. + + t must have floating point sort. The size of the resulting bit-vector is automatically determined. + + def_API('Z3_mk_fpa_to_ieee_bv', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t); #ifdef __cplusplus }; From e14819c1b1eddbe05e7240e43543cd0d8cbf8889 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 10 Jun 2013 15:54:20 +0100 Subject: [PATCH 005/507] FPA: Added .NET API calls Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 365 +++++++++++++++++++++++++++++ src/api/dotnet/FPExpr.cs | 46 ++++ src/api/dotnet/FPNum.cs | 47 ++++ src/api/dotnet/FPRMExpr.cs | 46 ++++ src/api/dotnet/FPRMNum.cs | 47 ++++ src/api/dotnet/FPRMSort.cs | 43 ++++ src/api/dotnet/FPSort.cs | 43 ++++ src/api/dotnet/Microsoft.Z3.csproj | 8 +- 8 files changed, 644 insertions(+), 1 deletion(-) create mode 100644 src/api/dotnet/FPExpr.cs create mode 100644 src/api/dotnet/FPNum.cs create mode 100644 src/api/dotnet/FPRMExpr.cs create mode 100644 src/api/dotnet/FPRMNum.cs create mode 100644 src/api/dotnet/FPRMSort.cs create mode 100644 src/api/dotnet/FPSort.cs diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 68cca046e..1e9bd1323 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3428,6 +3428,371 @@ namespace Microsoft.Z3 } #endregion + #region Floating-Point Arithmetic + /// + /// Create a floating point rounding mode sort. + /// + public FPRMSort MkFPRMSort() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMSort(this); + } + + /// + /// Create a NearestTiesToEven rounding mode numeral. + /// + public FPRMNum MkFPRMNearestTiesToEven() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_even(nCtx)); + } + + /// + /// Create a NearestTiesToAway rounding mode numeral. + /// + public FPRMNum MkFPRMNearestTiesToAway() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx)); + } + + /// + /// Create a TowardPositive rounding mode numeral. + /// + public FPRMNum MkFPRMTowardPositive() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_positive(nCtx)); + } + + /// + /// Create a TowardNegative rounding mode numeral. + /// + public FPRMNum MkFPRMTowardNegative() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_negative(nCtx)); + } + + /// + /// Create a TowardZero rounding mode numeral. + /// + public FPRMNum MkFPRMTowardZero() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_zero(nCtx)); + } + + /// + /// Create a floating point sort. + /// + /// exponent bits in the floating point sort. + /// significand bits in the floating point sort. + public FPSort MkFPSort(uint ebits, uint sbits) + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, ebits, sbits); + } + + /// + /// Create a floating point NaN numeral. + /// + /// A string representing the value in decimal notation. + /// floating point sort. + public FPNum MkFPNaN(double v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_nan(nCtx, s.NativeObject)); + } + + /// + /// Create a floating point Inf numeral. + /// + /// A string representing the value in decimal notation. + /// floating point sort. + /// indicates whether the result should be negative. + public FPNum MkFPInf(double v, FPSort s, bool negative) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_inf(nCtx, s.NativeObject, negative ? 1 : 0)); + } + + /// + /// Create a floating point numeral. + /// + /// A string representing the value in decimal notation. + /// floating point sort + public FPNum MkFP(double v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_double(this.nCtx, v, s.NativeObject)); + } + + /// + /// Floating-point absolute value + /// + /// floating point term + FPExpr MkFPAbs(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_abs(this.nCtx, t.NativeObject)); + } + + /// + /// Floating-point negation + /// + /// floating point term + FPExpr MkFPNeg(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_neg(this.nCtx, t.NativeObject)); + } + + /// + /// Floating-point addition + /// + /// rounding mode term + /// floating point term + /// floating point term + FPExpr MkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_add(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point subtraction + /// + /// rounding mode term + /// floating point term + /// floating point term + FPExpr MkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_sub(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point multiplication + /// + /// rounding mode term + /// floating point term + /// floating point term + FPExpr MkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_mul(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point division + /// + /// rounding mode term + /// floating point term + /// floating point term + FPExpr MkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_div(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point fused multiply-add + /// + /// + /// The result is round((t1 * t2) + t3) + /// + /// rounding mode term + /// floating point term + /// floating point term + /// floating point term + FPExpr MkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_fma(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject, t3.NativeObject)); + } + + /// + /// Floating-point square root + /// + /// floating point term + FPExpr MkFPSqrt(FPRMExpr rm, FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_sqrt(this.nCtx, rm.NativeObject, t.NativeObject)); + } + + /// + /// Floating-point remainder + /// + /// floating point term + /// floating point term + FPExpr MkFPRem(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_rem(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point equality + /// + /// + /// Note that this is IEEE 754 equality (as opposed to standard =). + /// + /// floating point term + /// floating point term + BoolExpr MkFPEq(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_eq(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point less than or equal + /// + /// floating point term + /// floating point term + BoolExpr MkFPLe(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_le(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point less than + /// + /// floating point term + /// floating point term + BoolExpr MkFPLt(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_lt(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point greater than or equal + /// + /// floating point term + /// floating point term + BoolExpr MkFPGe(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_ge(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point greater than + /// + /// floating point term + /// floating point term + BoolExpr MkFPGt(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_gt(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Predicate indicating whether t is a normal floating point number + /// + /// floating point term + BoolExpr MkFPIsNormal(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_normal(this.nCtx, t.NativeObject)); + } + + /// + /// Predicate indicating whether t is a subnormal floating point number + /// + /// floating point term + BoolExpr MkFPIsSubnormal(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_subnormal(this.nCtx, t.NativeObject)); + } + + /// + /// Predicate indicating whether t is a floating point number with zero value, i.e., +0 or -0. + /// + /// floating point term + BoolExpr MkFPIsZero(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_zero(this.nCtx, t.NativeObject)); + } + + /// + /// Predicate indicating whether t is a floating point number representing +Inf or -Inf + /// + /// floating point term + BoolExpr MkFPIsInf(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_inf(this.nCtx, t.NativeObject)); + } + + /// + /// Predicate indicating whether t is a NaN + /// + /// floating point term + BoolExpr MkFPIsNaN(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_nan(this.nCtx, t.NativeObject)); + } + + /// + /// Floating-point minimum + /// + /// floating point term + /// floating point term + FPExpr MkFPMin(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_min(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point maximium + /// + /// floating point term + /// floating point term + FPExpr MkFPMax(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_max(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Conversion of a floating point number to another floating-point sort s. + /// + /// + /// Produces a term that represents the conversion of a floating-point term t to a different + /// floating point sort s. If necessary, rounding according to rm is applied. + /// + /// floating point sort + /// floating point rounding mode term + /// floating point term + FPExpr MkFPConvert(FPSort s, FPRMExpr rm, FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_convert(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); + } + + /// + /// Conversion of a floating point term to a bit-vector term in IEEE754 format. + /// + /// + /// The size of the resulting bit-vector is automatically determined. + /// + /// floating point term + FPExpr MkFPToIEEEBV(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_to_ieee_bv(this.nCtx, t.NativeObject)); + } + + #endregion #region Miscellaneous /// diff --git a/src/api/dotnet/FPExpr.cs b/src/api/dotnet/FPExpr.cs new file mode 100644 index 000000000..66b3fc10d --- /dev/null +++ b/src/api/dotnet/FPExpr.cs @@ -0,0 +1,46 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPExpr.cs + +Abstract: + + Z3 Managed API: Floating Point Expressions + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Floating Point Expressions + /// + public class FPExpr : Expr + { + #region Internal + internal protected FPExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal FPExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/src/api/dotnet/FPNum.cs b/src/api/dotnet/FPNum.cs new file mode 100644 index 000000000..044598e58 --- /dev/null +++ b/src/api/dotnet/FPNum.cs @@ -0,0 +1,47 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPNum.cs + +Abstract: + + Z3 Managed API: Floating Point Numerals + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Floatiung Point Numerals + /// + [ContractVerification(true)] + public class FPNum : FPExpr + { + + #region Internal + internal FPNum(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + + /// + /// Returns a string representation of the numeral. + /// + public override string ToString() + { + return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); + } + } +} diff --git a/src/api/dotnet/FPRMExpr.cs b/src/api/dotnet/FPRMExpr.cs new file mode 100644 index 000000000..fa43a346a --- /dev/null +++ b/src/api/dotnet/FPRMExpr.cs @@ -0,0 +1,46 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMExpr.cs + +Abstract: + + Z3 Managed API: Floating Point Expressions over Rounding Modes + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Floating Point Expressions + /// + public class FPRMExpr : Expr + { + #region Internal + internal protected FPRMExpr(Context ctx) + : base(ctx) + { + Contract.Requires(ctx != null); + } + internal FPRMExpr(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/src/api/dotnet/FPRMNum.cs b/src/api/dotnet/FPRMNum.cs new file mode 100644 index 000000000..eaf105718 --- /dev/null +++ b/src/api/dotnet/FPRMNum.cs @@ -0,0 +1,47 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMNum.cs + +Abstract: + + Z3 Managed API: Floating Point Rounding Mode Numerals + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Floatiung Point Rounding Mode Numerals + /// + [ContractVerification(true)] + public class FPRMNum : FPRMExpr + { + + #region Internal + internal FPRMNum(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + + /// + /// Returns a string representation of the numeral. + /// + public override string ToString() + { + return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); + } + } +} diff --git a/src/api/dotnet/FPRMSort.cs b/src/api/dotnet/FPRMSort.cs new file mode 100644 index 000000000..23d454a65 --- /dev/null +++ b/src/api/dotnet/FPRMSort.cs @@ -0,0 +1,43 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMSort.cs + +Abstract: + + Z3 Managed API: Floating Point Rounding Mode Sorts + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A floating point rounding mode sort + /// + public class FPRMSort : Sort + { + #region Internal + internal FPRMSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal FPRMSort(Context ctx) + : base(ctx, Native.Z3_mk_fpa_rounding_mode_sort(ctx.nCtx)) + { + Contract.Requires(ctx != null); + } + #endregion + } +} \ No newline at end of file diff --git a/src/api/dotnet/FPSort.cs b/src/api/dotnet/FPSort.cs new file mode 100644 index 000000000..a79557ae6 --- /dev/null +++ b/src/api/dotnet/FPSort.cs @@ -0,0 +1,43 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPSort.cs + +Abstract: + + Z3 Managed API: Floating Point Sorts + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ + +using System; +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// A floating point sort + /// + public class FPSort : Sort + { + #region Internal + internal FPSort(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + internal FPSort(Context ctx, uint ebits, uint sbits) + : base(ctx, Native.Z3_mk_fpa_sort(ctx.nCtx, ebits, sbits)) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/src/api/dotnet/Microsoft.Z3.csproj b/src/api/dotnet/Microsoft.Z3.csproj index 9eb9eb660..083cd048f 100644 --- a/src/api/dotnet/Microsoft.Z3.csproj +++ b/src/api/dotnet/Microsoft.Z3.csproj @@ -341,6 +341,12 @@ + + + + + + @@ -399,4 +405,4 @@ --> - + \ No newline at end of file From a9840b291f2ce960910b7fec6209e74a8b02d665 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 10 Jun 2013 19:06:45 +0100 Subject: [PATCH 006/507] FPA API: Tied into rest of the API; added numeral/value handling through existing functions; added trivial .NET example. Signed-off-by: Christoph M. Wintersteiger --- examples/dotnet/Program.cs | 12 ++++++ src/api/api_ast.cpp | 6 +++ src/api/api_context.cpp | 2 + src/api/api_context.h | 5 +++ src/api/api_fpa.cpp | 78 ++++++++++++++++++------------------- src/api/api_numeral.cpp | 35 ++++++++++++++--- src/api/dotnet/Expr.cs | 8 +++- src/api/z3_api.h | 2 + src/ast/float_decl_plugin.h | 8 ++-- 9 files changed, 104 insertions(+), 52 deletions(-) diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index 2085de296..c75553e7b 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -2022,6 +2022,17 @@ namespace test_mapi // Console.WriteLine("{0}", ctx.MkEq(s1, t1)); } + public static void FloatingPointExample(Context ctx) + { + Console.WriteLine("FloatingPointExample"); + + FPSort s = ctx.MkFPSort(11, 53); + Console.WriteLine("Sort: {0}", s); + + FPNum n = (FPNum) ctx.MkNumeral("0.125", s); + Console.WriteLine("Numeral: {0}", n.ToString()); + } + static void Main(string[] args) { try @@ -2063,6 +2074,7 @@ namespace test_mapi FindSmallModelExample(ctx); SimplifierExample(ctx); FiniteDomainExample(ctx); + FloatingPointExample(ctx); } // These examples need proof generation turned on. diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 6855f6209..ccc2cbf88 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -647,6 +647,12 @@ extern "C" { else if (fid == mk_c(c)->get_datalog_fid() && k == datalog::DL_FINITE_SORT) { return Z3_FINITE_DOMAIN_SORT; } + else if (fid == mk_c(c)->get_fpa_fid() && k == FLOAT_SORT) { + return Z3_FLOATING_POINT_SORT; + } + else if (fid == mk_c(c)->get_fpa_fid() && k == ROUNDING_MODE_SORT) { + return Z3_FLOATING_POINT_ROUNDING_MODE_SORT; + } else { return Z3_UNKNOWN_SORT; } diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index cf179332a..f4314dcca 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -88,6 +88,7 @@ namespace api { m_arith_util(m()), m_bv_util(m()), m_datalog_util(m()), + m_float_util(m()), m_last_result(m()), m_ast_trail(m()), m_replay_stack() { @@ -112,6 +113,7 @@ namespace api { m_array_fid = m().mk_family_id("array"); m_dt_fid = m().mk_family_id("datatype"); m_datalog_fid = m().mk_family_id("datalog_relation"); + m_fpa_fid = m().mk_family_id("float"); m_dt_plugin = static_cast(m().get_plugin(m_dt_fid)); if (!m_user_ref_count) { diff --git a/src/api/api_context.h b/src/api/api_context.h index e0c95b07b..f409a4ece 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -27,6 +27,7 @@ Revision History: #include"bv_decl_plugin.h" #include"datatype_decl_plugin.h" #include"dl_decl_plugin.h" +#include"float_decl_plugin.h" #include"smt_kernel.h" #include"smt_params.h" #include"event_handler.h" @@ -56,6 +57,7 @@ namespace api { arith_util m_arith_util; bv_util m_bv_util; datalog::dl_decl_util m_datalog_util; + float_util m_float_util; // Support for old solver API smt_params m_fparams; @@ -75,6 +77,7 @@ namespace api { family_id m_bv_fid; family_id m_dt_fid; family_id m_datalog_fid; + family_id m_fpa_fid; datatype_decl_plugin * m_dt_plugin; std::string m_string_buffer; // temporary buffer used to cache strings sent to the "external" world. @@ -115,12 +118,14 @@ namespace api { arith_util & autil() { return m_arith_util; } bv_util & bvutil() { return m_bv_util; } datalog::dl_decl_util & datalog_util() { return m_datalog_util; } + float_util & float_util() { return m_float_util; } family_id get_basic_fid() const { return m_basic_fid; } family_id get_array_fid() const { return m_array_fid; } family_id get_arith_fid() const { return m_arith_fid; } family_id get_bv_fid() const { return m_bv_fid; } family_id get_dt_fid() const { return m_dt_fid; } family_id get_datalog_fid() const { return m_datalog_fid; } + family_id get_fpa_fid() const { return m_fpa_fid; } datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; } Z3_error_code get_error_code() const { return m_error_code; } diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index cfb5a2624..278a0556a 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -28,7 +28,7 @@ extern "C" { LOG_Z3_mk_fpa_rounding_mode_sort(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_sort r = of_sort(float_util(ctx->m()).mk_rm_sort()); + Z3_sort r = of_sort(ctx->float_util().mk_rm_sort()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -39,7 +39,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_round_nearest_ties_to_even()); + Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_even()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -50,7 +50,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_round_nearest_ties_to_away()); + Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_away()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -61,7 +61,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_round_toward_positive()); + Z3_ast r = of_ast(ctx->float_util().mk_round_toward_positive()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -72,7 +72,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_round_toward_negative()); + Z3_ast r = of_ast(ctx->float_util().mk_round_toward_negative()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -83,7 +83,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_round_toward_zero()); + Z3_ast r = of_ast(ctx->float_util().mk_round_toward_zero()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -95,9 +95,8 @@ extern "C" { if (ebits < 2 || sbits < 3) { SET_ERROR_CODE(Z3_INVALID_ARG); } - api::context * ctx = mk_c(c); - float_util fu(ctx->m()); - Z3_sort r = of_sort(fu.mk_float_sort(ebits, sbits)); + api::context * ctx = mk_c(c); + Z3_sort r = of_sort(ctx->float_util().mk_float_sort(ebits, sbits)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -107,7 +106,7 @@ extern "C" { LOG_Z3_mk_fpa_nan(c, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_nan(to_sort(s))); + Z3_ast r = of_ast(ctx->float_util().mk_nan(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -117,8 +116,7 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util fu(ctx->m()); - Z3_ast r = of_ast(negative != 0 ? fu.mk_minus_inf(to_sort(s)) : fu.mk_plus_inf(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->float_util().mk_minus_inf(to_sort(s)) : ctx->float_util().mk_plus_inf(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -128,10 +126,9 @@ extern "C" { LOG_Z3_mk_double(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util fu(ctx->m()); - mpf tmp; - fu.fm().set(tmp, fu.get_ebits(to_sort(ty)), fu.get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(fu.mk_value(tmp)); + scoped_mpf tmp(ctx->float_util().fm()); + ctx->float_util().fm().set(tmp, ctx->float_util().get_ebits(to_sort(ty)), ctx->float_util().get_sbits(to_sort(ty)), v); + Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -141,7 +138,7 @@ extern "C" { LOG_Z3_mk_fpa_abs(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_abs(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_abs(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -151,7 +148,7 @@ extern "C" { LOG_Z3_mk_fpa_neg(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_uminus(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_uminus(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -161,7 +158,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -171,7 +168,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -181,7 +178,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -191,7 +188,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -201,7 +198,7 @@ extern "C" { LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_fused_ma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); + Z3_ast r = of_ast(ctx->float_util().mk_fused_ma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -211,7 +208,7 @@ extern "C" { LOG_Z3_mk_fpa_sqrt(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_sqrt(to_expr(rm), to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_sqrt(to_expr(rm), to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -221,7 +218,7 @@ extern "C" { LOG_Z3_mk_fpa_rem(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_rem(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_rem(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -231,7 +228,7 @@ extern "C" { LOG_Z3_mk_fpa_eq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_float_eq(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_float_eq(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -241,7 +238,7 @@ extern "C" { LOG_Z3_mk_fpa_le(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_le(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_le(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -251,7 +248,7 @@ extern "C" { LOG_Z3_mk_fpa_lt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_lt(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_lt(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -261,7 +258,7 @@ extern "C" { LOG_Z3_mk_fpa_ge(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_ge(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_ge(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -271,7 +268,7 @@ extern "C" { LOG_Z3_mk_fpa_gt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_gt(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_gt(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -281,7 +278,7 @@ extern "C" { LOG_Z3_mk_fpa_is_normal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_is_normal(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_is_normal(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -291,7 +288,7 @@ extern "C" { LOG_Z3_mk_fpa_is_subnormal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_is_subnormal(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_is_subnormal(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -301,7 +298,7 @@ extern "C" { LOG_Z3_mk_fpa_is_zero(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_is_zero(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_is_zero(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -311,7 +308,7 @@ extern "C" { LOG_Z3_mk_fpa_is_inf(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_is_inf(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_is_inf(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -321,7 +318,7 @@ extern "C" { LOG_Z3_mk_fpa_is_nan(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_is_nan(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_is_nan(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -331,7 +328,7 @@ extern "C" { LOG_Z3_mk_fpa_min(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_min(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_min(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -341,7 +338,7 @@ extern "C" { LOG_Z3_mk_fpa_max(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_max(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_max(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -350,10 +347,9 @@ extern "C" { Z3_TRY; LOG_Z3_mk_fpa_convert(c, s, rm, t); RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); - float_util fu(ctx->m()); + api::context * ctx = mk_c(c); expr * args [2] = { to_expr(rm), to_expr(t) }; - Z3_ast r = of_ast(ctx->m().mk_app(fu.get_family_id(), OP_TO_FLOAT, + Z3_ast r = of_ast(ctx->m().mk_app(ctx->float_util().get_family_id(), OP_TO_FLOAT, to_sort(s)->get_num_parameters(), to_sort(s)->get_parameters(), 2, args)); RETURN_Z3(r); @@ -365,7 +361,7 @@ extern "C" { LOG_Z3_mk_fpa_to_ieee_bv(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(float_util(ctx->m()).mk_to_ieee_bv(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_to_ieee_bv(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index d4a6587bc..6924afff3 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -23,13 +23,15 @@ Revision History: #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" #include"algebraic_numbers.h" +#include"float_decl_plugin.h" bool is_numeral_sort(Z3_context c, Z3_sort ty) { sort * _ty = to_sort(ty); family_id fid = _ty->get_family_id(); if (fid != mk_c(c)->get_arith_fid() && fid != mk_c(c)->get_bv_fid() && - fid != mk_c(c)->get_datalog_fid()) { + fid != mk_c(c)->get_datalog_fid() && + fid != mk_c(c)->get_fpa_fid()) { return false; } return true; @@ -69,7 +71,19 @@ extern "C" { } ++m; } - ast * a = mk_c(c)->mk_numeral_core(rational(n), to_sort(ty)); + ast * a = 0; + sort * _ty = to_sort(ty); + if (_ty->get_family_id() == mk_c(c)->get_fpa_fid()) + { + // avoid expanding floats into huge rationals. + float_util & fu = mk_c(c)->float_util(); + scoped_mpf t(fu.fm()); + fu.fm().set(t, fu.get_ebits(_ty), fu.get_sbits(_ty), MPF_ROUND_TOWARD_ZERO, n); + a = fu.mk_value(t); + mk_c(c)->save_ast_trail(a); + } + else + a = mk_c(c)->mk_numeral_core(rational(n), _ty); RETURN_Z3(of_ast(a)); Z3_CATCH_RETURN(0); } @@ -131,7 +145,8 @@ extern "C" { expr* e = to_expr(a); return mk_c(c)->autil().is_numeral(e) || - mk_c(c)->bvutil().is_numeral(e); + mk_c(c)->bvutil().is_numeral(e) || + mk_c(c)->float_util().is_value(e); Z3_CATCH_RETURN(Z3_FALSE); } @@ -155,7 +170,7 @@ extern "C" { if (mk_c(c)->datalog_util().is_numeral(e, v)) { r = rational(v, rational::ui64()); return Z3_TRUE; - } + } return Z3_FALSE; Z3_CATCH_RETURN(Z3_FALSE); } @@ -172,8 +187,16 @@ extern "C" { return mk_c(c)->mk_external_string(r.to_string()); } else { - SET_ERROR_CODE(Z3_INVALID_ARG); - return ""; + // floats are separated from all others to avoid huge rationals. + float_util & fu = mk_c(c)->float_util(); + scoped_mpf tmp(fu.fm()); + if (mk_c(c)->float_util().is_numeral(to_expr(a), tmp)) { + return mk_c(c)->mk_external_string(fu.fm().to_string(tmp)); + } + else { + SET_ERROR_CODE(Z3_INVALID_ARG); + return ""; + } } Z3_CATCH_RETURN(""); } diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index b2927e2c3..367e62666 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1532,7 +1532,9 @@ namespace Microsoft.Z3 { case Z3_sort_kind.Z3_INT_SORT: return new IntNum(ctx, obj); case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); - case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); + case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); + case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); + case Z3_sort_kind.Z3_FLOATING_POINT_ROUNDING_MODE_SORT: return new FPRMNum(ctx, obj); } } @@ -1543,7 +1545,9 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_REAL_SORT: return new RealExpr(ctx, obj); case Z3_sort_kind.Z3_BV_SORT: return new BitVecExpr(ctx, obj); case Z3_sort_kind.Z3_ARRAY_SORT: return new ArrayExpr(ctx, obj); - case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); + case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); + case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPExpr(ctx, obj); + case Z3_sort_kind.Z3_FLOATING_POINT_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj); } return new Expr(ctx, obj); diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 6d59cf650..a761c89eb 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -194,6 +194,8 @@ typedef enum Z3_DATATYPE_SORT, Z3_RELATION_SORT, Z3_FINITE_DOMAIN_SORT, + Z3_FLOATING_POINT_SORT, + Z3_FLOATING_POINT_ROUNDING_MODE_SORT, Z3_UNKNOWN_SORT = 1000 } Z3_sort_kind; diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index deda7e045..0b8349793 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -201,9 +201,11 @@ public: app * mk_minus_inf(sort * s) { return mk_minus_inf(get_ebits(s), get_sbits(s)); } app * mk_value(mpf const & v) { return m_plugin->mk_value(v); } - bool is_value(expr * n) { return m_plugin->is_value(n); } - bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); } - bool is_rm(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm(n, v); } + bool is_value(expr * n) const { return m_plugin->is_value(n); } + bool is_numeral(expr * n) const { return is_value(n); } + bool is_value(expr * n, mpf & v) const { return m_plugin->is_value(n, v); } + bool is_numeral(expr * n, mpf & v) const { return is_value(n, v); } + bool is_rm(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm(n, v); } app * mk_pzero(unsigned ebits, unsigned sbits); app * mk_nzero(unsigned ebits, unsigned sbits); From cc5081587fd7025eff92fa9a41540668b86a9e7d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 14 Jun 2013 12:00:10 +0100 Subject: [PATCH 007/507] FPA API: made FPA functions public Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 1e9bd1323..452018ae4 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3532,7 +3532,7 @@ namespace Microsoft.Z3 /// Floating-point absolute value /// /// floating point term - FPExpr MkFPAbs(FPExpr t) + public FPExpr MkFPAbs(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_abs(this.nCtx, t.NativeObject)); @@ -3542,7 +3542,7 @@ namespace Microsoft.Z3 /// Floating-point negation /// /// floating point term - FPExpr MkFPNeg(FPExpr t) + public FPExpr MkFPNeg(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_neg(this.nCtx, t.NativeObject)); @@ -3554,7 +3554,7 @@ namespace Microsoft.Z3 /// rounding mode term /// floating point term /// floating point term - FPExpr MkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2) + public FPExpr MkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_add(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); @@ -3566,7 +3566,7 @@ namespace Microsoft.Z3 /// rounding mode term /// floating point term /// floating point term - FPExpr MkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2) + public FPExpr MkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_sub(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); @@ -3578,7 +3578,7 @@ namespace Microsoft.Z3 /// rounding mode term /// floating point term /// floating point term - FPExpr MkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2) + public FPExpr MkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_mul(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); @@ -3590,7 +3590,7 @@ namespace Microsoft.Z3 /// rounding mode term /// floating point term /// floating point term - FPExpr MkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2) + public FPExpr MkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_div(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject)); @@ -3606,7 +3606,7 @@ namespace Microsoft.Z3 /// floating point term /// floating point term /// floating point term - FPExpr MkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3) + public FPExpr MkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_fma(this.nCtx, rm.NativeObject, t1.NativeObject, t2.NativeObject, t3.NativeObject)); @@ -3616,7 +3616,7 @@ namespace Microsoft.Z3 /// Floating-point square root /// /// floating point term - FPExpr MkFPSqrt(FPRMExpr rm, FPExpr t) + public FPExpr MkFPSqrt(FPRMExpr rm, FPExpr t) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_sqrt(this.nCtx, rm.NativeObject, t.NativeObject)); @@ -3627,7 +3627,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - FPExpr MkFPRem(FPExpr t1, FPExpr t2) + public FPExpr MkFPRem(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_rem(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3641,7 +3641,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - BoolExpr MkFPEq(FPExpr t1, FPExpr t2) + public BoolExpr MkFPEq(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_eq(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3652,7 +3652,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - BoolExpr MkFPLe(FPExpr t1, FPExpr t2) + public BoolExpr MkFPLe(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_le(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3663,7 +3663,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - BoolExpr MkFPLt(FPExpr t1, FPExpr t2) + public BoolExpr MkFPLt(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_lt(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3674,7 +3674,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - BoolExpr MkFPGe(FPExpr t1, FPExpr t2) + public BoolExpr MkFPGe(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_ge(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3685,7 +3685,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - BoolExpr MkFPGt(FPExpr t1, FPExpr t2) + public BoolExpr MkFPGt(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_gt(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3695,7 +3695,7 @@ namespace Microsoft.Z3 /// Predicate indicating whether t is a normal floating point number /// /// floating point term - BoolExpr MkFPIsNormal(FPExpr t) + public BoolExpr MkFPIsNormal(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_normal(this.nCtx, t.NativeObject)); @@ -3705,7 +3705,7 @@ namespace Microsoft.Z3 /// Predicate indicating whether t is a subnormal floating point number /// /// floating point term - BoolExpr MkFPIsSubnormal(FPExpr t) + public BoolExpr MkFPIsSubnormal(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_subnormal(this.nCtx, t.NativeObject)); @@ -3715,7 +3715,7 @@ namespace Microsoft.Z3 /// Predicate indicating whether t is a floating point number with zero value, i.e., +0 or -0. /// /// floating point term - BoolExpr MkFPIsZero(FPExpr t) + public BoolExpr MkFPIsZero(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_zero(this.nCtx, t.NativeObject)); @@ -3725,7 +3725,7 @@ namespace Microsoft.Z3 /// Predicate indicating whether t is a floating point number representing +Inf or -Inf /// /// floating point term - BoolExpr MkFPIsInf(FPExpr t) + public BoolExpr MkFPIsInf(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_inf(this.nCtx, t.NativeObject)); @@ -3735,7 +3735,7 @@ namespace Microsoft.Z3 /// Predicate indicating whether t is a NaN /// /// floating point term - BoolExpr MkFPIsNaN(FPExpr t) + public BoolExpr MkFPIsNaN(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_nan(this.nCtx, t.NativeObject)); @@ -3746,7 +3746,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - FPExpr MkFPMin(FPExpr t1, FPExpr t2) + public FPExpr MkFPMin(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_min(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3757,7 +3757,7 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - FPExpr MkFPMax(FPExpr t1, FPExpr t2) + public FPExpr MkFPMax(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_max(this.nCtx, t1.NativeObject, t2.NativeObject)); @@ -3773,7 +3773,7 @@ namespace Microsoft.Z3 /// floating point sort /// floating point rounding mode term /// floating point term - FPExpr MkFPConvert(FPSort s, FPRMExpr rm, FPExpr t) + public FPExpr MkFPConvert(FPSort s, FPRMExpr rm, FPExpr t) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_convert(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); @@ -3786,7 +3786,7 @@ namespace Microsoft.Z3 /// The size of the resulting bit-vector is automatically determined. /// /// floating point term - FPExpr MkFPToIEEEBV(FPExpr t) + public FPExpr MkFPToIEEEBV(FPExpr t) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_to_ieee_bv(this.nCtx, t.NativeObject)); From 4af39b432cecc0fd3d3c1e4675154c4914ebad33 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 14 Jun 2013 12:25:43 +0100 Subject: [PATCH 008/507] FPA API: dotnet bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 452018ae4..7da54c5eb 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3499,7 +3499,7 @@ namespace Microsoft.Z3 /// /// A string representing the value in decimal notation. /// floating point sort. - public FPNum MkFPNaN(double v, FPSort s) + public FPNum MkFPNaN(FPSort s) { Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_nan(nCtx, s.NativeObject)); @@ -3511,7 +3511,7 @@ namespace Microsoft.Z3 /// A string representing the value in decimal notation. /// floating point sort. /// indicates whether the result should be negative. - public FPNum MkFPInf(double v, FPSort s, bool negative) + public FPNum MkFPInf(FPSort s, bool negative) { Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_inf(nCtx, s.NativeObject, negative ? 1 : 0)); From 165da842b7027e950d561363c23829aa74478896 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 14 Jun 2013 13:12:44 +0100 Subject: [PATCH 009/507] Numeral API: added floating-point numeral cases. Signed-off-by: Christoph M. Wintersteiger --- src/api/api_numeral.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 6924afff3..740fef2ac 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -58,6 +58,8 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); RETURN_Z3(0); } + sort * _ty = to_sort(ty); + bool is_float = mk_c(c)->float_util().is_float(_ty); std::string fixed_num; char const* m = n; while (*m) { @@ -65,14 +67,15 @@ extern "C" { ('/' == *m) || ('-' == *m) || (' ' == *m) || ('\n' == *m) || ('.' == *m) || ('e' == *m) || - ('E' == *m))) { + ('E' == *m) || + (('p' == *m) && is_float) || + (('P' == *m)) && is_float)) { SET_ERROR_CODE(Z3_PARSER_ERROR); return 0; } ++m; } - ast * a = 0; - sort * _ty = to_sort(ty); + ast * a = 0; if (_ty->get_family_id() == mk_c(c)->get_fpa_fid()) { // avoid expanding floats into huge rationals. From 8e497fbbaf06d179db93020d86c78e8479564aec Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 14 Jun 2013 13:13:14 +0100 Subject: [PATCH 010/507] Extended FPA dotnet example Signed-off-by: Christoph M. Wintersteiger --- examples/dotnet/Program.cs | 92 +++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index c75553e7b..2f9d24fb1 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -2029,8 +2029,46 @@ namespace test_mapi FPSort s = ctx.MkFPSort(11, 53); Console.WriteLine("Sort: {0}", s); - FPNum n = (FPNum) ctx.MkNumeral("0.125", s); - Console.WriteLine("Numeral: {0}", n.ToString()); + FPNum x = (FPNum)ctx.MkNumeral("-1e1", s); + Console.WriteLine("Numeral: {0}", x.ToString()); + + FPNum y = (FPNum)ctx.MkNumeral("-10", s); + Console.WriteLine("Numeral: {0}", y.ToString()); + + FPNum z = (FPNum)ctx.MkNumeral("-1.25p3", s); + Console.WriteLine("Numeral: {0}", z.ToString()); + + BoolExpr a = ctx.MkAnd(ctx.MkFPEq(x, y), ctx.MkFPEq(y, z)); + + Check(ctx, ctx.MkNot(a), Status.UNSATISFIABLE); + + x = ctx.MkFPNaN(s); + FPExpr c = (FPExpr)ctx.MkConst("y", s); + + // Note: We need to use a special solver for QF_FPA here; the + // general solver does not support FPA yet. + + Solver slvr = ctx.MkSolver("QF_FPA"); + slvr.Add(ctx.MkFPEq(x, c)); + if (slvr.Check() != Status.UNSATISFIABLE) // nothing is equal to NaN according to floating-point equality. + throw new TestFailedException(); + + slvr = ctx.MkSolver("QF_FPA"); + slvr.Add(ctx.MkEq(x, c)); // NaN is equal to NaN according to normal equality. + if (slvr.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + + + x = (FPNum)ctx.MkNumeral("-1e1", s); + y = (FPNum)ctx.MkNumeral("-10", s); + FPExpr q = (FPExpr)ctx.MkConst("q", s); + FPNum mh = (FPNum)ctx.MkNumeral("100", s); + slvr = ctx.MkSolver("QF_FPA"); + // Let's prove -1e1 * -10 == +100 + slvr.Add(ctx.MkEq(ctx.MkFPMul(ctx.MkFPRMNearestTiesToAway(), x, y), q)); + slvr.Add(ctx.MkNot(ctx.MkFPEq(q, mh))); + if (slvr.Check() != Status.UNSATISFIABLE) + throw new TestFailedException(); } static void Main(string[] args) @@ -2050,30 +2088,30 @@ namespace test_mapi // These examples need model generation turned on. using (Context ctx = new Context(new Dictionary() { { "model", "true" } })) { - BasicTests(ctx); - CastingTest(ctx); - SudokuExample(ctx); - QuantifierExample1(ctx); - QuantifierExample2(ctx); - LogicExample(ctx); - ParOrExample(ctx); - FindModelExample1(ctx); - FindModelExample2(ctx); - PushPopExample1(ctx); - ArrayExample1(ctx); - ArrayExample3(ctx); - BitvectorExample1(ctx); - BitvectorExample2(ctx); - ParserExample1(ctx); - ParserExample2(ctx); - ParserExample4(ctx); - ParserExample5(ctx); - ITEExample(ctx); - EvalExample1(ctx); - EvalExample2(ctx); - FindSmallModelExample(ctx); - SimplifierExample(ctx); - FiniteDomainExample(ctx); + //BasicTests(ctx); + //CastingTest(ctx); + //SudokuExample(ctx); + //QuantifierExample1(ctx); + //QuantifierExample2(ctx); + //LogicExample(ctx); + //ParOrExample(ctx); + //FindModelExample1(ctx); + //FindModelExample2(ctx); + //PushPopExample1(ctx); + //ArrayExample1(ctx); + //ArrayExample3(ctx); + //BitvectorExample1(ctx); + //BitvectorExample2(ctx); + //ParserExample1(ctx); + //ParserExample2(ctx); + //ParserExample4(ctx); + //ParserExample5(ctx); + //ITEExample(ctx); + //EvalExample1(ctx); + //EvalExample2(ctx); + //FindSmallModelExample(ctx); + //SimplifierExample(ctx); + //FiniteDomainExample(ctx); FloatingPointExample(ctx); } @@ -2099,7 +2137,7 @@ namespace test_mapi { QuantifierExample3(ctx); QuantifierExample4(ctx); - } + } Log.Close(); if (Log.isOpen()) From f50016d8a1ab69ad729182f4c0d01e07bae340d6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 14 Jun 2013 13:18:33 +0100 Subject: [PATCH 011/507] bugfix in .NET example Signed-off-by: Christoph M. Wintersteiger --- examples/dotnet/Program.cs | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index 2f9d24fb1..76624fa1c 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -2088,30 +2088,30 @@ namespace test_mapi // These examples need model generation turned on. using (Context ctx = new Context(new Dictionary() { { "model", "true" } })) { - //BasicTests(ctx); - //CastingTest(ctx); - //SudokuExample(ctx); - //QuantifierExample1(ctx); - //QuantifierExample2(ctx); - //LogicExample(ctx); - //ParOrExample(ctx); - //FindModelExample1(ctx); - //FindModelExample2(ctx); - //PushPopExample1(ctx); - //ArrayExample1(ctx); - //ArrayExample3(ctx); - //BitvectorExample1(ctx); - //BitvectorExample2(ctx); - //ParserExample1(ctx); - //ParserExample2(ctx); - //ParserExample4(ctx); - //ParserExample5(ctx); - //ITEExample(ctx); - //EvalExample1(ctx); - //EvalExample2(ctx); - //FindSmallModelExample(ctx); - //SimplifierExample(ctx); - //FiniteDomainExample(ctx); + BasicTests(ctx); + CastingTest(ctx); + SudokuExample(ctx); + QuantifierExample1(ctx); + QuantifierExample2(ctx); + LogicExample(ctx); + ParOrExample(ctx); + FindModelExample1(ctx); + FindModelExample2(ctx); + PushPopExample1(ctx); + ArrayExample1(ctx); + ArrayExample3(ctx); + BitvectorExample1(ctx); + BitvectorExample2(ctx); + ParserExample1(ctx); + ParserExample2(ctx); + ParserExample4(ctx); + ParserExample5(ctx); + ITEExample(ctx); + EvalExample1(ctx); + EvalExample2(ctx); + FindSmallModelExample(ctx); + SimplifierExample(ctx); + FiniteDomainExample(ctx); FloatingPointExample(ctx); } From fa9a9d13cf0d41fdbf409109999b9d31a574655a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Jun 2013 12:13:02 +0100 Subject: [PATCH 012/507] FPA: avoid compiler warnings Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/fpa2bv_converter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_converter.cpp b/src/tactic/fpa/fpa2bv_converter.cpp index 234c343b8..ff24d1ceb 100644 --- a/src/tactic/fpa/fpa2bv_converter.cpp +++ b/src/tactic/fpa/fpa2bv_converter.cpp @@ -2437,7 +2437,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & t = m_bv_util.mk_bv_sub(t, lz); t = m_bv_util.mk_bv_sub(t, m_bv_util.mk_sign_extend(2, e_min)); expr_ref TINY(m); - TINY = m_bv_util.mk_sle(t, m_bv_util.mk_numeral(-1, ebits+2)); + TINY = m_bv_util.mk_sle(t, m_bv_util.mk_numeral((unsigned)-1, ebits+2)); TRACE("fpa2bv_dbg", tout << "TINY = " << mk_ismt2_pp(TINY, m) << std::endl;); SASSERT(is_well_sorted(m, TINY)); @@ -2481,7 +2481,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & m_simp.mk_ite(sigma_le_cap, sigma_neg, sigma_cap, sigma_neg_capped); dbg_decouple("fpa2bv_rnd_sigma_neg", sigma_neg); dbg_decouple("fpa2bv_rnd_sigma_neg_capped", sigma_neg_capped); - sigma_lt_zero = m_bv_util.mk_sle(sigma, m_bv_util.mk_numeral(-1, sigma_size)); + sigma_lt_zero = m_bv_util.mk_sle(sigma, m_bv_util.mk_numeral((unsigned)-1, sigma_size)); dbg_decouple("fpa2bv_rnd_sigma_lt_zero", sigma_lt_zero); sig_ext = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, sig_size)); From 87c6fc66d60b7d1c0e571a920b7ec9f9a0e8001f Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 11 Feb 2014 17:44:59 +0000 Subject: [PATCH 013/507] sls tactic default --- src/tactic/portfolio/smt_strategic_solver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index ae79446e3..52b0a3c90 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -37,11 +37,13 @@ Notes: #include"horn_tactic.h" #include"smt_solver.h" +#include"sls_tactic.h" + tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") - return mk_qfbv_tactic(m, p); + return mk_qfbv_sls_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); else if (logic=="QF_LIA") From 25378f7989a5d4f38a40e104a3c9727fce3c7b0f Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 18 Feb 2014 14:01:47 +0000 Subject: [PATCH 014/507] some extensions/modifications. versions added. --- src/tactic/portfolio/default_tactic.cpp | 3 +- src/tactic/sls/sls_evaluator.h | 4 +- src/tactic/sls/sls_tactic.cpp | 146 ++++++++++++-- src/tactic/sls/sls_tracker.h | 249 +++++++++++++++++++++--- versions/z3-crsat-0.01.txt | 12 ++ versions/z3-gsat-0.01.txt | 10 + versions/z3-gsat-res-0.01.txt | 10 + versions/z3-wsat-0.01.txt | 12 ++ versions/z3-wsat-0.01b.txt | 12 ++ versions/z3-wsat-0.01c.txt | 12 ++ versions/z3-wsat-0.01d.txt | 11 ++ versions/z3-wsat-0.01e.txt | 11 ++ versions/z3-wsat-0.02.txt | 13 ++ versions/z3-wsat-res-0.01.txt | 13 ++ 14 files changed, 470 insertions(+), 48 deletions(-) create mode 100644 versions/z3-crsat-0.01.txt create mode 100644 versions/z3-gsat-0.01.txt create mode 100644 versions/z3-gsat-res-0.01.txt create mode 100644 versions/z3-wsat-0.01.txt create mode 100644 versions/z3-wsat-0.01b.txt create mode 100644 versions/z3-wsat-0.01c.txt create mode 100644 versions/z3-wsat-0.01d.txt create mode 100644 versions/z3-wsat-0.01e.txt create mode 100644 versions/z3-wsat-0.02.txt create mode 100644 versions/z3-wsat-res-0.01.txt diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 9ecc16ecf..b28b7bec0 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -28,10 +28,11 @@ Notes: #include"probe_arith.h" #include"quant_tactics.h" #include"qffpa_tactic.h" +#include"sls_tactic.h" tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 77ff50454..61305386e 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -584,8 +584,8 @@ public: run_update(cur_depth); } - void randomize_local(goal_ref const & g) { - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g); + void randomize_local(goal_ref const & g, unsigned int flip) { + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); // Randomize _all_ candidates: diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index ea5d60668..c84e68730 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -35,6 +35,17 @@ Notes: #include"sls_tactic.h" #include"nnf_tactic.h" +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 30 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 +#define _VNS_ 0 +#define _WEIGHT_DIST_ 3 +#define _WEIGHT_DIST_FACTOR_ 0.1 + #include"sls_params.hpp" #include"sls_evaluator.h" #include"sls_tracker.h" @@ -257,7 +268,7 @@ class sls_tactic : public tactic { // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g); + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; @@ -303,6 +314,82 @@ class sls_tactic : public tactic { m_mpz_manager.del(new_value); } + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -372,22 +459,29 @@ class sls_tactic : public tactic { unsigned plateau_cnt = 0; - while (plateau_cnt < m_plateau_limit) { - + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif do { checkpoint(); old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); - +#endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; for (unsigned i = 0; i < g->size(); i++) { @@ -400,9 +494,11 @@ class sls_tactic : public tactic { for (unsigned i = 0; i < g->size(); i++) tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << m_tracker.get_score(g->form(i)) << std::endl; ); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } else { + // Andreas: Why does randomizing not count as a move? (Now it does.) m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -441,6 +537,7 @@ class sls_tactic : public tactic { if (score >= 1.0) { // score could theoretically be imprecise. + // Andreas: Can it only be imprecise in one direction? bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -451,19 +548,30 @@ class sls_tactic : public tactic { } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ } while (score > old_score && res == l_undef); - - if (score != old_score) + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); plateau_cnt = 0; - else { + } else { + m_stats.m_moves++; plateau_cnt++; - if (plateau_cnt < m_plateau_limit) { + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); - m_evaluator.randomize_local(g); + m_evaluator.randomize_local(g, m_stats.m_moves); //mk_random_move(g); score = top_score(g); - } + //} } } @@ -484,7 +592,8 @@ class sls_tactic : public tactic { do { checkpoint(); - if ((m_stats.m_restarts % 100) == 0) + // Andreas: I think restarts are too impotant to ignore 99% of them are happening... + //if ((m_stats.m_restarts % 100) == 0) report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); res = search(g); @@ -492,9 +601,12 @@ class sls_tactic : public tactic { if (res == l_undef) m_tracker.randomize(); } - while (res != l_true && m_stats.m_restarts++ < m_max_restarts); + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - if (res == l_true) { + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -633,7 +745,13 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), +#if _CNF_ + // Andreas: We will probably never use this. CNF sucks. + mk_cnf_tactic(m, p)); +#else + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); +#endif } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 7fbafec60..1061bd90e 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -28,8 +28,8 @@ class sls_tracker { random_gen m_rng; unsigned m_random_bits; unsigned m_random_bits_cnt; - mpz m_zero, m_one, m_two; - + mpz m_zero, m_one, m_two; + struct value_score { value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0) { }; ~value_score() { if (m) m->del(value); } @@ -249,12 +249,46 @@ public: } } - void initialize(goal_ref const & g) { + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } + + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; + m_constants_occ.insert_if_not_there(e, t); + find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); + expr_fast_mark1 visited; + quick_for_each_expr(ffd_proc, visited, e); + } + + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); + // Andreas: Maybe not fully correct. +#if _FOCUS_ == 2 + initialize_recursive(proc, visited, e); +#endif for_each_expr(proc, visited, e); } @@ -262,6 +296,10 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); + // Andreas: Maybe not fully correct. +#if _FOCUS_ == 2 + initialize_recursive(e); +#endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -382,8 +420,6 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); } -#define _SCORE_AND_MIN - double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); @@ -400,30 +436,41 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - #ifdef _SCORE_AND_MIN - double min = 1.0; + // Andreas: Seems to have no effect. Probably it does not even occur. +#if _SCORE_AND_AVG_ + double sum = 0.0; + for (unsigned i = 0; i < a->get_num_args(); i++) + sum += get_score(args[i]); + res = sum / (double) a->get_num_args(); +#else + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; } res = min; - #else - double sum = 0.0; - for (unsigned i = 0; i < a->get_num_args(); i++) - sum += get_score(args[i]); - res = sum / (double) a->get_num_args(); - #endif +#endif } else if (m_manager.is_or(n)) { SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - double max = 0.0; + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. +#if _SCORE_OR_MUL_ + double inv = 1.0; + for (unsigned i = 0; i < a->get_num_args(); i++) { + double cur = get_score(args[i]); + inv *= (1.0 - get_score(args[i])); + } + res = 1.0 - inv; +#else + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur > max) max = cur; } res = max; +#endif } else if (m_manager.is_ite(n)) { SASSERT(!negated); @@ -468,7 +515,7 @@ public: } m_mpz_manager.machine_div(diff, m_two, diff); } - res = 1.0 - (hamming_distance / (double) bv_sz); + res = 1.0 - (hamming_distance / (double) bv_sz); #else rational r(diff); r /= m_powers(bv_sz); @@ -503,7 +550,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -564,7 +611,7 @@ public: TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -598,6 +645,20 @@ public: SASSERT(res >= 0.0 && res <= 1.0); +#if _WEIGHT_DIST_ + app * a = to_app(n); + family_id afid = a->get_family_id(); + if (afid == m_bv_util.get_family_id()) +#endif +#if _WEIGHT_DIST_ == 1 + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#elif _WEIGHT_DIST_ == 2 + res *= res; +#elif _WEIGHT_DIST_ == 3 + if (res < 1.0) res = 0.0; +#endif + + TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } @@ -647,7 +708,111 @@ public: NOT_IMPLEMENTED_YET(); } - ptr_vector & get_unsat_constants(goal_ref const & g) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + for (unsigned i = 0; i < sz; i++) { + expr * q = g->form(i); + if (m_mpz_manager.eq(get_value(q), m_one)) + continue; + ptr_vector const & this_decls = m_constants_occ.find(q); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + } + return m_temp_constants; + } + + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } + + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); + // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. + if (!q) + return m_temp_constants; + + ptr_vector const & this_decls = m_constants_occ.find(q); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); + if (!q) + return m_temp_constants; + + return go_deeper(q); + } + + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { @@ -655,19 +820,41 @@ public: } else { m_temp_constants.reset(); - for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); - if (m_mpz_manager.eq(get_value(q), m_one)) - continue; - ptr_vector const & this_decls = m_constants_occ.find(q); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } +#if _FOCUS_ == 1 +#if _BFS_ == 3 + unsigned int pos = 0; + double max = get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - return m_temp_constants; +#elif _BFS_ == 2 + unsigned int pos = 0; + double min = get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + } +#elif _BFS_ == 1 + unsigned int pos = flip % m_constants.size(); +#else + unsigned int pos = get_random_uint(16) % m_constants.size(); +#endif + return get_unsat_constants_walksat(g, sz, pos); +#elif _FOCUS_ == 2 +#if _BFS_ + unsigned int pos = flip % m_constants.size(); +#else + unsigned int pos = get_random_uint(16) % m_constants.size(); +#endif + return get_unsat_constants_crsat(g, sz, pos); +#else + return get_unsat_constants_gsat(g, sz); +#endif } } }; diff --git a/versions/z3-crsat-0.01.txt b/versions/z3-crsat-0.01.txt new file mode 100644 index 000000000..49e1a1525 --- /dev/null +++ b/versions/z3-crsat-0.01.txt @@ -0,0 +1,12 @@ +More focused (_FOCUS_ == 2) WalkSAT version. +Variables are chosen among candidates in only one unsatisfied bit-vector term. +Flip rate slightly slower; probably due to larger hash-table and recursive formula structure. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 3 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-gsat-0.01.txt b/versions/z3-gsat-0.01.txt new file mode 100644 index 000000000..eb806a67f --- /dev/null +++ b/versions/z3-gsat-0.01.txt @@ -0,0 +1,10 @@ +Basic GSAT version. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 0 +#define _FOCUS_ 0 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-gsat-res-0.01.txt b/versions/z3-gsat-res-0.01.txt new file mode 100644 index 000000000..6a211f2bc --- /dev/null +++ b/versions/z3-gsat-res-0.01.txt @@ -0,0 +1,10 @@ +Basic GSAT version corresponding to Christoph's original code. +Restarts after 100 plateaus. + +#define _CNF_ 0 +#define _BFS_ 0 +#define _FOCUS_ 0 +#define _RESTARTS_ 1 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt new file mode 100644 index 000000000..141193f76 --- /dev/null +++ b/versions/z3-wsat-0.01.txt @@ -0,0 +1,12 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Flip rate increased by roughly 10%-300%. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt new file mode 100644 index 000000000..2c0c0e7ad --- /dev/null +++ b/versions/z3-wsat-0.01b.txt @@ -0,0 +1,12 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Chooses a random top level assertion instead of using a BFS approach (_BFS_ == 0). +No restarts. + +#define _CNF_ 0 +#define _BFS_ 0 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01c.txt b/versions/z3-wsat-0.01c.txt new file mode 100644 index 000000000..223560e08 --- /dev/null +++ b/versions/z3-wsat-0.01c.txt @@ -0,0 +1,12 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +AND is scored by average; OR is scored by inverse multiplication. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 1 +#define _SCORE_OR_MUL_ 1 \ No newline at end of file diff --git a/versions/z3-wsat-0.01d.txt b/versions/z3-wsat-0.01d.txt new file mode 100644 index 000000000..072191370 --- /dev/null +++ b/versions/z3-wsat-0.01d.txt @@ -0,0 +1,11 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion with MINIMAL top_score. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 2 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01e.txt b/versions/z3-wsat-0.01e.txt new file mode 100644 index 000000000..b018c5e0d --- /dev/null +++ b/versions/z3-wsat-0.01e.txt @@ -0,0 +1,11 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion with MAXIMAL top_score. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 3 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.02.txt b/versions/z3-wsat-0.02.txt new file mode 100644 index 000000000..34dcb157c --- /dev/null +++ b/versions/z3-wsat-0.02.txt @@ -0,0 +1,13 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Score function reduced to 0/1. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 +#define _WEIGHTED_DIST_ 1 \ No newline at end of file diff --git a/versions/z3-wsat-res-0.01.txt b/versions/z3-wsat-res-0.01.txt new file mode 100644 index 000000000..575180a59 --- /dev/null +++ b/versions/z3-wsat-res-0.01.txt @@ -0,0 +1,13 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Flip rate increased by roughly 10%-300% compared to GSAT. +Restarts after 100 plateaus. +Fps slightly decreased due to restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 1 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file From 853ce522ccda06788da56198d9c3808df4a6cd73 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Sun, 9 Mar 2014 15:42:51 +0000 Subject: [PATCH 015/507] plenty of new stuff --- src/sat/tactic/sat_tactic.cpp | 4 +- src/tactic/portfolio/default_tactic.cpp | 1 + src/tactic/portfolio/smt_strategic_solver.cpp | 1 + src/tactic/sls/sls_evaluator.h | 323 ++++++++- src/tactic/sls/sls_tactic.cpp | 661 ++++++++++++++++-- src/tactic/sls/sls_tracker.h | 345 ++++++++- versions/z3-wsat-0.01.txt | 4 +- versions/z3-wsat-0.01b.txt | 4 +- 8 files changed, 1235 insertions(+), 108 deletions(-) diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index d48994861..717bf7007 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -66,7 +66,9 @@ class sat_tactic : public tactic { CASSERT("sat_solver", m_solver.check_invariant()); IF_VERBOSE(TACTIC_VERBOSITY_LVL, m_solver.display_status(verbose_stream());); TRACE("sat_dimacs", m_solver.display_dimacs(tout);); - + //m_solver.display_dimacs(std::cerr); + //exit(0); + lbool r = m_solver.check(); if (r == l_false) { g->assert_expr(m.mk_false(), 0, 0); diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index b28b7bec0..53da9a159 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -33,6 +33,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), + // cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index 52b0a3c90..f63b4fd8c 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -43,6 +43,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") + // return mk_qfbv_tactic(m, p); return mk_qfbv_sls_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 61305386e..eec9524a9 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -34,6 +34,9 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; +#if _EARLY_PRUNE_ + vector > m_traversal_stack_bool; +#endif public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -519,11 +522,15 @@ public: } } - void run_update(unsigned cur_depth) { + void run_serious_update(unsigned cur_depth) { // precondition: m_traversal_stack contains the entry point(s) expr_fast_mark1 visited; mpz new_value; +#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ + double new_score; +#endif + SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -533,8 +540,92 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - m_tracker.set_score(cur, m_tracker.score(cur)); +#if _REAL_RS_ || _REAL_PBFS_ + if (!m_tracker.has_uplinks(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } +#endif + +#if _EARLY_PRUNE_ + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); +#else +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif +#endif + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack[next_d].push_back(next); + visited.mark(next); + } + } + } + } + + cur_depth_exprs.reset(); + cur_depth--; + } + + m_mpz_manager.del(new_value); + } + + void run_update(unsigned cur_depth) { + // precondition: m_traversal_stack contains the entry point(s) + expr_fast_mark1 visited; + mpz new_value; + +#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ + double new_score; +#endif + + SASSERT(cur_depth < m_traversal_stack.size()); + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + (*this)(to_app(cur), new_value); + m_tracker.set_value(cur, new_value); +#if _EARLY_PRUNE_ + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); +#else +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -569,8 +660,11 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } - +#if _REAL_RS_ || _REAL_PBFS_ + run_serious_update(max_depth); +#else run_update(max_depth); +#endif } void update(func_decl * fd, const mpz & new_value) { @@ -584,6 +678,196 @@ public: run_update(cur_depth); } + void serious_update(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + m_traversal_stack[cur_depth].push_back(ep); + + run_serious_update(cur_depth); + } + +#if _EARLY_PRUNE_ + unsigned run_update_bool_prune(unsigned cur_depth) { + expr_fast_mark1 visited; + + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); + + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + prune_score = m_tracker.get_score_prune(cur); + m_tracker.set_score(cur, new_score); + + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; + + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + else + { + } + } + + cur_depth_exprs.reset(); + cur_depth--; + + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; + +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } + + return pot_benefits; + } + + void run_update_prune(unsigned max_depth) { + // precondition: m_traversal_stack contains the entry point(s) + expr_fast_mark1 visited; + mpz new_value; + + unsigned cur_depth = max_depth; + SASSERT(cur_depth < m_traversal_stack.size()); + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + (*this)(to_app(cur), new_value); + m_tracker.set_value(cur, new_value); + // should always have uplinks ... + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); + visited.mark(next); + } + } + } + } + + cur_depth_exprs.reset(); + cur_depth--; + } + + m_mpz_manager.del(new_value); + } + + unsigned update_prune(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + + if (m_traversal_stack_bool.size() <= cur_depth) + m_traversal_stack_bool.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); + } +#endif + + void randomize_local(expr * e, unsigned int flip) { + ptr_vector & unsat_constants = m_tracker.get_constants(e); + + // Randomize _one_ candidate: + unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); + func_decl * fd = unsat_constants[r]; +#if _PERC_CHANGE_ + sort * srt = fd->get_range(); + mpz temp; + + if (m_manager.is_bool(srt)) + m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); + + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } +#else + mpz temp = m_tracker.get_random(fd->get_range()); +#endif + update(fd, temp); + m_mpz_manager.del(temp); + } + void randomize_local(goal_ref const & g, unsigned int flip) { ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); @@ -603,8 +887,37 @@ public: // Randomize _one_ candidate: unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); func_decl * fd = unsat_constants[r]; - mpz temp = m_tracker.get_random(fd->get_range()); - update(fd, temp); +#if _PERC_CHANGE_ + sort * srt = fd->get_range(); + mpz temp; + + if (m_manager.is_bool(srt)) + m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); + + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } +#else + mpz temp = m_tracker.get_random(fd->get_range()); +#endif + +#if _REAL_RS_ || _REAL_PBFS_ + serious_update(fd, temp); +#else + update(fd, temp); +#endif m_mpz_manager.del(temp); TRACE("sls", /*tout << "Randomization candidates: "; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index c84e68730..3d5e3e438 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -35,16 +35,102 @@ Notes: #include"sls_tactic.h" #include"nnf_tactic.h" -#define _CNF_ 0 -#define _BFS_ 1 +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom #define _FOCUS_ 1 + +// do we use restarts? +// 0 = no, otherwise the value defines the maximum number of moves #define _RESTARTS_ 0 -#define _TIMELIMIT_ 30 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? #define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? #define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained #define _VNS_ 0 -#define _WEIGHT_DIST_ 3 -#define _WEIGHT_DIST_FACTOR_ 0.1 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 0 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.25 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 0 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 0.01 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +#define _PROBABILISTIC_UCT_ 0 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 1 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 1 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 1 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 1 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) + InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) + InvalidConfiguration; +#endif + #include"sls_params.hpp" #include"sls_evaluator.h" @@ -57,12 +143,17 @@ class sls_tactic : public tactic { stopwatch m_stopwatch; unsigned m_full_evals; unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + stats() : m_restarts(0), m_full_evals(0), m_incr_evals(0), m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -92,7 +183,9 @@ class sls_tactic : public tactic { unsigned m_max_restarts; unsigned m_plateau_limit; - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : m_manager(m), @@ -174,13 +267,20 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - top_sum += m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + return top_sum / (double) sz; #endif } @@ -191,22 +291,54 @@ class sls_tactic : public tactic { return top_score(g); } - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else return top_score(g); +#endif } + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; + } +#endif + + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { - + #ifdef Z3DEBUG mpz old_value; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else double r = incremental_score(g, fd, temp); - +#endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl; ); @@ -214,6 +346,22 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); #endif +// if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // same as what_if, but only applied to the score of a specific atom, not the total score + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -224,7 +372,35 @@ class sls_tactic : public tactic { return false; } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + + } + + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + } + + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); + } + + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -261,59 +437,73 @@ class sls_tactic : public tactic { void mk_random_move(goal_ref const & g) { unsigned rnd_mv = 0; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + if (m_stats.m_moves > 10000) + rnd_mv = 0; ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; - unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(fd->get_range()); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + mpz new_value; - m_evaluator.update(fd, new_value); + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; - m_mpz_manager.del(new_value); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } + + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -359,6 +549,7 @@ class sls_tactic : public tactic { SASSERT(check == score); } + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else @@ -390,9 +581,13 @@ class sls_tactic : public tactic { return new_score; } + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif unsigned bv_sz; double new_score = score; @@ -403,8 +598,12 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // first try to flip every bit - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { - // What would happen if we flipped bit #i ? +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -414,7 +613,8 @@ class sls_tactic : public tactic { } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -426,16 +626,99 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } - +#endif // try inverting mk_inv(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif } // reset to what it was before double check = incremental_score(g, fd, old_value); - SASSERT(check == score); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; + } + + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -443,7 +726,150 @@ class sls_tactic : public tactic { return new_score; } - lbool search(goal_ref const & g) { + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + + m_old_values.reset(); + + return 0; + } + + // what_if version needed in the context of 2nd intensification try, combining local and global score + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // find_best_move version needed in the context of 2nd intensification try + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) + { + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; + } + + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; + } + + // main search loop + lbool search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -463,16 +889,48 @@ class sls_tactic : public tactic { #if _RESTARTS_ while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { + if (m_stats.m_moves == 5590) checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif old_score = score; new_const = (unsigned)-1; ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -525,9 +983,17 @@ class sls_tactic : public tactic { case MV_INC: m_stats.m_incs++; break; case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - score = incremental_score(g, fd, new_value); +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif TRACE("sls", tout << "Score distribution:"; for (unsigned i = 0; i < g->size(); i++) @@ -535,9 +1001,10 @@ class sls_tactic : public tactic { tout << " TOP: " << score << std::endl; ); } - if (score >= 1.0) { + if (score >= 0.99999) { +// if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: Can it only be imprecise in one direction? + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -568,10 +1035,26 @@ class sls_tactic : public tactic { // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else m_evaluator.randomize_local(g, m_stats.m_moves); - //mk_random_move(g); +#endif + //mk_random_move(g); score = top_score(g); - //} + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } } } @@ -587,6 +1070,37 @@ class sls_tactic : public tactic { return; } + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif m_tracker.initialize(g); lbool res = l_undef; @@ -745,13 +1259,8 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), -#if _CNF_ - // Andreas: We will probably never use this. CNF sucks. - mk_cnf_tactic(m, p)); -#else // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); -#endif } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 1061bd90e..b26912e5c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -28,21 +28,32 @@ class sls_tracker { random_gen m_rng; unsigned m_random_bits; unsigned m_random_bits_cnt; - mpz m_zero, m_one, m_two; + mpz m_zero, m_one, m_two; struct value_score { - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0) { }; +#if _EARLY_PRUNE_ + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; +#else + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; +#endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; +#if _EARLY_PRUNE_ + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; +#endif unsigned distance; // max distance from any root + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; + touched = other.touched; return *this; } }; @@ -60,6 +71,20 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; +#if _UCT_ + unsigned m_touched; +#endif +#if _REAL_RS_ || _REAL_PBFS_ + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; +#endif +#if _CACHE_TOP_SCORE_ + double m_top_sum; +#endif +#if _WEIGHT_DIST_ == 4 + double m_weight_dist_factor; +#endif public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -79,6 +104,26 @@ public: m_mpz_manager.del(m_two); } +#if _WEIGHT_DIST_ == 4 + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } +#endif + +#if _CACHE_TOP_SCORE_ + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } + + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } + + inline double get_top_sum() { + return m_top_sum; + } +#endif + inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); m_mpz_manager.set(m_scores.find(n).value, r); @@ -123,6 +168,28 @@ public: return get_score(ep); } +#if _EARLY_PRUNE_ + inline void set_score_prune(expr * n, double score) { + SASSERT(m_scores.contains(n)); + m_scores.find(n).score_prune = score; + } + + inline double & get_score_prune(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).score_prune; + } + + inline unsigned has_pos_occ(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).has_pos_occ; + } + + inline unsigned has_neg_occ(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).has_neg_occ; + } +#endif + inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).distance; @@ -297,7 +364,7 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 +#if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); #endif ptr_vector t; @@ -310,8 +377,57 @@ public: calculate_expr_distances(g); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); + +#if _REAL_RS_ || _REAL_PBFS_ + m_list_false = new expr*[sz]; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + break_assertion(g->form(i)); +#endif + +#if _EARLY_PRUNE_ + for (unsigned i = 0; i < sz; i++) + setup_occs(g->form(i)); +#endif + +#if _UCT_ + m_touched = 1; +#endif } +#if _REAL_RS_ || _REAL_PBFS_ + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } +// printf("Going in %d\n", m_where_false.size()); + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } + + void break_assertion(expr * e) + { + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } +#endif + void show_model(std::ostream & out) { unsigned sz = get_num_constants(); for (unsigned i = 0; i < sz; i++) { @@ -420,10 +536,45 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); } +#if _EARLY_PRUNE_ + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } + else + NOT_IMPLEMENTED_YET(); + } +#endif + double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -488,7 +639,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -648,6 +799,7 @@ public: #if _WEIGHT_DIST_ app * a = to_app(n); family_id afid = a->get_family_id(); + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 @@ -656,13 +808,14 @@ public: res *= res; #elif _WEIGHT_DIST_ == 3 if (res < 1.0) res = 0.0; +#elif _WEIGHT_DIST_ == 4 + if (res < 1.0) res *= m_weight_dist_factor; #endif - TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -708,6 +861,44 @@ public: NOT_IMPLEMENTED_YET(); } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } + + ptr_vector & get_constants(expr * e) { + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz = this_decls.size(); + for (unsigned i = 0; i < sz; i++) { + func_decl * fd = this_decls[i]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); @@ -743,7 +934,6 @@ public: // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { @@ -754,6 +944,19 @@ public: return m_temp_constants; } + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz = this_decls.size(); + for (unsigned j = 0; j < sz; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + ptr_vector & go_deeper(expr * e) { if (m_manager.is_bool(e)) { if (m_manager.is_and(e)) { @@ -812,44 +1015,138 @@ public: return go_deeper(q); } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 -#if _BFS_ == 3 - unsigned int pos = 0; - double max = get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { +#if _UCT_ + unsigned pos = -1; + value_score vscore; +#if _PROBABILISTIC_UCT_ + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + } +#endif + if (pos == static_cast(-1)) + return m_temp_constants; + +#if _UCT_ == 1 + m_scores.find(g->form(pos)).touched++; + m_touched++; +#elif _UCT_ == 2 + m_scores.find(g->form(pos)).touched = flip; +#endif + expr * e = g->form(pos); + +#elif _BFS_ == 3 + unsigned int pos = -1; + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); double q = get_score(e); if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = 0; - double min = get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { + unsigned int pos = -1; + double min = 2.0; + for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); double q = get_score(e); if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - unsigned int pos = flip % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); +#elif _UNIFORM_RANDOM_ + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); +#elif _REAL_RS_ + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[get_random_uint(16) % sz]; +#elif _REAL_PBFS_ + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - unsigned int pos = get_random_uint(16) % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(g, sz, pos); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - unsigned int pos = flip % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - unsigned int pos = get_random_uint(16) % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif return get_unsat_constants_crsat(g, sz, pos); #else diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt index 141193f76..fec38518d 100644 --- a/versions/z3-wsat-0.01.txt +++ b/versions/z3-wsat-0.01.txt @@ -9,4 +9,6 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file +#define _SCORE_OR_MUL_ 0 + +BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt index 2c0c0e7ad..8bcf2ffeb 100644 --- a/versions/z3-wsat-0.01b.txt +++ b/versions/z3-wsat-0.01b.txt @@ -9,4 +9,6 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file +#define _SCORE_OR_MUL_ 0 + +BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file From 5aa352fd16170df754cc8155e3b930cb452211b0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 09:40:01 +0000 Subject: [PATCH 016/507] removed tabs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_evaluator.h | 268 ++++++------- src/tactic/sls/sls_tactic.cpp | 572 ++++++++++++++-------------- src/tactic/sls/sls_tracker.h | 672 ++++++++++++++++----------------- 3 files changed, 756 insertions(+), 756 deletions(-) diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index eec9524a9..cdb08038f 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -528,7 +528,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -542,33 +542,33 @@ public: m_tracker.set_value(cur, new_value); #if _REAL_RS_ || _REAL_PBFS_ - if (!m_tracker.has_uplinks(cur)) - { - if (m_mpz_manager.eq(new_value,m_one)) - m_tracker.make_assertion(cur); - else - m_tracker.break_assertion(cur); - } + if (!m_tracker.has_uplinks(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } #endif #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -596,7 +596,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -609,23 +609,23 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -661,7 +661,7 @@ public: if (cur_depth > max_depth) max_depth = cur_depth; } #if _REAL_RS_ || _REAL_PBFS_ - run_serious_update(max_depth); + run_serious_update(max_depth); #else run_update(max_depth); #endif @@ -693,27 +693,27 @@ public: unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { expr * cur = cur_depth_exprs[i]; - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - prune_score = m_tracker.get_score_prune(cur); + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); - if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -722,54 +722,54 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); + m_traversal_stack_bool[next_d].push_back(next); visited.mark(next); } } } - else - { - } - } + else + { + } + } - cur_depth_exprs.reset(); + cur_depth_exprs.reset(); cur_depth--; - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } - return pot_benefits; + return pot_benefits; } void run_update_prune(unsigned max_depth) { @@ -777,7 +777,7 @@ public: expr_fast_mark1 visited; mpz new_value; - unsigned cur_depth = max_depth; + unsigned cur_depth = max_depth; SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -787,7 +787,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // should always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -795,10 +795,10 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - if (m_manager.is_bool(next)) - m_traversal_stack_bool[max_depth].push_back(next); - else - m_traversal_stack[next_d].push_back(next); + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); visited.mark(next); } } @@ -817,23 +817,23 @@ public: expr * ep = m_tracker.get_entry_point(fd); unsigned cur_depth = m_tracker.get_distance(ep); - if (m_traversal_stack_bool.size() <= cur_depth) + if (m_traversal_stack_bool.size() <= cur_depth) m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune(cur_depth); + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); } #endif - void randomize_local(expr * e, unsigned int flip) { + void randomize_local(expr * e, unsigned int flip) { ptr_vector & unsat_constants = m_tracker.get_constants(e); // Randomize _one_ candidate: @@ -841,30 +841,30 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif - update(fd, temp); + update(fd, temp); m_mpz_manager.del(temp); } @@ -889,34 +889,34 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif #if _REAL_RS_ || _REAL_PBFS_ - serious_update(fd, temp); + serious_update(fd, temp); #else - update(fd, temp); + update(fd, temp); #endif m_mpz_manager.del(temp); diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 3d5e3e438..fe871cefa 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -125,10 +125,10 @@ Notes: #if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) - InvalidConfiguration; + InvalidConfiguration; #endif #if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; + InvalidConfiguration; #endif @@ -150,10 +150,10 @@ class sls_tactic : public tactic { m_full_evals(0), m_incr_evals(0), m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -183,8 +183,8 @@ class sls_tactic : public tactic { unsigned m_max_restarts; unsigned m_plateau_limit; - ptr_vector m_old_values; - + ptr_vector m_old_values; + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : @@ -267,18 +267,18 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); #if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); + m_tracker.set_top_sum(top_sum); #endif return top_sum / (double) sz; @@ -292,20 +292,20 @@ class sls_tactic : public tactic { } double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif } double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif @@ -314,18 +314,18 @@ class sls_tactic : public tactic { #if _EARLY_PRUNE_ double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) + if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(g); + return top_score(g); #endif - else - return 0.0; + else + return 0.0; } #endif - // checks whether the score outcome of a given move is better than the previous score + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { @@ -357,11 +357,11 @@ class sls_tactic : public tactic { return false; } - // same as what_if, but only applied to the score of a specific atom, not the total score + // same as what_if, but only applied to the score of a specific atom, not the total score bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -378,29 +378,29 @@ class sls_tactic : public tactic { m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); - } + } - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { mpz temp, mask, mask2; m_mpz_manager.mul(old_value, m_two, temp); m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); } void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { m_mpz_manager.div(old_value, m_two, result); } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -437,73 +437,73 @@ class sls_tactic : public tactic { void mk_random_move(goal_ref const & g) { unsigned rnd_mv = 0; - if (m_stats.m_moves > 10000) - rnd_mv = 0; + if (m_stats.m_moves > 10000) + rnd_mv = 0; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; + mpz new_value; - sort * srt = fd->get_range(); + sort * srt = fd->get_range(); if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { #if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + mt = MV_FLIP; #endif - unsigned bit = 0; + unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } - // will use VNS to ignore some possible moves and increase the flips per second + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -514,7 +514,7 @@ class sls_tactic : public tactic { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -536,12 +536,12 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } } // reset to what it was before @@ -549,12 +549,12 @@ class sls_tactic : public tactic { SASSERT(check == score); } - // we can either check the condition once in the beginning or check it repeatedly after every bit + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) #endif for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { func_decl * fd = to_evaluate[i]; @@ -563,30 +563,30 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } // reset to what it was before double check = incremental_score(g, fd, old_value); SASSERT(check == score); } - m_mpz_manager.del(old_value); + m_mpz_manager.del(old_value); m_mpz_manager.del(temp); return new_score; } - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; + mpz temp2; #endif unsigned bv_sz; double new_score = score; @@ -599,11 +599,11 @@ class sls_tactic : public tactic { // first try to flip every bit #if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { #else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { #endif - // What would happen if we flipped bit #i ? + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -614,7 +614,7 @@ class sls_tactic : public tactic { if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { #if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -660,7 +660,7 @@ class sls_tactic : public tactic { // reset to what it was before double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching + // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -669,17 +669,17 @@ class sls_tactic : public tactic { #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif - return new_score; + return new_score; } - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -718,7 +718,7 @@ class sls_tactic : public tactic { } // reset to what it was before - m_evaluator.update(fd, old_value); + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -726,37 +726,37 @@ class sls_tactic : public tactic { return new_score; } - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); #if _BFS_ - unsigned pos = m_stats.m_moves % sz; + unsigned pos = m_stats.m_moves % sz; #else - unsigned pos = m_tracker.get_random_uint(16) % sz; + unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); } else { m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -767,35 +767,35 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); } - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - m_old_values.reset(); + m_old_values.reset(); - return 0; - } + return 0; + } - // what_if version needed in the context of 2nd intensification try, combining local and global score + // what_if version needed in the context of 2nd intensification try, combining local and global score bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, double & best_score, mpz & best_value, unsigned i) { double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); + double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - if (new_score >= best_score) { + if (new_score >= best_score) { best_score = new_score; m_mpz_manager.set(best_value, temp); return true; @@ -804,17 +804,17 @@ class sls_tactic : public tactic { return false; } - // find_best_move version needed in the context of 2nd intensification try + // find_best_move version needed in the context of 2nd intensification try double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; + { + mpz old_value, temp; double best_score = 0; sort * srt = fd->get_range(); unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); what_if(g, e, fd, temp, best_score, best_value, i); } @@ -822,54 +822,54 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); m_mpz_manager.del(temp); - return best_score; + return best_score; } - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); #if _BFS_ - unsigned new_const = m_stats.m_moves % sz; + unsigned new_const = m_stats.m_moves % sz; #else - unsigned new_const = m_tracker.get_random_uint(16) % sz; + unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { new_score = find_best_move_local(g, q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - return 0; - } + return 0; + } - // main search loop - lbool search(goal_ref const & g) { + // main search loop + lbool search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -885,52 +885,52 @@ class sls_tactic : public tactic { unsigned plateau_cnt = 0; - // Andreas: Why do we only allow so few plateaus? + // Andreas: Why do we only allow so few plateaus? #if _RESTARTS_ - while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { - if (m_stats.m_moves == 5590) + if (m_stats.m_moves == 5590) checkpoint(); #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif #if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { #if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #elif _TYPE_RSTEP_ == 2 - mk_random_move(g); + mk_random_move(g); #endif score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } #endif old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -952,11 +952,11 @@ class sls_tactic : public tactic { for (unsigned i = 0; i < g->size(); i++) tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? + // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } else { - // Andreas: Why does randomizing not count as a move? (Now it does.) + // Andreas: Why does randomizing not count as a move? (Now it does.) m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -984,15 +984,15 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(g, fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; @@ -1004,7 +1004,7 @@ class sls_tactic : public tactic { if (score >= 0.99999) { // if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -1015,43 +1015,43 @@ class sls_tactic : public tactic { } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ } while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); + report_tactic_progress("This should not happen I guess.", plateau_cnt); plateau_cnt = 0; - } else { - m_stats.m_moves++; + } else { + m_stats.m_moves++; plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); #if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); + handle_plateau(g, score); + //handle_plateau(g); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #endif - //mk_random_move(g); + //mk_random_move(g); score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } @@ -1070,43 +1070,43 @@ class sls_tactic : public tactic { return; } - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif m_tracker.initialize(g); lbool res = l_undef; do { checkpoint(); - // Andreas: I think restarts are too impotant to ignore 99% of them are happening... + // Andreas: I think restarts are too impotant to ignore 99% of them are happening... //if ((m_stats.m_restarts % 100) == 0) report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); @@ -1115,12 +1115,12 @@ class sls_tactic : public tactic { if (res == l_undef) m_tracker.randomize(); } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); + report_tactic_progress("Number of flips:", m_stats.m_moves); if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -1259,7 +1259,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index b26912e5c..006bbb888 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -29,31 +29,31 @@ class sls_tracker { unsigned m_random_bits; unsigned m_random_bits_cnt; mpz m_zero, m_one, m_two; - + struct value_score { #if _EARLY_PRUNE_ - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; #else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; #endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; #if _EARLY_PRUNE_ - double score_prune; - unsigned has_pos_occ; - unsigned has_neg_occ; + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; #endif unsigned distance; // max distance from any root - unsigned touched; + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; - touched = other.touched; + touched = other.touched; return *this; } }; @@ -72,18 +72,18 @@ private: ptr_vector m_temp_constants; occ_type m_constants_occ; #if _UCT_ - unsigned m_touched; + unsigned m_touched; #endif #if _REAL_RS_ || _REAL_PBFS_ - ptr_vector m_unsat_expr; - obj_map m_where_false; - expr** m_list_false; + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; #endif #if _CACHE_TOP_SCORE_ - double m_top_sum; + double m_top_sum; #endif #if _WEIGHT_DIST_ == 4 - double m_weight_dist_factor; + double m_weight_dist_factor; #endif public: @@ -105,23 +105,23 @@ public: } #if _WEIGHT_DIST_ == 4 - inline void set_weight_dist_factor(double val) { - m_weight_dist_factor = val; - } + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } #endif #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { - m_top_sum += add - sub; - } + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } - inline void set_top_sum(double new_score) { - m_top_sum = new_score; - } + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } - inline double get_top_sum() { - return m_top_sum; - } + inline double get_top_sum() { + return m_top_sum; + } #endif inline void set_value(expr * n, const mpz & r) { @@ -174,20 +174,20 @@ public: m_scores.find(n).score_prune = score; } - inline double & get_score_prune(expr * n) { + inline double & get_score_prune(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).score_prune; } - inline unsigned has_pos_occ(expr * n) { + inline unsigned has_pos_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_pos_occ; - } + } - inline unsigned has_neg_occ(expr * n) { + inline unsigned has_neg_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; - } + } #endif inline unsigned get_distance(expr * n) { @@ -316,45 +316,45 @@ public: } } - void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(proc, visited, q); - } - } - for_each_expr(proc, visited, e); - } + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } - void initialize_recursive(expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(q); - } - } - ptr_vector t; + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + } - void initialize(goal_ref const & g) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 - initialize_recursive(proc, visited, e); + initialize_recursive(proc, visited, e); #endif for_each_expr(proc, visited, e); } @@ -363,9 +363,9 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ - initialize_recursive(e); + initialize_recursive(e); #endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); @@ -379,53 +379,53 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); #if _REAL_RS_ || _REAL_PBFS_ - m_list_false = new expr*[sz]; + m_list_false = new expr*[sz]; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - break_assertion(g->form(i)); + if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + break_assertion(g->form(i)); #endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = 1; + m_touched = 1; #endif } #if _REAL_RS_ || _REAL_PBFS_ - void make_assertion(expr * e) - { - if (m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) - { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - } -// printf("Going in %d\n", m_where_false.size()); - } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); - } + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } +// printf("Going in %d\n", m_where_false.size()); + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } - void break_assertion(expr * e) - { - if (!m_where_false.contains(e)) - { - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); - } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); - } + void break_assertion(expr * e) + { + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } #endif void show_model(std::ostream & out) { @@ -537,35 +537,35 @@ public: } #if _EARLY_PRUNE_ - void setup_occs(expr * n, bool negated = false) { - if (m_manager.is_bool(n)) - { - if (m_manager.is_and(n) || m_manager.is_or(n)) - { - SASSERT(!negated); - app * a = to_app(n); - expr * const * args = a->get_args(); - for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); - } - else if (m_manager.is_not(n)) - { - SASSERT(!negated); - app * a = to_app(n); - SASSERT(a->get_num_args() == 1); - expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); - setup_occs(child, true); - } - else - { - if (negated) - m_scores.find(n).has_neg_occ = 1; - else - m_scores.find(n).has_pos_occ = 1; - } - } + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } else NOT_IMPLEMENTED_YET(); } @@ -574,7 +574,7 @@ public: double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -587,14 +587,14 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. + // Andreas: Seems to have no effect. Probably it does not even occur. #if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) sum += get_score(args[i]); res = sum / (double) a->get_num_args(); #else - double min = 1.0; + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; @@ -606,16 +606,16 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. #if _SCORE_OR_MUL_ - double inv = 1.0; + double inv = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); inv *= (1.0 - get_score(args[i])); } res = 1.0 - inv; #else - double max = 0.0; + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur > max) max = cur; @@ -639,7 +639,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -701,7 +701,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -762,7 +762,7 @@ public: TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -797,25 +797,25 @@ public: SASSERT(res >= 0.0 && res <= 1.0); #if _WEIGHT_DIST_ - app * a = to_app(n); - family_id afid = a->get_family_id(); + app * a = to_app(n); + family_id afid = a->get_family_id(); - if (afid == m_bv_util.get_family_id()) + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; #elif _WEIGHT_DIST_ == 2 - res *= res; + res *= res; #elif _WEIGHT_DIST_ == 3 - if (res < 1.0) res = 0.0; + if (res < 1.0) res = 0.0; #elif _WEIGHT_DIST_ == 4 - if (res < 1.0) res *= m_weight_dist_factor; + if (res < 1.0) res *= m_weight_dist_factor; #endif TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -861,34 +861,34 @@ public: NOT_IMPLEMENTED_YET(); } - expr * get_unsat_expression(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - } - } - return e; - } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } - ptr_vector & get_constants(expr * e) { + ptr_vector & get_constants(expr * e) { ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned i = 0; i < sz; i++) { @@ -897,9 +897,9 @@ public: m_temp_constants.push_back(fd); } return m_temp_constants; - } + } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) @@ -913,244 +913,244 @@ public: } } return m_temp_constants; - } + } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { - for (unsigned i = pos; i < sz; i++) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; + return q; } - return 0; - } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. - if (!q) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); + if (!q) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned j = 0; j < sz; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & go_deeper(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - } - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); if (!q) - return m_temp_constants; + return m_temp_constants; - return go_deeper(q); - } + return go_deeper(q); + } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) - return m_temp_constants; - else - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 #if _UCT_ - unsigned pos = -1; - value_score vscore; + unsigned pos = -1; + value_score vscore; #if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - for (unsigned i = start_index; i < sz; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } #else - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - vscore = m_scores.find(e); + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); #elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } #endif - if (pos == static_cast(-1)) - return m_temp_constants; + if (pos == static_cast(-1)) + return m_temp_constants; #if _UCT_ == 1 - m_scores.find(g->form(pos)).touched++; - m_touched++; + m_scores.find(g->form(pos)).touched++; + m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(g->form(pos)).touched = flip; #endif - expr * e = g->form(pos); + expr * e = g->form(pos); #elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; + unsigned int pos = -1; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; + unsigned int pos = -1; + double min = 2.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); #elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[get_random_uint(16) % sz]; + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[get_random_uint(16) % sz]; #elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[flip % sz]; + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(e); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif - return get_unsat_constants_crsat(g, sz, pos); + return get_unsat_constants_crsat(g, sz, pos); #else - return get_unsat_constants_gsat(g, sz); + return get_unsat_constants_gsat(g, sz); #endif } } From 90245021b23f8402e13b4aa85f8ac5e629b7caf5 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Wed, 19 Mar 2014 11:49:44 +0000 Subject: [PATCH 017/507] Current version for relocating. --- src/tactic/sls/sls_evaluator.h | 298 +++++------ src/tactic/sls/sls_tactic.cpp | 842 ++++++++++++++++++----------- src/tactic/sls/sls_tracker.h | 947 +++++++++++++++++++++------------ 3 files changed, 1290 insertions(+), 797 deletions(-) diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index eec9524a9..696d7664a 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -78,7 +78,11 @@ public: case OP_AND: { m_mpz_manager.set(result, m_one); for (unsigned i = 0; i < n_args; i++) +#if _DIRTY_UP_ + if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) && !m_tracker.is_top_expr(args[i])) { +#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { +#endif m_mpz_manager.set(result, m_zero); break; } @@ -86,7 +90,11 @@ public: } case OP_OR: { for (unsigned i = 0; i < n_args; i++) +#if _DIRTY_UP_ + if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) || m_tracker.is_top_expr(args[i])) { +#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { +#endif m_mpz_manager.set(result, m_one); break; } @@ -94,9 +102,16 @@ public: } case OP_NOT: { SASSERT(n_args == 1); +#if _DIRTY_UP_ + if (m_tracker.is_top_expr(args[0])) + m_mpz_manager.set(result, m_zero); + else + m_mpz_manager.set(result, (m_mpz_manager.is_zero(m_tracker.get_value(args[0]))) ? m_one : m_zero); +#else const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); - m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); + m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); +#endif break; } case OP_EQ: { @@ -528,7 +543,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -542,31 +557,34 @@ public: m_tracker.set_value(cur, new_value); #if _REAL_RS_ || _REAL_PBFS_ - if (!m_tracker.has_uplinks(cur)) - { - if (m_mpz_manager.eq(new_value,m_one)) - m_tracker.make_assertion(cur); - else - m_tracker.break_assertion(cur); - } + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } #endif #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif #endif if (m_tracker.has_uplinks(cur)) { @@ -596,7 +614,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -609,21 +627,23 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif #endif if (m_tracker.has_uplinks(cur)) { @@ -661,7 +681,7 @@ public: if (cur_depth > max_depth) max_depth = cur_depth; } #if _REAL_RS_ || _REAL_PBFS_ - run_serious_update(max_depth); + run_serious_update(max_depth); #else run_update(max_depth); #endif @@ -693,27 +713,28 @@ public: unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { expr * cur = cur_depth_exprs[i]; - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - prune_score = m_tracker.get_score_prune(cur); + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); - if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -722,54 +743,55 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); + m_traversal_stack_bool[next_d].push_back(next); visited.mark(next); } } } - else - { - } - } + else + { + } + } - cur_depth_exprs.reset(); + cur_depth_exprs.reset(); cur_depth--; - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } - return pot_benefits; + return pot_benefits; } void run_update_prune(unsigned max_depth) { @@ -777,7 +799,7 @@ public: expr_fast_mark1 visited; mpz new_value; - unsigned cur_depth = max_depth; + unsigned cur_depth = max_depth; SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -787,7 +809,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // should always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -795,10 +817,10 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - if (m_manager.is_bool(next)) - m_traversal_stack_bool[max_depth].push_back(next); - else - m_traversal_stack[next_d].push_back(next); + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); visited.mark(next); } } @@ -817,60 +839,23 @@ public: expr * ep = m_tracker.get_entry_point(fd); unsigned cur_depth = m_tracker.get_distance(ep); - if (m_traversal_stack_bool.size() <= cur_depth) + if (m_traversal_stack_bool.size() <= cur_depth) m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune(cur_depth); + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); } #endif - void randomize_local(expr * e, unsigned int flip) { - ptr_vector & unsat_constants = m_tracker.get_constants(e); - - // Randomize _one_ candidate: - unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); - func_decl * fd = unsat_constants[r]; -#if _PERC_CHANGE_ - sort * srt = fd->get_range(); - mpz temp; - - if (m_manager.is_bool(srt)) - m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); - - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } -#else - mpz temp = m_tracker.get_random(fd->get_range()); -#endif - update(fd, temp); - m_mpz_manager.del(temp); - } - - void randomize_local(goal_ref const & g, unsigned int flip) { - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); - + void randomize_local(ptr_vector & unsat_constants) { // Randomize _all_ candidates: //// bool did_something = false; @@ -889,34 +874,34 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif #if _REAL_RS_ || _REAL_PBFS_ - serious_update(fd, temp); + serious_update(fd, temp); #else - update(fd, temp); + update(fd, temp); #endif m_mpz_manager.del(temp); @@ -927,6 +912,15 @@ public: tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + + } + + void randomize_local(expr * e) { + randomize_local(m_tracker.get_constants(e)); + } + + void randomize_local(goal_ref const & g, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(g, flip)); } }; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 3d5e3e438..ada0ec359 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -34,6 +34,8 @@ Notes: #include"propagate_values_tactic.h" #include"sls_tactic.h" #include"nnf_tactic.h" +#include"luby.h" +#include "ctx_simplify_tactic.h" // which unsatisfied assertion is selected? only works with _FOCUS_ > 0 // 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score @@ -43,9 +45,23 @@ Notes: // 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom #define _FOCUS_ 1 +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 0 + // do we use restarts? -// 0 = no, otherwise the value defines the maximum number of moves -#define _RESTARTS_ 0 +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 3.0 // timelimit #define _TIMELIMIT_ 3600 @@ -66,38 +82,58 @@ Notes: // 2 = yes, by squaring it // 3 = yes, by setting it to zero // 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 0 +#define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 #define _WEIGHT_DIST_FACTOR_ 0.25 +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + // do we use intensification steps in local minima? if so, how many? #define _INTENSIFICATION_ 0 #define _INTENSIFICATION_TRIES_ 0 +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + // do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 0 +#define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 0.01 +#define _UCT_CONSTANT_ 10.0 // is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score #define _PROBABILISTIC_UCT_ 0 +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 1 + // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 // shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 1 +#define _USE_MUL2DIV2_ 0 // shall we try multiplication by 3? -#define _USE_MUL3_ 1 +#define _USE_MUL3_ 0 // shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 1 +#define _USE_UNARY_MINUS_ 0 // is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 1 +#define _UNIFORM_RANDOM_ 0 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 @@ -124,13 +160,21 @@ Notes: #define _CACHE_TOP_SCORE_ 1 -#if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) - InvalidConfiguration; +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) + InvalidConfiguration; #endif #if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; + InvalidConfiguration; +#endif +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) + InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) + InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) + InvalidConfiguration; #endif - #include"sls_params.hpp" #include"sls_evaluator.h" @@ -150,10 +194,10 @@ class sls_tactic : public tactic { m_full_evals(0), m_incr_evals(0), m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -180,11 +224,12 @@ class sls_tactic : public tactic { sls_tracker m_tracker; sls_evaluator m_evaluator; + unsigned m_restart_limit; unsigned m_max_restarts; unsigned m_plateau_limit; - ptr_vector m_old_values; - + ptr_vector m_old_values; + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : @@ -208,6 +253,41 @@ class sls_tactic : public tactic { m_mpz_manager.del(m_two); } + double get_restart_armin(unsigned cnt_restarts) + { + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow(_RESTART_CONST_ARMIN_, inner_id + 1); + } + + inline unsigned check_restart(unsigned curr_value) + { + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; + } + ast_manager & m() const { return m_manager; } void set_cancel(bool f) { m_cancel = f; } @@ -267,18 +347,18 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); #if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); + m_tracker.set_top_sum(top_sum); #endif return top_sum / (double) sz; @@ -292,20 +372,20 @@ class sls_tactic : public tactic { } double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif } double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif @@ -314,18 +394,18 @@ class sls_tactic : public tactic { #if _EARLY_PRUNE_ double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) + if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(g); + return top_score(g); #endif - else - return 0.0; + else + return 0.0; } #endif - // checks whether the score outcome of a given move is better than the previous score + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { @@ -357,11 +437,11 @@ class sls_tactic : public tactic { return false; } - // same as what_if, but only applied to the score of a specific atom, not the total score + // same as what_if, but only applied to the score of a specific atom, not the total score bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -378,29 +458,29 @@ class sls_tactic : public tactic { m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); - } + } - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { mpz temp, mask, mask2; m_mpz_manager.mul(old_value, m_two, temp); m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); } void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { m_mpz_manager.div(old_value, m_two, result); } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -435,75 +515,77 @@ class sls_tactic : public tactic { NOT_IMPLEMENTED_YET(); } - void mk_random_move(goal_ref const & g) { + void mk_random_move(ptr_vector & unsat_constants) + { unsigned rnd_mv = 0; - if (m_stats.m_moves > 10000) - rnd_mv = 0; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; + mpz new_value; - sort * srt = fd->get_range(); + sort * srt = fd->get_range(); if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { #if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + mt = MV_FLIP; #endif - unsigned bit = 0; + unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } - // will use VNS to ignore some possible moves and increase the flips per second + void mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); + } + + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -514,7 +596,7 @@ class sls_tactic : public tactic { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -536,12 +618,12 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } } // reset to what it was before @@ -549,12 +631,12 @@ class sls_tactic : public tactic { SASSERT(check == score); } - // we can either check the condition once in the beginning or check it repeatedly after every bit + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) #endif for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { func_decl * fd = to_evaluate[i]; @@ -563,30 +645,30 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } // reset to what it was before double check = incremental_score(g, fd, old_value); SASSERT(check == score); } - m_mpz_manager.del(old_value); + m_mpz_manager.del(old_value); m_mpz_manager.del(temp); return new_score; } - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; + mpz temp2; #endif unsigned bv_sz; double new_score = score; @@ -599,11 +681,11 @@ class sls_tactic : public tactic { // first try to flip every bit #if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { #else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { #endif - // What would happen if we flipped bit #i ? + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -614,7 +696,7 @@ class sls_tactic : public tactic { if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { #if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -660,7 +742,7 @@ class sls_tactic : public tactic { // reset to what it was before double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching + // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -669,17 +751,17 @@ class sls_tactic : public tactic { #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif - return new_score; + return new_score; } - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -718,7 +800,7 @@ class sls_tactic : public tactic { } // reset to what it was before - m_evaluator.update(fd, old_value); + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -726,37 +808,37 @@ class sls_tactic : public tactic { return new_score; } - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); #if _BFS_ - unsigned pos = m_stats.m_moves % sz; + unsigned pos = m_stats.m_moves % sz; #else - unsigned pos = m_tracker.get_random_uint(16) % sz; + unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); } else { m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -767,35 +849,35 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); } - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - m_old_values.reset(); + m_old_values.reset(); - return 0; - } + return 0; + } - // what_if version needed in the context of 2nd intensification try, combining local and global score + // what_if version needed in the context of 2nd intensification try, combining local and global score bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, double & best_score, mpz & best_value, unsigned i) { double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); + double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - if (new_score >= best_score) { + if (new_score >= best_score) { best_score = new_score; m_mpz_manager.set(best_value, temp); return true; @@ -804,17 +886,17 @@ class sls_tactic : public tactic { return false; } - // find_best_move version needed in the context of 2nd intensification try + // find_best_move version needed in the context of 2nd intensification try double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; + { + mpz old_value, temp; double best_score = 0; sort * srt = fd->get_range(); unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); what_if(g, e, fd, temp, best_score, best_value, i); } @@ -822,54 +904,178 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); m_mpz_manager.del(temp); - return best_score; + return best_score; } - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); #if _BFS_ - unsigned new_const = m_stats.m_moves % sz; + unsigned new_const = m_stats.m_moves % sz; #else - unsigned new_const = m_tracker.get_random_uint(16) % sz; + unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { new_score = find_best_move_local(g, q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - return 0; - } + return 0; + } - // main search loop - lbool search(goal_ref const & g) { + // main search loop + lbool search(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + // main search loop + lbool search_old(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -885,52 +1091,52 @@ class sls_tactic : public tactic { unsigned plateau_cnt = 0; - // Andreas: Why do we only allow so few plateaus? + // Andreas: Why do we only allow so few plateaus? #if _RESTARTS_ - while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { - if (m_stats.m_moves == 5590) checkpoint(); #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif #if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { #if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #elif _TYPE_RSTEP_ == 2 - mk_random_move(g); + mk_random_move(g); #endif score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } #endif old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -952,11 +1158,11 @@ class sls_tactic : public tactic { for (unsigned i = 0; i < g->size(); i++) tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? + // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } else { - // Andreas: Why does randomizing not count as a move? (Now it does.) + // Andreas: Why does randomizing not count as a move? (Now it does.) m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -984,15 +1190,15 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(g, fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; @@ -1004,7 +1210,7 @@ class sls_tactic : public tactic { if (score >= 0.99999) { // if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -1015,43 +1221,43 @@ class sls_tactic : public tactic { } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ } while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); + report_tactic_progress("This should not happen I guess.", plateau_cnt); plateau_cnt = 0; - } else { - m_stats.m_moves++; + } else { + m_stats.m_moves++; plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); #if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); + handle_plateau(g, score); + //handle_plateau(g); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #endif - //mk_random_move(g); + //mk_random_move(g); score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } @@ -1070,57 +1276,82 @@ class sls_tactic : public tactic { return; } - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); #endif m_tracker.initialize(g); lbool res = l_undef; + m_restart_limit = _RESTART_LIMIT_; + do { checkpoint(); - // Andreas: I think restarts are too impotant to ignore 99% of them are happening... - //if ((m_stats.m_restarts % 100) == 0) - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); res = search(g); if (res == l_undef) - m_tracker.randomize(); + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -1251,6 +1482,9 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // conservative gaussian elimination. gaussian_p.set_uint("gaussian_max_occs", 2); + params_ref ctx_p; + ctx_p.set_uint("max_depth", 32); + ctx_p.set_uint("max_steps", 5000000); return and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), using_params(mk_solve_eqs_tactic(m), gaussian_p), @@ -1259,7 +1493,11 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? + // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? + //mk_ctx_simplify_tactic(m, ctx_p), + // Andreas: This one at least eliminates top level duplicates ... + mk_simplify_tactic(m), + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index b26912e5c..0aca1f59c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -29,31 +29,31 @@ class sls_tracker { unsigned m_random_bits; unsigned m_random_bits_cnt; mpz m_zero, m_one, m_two; - + struct value_score { #if _EARLY_PRUNE_ - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; #else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; #endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; #if _EARLY_PRUNE_ - double score_prune; - unsigned has_pos_occ; - unsigned has_neg_occ; + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; #endif unsigned distance; // max distance from any root - unsigned touched; + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; - touched = other.touched; + touched = other.touched; return *this; } }; @@ -65,6 +65,7 @@ private: typedef obj_map scores_type; typedef obj_map > uplinks_type; typedef obj_map > occ_type; + obj_hashtable m_top_expr; scores_type m_scores; uplinks_type m_uplinks; entry_point_type m_entry_points; @@ -72,18 +73,18 @@ private: ptr_vector m_temp_constants; occ_type m_constants_occ; #if _UCT_ - unsigned m_touched; + unsigned m_touched; #endif #if _REAL_RS_ || _REAL_PBFS_ - ptr_vector m_unsat_expr; - obj_map m_where_false; - expr** m_list_false; + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; #endif #if _CACHE_TOP_SCORE_ - double m_top_sum; + double m_top_sum; #endif -#if _WEIGHT_DIST_ == 4 - double m_weight_dist_factor; +#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ + double m_weight_dist_factor; #endif public: @@ -104,24 +105,24 @@ public: m_mpz_manager.del(m_two); } -#if _WEIGHT_DIST_ == 4 - inline void set_weight_dist_factor(double val) { - m_weight_dist_factor = val; - } +#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } #endif #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { - m_top_sum += add - sub; - } + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } - inline void set_top_sum(double new_score) { - m_top_sum = new_score; - } + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } - inline double get_top_sum() { - return m_top_sum; - } + inline double get_top_sum() { + return m_top_sum; + } #endif inline void set_value(expr * n, const mpz & r) { @@ -174,20 +175,20 @@ public: m_scores.find(n).score_prune = score; } - inline double & get_score_prune(expr * n) { + inline double & get_score_prune(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).score_prune; } - inline unsigned has_pos_occ(expr * n) { + inline unsigned has_pos_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_pos_occ; - } + } - inline unsigned has_neg_occ(expr * n) { + inline unsigned has_neg_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; - } + } #endif inline unsigned get_distance(expr * n) { @@ -213,11 +214,62 @@ public: return m_uplinks.contains(n); } + inline bool is_top_expr(expr * n) { + return m_top_expr.contains(n); + } + inline ptr_vector & get_uplinks(expr * n) { SASSERT(m_uplinks.contains(n)); return m_uplinks.find(n); } +#if _REAL_RS_ || _REAL_PBFS_ + void debug_real(goal_ref const & g, unsigned flip) + { + unsigned count = 0; + for (unsigned i = 0; i < g->size(); i++) + { + expr * e = g->form(i); + if (m_mpz_manager.eq(get_value(e),m_one) && m_where_false.contains(e)) + { + printf("iteration %d: ", flip); + printf("form %d is sat but in unsat list at position %d of %d\n", i, m_where_false.find(e), m_where_false.size()); + exit(4); + } + + if (m_mpz_manager.eq(get_value(e),m_zero) && !m_where_false.contains(e)) + { + printf("iteration %d: ", flip); + printf("form %d is unsat but not in unsat list\n", i); + exit(4); + } + + if (m_mpz_manager.eq(get_value(e),m_zero) && m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + expr * q = m_list_false[pos]; + if (q != e) + { + printf("iteration %d: ", flip); + printf("form %d is supposed to be at pos %d in unsat list but something else was there\n", i, pos); + exit(4); + } + } + + if (m_mpz_manager.eq(get_value(e),m_zero)) + count++; + } + + // should be true now that duplicate assertions are removed + if (count != m_where_false.size()) + { + printf("iteration %d: ", flip); + printf("%d are unsat but list is of size %d\n", count, m_where_false.size()); + exit(4); + } + } +#endif + void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -316,45 +368,49 @@ public: } } - void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(proc, visited, q); - } - } - for_each_expr(proc, visited, e); - } + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } - void initialize_recursive(expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(q); - } - } - ptr_vector t; + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + } - void initialize(goal_ref const & g) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + if (!m_top_expr.contains(e)) + m_top_expr.insert(e); + else + printf("this is already in ...\n"); + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 - initialize_recursive(proc, visited, e); + initialize_recursive(proc, visited, e); #endif for_each_expr(proc, visited, e); } @@ -363,9 +419,9 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ - initialize_recursive(e); + initialize_recursive(e); #endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); @@ -379,53 +435,61 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); #if _REAL_RS_ || _REAL_PBFS_ - m_list_false = new expr*[sz]; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - break_assertion(g->form(i)); + m_list_false = new expr*[sz]; + //for (unsigned i = 0; i < sz; i++) + //{ + // if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + // break_assertion(g->form(i)); + //} #endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; #endif } #if _REAL_RS_ || _REAL_PBFS_ - void make_assertion(expr * e) - { - if (m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) - { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - } + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + //printf("Moving %d from %d to %d\n", q, m_where_false.size(), pos); + } + //else + //printf("Erasing %d from %d to %d\n", e, pos); +// m_list_false[m_where_false.size()] = 0; // printf("Going in %d\n", m_where_false.size()); - } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); - } + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } - void break_assertion(expr * e) - { - if (!m_where_false.contains(e)) - { - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); - } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); - } + void break_assertion(expr * e) + { + //printf("I'm broken... that's still fine.\n"); + if (!m_where_false.contains(e)) + { + //printf("This however is not so cool...\n"); + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } #endif void show_model(std::ostream & out) { @@ -522,7 +586,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize() { + void randomize(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -534,38 +598,60 @@ public: } TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); + +#if _UCT_RESET_ + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; +#endif + } + + void reset(goal_ref const & g) { + TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); + + for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { + mpz temp = m_zero; + set_value(it->m_value, temp); + m_mpz_manager.del(temp); + } + +#if _UCT_RESET_ + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; +#endif } #if _EARLY_PRUNE_ - void setup_occs(expr * n, bool negated = false) { - if (m_manager.is_bool(n)) - { - if (m_manager.is_and(n) || m_manager.is_or(n)) - { - SASSERT(!negated); - app * a = to_app(n); - expr * const * args = a->get_args(); - for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); - } - else if (m_manager.is_not(n)) - { - SASSERT(!negated); - app * a = to_app(n); - SASSERT(a->get_num_args() == 1); - expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); - setup_occs(child, true); - } - else - { - if (negated) - m_scores.find(n).has_neg_occ = 1; - else - m_scores.find(n).has_pos_occ = 1; - } - } + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } else NOT_IMPLEMENTED_YET(); } @@ -574,7 +660,7 @@ public: double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -587,16 +673,24 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. + // Andreas: Seems to have no effect. Probably it does not even occur. #if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) +#if _DIRTY_UP_ + sum += is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else sum += get_score(args[i]); +#endif res = sum / (double) a->get_num_args(); #else - double min = 1.0; + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif if (cur < min) min = cur; } res = min; @@ -606,18 +700,26 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. #if _SCORE_OR_MUL_ - double inv = 1.0; + double inv = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif inv *= (1.0 - get_score(args[i])); } res = 1.0 - inv; #else - double max = 0.0; + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif if (cur > max) max = cur; } res = max; @@ -639,7 +741,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -701,7 +803,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -762,7 +864,7 @@ public: TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -772,7 +874,11 @@ public: expr * child = a->get_arg(0); if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. NOT_IMPLEMENTED_YET(); +#if _DIRTY_UP_ + res = is_top_expr(child) ? 0.0 : score_bool(child, true); +#else res = score_bool(child, true); +#endif } else if (m_manager.is_distinct(n)) { app * a = to_app(n); @@ -797,25 +903,29 @@ public: SASSERT(res >= 0.0 && res <= 1.0); #if _WEIGHT_DIST_ - app * a = to_app(n); - family_id afid = a->get_family_id(); + app * a = to_app(n); + family_id afid = a->get_family_id(); - if (afid == m_bv_util.get_family_id()) + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#if _WEIGHT_TOGGLE_ + if (res < 1.0) res *= m_weight_dist_factor; +#else + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#endif #elif _WEIGHT_DIST_ == 2 - res *= res; + res *= res; #elif _WEIGHT_DIST_ == 3 - if (res < 1.0) res = 0.0; + if (res < 1.0) res = 0.0; #elif _WEIGHT_DIST_ == 4 - if (res < 1.0) res *= m_weight_dist_factor; + if (res < 1.0) res *= m_weight_dist_factor; #endif TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -861,34 +971,34 @@ public: NOT_IMPLEMENTED_YET(); } - expr * get_unsat_expression(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - } - } - return e; - } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } - ptr_vector & get_constants(expr * e) { + ptr_vector & get_constants(expr * e) { ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned i = 0; i < sz; i++) { @@ -897,9 +1007,13 @@ public: m_temp_constants.push_back(fd); } return m_temp_constants; - } + } + + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + if (sz == 1) + return get_constants(); + m_temp_constants.reset(); - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) @@ -913,247 +1027,394 @@ public: } } return m_temp_constants; - } + } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { - for (unsigned i = pos; i < sz; i++) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; + return q; } - return 0; - } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. - if (!q) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); + if (!q) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e || m_temp_constants.size()) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned j = 0; j < sz; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & go_deeper(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - } - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); if (!q) - return m_temp_constants; + return m_temp_constants; - return go_deeper(q); - } + return go_deeper(q); + } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) - return m_temp_constants; - else - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 #if _UCT_ - unsigned pos = -1; - value_score vscore; + unsigned pos = -1; + value_score vscore; #if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - for (unsigned i = start_index; i < sz; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score; #else - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); -#elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); +// for (unsigned i = 0; i < m_where_false.size(); i++) { +// expr * e = m_list_false[i]; + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } #endif - if (pos == static_cast(-1)) - return m_temp_constants; + if (pos == static_cast(-1)) + return m_temp_constants; #if _UCT_ == 1 - m_scores.find(g->form(pos)).touched++; - m_touched++; + m_scores.find(g->form(pos)).touched++; + m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(g->form(pos)).touched = flip; #endif - expr * e = g->form(pos); + expr * e = g->form(pos); +// expr * e = m_list_false[pos]; #elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; + unsigned int pos = -1; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; + unsigned int pos = -1; + double min = 2.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); #elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[get_random_uint(16) % sz]; + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + expr * e = m_list_false[get_random_uint(16) % sz]; #elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[flip % sz]; + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(e); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif - return get_unsat_constants_crsat(g, sz, pos); + return get_unsat_constants_crsat(g, sz, pos); #else - return get_unsat_constants_gsat(g, sz); + return get_unsat_constants_gsat(g, sz); #endif } } + + + expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); + + if (sz == 1) + return g->form(0); + + m_temp_constants.reset(); +#if _FOCUS_ == 1 +#if _UCT_ + unsigned pos = -1; + value_score vscore; +#if _PROBABILISTIC_UCT_ + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score + _UCT_EPS_; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score + _UCT_EPS_; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); +// for (unsigned i = 0; i < m_where_false.size(); i++) { +// expr * e = m_list_false[i]; + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + } +#endif + if (pos == static_cast(-1)) + return 0; + +#if _UCT_ == 1 + m_scores.find(g->form(pos)).touched++; + m_touched++; +#elif _UCT_ == 2 + m_scores.find(g->form(pos)).touched = flip; +#endif +// return m_list_false[pos]; + return g->form(pos); + +#elif _BFS_ == 3 + unsigned int pos = -1; + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _BFS_ == 2 + unsigned int pos = -1; + double min = 2.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + } + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _BFS_ == 1 + unsigned int pos = flip % sz; + return get_unsat_assertion(g, sz, pos); +#elif _UNIFORM_RANDOM_ + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _REAL_RS_ + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return 0; + return m_list_false[get_random_uint(16) % sz]; +#elif _REAL_PBFS_ + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return0; + else + return m_list_false[flip % sz]; +#else + unsigned int pos = get_random_uint(16) % sz; + return get_unsat_assertion(g, sz, pos); +#endif + return g->form(pos); +#elif _FOCUS_ == 2 +#if _BFS_ + unsigned int pos = flip % sz; +#else + unsigned int pos = get_random_uint(16) % sz; +#endif + return get_unsat_constants_crsat(g, sz, pos); +#endif + } }; #endif \ No newline at end of file From 3d6f8840c65071f186a4955665cbd4db16a53be6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 17:04:38 +0000 Subject: [PATCH 018/507] SLS refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 158 +++ src/tactic/sls/sls_engine.cpp | 1160 +++++++++++++++++ src/tactic/sls/sls_engine.h | 159 +++ src/tactic/sls/sls_evaluator.h | 3 + src/tactic/sls/sls_tactic.cpp | 1396 +-------------------- src/tactic/sls/sls_tracker.h | 10 +- 6 files changed, 1520 insertions(+), 1366 deletions(-) create mode 100644 src/tactic/sls/sls_compilation_settings.h create mode 100644 src/tactic/sls/sls_engine.cpp create mode 100644 src/tactic/sls/sls_engine.h diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h new file mode 100644 index 000000000..aea4787b0 --- /dev/null +++ b/src/tactic/sls/sls_compilation_settings.h @@ -0,0 +1,158 @@ +/*++ +Copyright (c) 2014 Microsoft Corporation + +Module Name: + + sls_compilation_constants.h + +Abstract: + + Stochastic Local Search (SLS) compilation constants + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + + This file should go away completely once we have evaluated all options. + +--*/ +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom +#define _FOCUS_ 1 + +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 0 + +// do we use restarts? +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 3.0 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? +#define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? +#define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained +#define _VNS_ 0 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 1 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.25 + +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 1 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 10.0 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score +#define _PROBABILISTIC_UCT_ 0 + +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 1 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 0 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 0 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 0 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 0 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) +InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) +InvalidConfiguration; +#endif +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) +InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) +InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) +InvalidConfiguration; +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp new file mode 100644 index 000000000..92471aad8 --- /dev/null +++ b/src/tactic/sls/sls_engine.cpp @@ -0,0 +1,1160 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + sls_engine.cpp + +Abstract: + + A Stochastic Local Search (SLS) engine + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + +--*/ +#include + +#include"map.h" +#include"ast_smt2_pp.h" +#include"ast_pp.h" +#include"var_subst.h" +#include"model_pp.h" +#include"tactic.h" +#include"cooperate.h" +#include"luby.h" + +#include"sls_compilation_settings.h" +#include"sls_params.hpp" +#include"sls_engine.h" + + +sls_engine::sls_engine(ast_manager & m, params_ref const & p) : + m_manager(m), + m_powers(m_mpz_manager), + m_zero(m_mpz_manager.mk_z(0)), + m_one(m_mpz_manager.mk_z(1)), + m_two(m_mpz_manager.mk_z(2)), + m_cancel(false), + m_bv_util(m), + m_tracker(m, m_bv_util, m_mpz_manager, m_powers), + m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) +{ + updt_params(p); +} + +sls_engine::~sls_engine() { + m_mpz_manager.del(m_zero); + m_mpz_manager.del(m_one); + m_mpz_manager.del(m_two); +} + +double sls_engine::get_restart_armin(unsigned cnt_restarts) +{ + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); +} + +void sls_engine::updt_params(params_ref const & _p) { + sls_params p(_p); + m_produce_models = _p.get_bool("model", false); + m_max_restarts = p.restarts(); + m_tracker.set_random_seed(p.random_seed()); + m_plateau_limit = p.plateau_limit(); +} + +void sls_engine::checkpoint() { + if (m_cancel) + throw tactic_exception(TACTIC_CANCELED_MSG); + cooperate("sls"); +} + +bool sls_engine::full_eval(goal_ref const & g, model & mdl) { + bool res = true; + + unsigned sz = g->size(); + for (unsigned i = 0; i < sz && res; i++) { + checkpoint(); + expr_ref o(m_manager); + + if (!mdl.eval(g->form(i), o, true)) + exit(ERR_INTERNAL_FATAL); + + res = m_manager.is_true(o.get()); + } + + TRACE("sls", tout << "Evaluation: " << res << std::endl;); + + return res; +} + +double sls_engine::top_score(goal_ref const & g) { +#if 0 + double min = m_tracker.get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + double q = m_tracker.get_score(g->form(i)); + if (q < min) min = q; + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " MIN: " << min << std::endl;); + return min; +#else + double top_sum = 0.0; + unsigned sz = g->size(); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); + } + + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " AVG: " << top_sum / (double)sz << std::endl;); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + + return top_sum / (double)sz; +#endif +} + +double sls_engine::rescore(goal_ref const & g) { + m_evaluator.update_all(); + m_stats.m_full_evals++; + return top_score(g); +} + +double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif +} + +double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif +} + +double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { +#if _EARLY_PRUNE_ + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; +#else + NOT_IMPLEMENTED_YET(); +#endif +} + +// checks whether the score outcome of a given move is better than the previous score +bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + +#ifdef Z3DEBUG + mpz old_value; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); +#endif + +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else + double r = incremental_score(g, fd, temp); +#endif +#ifdef Z3DEBUG + TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << + " --> " << r << std::endl;); + + m_mpz_manager.del(old_value); +#endif + + // if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +// same as what_if, but only applied to the score of a specific atom, not the total score +bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); + if (r >= best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +void sls_engine::mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + +} + +// Andreas: do we really need all those temporary mpzs? +void sls_engine::mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); +} + +void sls_engine::mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); +} + +void sls_engine::mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + unsigned shift; + m_mpz_manager.add(old_value, m_one, incremented); + if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) + m_mpz_manager.set(incremented, m_zero); +} + +void sls_engine::mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { + if (m_mpz_manager.is_zero(old_value)) { + m_mpz_manager.set(decremented, m_powers(bv_sz)); + m_mpz_manager.dec(decremented); + } + else + m_mpz_manager.sub(old_value, m_one, decremented); +} + +void sls_engine::mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { + m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); +} + +void sls_engine::mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { + m_mpz_manager.set(flipped, m_zero); + + if (m_bv_util.is_bv_sort(s)) { + mpz mask; + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(old_value, mask, flipped); + m_mpz_manager.del(mask); + } + else if (m_manager.is_bool(s)) + m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); + else + NOT_IMPLEMENTED_YET(); +} + +void sls_engine::mk_random_move(ptr_vector & unsat_constants) +{ + unsigned rnd_mv = 0; + unsigned ucc = unsat_constants.size(); + unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; + func_decl * fd = unsat_constants[rc]; + + mpz new_value; + + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type)rnd_mv; + + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; + + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout);); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); +} + +void sls_engine::mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); +} + +// will use VNS to ignore some possible moves and increase the flips per second +double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + // we can either check the condition once in the beginning or check it repeatedly after every bit +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif + unsigned bv_sz; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } +#endif + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; +} + +// same as find_best_move but only considers the score of the current expression instead of the overall score +double sls_engine::find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + +// first try of intensification ... does not seem to be efficient +bool sls_engine::handle_plateau(goal_ref const & g) +{ + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back(&m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } + else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], *m_old_values[i]); + + m_old_values.reset(); + + return 0; +} + +// what_if version needed in the context of 2nd intensification try, combining local and global score +bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +// find_best_move version needed in the context of 2nd intensification try +double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) +{ + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; +} + +// second try to use intensification ... also not very effective +bool sls_engine::handle_plateau(goal_ref const & g, double old_score) +{ + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; +} + +// main search loop +lbool sls_engine::search(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + +bailout: + m_mpz_manager.del(new_value); + + return res; +} + +// main search loop +lbool sls_engine::search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + + score = rescore(g); + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + + unsigned plateau_cnt = 0; + + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { +#endif + do { + checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif + old_score = score; + new_const = (unsigned)-1; + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } + TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; + for (unsigned i = 0; i < to_evaluate.size(); i++) + tout << to_evaluate[i]->get_name() << std::endl;); + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + if (new_const == static_cast(-1)) { + TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + }); + + TRACE("sls_max", m_tracker.show_model(tout); + tout << "Scores: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl;); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? + score = old_score; + } + else { + // Andreas: Why does randomizing not count as a move? (Now it does.) + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; + switch (move) { + case MV_FLIP: + tout << "Flip"; + if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; + break; + case MV_INC: + tout << "+1"; + break; + case MV_DEC: + tout << "-1"; + break; + case MV_INV: + tout << "NEG"; + break; + }; + tout << ") ; new score = " << std::setprecision(32) << score << std::endl;); + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + + TRACE("sls", tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + } + + if (score >= 0.99999) { + // if (score >= 1.0) { + // score could theoretically be imprecise. + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ + } while (score > old_score && res == l_undef); + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); + plateau_cnt = 0; + } + else { + m_stats.m_moves++; + plateau_cnt++; + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { + TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else + m_evaluator.randomize_local(g, m_stats.m_moves); +#endif + //mk_random_move(g); + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } + } + +bailout: + m_mpz_manager.del(new_value); + + return res; +} + +void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { + if (g->inconsistent()) { + mc = 0; + return; + } + + m_produce_models = g->models_enabled(); + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout);); + } + g->reset(); + } + else + mc = 0; +} + +unsigned sls_engine::check_restart(unsigned curr_value) +{ + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; +} \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h new file mode 100644 index 000000000..878354c6d --- /dev/null +++ b/src/tactic/sls/sls_engine.h @@ -0,0 +1,159 @@ +/*++ +Copyright (c) 2014 Microsoft Corporation + +Module Name: + + sls_engine.h + +Abstract: + + A Stochastic Local Search (SLS) engine + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + +--*/ +#ifndef _SLS_ENGINE_H_ +#define _SLS_ENGINE_H_ + +#include"stopwatch.h" +#include"lbool.h" +#include"model_converter.h" + +#include"sls_compilation_settings.h" +#include"sls_tracker.h" +#include"sls_evaluator.h" + +class sls_engine { +public: + class stats { + public: + unsigned m_restarts; + stopwatch m_stopwatch; + unsigned m_full_evals; + unsigned m_incr_evals; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + + stats() : + m_restarts(0), + m_full_evals(0), + m_incr_evals(0), + m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), + m_flips(0), + m_incs(0), + m_decs(0), + m_invs(0) { + m_stopwatch.reset(); + m_stopwatch.start(); + } + void reset() { + m_full_evals = m_flips = m_incr_evals = 0; + m_stopwatch.reset(); + m_stopwatch.start(); + } + }; + +protected: + ast_manager & m_manager; + stats m_stats; + unsynch_mpz_manager m_mpz_manager; + powers m_powers; + mpz m_zero, m_one, m_two; + bool m_produce_models; + volatile bool m_cancel; + bv_util m_bv_util; + sls_tracker m_tracker; + sls_evaluator m_evaluator; + + unsigned m_restart_limit; + unsigned m_max_restarts; + unsigned m_plateau_limit; + + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; + +public: + sls_engine(ast_manager & m, params_ref const & p); + ~sls_engine(); + + ast_manager & m() const { return m_manager; } + + void set_cancel(bool f) { m_cancel = f; } + void cancel() { set_cancel(true); } + void reset_cancel() { set_cancel(false); } + + void updt_params(params_ref const & _p); + + stats const & get_stats(void) { return m_stats; } + void reset_statistics(void) { m_stats.reset(); } + + bool full_eval(goal_ref const & g, model & mdl); + + + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result); + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); + void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); + void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + + + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); + + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); + + + lbool search(goal_ref const & g); + + void operator()(goal_ref const & g, model_converter_ref & mc); + +protected: + void checkpoint(); + lbool search_old(goal_ref const & g); + double get_restart_armin(unsigned cnt_restarts); + + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + + double top_score(goal_ref const & g); + double rescore(goal_ref const & g); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); +#endif + + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + void mk_random_move(ptr_vector & unsat_constants); + void mk_random_move(goal_ref const & g); + + bool handle_plateau(goal_ref const & g); + bool handle_plateau(goal_ref const & g, double old_score); + + inline unsigned check_restart(unsigned curr_value); +}; + +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 97860e3a2..8d2a7ba1d 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -20,6 +20,9 @@ Notes: #ifndef _SLS_EVALUATOR_H_ #define _SLS_EVALUATOR_H_ +#include"model_evaluator.h" + +#include"sls_compilation_settings.h" #include"sls_powers.h" #include"sls_tracker.h" diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 743ad00bc..0f157d3a6 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,1363 +16,31 @@ Author: Notes: --*/ -#include -#include"map.h" #include"nnf.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"model_pp.h" -#include"model_evaluator.h" #include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"stopwatch.h" #include"propagate_values_tactic.h" -#include"sls_tactic.h" +#include"ctx_simplify_tactic.h" +#include"elim_uncnstr_tactic.h" #include"nnf_tactic.h" -#include"luby.h" -#include "ctx_simplify_tactic.h" - -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 0 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick clause when randomizing in a plateau or use the current one? -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 - -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 - -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? -#define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 - -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) - InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) - InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) - InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) - InvalidConfiguration; -#endif +#include"stopwatch.h" +#include"sls_tactic.h" #include"sls_params.hpp" -#include"sls_evaluator.h" -#include"sls_tracker.h" +#include"sls_engine.h" -class sls_tactic : public tactic { - class stats { - public: - unsigned m_restarts; - stopwatch m_stopwatch; - unsigned m_full_evals; - unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; - - stats() : - m_restarts(0), - m_full_evals(0), - m_incr_evals(0), - m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), - m_flips(0), - m_incs(0), - m_decs(0), - m_invs(0) { - m_stopwatch.reset(); - m_stopwatch.start(); - } - void reset() { - m_full_evals = m_flips = m_incr_evals = 0; - m_stopwatch.reset(); - m_stopwatch.start(); - } - }; - - struct imp { - ast_manager & m_manager; - stats & m_stats; - unsynch_mpz_manager m_mpz_manager; - powers m_powers; - mpz m_zero, m_one, m_two; - bool m_produce_models; - volatile bool m_cancel; - bv_util m_bv_util; - sls_tracker m_tracker; - sls_evaluator m_evaluator; - - unsigned m_restart_limit; - unsigned m_max_restarts; - unsigned m_plateau_limit; - - ptr_vector m_old_values; - - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; - - imp(ast_manager & m, params_ref const & p, stats & s) : - m_manager(m), - m_stats(s), - m_powers(m_mpz_manager), - m_zero(m_mpz_manager.mk_z(0)), - m_one(m_mpz_manager.mk_z(1)), - m_two(m_mpz_manager.mk_z(2)), - m_cancel(false), - m_bv_util(m), - m_tracker(m, m_bv_util, m_mpz_manager, m_powers), - m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) - { - updt_params(p); - } - - ~imp() { - m_mpz_manager.del(m_zero); - m_mpz_manager.del(m_one); - m_mpz_manager.del(m_two); - } - - double get_restart_armin(unsigned cnt_restarts) - { - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow(_RESTART_CONST_ARMIN_, inner_id + 1); - } - - inline unsigned check_restart(unsigned curr_value) - { - if (curr_value > m_restart_limit) - { -#if _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); -#elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 1 - if (m_stats.m_restarts & 1) - m_restart_limit += _RESTART_LIMIT_; - else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; -#else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif - return 0; - } - return 1; - } - - ast_manager & m() const { return m_manager; } - - void set_cancel(bool f) { m_cancel = f; } - void cancel() { set_cancel(true); } - void reset_cancel() { set_cancel(false); } - - static void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); - } - - void updt_params(params_ref const & _p) { - sls_params p(_p); - m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); - m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); - } - - void checkpoint() { - if (m_cancel) - throw tactic_exception(TACTIC_CANCELED_MSG); - cooperate("sls"); - } - - bool full_eval(goal_ref const & g, model & mdl) { - bool res = true; - - unsigned sz = g->size(); - for (unsigned i = 0; i < sz && res; i++) { - checkpoint(); - expr_ref o(m_manager); - - if (!mdl.eval(g->form(i), o, true)) - exit(ERR_INTERNAL_FATAL); - - res = m_manager.is_true(o.get()); - } - - TRACE("sls", tout << "Evaluation: " << res << std::endl;); - - return res; - } - - double top_score(goal_ref const & g) { - #if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl; ); - return min; - #else - double top_sum = 0.0; - unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - top_sum += m_tracker.get_score(e); - } - - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " AVG: " << top_sum / (double) sz << std::endl; ); - -#if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); -#endif - - return top_sum / (double) sz; - #endif - } - - double rescore(goal_ref const & g) { - m_evaluator.update_all(); - m_stats.m_full_evals++; - return top_score(g); - } - - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; - } -#endif - - // checks whether the score outcome of a given move is better than the previous score - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - #ifdef Z3DEBUG - mpz old_value; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - #endif - -#if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); -#else - double r = incremental_score(g, fd, temp); -#endif - #ifdef Z3DEBUG - TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << - " --> " << r << std::endl; ); - - m_mpz_manager.del(old_value); - #endif - -// if (r >= best_score) { - if (r > best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // same as what_if, but only applied to the score of a specific atom, not the total score - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.add(old_value, add_value, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - - } - - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - } - - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); - } - - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { - unsigned shift; - m_mpz_manager.add(old_value, m_one, incremented); - if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) - m_mpz_manager.set(incremented, m_zero); - } - - void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { - if (m_mpz_manager.is_zero(old_value)) { - m_mpz_manager.set(decremented, m_powers(bv_sz)); - m_mpz_manager.dec(decremented); - } - else - m_mpz_manager.sub(old_value, m_one, decremented); - } - - void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { - m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); - } - - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { - m_mpz_manager.set(flipped, m_zero); - - if (m_bv_util.is_bv_sort(s)) { - mpz mask; - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(old_value, mask, flipped); - m_mpz_manager.del(mask); - } - else if (m_manager.is_bool(s)) - m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); - else - NOT_IMPLEMENTED_YET(); - } - - void mk_random_move(ptr_vector & unsat_constants) - { - unsigned rnd_mv = 0; - unsigned ucc = unsat_constants.size(); - unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; - func_decl * fd = unsat_constants[rc]; - - mpz new_value; - - sort * srt = fd->get_range(); - if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { -#if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; -#else - mt = MV_FLIP; -#endif - unsigned bit = 0; - - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } - - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } - - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } - - void mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); - } - - // will use VNS to ignore some possible moves and increase the flips per second - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif - unsigned bv_sz; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { -#else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { -#endif - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } -#endif - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - return new_score; - } - - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - - m_old_values.reset(); - - return 0; - } - - // what_if version needed in the context of 2nd intensification try, combining local and global score - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // find_best_move version needed in the context of 2nd intensification try - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; - } - - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; - } - - // main search loop - lbool search(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - unsigned plateau_cnt = 0; - - score = rescore(g); - unsigned sz = g->size(); -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - checkpoint(); - m_stats.m_moves++; - -#if _REAL_RS_ || _REAL_PBFS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } - continue; -#endif - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - old_score = score; - new_const = (unsigned)-1; - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - - if (new_const == static_cast(-1)) { - score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); - else -#endif -#if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); -#else - m_evaluator.randomize_local(to_evaluate); -#endif -#endif - -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } else { - func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - // main search loop - lbool search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0 ; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl; ); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - } - - if (score >= 0.99999) { -// if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } - while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - void operator()(goal_ref const & g, model_converter_ref & mc) { - if (g->inconsistent()) { - mc = 0; - return; - } - - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout); ); - } - g->reset(); - } - else - mc = 0; - } - }; - +class sls_tactic : public tactic { ast_manager & m; params_ref m_params; - imp * m_imp; - stats m_stats; + sls_engine * m_engine; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_imp = alloc(imp, m, p, m_stats); + m_engine = alloc(sls_engine, m, p); } virtual tactic * translate(ast_manager & m) { @@ -1380,16 +48,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_imp); + dealloc(m_engine); } virtual void updt_params(params_ref const & p) { m_params = p; - m_imp->updt_params(p); + m_engine->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - imp::collect_param_descrs(r); + sls_params::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -1397,14 +65,13 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); - m_imp->m_produce_models = g->models_enabled(); + SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_imp->operator()(g, mc); + m_engine->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -1413,40 +80,41 @@ public: } virtual void cleanup() { - imp * d = m_imp; + sls_engine * d = m_engine; #pragma omp critical (tactic_cancel) { - d = m_imp; + d = m_engine; } dealloc(d); - d = alloc(imp, m, m_params, m_stats); + d = alloc(sls_engine, m, m_params); #pragma omp critical (tactic_cancel) { - m_imp = d; + m_engine = d; } } virtual void collect_statistics(statistics & st) const { - double seconds = m_stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", m_stats.m_restarts); - st.update("sls full evals", m_stats.m_full_evals); - st.update("sls incr evals", m_stats.m_incr_evals); - st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); - st.update("sls FLIP moves", m_stats.m_flips); - st.update("sls INC moves", m_stats.m_incs); - st.update("sls DEC moves", m_stats.m_decs); - st.update("sls INV moves", m_stats.m_invs); - st.update("sls moves", m_stats.m_moves); - st.update("sls moves/sec", m_stats.m_moves / seconds); + sls_engine::stats const & stats = m_engine->get_stats(); + double seconds = stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", stats.m_restarts); + st.update("sls full evals", stats.m_full_evals); + st.update("sls incr evals", stats.m_incr_evals); + st.update("sls incr evals/sec", stats.m_incr_evals / seconds); + st.update("sls FLIP moves", stats.m_flips); + st.update("sls INC moves", stats.m_incs); + st.update("sls DEC moves", stats.m_decs); + st.update("sls INV moves", stats.m_invs); + st.update("sls moves", stats.m_moves); + st.update("sls moves/sec", stats.m_moves / seconds); } virtual void reset_statistics() { - m_stats.reset(); + m_engine->reset_statistics(); } virtual void set_cancel(bool f) { - if (m_imp) - m_imp->set_cancel(f); + if (m_engine) + m_engine->set_cancel(f); } }; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 4d9c078b6..7d1d4c0f1 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,12 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include"goal.h" +#include"model.h" + +#include"sls_compilation_settings.h" +#include"sls_powers.h" + class sls_tracker { ast_manager & m_manager; unsynch_mpz_manager & m_mpz_manager; @@ -1187,7 +1193,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif @@ -1335,7 +1341,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif From e3ae0ba0bd67b40944efc9afacc65d5eacc024d5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 17:26:05 +0000 Subject: [PATCH 019/507] SLS refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index aea4787b0..8e52596e0 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -18,6 +18,10 @@ Notes: This file should go away completely once we have evaluated all options. --*/ + +#ifndef _SLS_COMPILATION_SETTINGS_H_ +#define _SLS_COMPILATION_SETTINGS_H_ + // which unsatisfied assertion is selected? only works with _FOCUS_ > 0 // 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score #define _BFS_ 0 @@ -155,4 +159,6 @@ InvalidConfiguration; #endif #if (_PERC_STICKY_ && !_FOCUS_) InvalidConfiguration; +#endif + #endif \ No newline at end of file From c615bc0c34fa3646e0312c89e5fd7f0ce51efbe7 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Thu, 20 Mar 2014 15:58:53 +0000 Subject: [PATCH 020/507] uct forget and minisat restarts added --- src/tactic/sls/sls_tactic.cpp | 31 +++++++++++++++++++++++-------- src/tactic/sls/sls_tracker.h | 22 ++++++++++++++++++++-- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 743ad00bc..b2b7035e0 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -49,7 +49,7 @@ Notes: #define _PERC_STICKY_ 0 // do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 0 +#define _DIRTY_UP_ 1 // do we use restarts? // 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time @@ -58,10 +58,10 @@ Notes: #define _RESTART_LIMIT_ 10 // 0 = initialize with all zero, 1 initialize with random value #define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat #define _RESTART_SCHEME_ 1 // base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 +#define _RESTART_CONST_ARMIN_ 4.0 // timelimit #define _TIMELIMIT_ 3600 @@ -85,7 +85,7 @@ Notes: #define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 +#define _WEIGHT_DIST_FACTOR_ 0.5 // shall we toggle the weight after each restart? #define _WEIGHT_TOGGLE_ 0 @@ -104,7 +104,7 @@ Notes: #define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 +#define _UCT_CONSTANT_ 20.0 // is uct clause selection probabilistic similar to variable selection in sparrow? // 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score @@ -116,9 +116,13 @@ Notes: // shall we reset _UCT_ touched values after restart? #define _UCT_RESET_ 0 +// do we gradually reduce the touched values of _UCT_? +#define _UCT_FORGET_ 0 +#define _UCT_FORGET_FACTOR_ 0.5 + // how shall we initialize the _UCT_ total touched counter? // 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 +#define _UCT_INIT_ 0 // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 @@ -265,7 +269,9 @@ class sls_tactic : public tactic { { if (curr_value > m_restart_limit) { -#if _RESTART_SCHEME_ == 4 +#if _RESTART_SCHEME_ == 5 + m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); +#elif _RESTART_SCHEME_ == 4 m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; @@ -976,6 +982,11 @@ class sls_tactic : public tactic { checkpoint(); m_stats.m_moves++; +#if _UCT_FORGET_ + if (m_stats.m_moves % _UCT_FORGET_ == 0) + m_tracker.uct_forget(g); +#endif + #if _REAL_RS_ || _REAL_PBFS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif @@ -1277,11 +1288,13 @@ class sls_tactic : public tactic { verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_DIRTY_UP_ " << _DIRTY_UP_ << std::endl; verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_RESTART_CONST_ARMIN_ " << std::fixed << std::setprecision(2) << _RESTART_CONST_ARMIN_ << std::endl; verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; @@ -1296,6 +1309,8 @@ class sls_tactic : public tactic { verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; + verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; @@ -1495,7 +1510,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? //mk_ctx_simplify_tactic(m, ctx_p), // Andreas: This one at least eliminates top level duplicates ... - mk_simplify_tactic(m), + //mk_simplify_tactic(m), // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 4d9c078b6..45e1719d2 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -270,6 +270,20 @@ public: } #endif + void uct_forget(goal_ref const & g) { + expr * e; + unsigned touched_old, touched_new; + + for (unsigned i = 0; i < g->size(); i++) + { + e = g->form(i); + touched_old = m_scores.find(e).touched; + touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); + m_scores.find(e).touched = touched_new; + m_touched += touched_new - touched_old; + } + } + void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -1190,6 +1204,8 @@ public: double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#elif _UCT_ == 3 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } @@ -1197,7 +1213,7 @@ public: if (pos == static_cast(-1)) return m_temp_constants; -#if _UCT_ == 1 +#if _UCT_ == 1 || _UCT_ == 3 m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 @@ -1338,6 +1354,8 @@ public: double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#elif _UCT_ == 3 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } @@ -1345,7 +1363,7 @@ public: if (pos == static_cast(-1)) return 0; -#if _UCT_ == 1 +#if _UCT_ == 1 || _UCT_ == 3 m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 From 6f9a348f6398cecd0852f2d74d4d25ebb4d670fc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 26 Mar 2014 17:26:06 +0000 Subject: [PATCH 021/507] removed dependency of bvsls on goal_refs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 219 +++++++++++++++++++-------------- src/tactic/sls/sls_engine.h | 58 ++++----- src/tactic/sls/sls_evaluator.h | 4 +- src/tactic/sls/sls_tracker.h | 84 ++++++------- 4 files changed, 195 insertions(+), 170 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 92471aad8..9fa2cc263 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -74,15 +74,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(goal_ref const & g, model & mdl) { +bool sls_engine::full_eval(model & mdl) { bool res = true; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(g->form(i), o, true)) + if (!mdl.eval(m_assertions[i], o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,7 +93,7 @@ bool sls_engine::full_eval(goal_ref const & g, model & mdl) { return res; } -double sls_engine::top_score(goal_ref const & g) { +double sls_engine::top_score() { #if 0 double min = m_tracker.get_score(g->form(0)); unsigned sz = g->size(); @@ -108,15 +108,15 @@ double sls_engine::top_score(goal_ref const & g) { return min; #else double top_sum = 0.0; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = m_assertions[i]; top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); + tout << " " << m_tracker.get_score(m_assertions[i]); tout << " AVG: " << top_sum / (double)sz << std::endl;); #if _CACHE_TOP_SCORE_ @@ -127,40 +127,40 @@ double sls_engine::top_score(goal_ref const & g) { #endif } -double sls_engine::rescore(goal_ref const & g) { +double sls_engine::rescore() { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(g); + return top_score(); } -double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif } -double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif } -double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { #if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif else return 0.0; @@ -170,8 +170,13 @@ double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, c } // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if( + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -179,9 +184,9 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); + double r = incremental_score_prune(fd, temp); #else - double r = incremental_score(g, fd, temp); + double r = incremental_score(fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -202,8 +207,15 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd } // same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if_local( + expr * e, + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) +{ m_evaluator.update(fd, temp); double r = m_tracker.get_score(e); if (r >= best_score) { @@ -344,13 +356,19 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); +void sls_engine::mk_random_move() { + mk_random_move(m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves)); } // will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move_vns( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; unsigned bv_sz, max_bv_sz = 0; double new_score = score; @@ -366,31 +384,31 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; // try to flip lsb mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = 0; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); SASSERT(check == score); } @@ -412,13 +430,13 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector { mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); SASSERT(check == score); } m_mpz_manager.del(old_value); @@ -427,8 +445,14 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector } // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ mpz temp2; @@ -451,7 +475,7 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } @@ -462,19 +486,19 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; #if _USE_UNARY_MINUS_ @@ -504,7 +528,7 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -572,15 +596,15 @@ double sls_engine::find_best_move_local(expr * e, ptr_vector & to_eva } // first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau(goal_ref const & g) +bool sls_engine::handle_plateau() { - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); #if _BFS_ unsigned pos = m_stats.m_moves % sz; #else unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + expr * e = m_tracker.get_unsat_assertion(sz, pos); if (!e) return 0; @@ -634,10 +658,15 @@ bool sls_engine::handle_plateau(goal_ref const & g) } // what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); +bool sls_engine::what_if( + expr * e, + func_decl * fd, + const mpz & temp, + double & best_score, + mpz & best_value, + unsigned i) +{ + double global_score = incremental_score(fd, temp); double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; @@ -651,7 +680,7 @@ bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz } // find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) +double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i) { mpz old_value, temp; double best_score = 0; @@ -662,7 +691,7 @@ double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); + what_if(e, fd, temp, best_score, best_value, i); } m_mpz_manager.del(old_value); @@ -672,15 +701,15 @@ double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl } // second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(goal_ref const & g, double old_score) +bool sls_engine::handle_plateau(double old_score) { - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); #if _BFS_ unsigned new_const = m_stats.m_moves % sz; #else unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + expr * e = m_tracker.get_unsat_assertion(m_assertions, sz, new_const); if (!e) return 0; @@ -697,12 +726,12 @@ bool sls_engine::handle_plateau(goal_ref const & g, double old_score) for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) { - new_score = find_best_move_local(g, q, fd, new_value, i); + new_score = find_best_move_local(q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); + global_score = incremental_score(fd, new_value); local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -715,7 +744,7 @@ bool sls_engine::handle_plateau(goal_ref const & g, double old_score) } // main search loop -lbool sls_engine::search(goal_ref const & g) { +lbool sls_engine::search() { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -723,8 +752,8 @@ lbool sls_engine::search(goal_ref const & g) { move_type move; unsigned plateau_cnt = 0; - score = rescore(g); - unsigned sz = g->size(); + score = rescore(); + unsigned sz = m_assertions.size(); #if _PERC_STICKY_ expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif @@ -750,7 +779,7 @@ lbool sls_engine::search(goal_ref const & g) { if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + expr * e = m_tracker.get_unsat_assertion(m_assertions, m_stats.m_moves); #endif if (!e) { @@ -793,7 +822,7 @@ lbool sls_engine::search(goal_ref const & g) { #if _VNS_ score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { @@ -811,14 +840,14 @@ lbool sls_engine::search(goal_ref const & g) { else #endif #if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(m_assertions, m_stats.m_moves); #else m_evaluator.randomize_local(to_evaluate); #endif #endif #if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); + score = m_tracker.get_top_sum() / m_assertions.size(); #else score = top_score(g); #endif @@ -828,7 +857,7 @@ lbool sls_engine::search(goal_ref const & g) { #if _REAL_RS_ || _REAL_PBFS_ score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(fd, new_value); #endif } } @@ -840,18 +869,18 @@ bailout: } // main search loop -lbool sls_engine::search_old(goal_ref const & g) { +lbool sls_engine::search_old() { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - score = rescore(g); + score = rescore(); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); tout << " TOP: " << score << std::endl;); unsigned plateau_cnt = 0; @@ -897,7 +926,7 @@ lbool sls_engine::search_old(goal_ref const & g) { old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves); if (!to_evaluate.size()) { res = l_true; @@ -908,22 +937,22 @@ lbool sls_engine::search_old(goal_ref const & g) { tout << to_evaluate[i]->get_name() << std::endl;); #if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move_vns(to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + for (unsigned i = 0; i < m_assertions.size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + tout << mk_ismt2_pp(m_assertions[i], m_manager) << std::endl; }); TRACE("sls_max", m_tracker.show_model(tout); tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl;); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << mk_ismt2_pp(m_assertions[i], m_manager) << " ---> " << + m_tracker.get_score(m_assertions[i]) << std::endl;); // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } @@ -962,14 +991,14 @@ lbool sls_engine::search_old(goal_ref const & g) { } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); tout << " TOP: " << score << std::endl;); } @@ -978,8 +1007,8 @@ lbool sls_engine::search_old(goal_ref const & g) { // score could theoretically be imprecise. // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + for (unsigned i = 0; i < m_assertions.size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) all_true = false; if (all_true) { res = l_true; // sat @@ -1010,17 +1039,17 @@ lbool sls_engine::search_old(goal_ref const & g) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); #if _INTENSIFICATION_ handle_plateau(g, score); - //handle_plateau(g); + //handle_plateau(); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(m_assertions, m_stats.m_moves); #endif - //mk_random_move(g); - score = top_score(g); + //mk_random_move(); + score = top_score(); if (score >= 1.0) { bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + for (unsigned i = 0; i < m_assertions.size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) all_true = false; if (all_true) { res = l_true; // sat @@ -1046,6 +1075,10 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); + for (unsigned i = 0; i < g->size(); i++) + assert_expr(g->form(i)); + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; @@ -1089,7 +1122,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { #if _WEIGHT_TOGGLE_ m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); #endif - m_tracker.initialize(g); + m_tracker.initialize(m_assertions); lbool res = l_undef; m_restart_limit = _RESTART_LIMIT_; @@ -1098,14 +1131,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { checkpoint(); report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); + res = search(); if (res == l_undef) { #if _RESTART_INIT_ - m_tracker.randomize(g); + m_tracker.randomize(); #else - m_tracker.reset(g); + m_tracker.reset(m_assertions); #endif } } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 878354c6d..8458817b6 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -71,6 +71,7 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; + ptr_vector m_assertions; unsigned m_restart_limit; unsigned m_max_restarts; @@ -92,11 +93,12 @@ public: void updt_params(params_ref const & _p); + void assert_expr(expr * e) { m_assertions.push_back(e); } + stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(goal_ref const & g, model & mdl); - + bool full_eval(model & mdl); void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); @@ -104,54 +106,44 @@ public: void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - - - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); - - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); - - - lbool search(goal_ref const & g); + lbool search(void); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); - lbool search_old(goal_ref const & g); + lbool search_old(void); double get_restart_armin(unsigned cnt_restarts); - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - + bool what_if(expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - double top_score(goal_ref const & g); - double rescore(goal_ref const & g); - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double top_score(); + double rescore(); + double serious_score(func_decl * fd, const mpz & new_value); + double incremental_score(func_decl * fd, const mpz & new_value); #if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score_prune(func_decl * fd, const mpz & new_value); #endif - - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - + double find_best_move(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i); + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_vns(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(goal_ref const & g); + void mk_random_move(); - bool handle_plateau(goal_ref const & g); - bool handle_plateau(goal_ref const & g, double old_score); + bool handle_plateau(void); + bool handle_plateau(double old_score); inline unsigned check_restart(unsigned curr_value); }; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 8d2a7ba1d..0053763bb 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -922,8 +922,8 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(goal_ref const & g, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(g, flip)); + void randomize_local(ptr_vector const & as, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(as, flip)); } }; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 6ac054246..1b451e8fd 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,7 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"goal.h" +#include"bv_decl_plugin.h" #include"model.h" #include"sls_compilation_settings.h" @@ -365,12 +365,12 @@ public: } }; - void calculate_expr_distances(goal_ref const & g) { + void calculate_expr_distances(ptr_vector const & as) { // precondition: m_scores is set up. - unsigned sz = g->size(); + unsigned sz = as.size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(g->form(i))); + stack.push_back(to_app(as[i])); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -418,12 +418,12 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(goal_ref const & g) { + void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = g->size(); + unsigned sz = as.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); else @@ -438,7 +438,7 @@ public: visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); @@ -450,7 +450,7 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(g); + calculate_expr_distances(as); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); @@ -465,11 +465,11 @@ public: #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(as[i]); #endif #if _UCT_ - m_touched = _UCT_INIT_ ? g->size() : 1; + m_touched = _UCT_INIT_ ? as.size() : 1; #endif } @@ -606,7 +606,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(goal_ref const & g) { + void randomize(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -620,13 +620,13 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; + m_touched = _UCT_INIT_ ? as.size() : 1; + for (unsigned i = 0; i < as.size(); i++) + m_scores.find(as[i]).touched = 1; #endif } - void reset(goal_ref const & g) { + void reset(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -636,9 +636,9 @@ public: } #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; + m_touched = _UCT_INIT_ ? as.size() : 1; + for (unsigned i = 0; i < as.size(); i++) + m_scores.find(as[i]).touched = 1; #endif } @@ -1029,13 +1029,13 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(ptr_vector const & as, unsigned sz) { if (sz == 1) return get_constants(); m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1049,22 +1049,22 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * get_unsat_assertion(ptr_vector const & as, unsigned sz, unsigned int pos) { for (unsigned i = pos; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.neq(get_value(q), m_one)) return q; } for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.neq(get_value(q), m_one)) return q; } return 0; } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(as, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; @@ -1141,19 +1141,19 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(as, sz, pos); if (!q) return m_temp_constants; return go_deeper(q); } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); + ptr_vector & get_unsat_constants(ptr_vector const & as, unsigned int flip) { + unsigned sz = as.size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + if (m_mpz_manager.eq(get_value(as[0]), m_one)) return m_temp_constants; else return get_constants(); @@ -1202,7 +1202,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1220,12 +1220,12 @@ public: return m_temp_constants; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; + m_scores.find(as[pos]).touched++; m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(as[pos]).touched = flip; #endif - expr * e = g->form(pos); + expr * e = as[pos]; // expr * e = m_list_false[pos]; #elif _BFS_ == 3 @@ -1304,11 +1304,11 @@ public: } - expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); + expr * get_unsat_assertion(ptr_vector const & as, unsigned int flip) { + unsigned sz = as.size(); if (sz == 1) - return g->form(0); + return as[0]; m_temp_constants.reset(); #if _FOCUS_ == 1 @@ -1352,7 +1352,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1370,13 +1370,13 @@ public: return 0; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; + m_scores.find(as[pos]).touched++; m_touched++; #elif _UCT_ == 2 m_scores.find(g->form(pos)).touched = flip; #endif // return m_list_false[pos]; - return g->form(pos); + return as[pos]; #elif _BFS_ == 3 unsigned int pos = -1; @@ -1430,7 +1430,7 @@ public: unsigned int pos = get_random_uint(16) % sz; return get_unsat_assertion(g, sz, pos); #endif - return g->form(pos); + return as[pos]; #elif _FOCUS_ == 2 #if _BFS_ unsigned int pos = flip % sz; From be2066a1a63158d2087fa9ee33d537c28dd52af5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Mar 2014 13:34:21 +0000 Subject: [PATCH 022/507] disabled old code --- src/tactic/sls/sls_engine.cpp | 4 +++- src/tactic/sls/sls_engine.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 9fa2cc263..cc06e4f78 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -868,6 +868,7 @@ bailout: return res; } +#if 0 // Old code. // main search loop lbool sls_engine::search_old() { lbool res = l_undef; @@ -1060,6 +1061,7 @@ lbool sls_engine::search_old() { } } } +#endif bailout: m_mpz_manager.del(new_value); @@ -1190,4 +1192,4 @@ unsigned sls_engine::check_restart(unsigned curr_value) return 0; } return 1; -} \ No newline at end of file +} diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8458817b6..5d4c9a0fc 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -114,7 +114,6 @@ public: protected: void checkpoint(); - lbool search_old(void); double get_restart_armin(unsigned cnt_restarts); bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, @@ -148,4 +147,4 @@ protected: inline unsigned check_restart(unsigned curr_value); }; -#endif \ No newline at end of file +#endif From c5e059211f5e1c919ab21714520d4f2434a50c07 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Mar 2014 13:37:04 +0000 Subject: [PATCH 023/507] bugfix --- src/tactic/sls/sls_engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index cc06e4f78..10aaf6601 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1061,13 +1061,13 @@ lbool sls_engine::search_old() { } } } -#endif bailout: m_mpz_manager.del(new_value); return res; } +#endif void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { From 883762d54a7352997bb496a0d75e29d48df851f7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:27:06 +0000 Subject: [PATCH 024/507] removed dependency of bvsls on goal_refs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 1b451e8fd..e29cebe90 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -276,13 +276,13 @@ public: } #endif - void uct_forget(goal_ref const & g) { + void uct_forget(ptr_vector & as) { expr * e; unsigned touched_old, touched_new; - for (unsigned i = 0; i < g->size(); i++) + for (unsigned i = 0; i < as.size(); i++) { - e = g->form(i); + e = as[i]; touched_old = m_scores.find(e).touched; touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); m_scores.find(e).touched = touched_new; From 176715aea07ed98b4fedf188cf2e1af1a3e4f624 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:28:40 +0000 Subject: [PATCH 025/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index e29cebe90..f5c77fc35 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include"for_each_expr.h" #include"bv_decl_plugin.h" #include"model.h" From 8e5659ac4cf795ba2f375515cbb2a5c0874ec0c0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:30:15 +0000 Subject: [PATCH 026/507] compilation fixes Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.h | 1 + src/tactic/sls/sls_tracker.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 5d4c9a0fc..96041d09e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,6 +22,7 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" +#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index f5c77fc35..50d0e4188 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -21,6 +21,7 @@ Notes: #define _SLS_TRACKER_H_ #include"for_each_expr.h" +#include"ast_smt2_pp.h" #include"bv_decl_plugin.h" #include"model.h" From 24d662ba49a487517758e6e2e7489ffdf47075fb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 14:58:59 +0000 Subject: [PATCH 027/507] bvsls refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 21 ++++++++++++--------- src/tactic/sls/sls_engine.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 10aaf6601..e7ee2abbd 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1069,6 +1069,16 @@ bailout: } #endif +void sls_engine::init_tracker() { +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(m_assertions); +} + void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { mc = 0; @@ -1078,8 +1088,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); for (unsigned i = 0; i < g->size(); i++) - assert_expr(g->form(i)); - + assert_expr(g->form(i)); verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; @@ -1118,13 +1127,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(m_assertions); + init_tracker(); lbool res = l_undef; m_restart_limit = _RESTART_LIMIT_; diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 96041d09e..c56d6ec40 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -109,6 +109,8 @@ public: void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void init_tracker(void); + lbool search(void); void operator()(goal_ref const & g, model_converter_ref & mc); From 0f5d2e010dd207b99c20696bef8eb0945d569be5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 15:26:52 +0000 Subject: [PATCH 028/507] bvsls refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 44 +++++++++++++++++++---------------- src/tactic/sls/sls_engine.h | 1 + 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index e7ee2abbd..2b359608a 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1125,8 +1125,31 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + lbool res = operator()(); + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout);); + } + g->reset(); + } + else + mc = 0; +} + +lbool sls_engine::operator()() { init_tracker(); lbool res = l_undef; @@ -1149,25 +1172,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout);); - } - g->reset(); - } - else - mc = 0; } unsigned sls_engine::check_restart(unsigned curr_value) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index c56d6ec40..c6e3af155 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -113,6 +113,7 @@ public: lbool search(void); + lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: From f8ee58b30122b53e5cd2fb9c346788c2c732f0f0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 15:28:02 +0000 Subject: [PATCH 029/507] bvsls bugfix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 2b359608a..dc4451bb5 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1172,6 +1172,8 @@ lbool sls_engine::operator()() { } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + return res; } unsigned sls_engine::check_restart(unsigned curr_value) From ef1d8f2acc9aca562a83e55f89e8820b48c525d5 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Sun, 20 Apr 2014 16:38:49 +0100 Subject: [PATCH 030/507] Current version before integration ... --- src/tactic/sls/sls_compilation_settings.h | 36 +- src/tactic/sls/sls_engine.cpp | 348 ++++++++++++++++++-- src/tactic/sls/sls_engine.h | 12 +- src/tactic/sls/sls_evaluator.h | 146 ++++++++- src/tactic/sls/sls_tactic.cpp | 4 +- src/tactic/sls/sls_tracker.h | 379 +++++++++++++++++++++- src/tactic/smtlogics/qfbv_tactic.cpp | 28 ++ 7 files changed, 885 insertions(+), 68 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 4d8c83599..d2b899dd8 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -36,17 +36,21 @@ Notes: // do we use dirty unit propagation to get rid of nested top level assertions? #define _DIRTY_UP_ 0 +// shall we use additive weighting scheme? +#define _PAWS_ 5 +#define _PAWS_INIT_ 40 + // do we use restarts? // 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 +#define _RESTARTS_ 1 // limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 +#define _RESTART_LIMIT_ 100 // 0 = initialize with all zero, 1 initialize with random value #define _RESTART_INIT_ 0 // 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat #define _RESTART_SCHEME_ 1 // base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 +#define _RESTART_CONST_ARMIN_ 2.0 // timelimit #define _TIMELIMIT_ 3600 @@ -61,6 +65,21 @@ Notes: // 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained #define _VNS_ 0 +// shall we check 2-bit flips in plateaus using Monte Carlo? +#define _VNS_MC_ 0 + +// how many 2-bit flips shall we try per bit? +#define _VNS_MC_TRIES_ 1 + +// shall we check another assertion if no improving step was found in the first one? +#define _VNS_REPICK_ 0 + +// what is the probability of doing so (percentage)? +#define _VNS_PERC_ 100 + +// do a decreasing move with percentage ... +#define _INSIST_PERC_ 0 + // do we reduce the score of unsatisfied literals? // 0 = no // 1 = yes, by multiplying it with some factor @@ -70,7 +89,7 @@ Notes: #define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 +#define _WEIGHT_DIST_FACTOR_ 0.5 // shall we toggle the weight after each restart? #define _WEIGHT_TOGGLE_ 0 @@ -82,14 +101,15 @@ Notes: // what is the percentage of random moves in plateaus (instead of full randomization)? #define _PERC_PLATEAU_MOVES_ 0 -// shall we repick clause when randomizing in a plateau or use the current one? +// shall we repick assertion when randomizing in a plateau or use the current one? +// 0 = use old one, 1 = repick according to usual scheme, 2 = repick randomly and force different one #define _REPICK_ 1 // do we use some UCT-like scheme for assertion-selection? overrides _BFS_ #define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 +#define _UCT_CONSTANT_ 20.0 // is uct clause selection probabilistic similar to variable selection in sparrow? // 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score @@ -103,11 +123,11 @@ Notes: // how shall we initialize the _UCT_ total touched counter? // 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 +#define _UCT_INIT_ 0 // do we gradually reduce the touched values of _UCT_? #define _UCT_FORGET_ 0 -#define _UCT_FORGET_FACTOR_ 0.5 +#define _UCT_FORGET_FACTOR_ 0.9 // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 92471aad8..342e649af 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -169,6 +169,14 @@ double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, c #endif } +double sls_engine::incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune_new(fd, new_value)) + return (m_tracker.get_top_sum() / g->size()); + else + return 0.0; +} + // checks whether the score outcome of a given move is better than the previous score bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { @@ -190,8 +198,33 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd m_mpz_manager.del(old_value); #endif - // if (r >= best_score) { + //if (r >= best_score) { if (r > best_score) { + m_tracker.reset_equal_scores(); + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + /*else if (r == best_score) { + if (m_tracker.get_random_uint(16) % m_tracker.inc_equal_scores() == 0) + { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + }*/ + + return false; +} + +bool sls_engine::what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + + double r = incremental_score_prune_new(g, fd, temp); + + if (r >= best_score) { best_score = r; best_const = fd_inx; m_mpz_manager.set(best_value, temp); @@ -426,39 +459,25 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector return new_score; } -// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif - unsigned bv_sz; + unsigned bv_sz, max_bv_sz = 0; double new_score = score; - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { -#else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { -#endif - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); @@ -471,9 +490,121 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + for (unsigned j = 1; j < max_bv_sz; j++) + { + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif + unsigned bv_sz; +#if _INSIST_PERC_ + double new_score = m_tracker.get_random_uint(16) % 100 < _INSIST_PERC_ ? 0.0 : score; +#else + double new_score = score; +#endif + + m_tracker.reset_equal_scores(); + +// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { +// for (unsigned i = m_tracker.get_random_uint(16) % to_evaluate.size(); i != to_evaluate.size(); i = to_evaluate.size()) { +// for (unsigned i = to_evaluate.size(); i-- > 0; ) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { +#else +// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz; j++) { +// for (unsigned j = bv_sz; j-- > 0; ) { +#endif + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + //if (m_tracker.get_random_uint(1)) + //if ((move != MV_FLIP) || (new_bit > j)) + //{ + //if (what_if_new(g, fd, i, temp, new_score, best_const, best_value)) { + // new_bit = j; + // move = MV_FLIP; + //} + //} + //else + //{ + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + //} + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } #endif // try inverting mk_inv(bv_sz, old_value, temp); + //if (m_tracker.get_random_uint(1)) if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; @@ -514,6 +645,50 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif + + if ((new_score == score) && 1)// (m_tracker.get_random_uint(1))) + best_const = -1; + + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value) { + mpz old_value, temp, temp2; + unsigned bv_sz; + double new_score = score; + +// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { +// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz; j++) { + mk_flip(srt, old_value, j, temp); + for (unsigned l = 0; l < _VNS_MC_TRIES_ && l < bv_sz / 2; l++) + { + unsigned k = m_tracker.get_random_uint(16) % bv_sz; + while (k == j) + k = m_tracker.get_random_uint(16) % bv_sz; + mk_flip(srt, temp, k, temp2); + what_if(g, fd, i, temp2, new_score, best_const, best_value); + } + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + m_mpz_manager.del(temp2); + return new_score; } @@ -725,6 +900,13 @@ lbool sls_engine::search(goal_ref const & g) { score = rescore(g); unsigned sz = g->size(); + + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + #if _PERC_STICKY_ expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif @@ -738,9 +920,18 @@ lbool sls_engine::search(goal_ref const & g) { #else while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #endif + //if (m_stats.m_stopwatch.get_current_seconds() > 10.0) + //{printf("Got %f fps and size is %d with avg bw %f\n", m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds(), m_tracker.get_formula_size(), m_tracker.get_avg_bw(g)); exit(0);} + checkpoint(); m_stats.m_moves++; +#if _UCT_FORGET_ + //if (m_stats.m_moves % sz == 0) + if (m_stats.m_moves % _UCT_FORGET_ == 0) + m_tracker.uct_forget(g); +#endif + #if _REAL_RS_ || _REAL_PBFS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif @@ -757,6 +948,7 @@ lbool sls_engine::search(goal_ref const & g) { res = l_true; goto bailout; } + //ptr_vector & to_evaluate = m_tracker.get_unsat_constants_only(e); ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); #else ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); @@ -789,6 +981,8 @@ lbool sls_engine::search(goal_ref const & g) { #endif old_score = score; new_const = (unsigned)-1; + move = MV_FLIP; + new_bit = 0; #if _VNS_ score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); @@ -796,6 +990,60 @@ lbool sls_engine::search(goal_ref const & g) { score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); #endif +#if _VNS_MC_ > _VNS_REPICK_ +#if _VNS_MC_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); +#endif +#if _VNS_REPICK_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } +#endif +#endif + +#if _VNS_MC_ < _VNS_REPICK_ +#if _VNS_REPICK_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } +#endif +#if _VNS_MC_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); +#endif +#endif + +#if (_VNS_MC_ == _VNS_REPICK_) && _VNS_MC_ && _VNS_REPICK_ + if (new_const == static_cast(-1)) { + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); + else { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } + } +#endif + + if (new_const == static_cast(-1)) { score = old_score; plateau_cnt++; @@ -810,10 +1058,19 @@ lbool sls_engine::search(goal_ref const & g) { mk_random_move(to_evaluate); else #endif -#if _REPICK_ +#if _REPICK_ == 1 m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _REPICK_ == 2 + { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + m_evaluator.randomize_local(q); + else + m_evaluator.randomize_local(e); + } #else - m_evaluator.randomize_local(to_evaluate); + m_evaluator.randomize_local_n(g, to_evaluate); + //m_evaluator.randomize_local(to_evaluate); #endif #endif @@ -822,10 +1079,28 @@ lbool sls_engine::search(goal_ref const & g) { #else score = top_score(g); #endif + +#if _PAWS_ + for (unsigned i = 0; i < sz; i++) + { + expr * q = g->form(i); + if (m_tracker.get_random_uint(16) % 100 < _PAWS_) + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) + m_tracker.decrease_weight(q); + } + else + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) + m_tracker.increase_weight(q); + } + } +#endif + } else { func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ score = serious_score(g, fd, new_value); #else score = incremental_score(g, fd, new_value); @@ -961,7 +1236,7 @@ lbool sls_engine::search_old(goal_ref const & g) { case MV_DIV2: m_stats.m_div2s++; break; } -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ score = serious_score(g, fd, new_value); #else score = incremental_score(g, fd, new_value); @@ -1056,7 +1331,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_PAWS_ " << _PAWS_ << std::endl; + verbose_stream() << "_PAWS_INIT_ " << _PAWS_INIT_ << std::endl; verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_VNS_MC_ " << _VNS_MC_ << std::endl; + verbose_stream() << "_VNS_MC_TRIES_ " << _VNS_MC_TRIES_ << std::endl; + verbose_stream() << "_VNS_REPICK_ " << _VNS_REPICK_ << std::endl; + verbose_stream() << "_VNS_PERC_ " << _VNS_PERC_ << std::endl; + verbose_stream() << "_INSIST_PERC_ " << _INSIST_PERC_ << std::endl; verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; @@ -1067,6 +1349,8 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; + verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; @@ -1136,7 +1420,9 @@ unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_limit) { -#if _RESTART_SCHEME_ == 4 +#if _RESTART_SCHEME_ == 5 + m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); +#elif _RESTART_SCHEME_ == 4 m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; @@ -1144,9 +1430,11 @@ unsigned sls_engine::check_restart(unsigned curr_value) m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) + //if (m_stats.m_restarts % 3 == 2) m_restart_limit += _RESTART_LIMIT_; else m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; + //m_restart_limit += (2 << (m_stats.m_restarts / 3)) * _RESTART_LIMIT_; #else m_restart_limit += _RESTART_LIMIT_; #endif diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 878354c6d..902c6b7a0 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -108,7 +108,13 @@ public: double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - + + double find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + double find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value); + double find_best_move_local(expr * e, ptr_vector & to_evaluate, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); @@ -132,6 +138,10 @@ protected: bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); + bool what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + double incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value); + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 8d2a7ba1d..78f2cb79a 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -575,7 +575,7 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); @@ -584,12 +584,13 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif #endif + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -634,7 +635,7 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); @@ -643,7 +644,7 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); @@ -683,7 +684,7 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ run_serious_update(max_depth); #else run_update(max_depth); @@ -729,14 +730,16 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + //if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) pot_benefits = 1; if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + //if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { @@ -771,7 +774,7 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); @@ -858,6 +861,104 @@ public: } #endif + unsigned run_update_bool_prune_new(unsigned cur_depth) { + expr_fast_mark1 visited; + + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); + + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + prune_score = m_tracker.get_score_prune(cur); + m_tracker.set_score(cur, new_score); + + if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; + + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + else + { + } + } + + cur_depth_exprs.reset(); + cur_depth--; + + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } + + return pot_benefits; + } + + unsigned update_prune_new(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + + if (m_traversal_stack_bool.size() <= cur_depth) + m_traversal_stack_bool.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune_new(cur_depth); + } + void randomize_local(ptr_vector & unsat_constants) { // Randomize _all_ candidates: @@ -901,7 +1002,7 @@ public: mpz temp = m_tracker.get_random(fd->get_range()); #endif -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ serious_update(fd, temp); #else update(fd, temp); @@ -922,9 +1023,36 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(goal_ref const & g, unsigned int flip) { + void randomize_local(goal_ref const & g, unsigned int flip) { randomize_local(m_tracker.get_unsat_constants(g, flip)); } + + void randomize_local_n(goal_ref const & g, ptr_vector & unsat_constants) { + unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); + func_decl * fd = unsat_constants[r]; + sort * srt = fd->get_range(); + unsigned bv_sz = m_manager.is_bool(srt) ? 1 : m_bv_util.get_bv_size(srt); + mpz max_val = m_tracker.get_random(srt); + update(fd, max_val); + double max_score = m_tracker.get_top_sum() / g->size(); + mpz temp_val; + double temp_score; + for (unsigned i = 1; i < 2; i++) + //for (unsigned i = 1; i < bv_sz; i++) + { + m_mpz_manager.set(temp_val, m_tracker.get_random(srt)); + update(fd, temp_val); + temp_score = m_tracker.get_top_sum() / g->size(); + if (temp_score > max_score) + { + m_mpz_manager.set(max_val, temp_val); + max_score = temp_score; + } + } + update(fd, max_val); + m_mpz_manager.del(temp_val); + m_mpz_manager.del(max_val); + } }; #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index a9b110224..7a9252fe2 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -161,14 +161,14 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { mk_max_bv_sharing_tactic(m), // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? //mk_ctx_simplify_tactic(m, ctx_p), - // Andreas: This one at least eliminates top level duplicates ... + // Andreas: This one at least eliminates top level duplicates ... but has very bad effects on performance! //mk_simplify_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); +// tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 6ac054246..87c90f1f8 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -86,12 +86,17 @@ private: obj_map m_where_false; expr** m_list_false; #endif +#if _PAWS_ + obj_map m_weights; + //obj_map m_weights; +#endif #if _CACHE_TOP_SCORE_ double m_top_sum; #endif #if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ double m_weight_dist_factor; #endif + unsigned m_equal_scores; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -111,15 +116,52 @@ public: m_mpz_manager.del(m_two); } + unsigned get_formula_size() { + return m_scores.size(); + } + + double get_avg_bw(goal_ref const & g) { + double sum = 0.0; + unsigned count = 0; + + for (unsigned i = 0; i < g->size(); i++) + { + m_temp_constants.reset(); + ptr_vector const & this_decls = m_constants_occ.find(g->form(i)); + unsigned sz = this_decls.size(); + for (unsigned i = 0; i < sz; i++) { + func_decl * fd = this_decls[i]; + m_temp_constants.push_back(fd); + sort * srt = fd->get_range(); + sum += (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + count++; + } + } + + return sum / count; + } + #if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ inline void set_weight_dist_factor(double val) { m_weight_dist_factor = val; } #endif + void reset_equal_scores() { + m_equal_scores = 1; + } + + unsigned inc_equal_scores() { + return ++m_equal_scores; + } + #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { + inline void adapt_top_sum(expr * e, double add, double sub) { +#if _PAWS_ + m_top_sum += m_weights.find(e) * (add - sub); +#else m_top_sum += add - sub; +#endif } inline void set_top_sum(double new_score) { @@ -276,6 +318,7 @@ public: } #endif +#if _UCT_ void uct_forget(goal_ref const & g) { expr * e; unsigned touched_old, touched_new; @@ -289,6 +332,7 @@ public: m_touched += touched_new - touched_old; } } +#endif void initialize(app * n) { // Build score table @@ -463,6 +507,15 @@ public: //} #endif +#if _PAWS_ + for (unsigned i = 0; i < sz; i++) + { + expr * e = g->form(i); + if (!m_weights.contains(e)) + m_weights.insert(e, _PAWS_INIT_); + } +#endif + #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) setup_occs(g->form(i)); @@ -473,6 +526,30 @@ public: #endif } +#if _PAWS_ + void increase_weight(expr * e) + { + //printf("Increasing %d to", m_weights.find(e)); + m_weights.find(e)++; + //m_weights.find(e) *= 1.1; + //printf(" %d\n", m_weights.find(e)); + } + + void decrease_weight(expr * e) + { + unsigned old_weight = m_weights.find(e); + m_weights.find(e) = old_weight > _PAWS_INIT_ ? old_weight - 1 : _PAWS_INIT_; + //m_weights.find(e) = old_weight > 1.1 ? old_weight / 1.1 : 1; + //printf("Decreasing %d to %d\n", old_weight, m_weights.find(e)); + } + + unsigned get_weight(expr * e) + //double get_weight(expr * e) + { + return m_weights.find(e); + } +#endif + #if _REAL_RS_ || _REAL_PBFS_ void make_assertion(expr * e) { @@ -763,6 +840,7 @@ public: const mpz & v1 = get_value(arg1); if (negated) { + //res = (m_mpz_manager.eq(v0, v1)) ? 0.5 * (m_bv_util.get_bv_size(arg0) - 1.0) / m_bv_util.get_bv_size(arg0) : 1.0; res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << std::endl; ); @@ -809,40 +887,209 @@ public: SASSERT(a->get_num_args() == 2); const mpz & x = get_value(a->get_arg(0)); const mpz & y = get_value(a->get_arg(1)); - unsigned bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); if (negated) { if (m_mpz_manager.gt(x, y)) + { + /*mpz diff; + m_mpz_manager.sub(x, y, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +/* mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_gt = 0; + unsigned curr_gt = 0; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 1; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 0; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); + m_mpz_manager.del(x_copy); + m_mpz_manager.del(y_copy);*/ +#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= rational(m_powers(bv_sz)); + double dbl = 1.0 - n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + m_mpz_manager.del(diff); +#endif + } + } + else { + if (m_mpz_manager.le(x, y)) + { + /*mpz diff; + m_mpz_manager.sub(y, x, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); - } - } - else { - if (m_mpz_manager.le(x, y)) + res = 1.0 + 0.5 * dbl;*/ res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +/* mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_le = 1; + unsigned curr_le = 1; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_le = curr_le; + curr_le = 0; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_le = curr_le; + curr_le = 1; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2);*/ +#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); + double dbl = 1.0 - n.get_double(); res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - else if (m_bv_util.is_bv_sle(n)) { // x <= y +/* else if (m_bv_util.is_bv_sle(n)) { // x <= y + app * a = to_app(n); + SASSERT(a->get_num_args() == 2); + const mpz & x = get_value(a->get_arg(0)); + const mpz & y = get_value(a->get_arg(1)); + int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + + mpz x_unsigned; + mpz y_unsigned; + const mpz & p = m_powers(bv_sz); + const mpz & p_half = m_powers(bv_sz-1); + if (x >= p_half) { m_mpz_manager.sub(x, p, x_unsigned); } + if (y >= p_half) { m_mpz_manager.sub(y, p, y_unsigned); } + + if (negated) { + if (x_unsigned > y_unsigned) + res = 1.0; + else { + mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_gt = 0; + unsigned curr_gt = 0; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 1; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 0; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); + m_mpz_manager.del(x_copy); + m_mpz_manager.del(y_copy); + } + } + else { + if (x_unsigned <= y_unsigned) + res = 1.0; + else { + mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_le = 1; + unsigned curr_le = 1; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_le = curr_le; + curr_le = 0; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_le = curr_le; + curr_le = 1; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2); + } + } + TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << + m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); + + m_mpz_manager.del(x_unsigned); + m_mpz_manager.del(y_unsigned); + }*/ + else if (m_bv_util.is_bv_sle(n)) { // x <= y app * a = to_app(n); SASSERT(a->get_num_args() == 2); mpz x; m_mpz_manager.set(x, get_value(a->get_arg(0))); @@ -855,31 +1102,61 @@ public: if (negated) { if (x > y) - res = 1.0; + { + /*mpz diff; + m_mpz_manager.sub(x, y, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ + res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= p; - double dbl = n.get_double(); - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + double dbl = 1.0 - n.get_double(); + //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } else { if (x <= y) - res = 1.0; + { + /*mpz diff; + m_mpz_manager.sub(y, x, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ + res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); + SASSERT(!m_mpz_manager.is_neg(diff)); rational n(diff); n /= p; - double dbl = n.get_double(); + double dbl = 1.0 - n.get_double(); res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); @@ -1149,12 +1426,58 @@ public: return go_deeper(q); } + void go_deeper_only(expr * e) { + //if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + //if (m_mpz_manager.neq(get_value(q), m_one)) go_deeper(q); + } + go_deeper(args[pos]); + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + go_deeper(q); + } + } + //} + else + { + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + } + } + + ptr_vector & get_unsat_constants_only(expr * e) { + if (e && !m_temp_constants.size()) + go_deeper_only(e); + + return m_temp_constants; + } + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + { + m_temp_constants.reset(); return m_temp_constants; + } else return get_constants(); } @@ -1303,12 +1626,15 @@ public: } } - expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); - if (sz == 1) - return g->form(0); + if (sz == 1) { + if (m_mpz_manager.eq(get_value(g->form(0)), m_zero)) + return g->form(0); + else + return 0; + } m_temp_constants.reset(); #if _FOCUS_ == 1 @@ -1357,7 +1683,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #elif _UCT_ == 3 @@ -1440,6 +1766,23 @@ public: return get_unsat_constants_crsat(g, sz, pos); #endif } + + expr * get_new_unsat_assertion(goal_ref const & g, expr * e) { + unsigned sz = g->size(); + + if (sz == 1) + return 0; + + m_temp_constants.reset(); + + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (g->form(i) != e)) pos = i; + + if (pos == static_cast(-1)) + return 0; + return g->form(pos); + } }; #endif \ No newline at end of file diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index ac53ca0c8..a7870176d 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -28,6 +28,8 @@ Notes: #include"bv_size_reduction_tactic.h" #include"aig_tactic.h" #include"sat_tactic.h" +//#include"nnf_tactic.h" +//#include"sls_tactic.h" #define MEMLIMIT 300 @@ -93,6 +95,32 @@ tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) { mk_sat_tactic(m)); #endif + /* use full sls + tactic * st = using_params(and_then(preamble_st, + cond(mk_is_qfbv_probe(), + cond(mk_is_qfbv_eq_probe(), + and_then(mk_bv1_blaster_tactic(m), + using_params(mk_smt_tactic(), solver_p)), + and_then(mk_nnf_tactic(m, p), mk_sls_tactic(m))), + mk_smt_tactic())), + main_p);*/ + + /* use pure dpll + tactic * st = using_params(and_then(mk_simplify_tactic(m), + cond(mk_is_qfbv_probe(), + and_then(mk_bit_blaster_tactic(m), + when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)), + and_then(using_params(and_then(mk_simplify_tactic(m), + mk_solve_eqs_tactic(m)), + local_ctx_p), + if_no_proofs(cond(mk_produce_unsat_cores_probe(), + mk_aig_tactic(), + using_params(mk_aig_tactic(), + big_aig_p))))), + new_sat), + mk_smt_tactic())), + main_p);*/ + tactic * st = using_params(and_then(preamble_st, // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function // symbols. In this case, we should not use From c1741d794155eea8041ef78075aff29b6bbce900 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 00:32:45 +0100 Subject: [PATCH 031/507] Almost cleaned up version. --- src/tactic/sls/sls_compilation_settings.h | 72 +------ src/tactic/sls/sls_engine.cpp | 231 +++++++--------------- src/tactic/sls/sls_engine.h | 13 +- src/tactic/sls/sls_evaluator.h | 175 ++-------------- src/tactic/sls/sls_tactic.cpp | 6 +- src/tactic/sls/sls_tracker.h | 170 ++++++++-------- 6 files changed, 177 insertions(+), 490 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 73ba1ffab..9add78daa 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,83 +22,13 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT) -#define _FOCUS_ 1 - -// shall we use additive weighting scheme? -#define _PAWS_ 5 -#define _PAWS_INIT_ 40 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 1 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 100 -//// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 2.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// shall we check 2-bit flips in plateaus using Monte Carlo? -#define _VNS_MC_ 0 - -// how many 2-bit flips shall we try per bit? -#define _VNS_MC_TRIES_ 1 - -// shall we check another assertion if no improving step was found in the first one? -#define _VNS_REPICK_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no, 1 = yes, by multiplying it with some factor -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.5 - -// shall we repick assertion when randomizing in a plateau or use the current one? -// 0 = use old one, 1 = repick according to usual scheme, 2 = repick randomly and force different one -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 20.0 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 0 - -// do we gradually reduce the touched values of _UCT_? -#define _UCT_FORGET_ 0 -#define _UCT_FORGET_FACTOR_ 0.9 - // shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 +#define _USE_ADDSUB_ 0 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 - // shall we use early pruning for incremental update? #define _EARLY_PRUNE_ 1 -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - -#if ((_UCT_ > 0) + _REAL_RS_ > 1) -InvalidConfiguration; -#endif - #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 938b6e0df..c240a0c51 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -44,6 +44,7 @@ sls_engine::sls_engine(ast_manager & m, params_ref const & p) : m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) { updt_params(p); + m_tracker.updt_params(p); } sls_engine::~sls_engine() { @@ -52,19 +53,21 @@ sls_engine::~sls_engine() { m_mpz_manager.del(m_two); } -double sls_engine::get_restart_armin(unsigned cnt_restarts) -{ - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); -} - void sls_engine::updt_params(params_ref const & _p) { sls_params p(_p); m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); + m_max_restarts = p.max_restarts(); m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); + m_walksat = p.walksat(); + m_walksat_repick = p.walksat_repick(); + m_paws_sp = p.paws_sp(); + m_wp = p.wp(); + m_vns_mc = p.vns_mc(); + m_vns_repick = p.vns_repick(); + + m_restart_base = p.restart_base(); + m_restart_next = m_restart_base; + m_restart_init = p.restart_init(); } void sls_engine::checkpoint() { @@ -105,9 +108,7 @@ double sls_engine::top_score() { tout << " " << m_tracker.get_score(m_assertions[i]); tout << " AVG: " << top_sum / (double)sz << std::endl;); -#if _CACHE_TOP_SCORE_ m_tracker.set_top_sum(top_sum); -#endif return top_sum / (double)sz; } @@ -121,37 +122,21 @@ double sls_engine::rescore() { double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ return (m_tracker.get_top_sum() / m_assertions.size()); -#else - return top_score(); -#endif } double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ return (m_tracker.get_top_sum() / m_assertions.size()); -#else - return top_score(); -#endif } double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { -#if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ return (m_tracker.get_top_sum() / m_assertions.size()); -#else - return top_score(); -#endif else return 0.0; -#else - NOT_IMPLEMENTED_YET(); -#endif } // checks whether the score outcome of a given move is better than the previous score @@ -261,7 +246,7 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + move_type mt = MV_FLIP; #endif unsigned bit = 0; @@ -300,7 +285,7 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout);); } - m_evaluator.update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_mpz_manager.del(new_value); } @@ -385,7 +370,7 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { for (unsigned j = 0; j < bv_sz; j++) { mk_flip(srt, old_value, j, temp); - for (unsigned l = 0; l < _VNS_MC_TRIES_ && l < bv_sz / 2; l++) + for (unsigned l = 0; l < m_vns_mc && l < bv_sz / 2; l++) { unsigned k = m_tracker.get_random_uint(16) % bv_sz; while (k == j) @@ -411,144 +396,85 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double lbool sls_engine::search() { lbool res = l_undef; double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; + unsigned new_const = (unsigned)-1, new_bit; mpz new_value; move_type move; - unsigned plateau_cnt = 0; score = rescore(); unsigned sz = m_assertions.size(); -#if _RESTARTS_ - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - + while (check_restart(m_stats.m_moves)) { checkpoint(); m_stats.m_moves++; - -#if _UCT_FORGET_ - if (m_stats.m_moves % _UCT_FORGET_ == 0) - m_tracker.uct_forget(g); -#endif + if (m_stats.m_moves % m_restart_base == 0) + m_tracker.ucb_forget(m_assertions); #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif - -#if _FOCUS_ - expr * e = m_tracker.get_unsat_assertion(m_assertions); - - if (!e) - { - res = l_true; - goto bailout; - } - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(m_assertions, sz); + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) { res = l_true; goto bailout; } -#endif - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); -#if _CACHE_TOP_SCORE_ score = m_tracker.get_top_sum() / sz; -#else - score = top_score(g); -#endif continue; } old_score = score; new_const = (unsigned)-1; - move = MV_FLIP; - new_bit = 0; score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); -#if _VNS_MC_ > _VNS_REPICK_ -#if _VNS_MC_ - if (new_const == static_cast(-1)) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); -#endif -#if _VNS_REPICK_ - if (new_const == static_cast(-1)) + if (m_vns_mc && (new_const == static_cast(-1))) + score = find_best_move_mc(to_evaluate, score, new_const, new_value); + + /*if (m_vns_repick && (new_const == static_cast(-1))) { - expr * q = m_tracker.get_new_unsat_assertion(g, e); + expr * q = m_tracker.get_new_unsat_assertion(m_assertions, e); if (q) { ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); } - } -#endif -#endif - -#if _VNS_MC_ < _VNS_REPICK_ -#if _VNS_REPICK_ - if (new_const == static_cast(-1)) - { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } - } -#endif -#if _VNS_MC_ - if (new_const == static_cast(-1)) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); -#endif -#endif + }*/ if (new_const == static_cast(-1)) { score = old_score; - plateau_cnt++; -#if _REPICK_ + if (m_walksat && m_walksat_repick) m_evaluator.randomize_local(m_assertions); -#else + else m_evaluator.randomize_local(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ score = m_tracker.get_top_sum() / m_assertions.size(); -#else - score = top_score(g); -#endif -#if _PAWS_ - for (unsigned i = 0; i < sz; i++) + if (m_paws_sp < 1024) { - expr * q = m_assertions[i]; - if (m_tracker.get_random_uint(16) % 100 < _PAWS_) + for (unsigned i = 0; i < sz; i++) { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) - m_tracker.decrease_weight(q); - } - else - { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) - m_tracker.increase_weight(q); + expr * q = m_assertions[i]; + if (m_tracker.get_random_uint(10) < m_paws_sp) + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) + m_tracker.decrease_weight(q); + } + else + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) + m_tracker.increase_weight(q); + } } } -#endif - } else { func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _PAWS_ score = serious_score(fd, new_value); -#else - score = incremental_score(fd, new_value); -#endif } } @@ -569,30 +495,9 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_PAWS_ " << _PAWS_ << std::endl; - verbose_stream() << "_PAWS_INIT_ " << _PAWS_INIT_ << std::endl; - verbose_stream() << "_VNS_MC_ " << _VNS_MC_ << std::endl; - verbose_stream() << "_VNS_MC_TRIES_ " << _VNS_MC_TRIES_ << std::endl; - verbose_stream() << "_VNS_REPICK_ " << _VNS_REPICK_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; - verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; lbool res = operator()(); @@ -620,8 +525,6 @@ lbool sls_engine::operator()() { m_tracker.initialize(m_assertions); lbool res = l_undef; - m_restart_limit = _RESTART_LIMIT_; - do { checkpoint(); @@ -630,39 +533,53 @@ lbool sls_engine::operator()() { if (res == l_undef) { -#if _RESTART_INIT_ - m_tracker.randomize(); -#else - m_tracker.reset(m_assertions); -#endif + if (m_restart_init) + m_tracker.randomize(m_assertions); + else + m_tracker.reset(m_assertions); } - } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + } while (res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; return res; } -unsigned sls_engine::check_restart(unsigned curr_value) +/* Andreas: Needed for Armin's restart scheme if we don't want to use loops. +inline double sls_engine::get_restart_armin(unsigned cnt_restarts) { - if (curr_value > m_restart_limit) + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); +} +*/ + +inline unsigned sls_engine::check_restart(unsigned curr_value) +{ + if (curr_value > m_restart_next) { + /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save 1 parameter. + I leave the other versions as comments in case you want to try it again somewhen. #if _RESTART_SCHEME_ == 5 - m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); + m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); #elif _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); + m_restart_next += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? m_restart_base : (m_restart_base * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; + m_restart_next += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * m_restart_base; #elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; + m_restart_next += get_luby(m_stats.m_restarts + 1) * m_restart_base; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) - m_restart_limit += _RESTART_LIMIT_; + m_restart_next += m_restart_base; else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; + m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; #else - m_restart_limit += _RESTART_LIMIT_; -#endif + m_restart_limit += m_restart_base; +#endif */ + if (m_stats.m_restarts & 1) + m_restart_next += m_restart_base; + else + m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; return 0; } return 1; diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 4e5af8c93..ff0e55f24 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -70,9 +70,16 @@ protected: sls_evaluator m_evaluator; ptr_vector m_assertions; - unsigned m_restart_limit; unsigned m_max_restarts; - unsigned m_plateau_limit; + unsigned m_walksat; + unsigned m_walksat_repick; + unsigned m_wp; + unsigned m_vns_mc; + unsigned m_vns_repick; + unsigned m_paws_sp; + unsigned m_restart_base; + unsigned m_restart_next; + unsigned m_restart_init; ptr_vector m_old_values; @@ -110,7 +117,6 @@ public: protected: void checkpoint(); - double get_restart_armin(unsigned cnt_restarts); bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); @@ -129,6 +135,7 @@ protected: void mk_random_move(ptr_vector & unsat_constants); + //inline double get_restart_armin(unsigned cnt_restarts); inline unsigned check_restart(unsigned curr_value); }; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index da2a4b29f..37bfa5a2d 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -81,11 +81,7 @@ public: case OP_AND: { m_mpz_manager.set(result, m_one); for (unsigned i = 0; i < n_args; i++) -#if _DIRTY_UP_ - if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) && !m_tracker.is_top_expr(args[i])) { -#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { -#endif m_mpz_manager.set(result, m_zero); break; } @@ -93,11 +89,7 @@ public: } case OP_OR: { for (unsigned i = 0; i < n_args; i++) -#if _DIRTY_UP_ - if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) || m_tracker.is_top_expr(args[i])) { -#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { -#endif m_mpz_manager.set(result, m_one); break; } @@ -105,16 +97,9 @@ public: } case OP_NOT: { SASSERT(n_args == 1); -#if _DIRTY_UP_ - if (m_tracker.is_top_expr(args[0])) - m_mpz_manager.set(result, m_zero); - else - m_mpz_manager.set(result, (m_mpz_manager.is_zero(m_tracker.get_value(args[0]))) ? m_one : m_zero); -#else const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); -#endif break; } case OP_EQ: { @@ -545,9 +530,7 @@ public: expr_fast_mark1 visited; mpz new_value; -#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ double new_score; -#endif SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { @@ -569,23 +552,12 @@ public: } #endif + new_score = m_tracker.score(cur); + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif - m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); -#else -#if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif #endif if (m_tracker.has_uplinks(cur)) { @@ -614,9 +586,7 @@ public: expr_fast_mark1 visited; mpz new_value; -#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ double new_score; -#endif SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { @@ -627,23 +597,12 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); + new_score = m_tracker.score(cur); + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif - m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); -#else -#if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif #endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -679,11 +638,7 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } -#if _REAL_RS_ || _PAWS_ run_serious_update(max_depth); -#else - run_update(max_depth); -#endif } void update(func_decl * fd, const mpz & new_value) { @@ -708,7 +663,6 @@ public: run_serious_update(cur_depth); } -#if _EARLY_PRUNE_ unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; @@ -722,10 +676,9 @@ public: expr * cur = cur_depth_exprs[i]; new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); @@ -746,9 +699,6 @@ public: } } } - else - { - } } cur_depth_exprs.reset(); @@ -762,14 +712,11 @@ public: for (unsigned i = 0; i < cur_size; i++) { expr * cur = cur_depth_exprs[i]; -#if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -850,103 +797,6 @@ public: } return run_update_bool_prune(cur_depth); } -#endif - - unsigned run_update_bool_prune_new(unsigned cur_depth) { - expr_fast_mark1 visited; - - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); - - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - - for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - prune_score = m_tracker.get_score_prune(cur); - m_tracker.set_score(cur, new_score); - - if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; - - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - else - { - } - } - - cur_depth_exprs.reset(); - cur_depth--; - - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } - - return pot_benefits; - } - - unsigned update_prune_new(func_decl * fd, const mpz & new_value) { - m_tracker.set_value(fd, new_value); - expr * ep = m_tracker.get_entry_point(fd); - unsigned cur_depth = m_tracker.get_distance(ep); - - if (m_traversal_stack_bool.size() <= cur_depth) - m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); - - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune_new(cur_depth); - } void randomize_local(ptr_vector & unsat_constants) { // Randomize _one_ candidate: @@ -954,11 +804,8 @@ public: func_decl * fd = unsat_constants[r]; mpz temp = m_tracker.get_random(fd->get_range()); -#if _REAL_RS_ || _PAWS_ serious_update(fd, temp); -#else - update(fd, temp); -#endif + m_mpz_manager.del(temp); TRACE("sls", tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 7a9252fe2..2a40e908d 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -159,16 +159,12 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? - //mk_ctx_simplify_tactic(m, ctx_p), - // Andreas: This one at least eliminates top level duplicates ... but has very bad effects on performance! - //mk_simplify_tactic(m), mk_nnf_tactic(m, p)); } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); -// tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); + //tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 235ab9471..65011dc8d 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -39,11 +39,7 @@ class sls_tracker { mpz m_zero, m_one, m_two; struct value_score { -#if _EARLY_PRUNE_ value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; -#else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; -#endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; @@ -80,20 +76,22 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; -#if _UCT_ + + unsigned m_walksat; + unsigned m_ucb; + double m_ucb_constant; + unsigned m_ucb_init; + double m_ucb_forget; unsigned m_touched; -#endif + double m_scale_unsat; + unsigned m_paws_init; #if _REAL_RS_ ptr_vector m_unsat_expr; obj_map m_where_false; expr** m_list_false; #endif -#if _PAWS_ obj_map m_weights; -#endif -#if _CACHE_TOP_SCORE_ double m_top_sum; -#endif unsigned m_equal_scores; public: @@ -114,6 +112,17 @@ public: m_mpz_manager.del(m_two); } + void updt_params(params_ref const & _p) { + sls_params p(_p); + m_walksat = p.walksat(); + m_ucb = p.walksat_ucb(); + m_ucb_constant = p.walksat_ucb_constant(); + m_ucb_init = p.walksat_ucb_init(); + m_ucb_forget = p.walksat_ucb_forget(); + m_scale_unsat = p.scale_unsat(); + m_paws_init = p.paws_init(); + } + unsigned get_formula_size() { return m_scores.size(); } @@ -147,13 +156,8 @@ public: return ++m_equal_scores; } -#if _CACHE_TOP_SCORE_ inline void adapt_top_sum(expr * e, double add, double sub) { -#if _PAWS_ m_top_sum += m_weights.find(e) * (add - sub); -#else - m_top_sum += add - sub; -#endif } inline void set_top_sum(double new_score) { @@ -163,7 +167,6 @@ public: inline double get_top_sum() { return m_top_sum; } -#endif inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); @@ -209,7 +212,6 @@ public: return get_score(ep); } -#if _EARLY_PRUNE_ inline void set_score_prune(expr * n, double score) { SASSERT(m_scores.contains(n)); m_scores.find(n).score_prune = score; @@ -229,7 +231,6 @@ public: SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; } -#endif inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); @@ -310,17 +311,20 @@ public: } #endif - void uct_forget(ptr_vector & as) { - expr * e; - unsigned touched_old, touched_new; - - for (unsigned i = 0; i < as.size(); i++) + inline void ucb_forget(ptr_vector & as) { + if (m_ucb_forget < 1.0) { - e = as[i]; - touched_old = m_scores.find(e).touched; - touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); - m_scores.find(e).touched = touched_new; - m_touched += touched_new - touched_old; + expr * e; + unsigned touched_old, touched_new; + + for (unsigned i = 0; i < as.size(); i++) + { + e = as[i]; + touched_old = m_scores.find(e).touched; + touched_new = (unsigned)((touched_old - 1) * m_ucb_forget + 1); + m_scores.find(e).touched = touched_new; + m_touched += touched_new - touched_old; + } } } @@ -490,26 +494,21 @@ public: //} #endif -#if _PAWS_ for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; if (!m_weights.contains(e)) - m_weights.insert(e, _PAWS_INIT_); + m_weights.insert(e, m_paws_init); } -#endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) setup_occs(as[i]); #endif -#if _UCT_ - m_touched = _UCT_INIT_ ? as.size() : 1; -#endif + m_touched = m_ucb_init ? as.size() : 1; } -#if _PAWS_ void increase_weight(expr * e) { m_weights.find(e)++; @@ -518,14 +517,13 @@ public: void decrease_weight(expr * e) { unsigned old_weight = m_weights.find(e); - m_weights.find(e) = old_weight > _PAWS_INIT_ ? old_weight - 1 : _PAWS_INIT_; + m_weights.find(e) = old_weight > m_paws_init ? old_weight - 1 : m_paws_init; } unsigned get_weight(expr * e) { return m_weights.find(e); } -#endif #if _REAL_RS_ void make_assertion(expr * e) @@ -684,7 +682,6 @@ public: } } -#if _EARLY_PRUNE_ void setup_occs(expr * n, bool negated = false) { if (m_manager.is_bool(n)) { @@ -717,7 +714,6 @@ public: else NOT_IMPLEMENTED_YET(); } -#endif double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); @@ -735,20 +731,17 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. -#if _SCORE_AND_AVG_ + /* Andreas: Seems to have no effect. But maybe you want to try it again at some point. double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) sum += get_score(args[i]); - res = sum / (double) a->get_num_args(); -#else + res = sum / (double) a->get_num_args(); */ double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; } res = min; -#endif } else if (m_manager.is_or(n)) { SASSERT(!negated); @@ -927,13 +920,11 @@ public: SASSERT(res >= 0.0 && res <= 1.0); -#if _WEIGHT_DIST_ app * a = to_app(n); family_id afid = a->get_family_id(); if (afid == m_bv_util.get_family_id()) - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; -#endif + if (res < 1.0) res *= m_scale_unsat; TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; @@ -995,8 +986,8 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(ptr_vector const & as, unsigned sz) { - + ptr_vector & get_unsat_constants_gsat(ptr_vector const & as) { + unsigned sz = as.size(); if (sz == 1) { if (m_mpz_manager.neq(get_value(as[0]), m_one)) return get_constants(); @@ -1033,89 +1024,88 @@ public: } ptr_vector & get_unsat_constants(ptr_vector const & as) { -#if _FOCUS_ - expr * e = get_unsat_assertion(as); - - if (!e) + if (m_walksat) { - m_temp_constants.reset(); - return m_temp_constants; - } + expr * e = get_unsat_assertion(as); - return get_unsat_constants_walksat(e); -#else - return m_tracker.get_unsat_constants_gsat(as, sz); -#endif + if (!e) + { + m_temp_constants.reset(); + return m_temp_constants; + } + + return get_unsat_constants_walksat(e); + } + else + return get_unsat_constants_gsat(as); } expr * get_unsat_assertion(ptr_vector const & as) { unsigned sz = as.size(); - if (sz == 1) { if (m_mpz_manager.neq(get_value(as[0]), m_one)) return as[0]; else return 0; } - m_temp_constants.reset(); -#if _UCT_ + unsigned pos = -1; - value_score vscore; - double max = -1.0; + if (m_ucb) + { + value_score vscore; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); -#if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); -#elif _UCT_ == 3 + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); +#if _UCT_ == 3 double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - if (pos == static_cast(-1)) - return 0; + if (pos == static_cast(-1)) + return 0; -#if _UCT_ - m_scores.find(as[pos]).touched++; - m_touched++; -#endif + m_scores.find(as[pos]).touched++; + m_touched++; // return m_list_false[pos]; + } + else + { + unsigned cnt_unsat = 0; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return 0; + } + return as[pos]; -#elif _REAL_RS_ +#if _REAL_RS_ //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; sz = m_where_false.size(); if (sz == 0) return 0; return m_list_false[get_random_uint(16) % sz]; -#else - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return 0; #endif - return as[pos]; } - expr * get_new_unsat_assertion(goal_ref const & g, expr * e) { - unsigned sz = g->size(); - + expr * get_new_unsat_assertion(ptr_vector const & as, expr * e) { + unsigned sz = as.size(); if (sz == 1) return 0; - m_temp_constants.reset(); - + unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (g->form(i) != e)) pos = i; + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (as[i] != e)) pos = i; if (pos == static_cast(-1)) return 0; - return g->form(pos); + return as[pos]; } }; From 8346aed39c927923365efa3c2dbabc5bace18cb7 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 01:07:30 +0100 Subject: [PATCH 032/507] Fixed bug with VNS repick. --- src/tactic/sls/sls_compilation_settings.h | 2 +- src/tactic/sls/sls_engine.cpp | 22 +++++++++++++++++----- src/tactic/sls/sls_tracker.h | 7 ++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 9add78daa..a649bc9ed 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -23,7 +23,7 @@ Notes: #define _SLS_COMPILATION_SETTINGS_H_ // shall we use addition/subtraction? -#define _USE_ADDSUB_ 0 +#define _USE_ADDSUB_ 1 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index c240a0c51..af8ae1df2 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -68,6 +68,12 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_base = p.restart_base(); m_restart_next = m_restart_base; m_restart_init = p.restart_init(); + + // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. + if (m_walksat_repick && !m_walksat) + NOT_IMPLEMENTED_YET(); + if (m_vns_repick && !m_walksat) + NOT_IMPLEMENTED_YET(); } void sls_engine::checkpoint() { @@ -435,19 +441,25 @@ lbool sls_engine::search() { if (m_vns_mc && (new_const == static_cast(-1))) score = find_best_move_mc(to_evaluate, score, new_const, new_value); - /*if (m_vns_repick && (new_const == static_cast(-1))) + if (m_vns_repick && (new_const == static_cast(-1))) { - expr * q = m_tracker.get_new_unsat_assertion(m_assertions, e); + expr * q = m_tracker.get_new_unsat_assertion(m_assertions); if (q) { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); + + if (new_const != static_cast(-1)) { + func_decl * fd = to_evaluate2[new_const]; + score = serious_score(fd, new_value); + continue; + } } - }*/ + } if (new_const == static_cast(-1)) { score = old_score; - if (m_walksat && m_walksat_repick) + if (m_walksat_repick) m_evaluator.randomize_local(m_assertions); else m_evaluator.randomize_local(to_evaluate); diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 65011dc8d..7b48057d4 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -76,7 +76,7 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; - + unsigned m_last_pos; unsigned m_walksat; unsigned m_ucb; double m_ucb_constant; @@ -1082,6 +1082,7 @@ public: return 0; } + m_last_pos = pos; return as[pos]; #if _REAL_RS_ //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; @@ -1093,7 +1094,7 @@ public: #endif } - expr * get_new_unsat_assertion(ptr_vector const & as, expr * e) { + expr * get_new_unsat_assertion(ptr_vector const & as) { unsigned sz = as.size(); if (sz == 1) return 0; @@ -1101,7 +1102,7 @@ public: unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (as[i] != e)) pos = i; + if ((i != m_last_pos) && m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return 0; From c441bb4388e6cd007c68e0974f4acf2c3a4e7d33 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 16:10:44 +0100 Subject: [PATCH 033/507] Backup before I touch early pruning ... --- src/tactic/sls/sls_compilation_settings.h | 3 --- src/tactic/sls/sls_engine.cpp | 30 +++++++++++++---------- src/tactic/sls/sls_engine.h | 1 + src/tactic/sls/sls_evaluator.h | 4 +-- src/tactic/sls/sls_tracker.h | 9 ------- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index a649bc9ed..5c837b4b2 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,9 +22,6 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index af8ae1df2..5d4df237e 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -61,6 +61,7 @@ void sls_engine::updt_params(params_ref const & _p) { m_walksat = p.walksat(); m_walksat_repick = p.walksat_repick(); m_paws_sp = p.paws_sp(); + m_paws = m_paws_sp < 1024; m_wp = p.wp(); m_vns_mc = p.vns_mc(); m_vns_repick = p.vns_repick(); @@ -173,7 +174,6 @@ bool sls_engine::what_if( // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { - m_tracker.reset_equal_scores(); best_score = r; best_const = fd_inx; m_mpz_manager.set(best_value, temp); @@ -244,16 +244,12 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); else { -#if _USE_ADDSUB_ if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; move_type mt = (move_type)rnd_mv; // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; -#else - move_type mt = MV_FLIP; -#endif unsigned bit = 0; switch (mt) @@ -308,8 +304,9 @@ double sls_engine::find_best_move( unsigned bv_sz; double new_score = score; - m_tracker.reset_equal_scores(); - + //unsigned offset = m_tracker.get_random_uint(16) % to_evaluate.size(); + //for (unsigned j = 0; j < to_evaluate.size(); j++) { + //unsigned i = (j + offset) % to_evaluate.size(); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -328,7 +325,6 @@ double sls_engine::find_best_move( } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); @@ -341,7 +337,6 @@ double sls_engine::find_best_move( if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } -#endif // try inverting mk_inv(bv_sz, old_value, temp); if (what_if(fd, i, temp, new_score, best_const, best_value)) @@ -418,7 +413,7 @@ lbool sls_engine::search() { #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif - + // get candidate variables ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) { @@ -426,6 +421,7 @@ lbool sls_engine::search() { goto bailout; } + // random walk with probability wp / 1024 if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); @@ -436,14 +432,18 @@ lbool sls_engine::search() { old_score = score; new_const = (unsigned)-1; + // find best increasing move score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + // use Monte Carlo 2-bit-flip sampling if no increasing move was found previously if (m_vns_mc && (new_const == static_cast(-1))) score = find_best_move_mc(to_evaluate, score, new_const, new_value); + // repick assertion if no increasing move was found previously if (m_vns_repick && (new_const == static_cast(-1))) { expr * q = m_tracker.get_new_unsat_assertion(m_assertions); + // only apply if another unsatisfied assertion actually exists if (q) { ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); @@ -457,6 +457,7 @@ lbool sls_engine::search() { } } + // randomize if no increasing move was found if (new_const == static_cast(-1)) { score = old_score; if (m_walksat_repick) @@ -466,16 +467,19 @@ lbool sls_engine::search() { score = m_tracker.get_top_sum() / m_assertions.size(); - if (m_paws_sp < 1024) + // update assertion weights if a weigthing is enabled (sp < 1024) + if (m_paws) { for (unsigned i = 0; i < sz; i++) { expr * q = m_assertions[i]; + // smooth weights with probability sp / 1024 if (m_tracker.get_random_uint(10) < m_paws_sp) { if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) m_tracker.decrease_weight(q); } + // increase weights otherwise else { if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) @@ -484,6 +488,7 @@ lbool sls_engine::search() { } } } + // otherwise, apply most increasing move else { func_decl * fd = to_evaluate[new_const]; score = serious_score(fd, new_value); @@ -507,7 +512,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; @@ -570,7 +574,7 @@ inline unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_next) { - /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save 1 parameter. + /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save one parameter. I leave the other versions as comments in case you want to try it again somewhen. #if _RESTART_SCHEME_ == 5 m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ff0e55f24..94f3fa626 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -76,6 +76,7 @@ protected: unsigned m_wp; unsigned m_vns_mc; unsigned m_vns_repick; + unsigned m_paws; unsigned m_paws_sp; unsigned m_restart_base; unsigned m_restart_next; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 37bfa5a2d..200a0e380 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -37,9 +37,7 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; -#if _EARLY_PRUNE_ vector > m_traversal_stack_bool; -#endif public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -753,7 +751,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // Andreas: Should actually always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 7b48057d4..a815c9ad3 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -92,7 +92,6 @@ private: #endif obj_map m_weights; double m_top_sum; - unsigned m_equal_scores; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -148,14 +147,6 @@ public: return sum / count; } - void reset_equal_scores() { - m_equal_scores = 1; - } - - unsigned inc_equal_scores() { - return ++m_equal_scores; - } - inline void adapt_top_sum(expr * e, double add, double sub) { m_top_sum += m_weights.find(e) * (add - sub); } From 9ebfb119dbd87babb52bed8eb55eee5c061cbcba Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Wed, 23 Apr 2014 14:52:18 +0100 Subject: [PATCH 034/507] Moved parameters to the right file. Almost clean. --- src/tactic/sls/sls_compilation_settings.h | 5 +-- src/tactic/sls/sls_engine.cpp | 38 +++++++++++------------ src/tactic/sls/sls_engine.h | 3 +- src/tactic/sls/sls_evaluator.h | 5 --- src/tactic/sls/sls_params.pyg | 20 ++++++++++-- src/tactic/sls/sls_tracker.h | 33 +++++++++----------- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 5c837b4b2..707802cf4 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,10 +22,7 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +// should we use unsat-structures as done in SLS 4 SAT? #define _REAL_RS_ 0 -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 5d4df237e..a1c72609c 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -70,6 +70,8 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_next = m_restart_base; m_restart_init = p.restart_init(); + m_early_prune = p.early_prune(); + // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. if (m_walksat_repick && !m_walksat) NOT_IMPLEMENTED_YET(); @@ -117,7 +119,7 @@ double sls_engine::top_score() { m_tracker.set_top_sum(top_sum); - return top_sum / (double)sz; + return top_sum; } double sls_engine::rescore() { @@ -129,21 +131,21 @@ double sls_engine::rescore() { double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); } double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); } double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); else - return 0.0; + return -DBL_MAX; } // checks whether the score outcome of a given move is better than the previous score @@ -160,11 +162,11 @@ bool sls_engine::what_if( m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif -#if _EARLY_PRUNE_ - double r = incremental_score_prune(fd, temp); -#else - double r = incremental_score(fd, temp); -#endif + double r; + if (m_early_prune) + r = incremental_score_prune(fd, temp); + else + r = incremental_score(fd, temp); #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl;); @@ -342,11 +344,8 @@ double sls_engine::find_best_move( if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; } - // reset to what it was before - double check = incremental_score(fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); + incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -381,9 +380,8 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double } } } - // reset to what it was before - double check = incremental_score(fd, old_value); + incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -408,7 +406,10 @@ lbool sls_engine::search() { checkpoint(); m_stats.m_moves++; if (m_stats.m_moves % m_restart_base == 0) + { m_tracker.ucb_forget(m_assertions); + //score = rescore(); + } #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); @@ -425,7 +426,7 @@ lbool sls_engine::search() { if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); - score = m_tracker.get_top_sum() / sz; + score = m_tracker.get_top_sum(); continue; } @@ -465,7 +466,7 @@ lbool sls_engine::search() { else m_evaluator.randomize_local(to_evaluate); - score = m_tracker.get_top_sum() / m_assertions.size(); + score = m_tracker.get_top_sum(); // update assertion weights if a weigthing is enabled (sp < 1024) if (m_paws) @@ -513,7 +514,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { assert_expr(g->form(i)); verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; lbool res = operator()(); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 94f3fa626..ac8610871 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -81,8 +81,7 @@ protected: unsigned m_restart_base; unsigned m_restart_next; unsigned m_restart_init; - - ptr_vector m_old_values; + unsigned m_early_prune; typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 200a0e380..e4cf3c466 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -554,9 +554,7 @@ public: if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#if _EARLY_PRUNE_ m_tracker.set_score_prune(cur, new_score); -#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -599,9 +597,6 @@ public: if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#if _EARLY_PRUNE_ - m_tracker.set_score_prune(cur, new_score); -#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index cc3e05966..98875b20d 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -2,7 +2,21 @@ def_module_params('sls', export=True, description='Experimental Stochastic Local Search Solver (for QFBV only).', params=(max_memory_param(), - ('restarts', UINT, UINT_MAX, '(max) number of restarts'), - ('plateau_limit', UINT, 10, 'pleateau limit'), - ('random_seed', UINT, 0, 'random seed') + ('max_restarts', UINT, UINT_MAX, 'maximum number of restarts'), + ('walksat', BOOL, 1, 'use walksat assertion selection (instead of gsat)'), + ('walksat_ucb', BOOL, 1, 'use bandit heuristic for walksat assertion selection (instead of random)'), + ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), + ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), + ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), + ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), + ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), + ('paws_init', UINT, 40, 'initial/minimum assertion weights'), + ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), + ('wp', UINT, 0, 'random walk with probability wp / 1024'), + ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), + ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), + ('restart_base', UINT, 100, 'base restart interval given by moves per run'), + ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), + ('early_prune', BOOL, 1, 'use early pruning for score prediction'), + ('random_seed', UINT, 0, 'random seed') )) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index a815c9ad3..507596273 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -44,11 +44,9 @@ class sls_tracker { unsynch_mpz_manager * m; mpz value; double score; -#if _EARLY_PRUNE_ double score_prune; unsigned has_pos_occ; unsigned has_neg_occ; -#endif unsigned distance; // max distance from any root unsigned touched; value_score & operator=(const value_score & other) { @@ -122,6 +120,7 @@ public: m_paws_init = p.paws_init(); } + /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. unsigned get_formula_size() { return m_scores.size(); } @@ -145,7 +144,7 @@ public: } return sum / count; - } + }*/ inline void adapt_top_sum(expr * e, double add, double sub) { m_top_sum += m_weights.find(e) * (add - sub); @@ -417,6 +416,8 @@ public: } } + /* Andreas: Used this at some point to have values for the non-top-level expressions. + However, it did not give better performance but even cause some additional m/o - is not used currently. void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { if (m_manager.is_and(e) || m_manager.is_or(e)) { app * a = to_app(e); @@ -445,7 +446,7 @@ public: find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + }*/ void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); @@ -455,8 +456,6 @@ public: expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); - else - printf("this is already in ...\n"); for_each_expr(proc, visited, e); } @@ -464,7 +463,6 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; - // Andreas: Maybe not fully correct. ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -488,15 +486,16 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; - if (!m_weights.contains(e)) + + // initialize weights + if (!m_weights.contains(e)) m_weights.insert(e, m_paws_init); + + // positive/negative occurences used for early pruning + setup_occs(as[i]); } -#if _EARLY_PRUNE_ - for (unsigned i = 0; i < sz; i++) - setup_occs(as[i]); -#endif - + // initialize ucb total touched value (individual ones are always initialized to 1) m_touched = m_ucb_init ? as.size() : 1; } @@ -738,7 +737,6 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); @@ -764,7 +762,6 @@ public: const mpz & v1 = get_value(arg1); if (negated) { - //res = (m_mpz_manager.eq(v0, v1)) ? 0.5 * (m_bv_util.get_bv_size(arg0) - 1.0) / m_bv_util.get_bv_size(arg0) : 1.0; res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << std::endl; ); @@ -1051,10 +1048,8 @@ public: // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); -#if _UCT_ == 3 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); -#endif + //double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + (get_random_uint(8) * 0.0000002); if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } if (pos == static_cast(-1)) From 0279a1042d6f7088e4628e592dc5ac9ef253bc92 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Apr 2014 18:39:36 +0100 Subject: [PATCH 035/507] FPA API documentation fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 7 +++---- src/api/dotnet/FPExpr.cs | 3 ++- src/api/dotnet/FPRMExpr.cs | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 7ef91f7ac..b654feb7e 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3506,8 +3506,7 @@ namespace Microsoft.Z3 /// /// Create a floating point NaN numeral. - /// - /// A string representing the value in decimal notation. + /// /// floating point sort. public FPNum MkFPNaN(FPSort s) { @@ -3517,8 +3516,7 @@ namespace Microsoft.Z3 /// /// Create a floating point Inf numeral. - /// - /// A string representing the value in decimal notation. + /// /// floating point sort. /// indicates whether the result should be negative. public FPNum MkFPInf(FPSort s, bool negative) @@ -3625,6 +3623,7 @@ namespace Microsoft.Z3 /// /// Floating-point square root /// + /// rounding mode term /// floating point term public FPExpr MkFPSqrt(FPRMExpr rm, FPExpr t) { diff --git a/src/api/dotnet/FPExpr.cs b/src/api/dotnet/FPExpr.cs index 66b3fc10d..0bb1e4c09 100644 --- a/src/api/dotnet/FPExpr.cs +++ b/src/api/dotnet/FPExpr.cs @@ -30,7 +30,8 @@ namespace Microsoft.Z3 /// public class FPExpr : Expr { - #region Internal + #region Internal + /// Constructor for FPExpr internal protected FPExpr(Context ctx) : base(ctx) { diff --git a/src/api/dotnet/FPRMExpr.cs b/src/api/dotnet/FPRMExpr.cs index fa43a346a..b95816023 100644 --- a/src/api/dotnet/FPRMExpr.cs +++ b/src/api/dotnet/FPRMExpr.cs @@ -31,6 +31,7 @@ namespace Microsoft.Z3 public class FPRMExpr : Expr { #region Internal + /// Constructor for FPRMExpr internal protected FPRMExpr(Context ctx) : base(ctx) { From a8b65ebb360168c9659e943e3f264690c5d8e3f8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Apr 2014 20:10:53 +0100 Subject: [PATCH 036/507] added stubs for theory_fpa Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 36 +++++++++++++++++++++++++++++++++++ src/ast/fpa/fpa2bv_rewriter.h | 6 ++---- src/smt/smt_setup.cpp | 15 +++++++++++++++ src/smt/smt_setup.h | 6 +++++- src/smt/theory_fpa.cpp | 19 ++++++++++++++++-- src/smt/theory_fpa.h | 8 +++++--- 6 files changed, 80 insertions(+), 10 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 27bf6de2c..4363ee382 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2595,6 +2595,42 @@ void substitute_vars_example() { Z3_del_context(ctx); } +void fpa_example() { + Z3_config cfg; + Z3_context ctx; + Z3_sort double_sort, rm_sort; + Z3_symbol symbol_rm, symbol_x, symbol_y; + Z3_ast rm, x, y, n, c; + + printf("\nFPA-example\n"); + LOG_MSG("FPA-example"); + + enable_trace("fpa"); + + cfg = Z3_mk_config(); + ctx = Z3_mk_context(cfg); + Z3_del_config(cfg); + + double_sort = Z3_mk_fpa_sort(ctx, 11, 53); + rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); + + symbol_rm = Z3_mk_string_symbol(ctx, "rm"); + rm = Z3_mk_const(ctx, symbol_rm, rm_sort); + symbol_x = Z3_mk_string_symbol(ctx, "x"); + symbol_y = Z3_mk_string_symbol(ctx, "y"); + x = Z3_mk_const(ctx, symbol_x, double_sort); + y = Z3_mk_const(ctx, symbol_y, double_sort); + n = Z3_mk_double(ctx, 42.0, double_sort); + + c = Z3_mk_eq(ctx, Z3_mk_fpa_add(ctx, rm, x, y), n); + + Z3_assert_cnstr(ctx, c); + if (Z3_check(ctx) != Z3_L_TRUE) + printf("FPA-example not satisfied!\n"); + + Z3_del_context(ctx); +} + /*@}*/ /*@}*/ diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index b2e3da939..bdfa6ca3f 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -64,9 +64,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { } bool max_steps_exceeded(unsigned num_steps) const { - cooperate("fpa2bv"); - if (memory::get_allocation_size() > m_max_memory) - throw tactic_exception(TACTIC_MAX_MEMORY_MSG); + cooperate("fpa2bv"); return num_steps > m_max_steps; } @@ -147,7 +145,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { default: TRACE("fpa2bv", tout << "unsupported operator: " << f->get_name() << "\n"; for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << std::endl;); - throw tactic_exception("NYI"); + NOT_IMPLEMENTED_YET(); } } diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 51b83d61c..64477164a 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -30,6 +30,7 @@ Revision History: #include"theory_dummy.h" #include"theory_dl.h" #include"theory_seq_empty.h" +#include"theory_fpa.h" namespace smt { @@ -679,6 +680,15 @@ namespace smt { setup_mi_arith(); } + void setup::setup_QF_FPA() { + m_context.register_plugin(alloc(smt::theory_fpa, m_manager)); + } + + void setup::setup_QF_FPABV() { + setup_QF_BV(); + m_context.register_plugin(alloc(smt::theory_fpa, m_manager)); + } + bool is_arith(static_features const & st) { return st.m_num_arith_ineqs > 0 || st.m_num_arith_terms > 0 || st.m_num_arith_eqs > 0; } @@ -780,6 +790,10 @@ namespace smt { m_context.register_plugin(alloc(theory_seq_empty, m_manager)); } + void setup::setup_fpa() { + m_context.register_plugin(alloc(theory_fpa, m_manager)); + } + void setup::setup_unknown() { setup_arith(); setup_arrays(); @@ -787,6 +801,7 @@ namespace smt { setup_datatypes(); setup_dl(); setup_seq(); + setup_fpa(); } void setup::setup_unknown(static_features & st) { diff --git a/src/smt/smt_setup.h b/src/smt/smt_setup.h index e0188537e..299ce7834 100644 --- a/src/smt/smt_setup.h +++ b/src/smt/smt_setup.h @@ -75,6 +75,8 @@ namespace smt { void setup_QF_AX(static_features const & st); void setup_QF_AUFLIA(); void setup_QF_AUFLIA(static_features const & st); + void setup_QF_FPA(); + void setup_QF_FPABV(); void setup_LRA(); void setup_AUFLIA(bool simple_array = true); void setup_AUFLIA(static_features const & st); @@ -91,10 +93,12 @@ namespace smt { void setup_bv(); void setup_arith(); void setup_dl(); - void setup_seq(); + void setup_seq(); void setup_instgen(); void setup_i_arith(); void setup_mi_arith(); + void setup_fpa(); + public: setup(context & c, smt_params & params); void mark_already_configured() { m_already_configured = true; } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 147d87496..e235dbb06 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -17,14 +17,29 @@ Revision History: --*/ #include"ast_smt2_pp.h" +#include"smt_context.h" #include"theory_fpa.h" namespace smt { + theory_fpa::theory_fpa(ast_manager & m) : + theory(m.mk_family_id("float")), + m_converter(m), + m_rw(m, m_converter, params_ref()) + { + } + bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { - TRACE("bv", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); + TRACE("fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); - NOT_IMPLEMENTED_YET(); + + ast_manager & m = get_manager(); + context & ctx = get_context(); + + expr_ref res(m); + m_rw(atom, res); + SASSERT(res.get() != atom); + ctx.internalize(res, gate_ctx); return true; } diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 3716247d3..bb3a8b786 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -21,14 +21,16 @@ Revision History: #include"smt_theory.h" #include"fpa2bv_converter.h" +#include"fpa2bv_rewriter.h" namespace smt { class theory_fpa : public theory { fpa2bv_converter m_converter; + fpa2bv_rewriter m_rw; virtual final_check_status final_check_eh() { return FC_DONE; } - virtual bool internalize_atom(app*, bool); - virtual bool internalize_term(app*) { return internalize_atom(0, false); } + virtual bool internalize_atom(app * a, bool); + virtual bool internalize_term(app * a) { return internalize_atom(a, false); } virtual void new_eq_eh(theory_var, theory_var); virtual void new_diseq_eh(theory_var, theory_var); virtual void push_scope_eh(); @@ -36,7 +38,7 @@ namespace smt { virtual theory* mk_fresh(context*) { return alloc(theory_fpa, get_manager()); } virtual char const * get_name() const { return "fpa"; } public: - theory_fpa(ast_manager& m) : theory(m.mk_family_id("fpa")), m_converter(m) {} + theory_fpa(ast_manager& m); }; }; From 3df2967be92549427ad1410c41f37c80df8e3726 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Fri, 25 Apr 2014 13:56:15 +0100 Subject: [PATCH 037/507] Cleaned up final SLS version. Enjoy! --- src/tactic/sls/sls_compilation_settings.h | 28 ---- src/tactic/sls/sls_engine.cpp | 43 ++++-- src/tactic/sls/sls_engine.h | 2 + src/tactic/sls/sls_evaluator.h | 8 +- src/tactic/sls/sls_params.pyg | 6 +- src/tactic/sls/sls_tracker.h | 153 ++++++++-------------- 6 files changed, 94 insertions(+), 146 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 707802cf4..e69de29bb 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -1,28 +0,0 @@ -/*++ -Copyright (c) 2014 Microsoft Corporation - -Module Name: - - sls_compilation_constants.h - -Abstract: - - Stochastic Local Search (SLS) compilation constants - -Author: - - Christoph (cwinter) 2014-03-19 - -Notes: - - This file should go away completely once we have evaluated all options. - ---*/ - -#ifndef _SLS_COMPILATION_SETTINGS_H_ -#define _SLS_COMPILATION_SETTINGS_H_ - -// should we use unsat-structures as done in SLS 4 SAT? -#define _REAL_RS_ 0 - -#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index a1c72609c..269790902 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -71,6 +71,8 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_init = p.restart_init(); m_early_prune = p.early_prune(); + m_random_offset = p.random_offset(); + m_rescore = p.rescore(); // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. if (m_walksat_repick && !m_walksat) @@ -174,6 +176,9 @@ bool sls_engine::what_if( m_mpz_manager.del(old_value); #endif + // Andreas: Had this idea on my last day. Maybe we could add a noise here similar to the one that worked so well for ucb assertion selection. + // r += 0.0001 * m_tracker.get_random_uint(8); + // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { best_score = r; @@ -248,9 +253,15 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) { if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + + // Andreas: The other option would be to scale the probability for flips according to the bit-width. + /* unsigned bv_sz2 = m_bv_util.get_bv_size(srt); + rnd_mv = m_tracker.get_random_uint(16) % (bv_sz2 + 3); + if (rnd_mv > 3) rnd_mv = 0; */ + move_type mt = (move_type)rnd_mv; - // inversion doesn't make sense, let's do a flip instead. + // Andreas: Christoph claimed inversion doesn't make sense, let's do a flip instead. Is this really true? if (mt == MV_INV) mt = MV_FLIP; unsigned bit = 0; @@ -306,10 +317,13 @@ double sls_engine::find_best_move( unsigned bv_sz; double new_score = score; - //unsigned offset = m_tracker.get_random_uint(16) % to_evaluate.size(); - //for (unsigned j = 0; j < to_evaluate.size(); j++) { - //unsigned i = (j + offset) % to_evaluate.size(); - for (unsigned i = 0; i < to_evaluate.size(); i++) { + // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. + unsigned sz = to_evaluate.size(); + unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; + for (unsigned j = 0; j < sz; j++) { + unsigned i = j + offset; + if (i >= sz) i -= sz; + //for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -361,7 +375,13 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double unsigned bv_sz; double new_score = score; - for (unsigned i = 0; i < to_evaluate.size(); i++) { + // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. + unsigned sz = to_evaluate.size(); + unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; + for (unsigned j = 0; j < sz; j++) { + unsigned i = j + offset; + if (i >= sz) i -= sz; + //for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -405,15 +425,16 @@ lbool sls_engine::search() { while (check_restart(m_stats.m_moves)) { checkpoint(); m_stats.m_moves++; + + // Andreas: Every base restart interval ... if (m_stats.m_moves % m_restart_base == 0) { + // ... potentially smooth the touched counters ... m_tracker.ucb_forget(m_assertions); - //score = rescore(); + // ... or normalize the top-level score. + if (m_rescore) score = rescore(); } -#if _REAL_RS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif // get candidate variables ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) @@ -513,8 +534,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - lbool res = operator()(); if (res == l_true) { diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ac8610871..8158808fa 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -82,6 +82,8 @@ protected: unsigned m_restart_next; unsigned m_restart_init; unsigned m_early_prune; + unsigned m_random_offset; + unsigned m_rescore; typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index e4cf3c466..61afb7457 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -22,7 +22,6 @@ Notes: #include"model_evaluator.h" -#include"sls_compilation_settings.h" #include"sls_powers.h" #include"sls_tracker.h" @@ -540,19 +539,16 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); -#if _REAL_RS_ + new_score = m_tracker.score(cur); if (m_tracker.is_top_expr(cur)) { + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); if (m_mpz_manager.eq(new_value,m_one)) m_tracker.make_assertion(cur); else m_tracker.break_assertion(cur); } -#endif - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index 98875b20d..ad7a22675 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -8,15 +8,19 @@ def_module_params('sls', ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), + ('walksat_ucb_noise', DOUBLE, 0.0002, 'add noise 0 <= 256 * ucb_noise to ucb score for assertion selection'), ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), ('paws_init', UINT, 40, 'initial/minimum assertion weights'), ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), - ('wp', UINT, 0, 'random walk with probability wp / 1024'), + ('wp', UINT, 100, 'random walk with probability wp / 1024'), ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), + ('random_offset', BOOL, 1, 'use random offset vor candidate evaluation'), + ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), + ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') )) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 507596273..4356bcc9b 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -80,14 +80,13 @@ private: double m_ucb_constant; unsigned m_ucb_init; double m_ucb_forget; + double m_ucb_noise; unsigned m_touched; double m_scale_unsat; unsigned m_paws_init; -#if _REAL_RS_ - ptr_vector m_unsat_expr; obj_map m_where_false; expr** m_list_false; -#endif + unsigned m_track_unsat; obj_map m_weights; double m_top_sum; @@ -116,8 +115,12 @@ public: m_ucb_constant = p.walksat_ucb_constant(); m_ucb_init = p.walksat_ucb_init(); m_ucb_forget = p.walksat_ucb_forget(); + m_ucb_noise = p.walksat_ucb_noise(); m_scale_unsat = p.scale_unsat(); m_paws_init = p.paws_init(); + // Andreas: track_unsat is currently disabled because I cannot guarantee that it is not buggy. + // If you want to use it, you will also need to change comments in the assertion selection. + m_track_unsat = 0;//p.track_unsat(); } /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. @@ -254,53 +257,6 @@ public: return m_uplinks.find(n); } -#if _REAL_RS_ - void debug_real(goal_ref const & g, unsigned flip) - { - unsigned count = 0; - for (unsigned i = 0; i < g->size(); i++) - { - expr * e = g->form(i); - if (m_mpz_manager.eq(get_value(e),m_one) && m_where_false.contains(e)) - { - printf("iteration %d: ", flip); - printf("form %d is sat but in unsat list at position %d of %d\n", i, m_where_false.find(e), m_where_false.size()); - exit(4); - } - - if (m_mpz_manager.eq(get_value(e),m_zero) && !m_where_false.contains(e)) - { - printf("iteration %d: ", flip); - printf("form %d is unsat but not in unsat list\n", i); - exit(4); - } - - if (m_mpz_manager.eq(get_value(e),m_zero) && m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - expr * q = m_list_false[pos]; - if (q != e) - { - printf("iteration %d: ", flip); - printf("form %d is supposed to be at pos %d in unsat list but something else was there\n", i, pos); - exit(4); - } - } - - if (m_mpz_manager.eq(get_value(e),m_zero)) - count++; - } - - // should be true now that duplicate assertions are removed - if (count != m_where_false.size()) - { - printf("iteration %d: ", flip); - printf("%d are unsat but list is of size %d\n", count, m_where_false.size()); - exit(4); - } - } -#endif - inline void ucb_forget(ptr_vector & as) { if (m_ucb_forget < 1.0) { @@ -474,14 +430,15 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); -#if _REAL_RS_ - m_list_false = new expr*[sz]; - //for (unsigned i = 0; i < sz; i++) - //{ - // if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - // break_assertion(g->form(i)); - //} -#endif + if (m_track_unsat) + { + m_list_false = new expr*[sz]; + for (unsigned i = 0; i < sz; i++) + { + if (m_mpz_manager.eq(get_value(as[i]), m_zero)) + break_assertion(as[i]); + } + } for (unsigned i = 0; i < sz; i++) { @@ -515,44 +472,36 @@ public: return m_weights.find(e); } -#if _REAL_RS_ void make_assertion(expr * e) { - if (m_where_false.contains(e)) + if (m_track_unsat) { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) + if (m_where_false.contains(e)) { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - //printf("Moving %d from %d to %d\n", q, m_where_false.size(), pos); + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } } - //else - //printf("Erasing %d from %d to %d\n", e, pos); -// m_list_false[m_where_false.size()] = 0; -// printf("Going in %d\n", m_where_false.size()); } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); } void break_assertion(expr * e) { - //printf("I'm broken... that's still fine.\n"); - if (!m_where_false.contains(e)) + if (m_track_unsat) { - //printf("This however is not so cool...\n"); - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + } } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); } -#endif void show_model(std::ostream & out) { unsigned sz = get_num_constants(); @@ -1043,24 +992,38 @@ public: { value_score vscore; double max = -1.0; + // Andreas: Commented things here might be used for track_unsat data structures as done in SLS for SAT. But seems to have no benefit. + /* for (unsigned i = 0; i < m_where_false.size(); i++) { + expr * e = m_list_false[i]; */ for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; -// for (unsigned i = 0; i < m_where_false.size(); i++) { -// expr * e = m_list_false[i]; - vscore = m_scores.find(e); - //double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + (get_random_uint(8) * 0.0000002); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (m_mpz_manager.neq(get_value(e), m_one)) + { + vscore = m_scores.find(e); + // Andreas: Select the assertion with the greatest ucb score. Potentially add some noise. + // double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + m_ucb_noise * get_random_uint(8); + if (q > max) { max = q; pos = i; } + } } if (pos == static_cast(-1)) return 0; - m_scores.find(as[pos]).touched++; m_touched++; -// return m_list_false[pos]; + m_scores.find(as[pos]).touched++; + // Andreas: Also part of track_unsat data structures. Additionally disable the previous line! + /* m_last_pos = pos; + m_scores.find(m_list_false[pos]).touched++; + return m_list_false[pos]; */ } else { + // Andreas: The track_unsat data structures for random assertion selection. + /* sz = m_where_false.size(); + if (sz == 0) + return 0; + return m_list_false[get_random_uint(16) % sz]; */ + unsigned cnt_unsat = 0; for (unsigned i = 0; i < sz; i++) if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; @@ -1070,14 +1033,6 @@ public: m_last_pos = pos; return as[pos]; -#if _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return 0; - return m_list_false[get_random_uint(16) % sz]; -#endif } expr * get_new_unsat_assertion(ptr_vector const & as) { From a3f20774a8538eeec48191ae474ae2416750527c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 17:17:47 +0100 Subject: [PATCH 038/507] BVSLS comments Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_params.pyg | 2 +- src/tactic/sls/sls_tracker.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index ad7a22675..bf5bd181a 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -19,7 +19,7 @@ def_module_params('sls', ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), - ('random_offset', BOOL, 1, 'use random offset vor candidate evaluation'), + ('random_offset', BOOL, 1, 'use random offset for candidate evaluation'), ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 4356bcc9b..d58f94af2 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -831,7 +831,9 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. + // Precondition: Assertion set is in NNF. + // Also: careful about the unsat assertion scaling further down. + if (m_manager.is_and(child) || m_manager.is_or(child)) NOT_IMPLEMENTED_YET(); res = score_bool(child, true); } From bfdea4242c9a26b43432040126a98fcf85a46075 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 18:03:35 +0100 Subject: [PATCH 039/507] removed unused file Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 0 src/tactic/sls/sls_engine.cpp | 1 - src/tactic/sls/sls_engine.h | 1 - src/tactic/sls/sls_tracker.h | 1 - 4 files changed, 3 deletions(-) delete mode 100644 src/tactic/sls/sls_compilation_settings.h diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 269790902..67dba0237 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -27,7 +27,6 @@ Notes: #include"cooperate.h" #include"luby.h" -#include"sls_compilation_settings.h" #include"sls_params.hpp" #include"sls_engine.h" diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8158808fa..8a8a57e0e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -24,7 +24,6 @@ Notes: #include"model_converter.h" #include"goal.h" -#include"sls_compilation_settings.h" #include"sls_tracker.h" #include"sls_evaluator.h" diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index d58f94af2..186fae250 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -25,7 +25,6 @@ Notes: #include"bv_decl_plugin.h" #include"model.h" -#include"sls_compilation_settings.h" #include"sls_powers.h" class sls_tracker { From 4ff6a7c38dd86497eee7543a3fea54b75e03bcf2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 18:11:30 +0100 Subject: [PATCH 040/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 186fae250..73355197a 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -25,6 +25,7 @@ Notes: #include"bv_decl_plugin.h" #include"model.h" +#include"sls_params.hpp" #include"sls_powers.h" class sls_tracker { @@ -1052,4 +1053,4 @@ public: } }; -#endif \ No newline at end of file +#endif From c9c40877a70f08cef1d48af3ecd805ff173be931 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 21:49:35 +0100 Subject: [PATCH 041/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8a8a57e0e..b056c438e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -136,8 +136,8 @@ protected: void mk_random_move(ptr_vector & unsat_constants); - //inline double get_restart_armin(unsigned cnt_restarts); - inline unsigned check_restart(unsigned curr_value); + //double get_restart_armin(unsigned cnt_restarts); + unsigned check_restart(unsigned curr_value); }; #endif From 23dccdc7d519a86d779ae8b582663885e4548520 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 21:54:08 +0100 Subject: [PATCH 042/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 67dba0237..5b32e5790 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -16,6 +16,7 @@ Author: Notes: --*/ +#include #include #include"map.h" From 39b562da44d4cc63374c1904d378b9b41a406ee7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 22:03:26 +0100 Subject: [PATCH 043/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 5b32e5790..c0c319ab4 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -581,7 +581,7 @@ lbool sls_engine::operator()() { } /* Andreas: Needed for Armin's restart scheme if we don't want to use loops. -inline double sls_engine::get_restart_armin(unsigned cnt_restarts) +double sls_engine::get_restart_armin(unsigned cnt_restarts) { unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; @@ -589,7 +589,7 @@ inline double sls_engine::get_restart_armin(unsigned cnt_restarts) } */ -inline unsigned sls_engine::check_restart(unsigned curr_value) +unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_next) { From baee61a2e48e7c601aad89797e15133f8768af0e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 2 Jun 2014 17:57:59 +0100 Subject: [PATCH 044/507] More experimental FPA theory code Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 254 +++++++++++++++++++++++++++++++++++++++-- src/smt/theory_fpa.h | 23 +++- 2 files changed, 263 insertions(+), 14 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index e235dbb06..bd95d78f1 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -19,43 +19,275 @@ Revision History: #include"ast_smt2_pp.h" #include"smt_context.h" #include"theory_fpa.h" +#include"smt_model_generator.h" namespace smt { theory_fpa::theory_fpa(ast_manager & m) : theory(m.mk_family_id("float")), m_converter(m), - m_rw(m, m_converter, params_ref()) + m_rw(m, m_converter, params_ref()), + m_trans_map(m), + m_trail_stack(*this) { } bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { TRACE("fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); + NOT_IMPLEMENTED_YET(); + } + + bool theory_fpa::internalize_term(app * term) { + TRACE("fpa", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); + SASSERT(term->get_family_id() == get_family_id()); + SASSERT(!get_context().e_internalized(term)); ast_manager & m = get_manager(); context & ctx = get_context(); + simplifier & simp = ctx.get_simplifier(); + unsigned num_args = term->get_num_args(); + for (unsigned i = 0; i < num_args; i++) + ctx.internalize(term->get_arg(i), false); + expr_ref res(m); - m_rw(atom, res); - SASSERT(res.get() != atom); - ctx.internalize(res, gate_ctx); - return true; + m_rw(term, res); + SASSERT(is_app(res) && to_app(res)->get_num_args() == 3); + app * a = to_app(res); + TRACE("fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); + + expr_ref sgn(m), sig(m), exp(m); + proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); + simp(a->get_arg(0), sgn, pr_sgn); + simp(a->get_arg(1), sig, pr_sig); + simp(a->get_arg(2), exp, pr_exp); + + ctx.internalize(sgn, false); + ctx.internalize(sig, false); + ctx.internalize(exp, false); + + expr_ref s_term(m); + m_converter.mk_triple(sgn, sig, exp, s_term); + + SASSERT(!m_trans_map.contains(term)); + m_trans_map.insert(term, s_term, 0); + + enode * e = ctx.mk_enode(term, false, false, true); + theory_var v = mk_var(e); + ctx.attach_th_var(e, this, v); + TRACE("fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); + SASSERT(e->get_th_var(get_id()) != null_theory_var); + + return v != null_theory_var; } - void theory_fpa::new_eq_eh(theory_var, theory_var) { - NOT_IMPLEMENTED_YET(); + void theory_fpa::apply_sort_cnstr(enode * n, sort * s) { + if (!is_attached_to_var(n)) { + context & ctx = get_context(); + ast_manager & m = get_manager(); + simplifier & simp = ctx.get_simplifier(); + app * owner = n->get_owner(); + expr_ref converted(m); + + theory_var v = mk_var(n); + ctx.attach_th_var(n, this, v); + m_rw(owner, converted); + m_trans_map.insert(owner, converted, 0); + + if (m_converter.is_rm_sort(m.get_sort(owner))) { + ctx.internalize(converted, false); + } + else { + app * a = to_app(converted); + expr_ref sgn(m), sig(m), exp(m); + proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); + simp(a->get_arg(0), sgn, pr_sgn); + simp(a->get_arg(1), sig, pr_sig); + simp(a->get_arg(2), exp, pr_exp); + + ctx.internalize(sgn, false); + ctx.internalize(sig, false); + ctx.internalize(exp, false); + } + + TRACE("fpa", tout << "new const: " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); + } } - void theory_fpa::new_diseq_eh(theory_var, theory_var) { - NOT_IMPLEMENTED_YET(); + void theory_fpa::new_eq_eh(theory_var x, theory_var y) { + TRACE("fpa", tout << "new eq: " << x << " = " << y << "\n";); + ast_manager & m = get_manager(); + context & ctx = get_context(); + app * ax = get_enode(x)->get_owner(); + app * ay = get_enode(y)->get_owner(); + + expr * ex, * ey; + proof * px, * py; + m_trans_map.get(ax, ex, px); + m_trans_map.get(ay, ey, py); + + expr * sgn_x, * sig_x, * exp_x; + expr * sgn_y, * sig_y, * exp_y; + split_triple(ex, sgn_x, sig_x, exp_x); + split_triple(ey, sgn_y, sig_y, exp_y); + + literal_vector lits; + lits.push_back(mk_eq(ax, ay, true)); + + expr_ref e1(m), e2(m), e3(m); + e1 = m.mk_eq(sgn_x, sgn_y); + e2 = m.mk_eq(sig_x, sig_y); + e3 = m.mk_eq(exp_x, exp_y); + ctx.internalize(e1, true); + ctx.internalize(e2, true); + ctx.internalize(e3, true); + lits.push_back(ctx.get_literal(e1)); + lits.push_back(ctx.get_literal(e2)); + lits.push_back(ctx.get_literal(e3)); + + ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); + } + + void theory_fpa::new_diseq_eh(theory_var x, theory_var y) { + TRACE("fpa", tout << "new eq: " << x << " = " << y << "\n";); + ast_manager & m = get_manager(); + context & ctx = get_context(); + app * ax = get_enode(x)->get_owner(); + app * ay = get_enode(y)->get_owner(); + + expr * ex, *ey; + proof * px, *py; + m_trans_map.get(ax, ex, px); + m_trans_map.get(ay, ey, py); + + expr * sgn_x, *sig_x, *exp_x; + expr * sgn_y, *sig_y, *exp_y; + split_triple(ex, sgn_x, sig_x, exp_x); + split_triple(ex, sgn_y, sig_y, exp_y); + + ctx.internalize(m.mk_not(m.mk_eq(sgn_x, sgn_y)), true); + ctx.internalize(m.mk_not(m.mk_eq(sig_x, sig_y)), true); + ctx.internalize(m.mk_not(m.mk_eq(exp_x, exp_y)), true); } void theory_fpa::push_scope_eh() { - NOT_IMPLEMENTED_YET(); + theory::push_scope_eh(); + m_trail_stack.push_scope(); } void theory_fpa::pop_scope_eh(unsigned num_scopes) { - NOT_IMPLEMENTED_YET(); + m_trail_stack.pop_scope(num_scopes); + theory::pop_scope_eh(num_scopes); + } + + model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { + ast_manager & m = get_manager(); + context & ctx = get_context(); + bv_util & bu = m_converter.bu(); + float_util & fu = m_converter.fu(); + unsynch_mpz_manager & mpzm = fu.fm().mpz_manager(); + unsynch_mpq_manager & mpqm = fu.fm().mpq_manager(); + + theory_var v = n->get_th_var(get_id()); + SASSERT(v != null_theory_var); + expr * fpa_e = get_enode(v)->get_owner(); + TRACE("fpa", tout << "mk_value for: " << mk_ismt2_pp(fpa_e, m) << "\n";); + + expr * bv_e; + proof * bv_pr; + m_trans_map.get(fpa_e, bv_e, bv_pr); + + expr_wrapper_proc * res = 0; + + if (fu.is_rm(m.get_sort(fpa_e))) { + SASSERT(ctx.e_internalized(bv_e)); + sort * s = m.get_sort(bv_e); + family_id fid = s->get_family_id(); + theory * bv_th = ctx.get_theory(fid); + + enode * ev = ctx.get_enode(bv_e); + ptr_vector pve; + app_ref mv(m); + mv = ((expr_wrapper_proc*)bv_th->mk_value(ev, mg))->mk_value(mg, pve); + + rational val(0); + unsigned sz = 0; + if (bu.is_numeral(mv, val, sz)) { + app_ref fp_val_e(m); + SASSERT(val.is_uint64()); + switch (val.get_uint64()) + { + case BV_RM_TIES_TO_AWAY: fp_val_e = fu.mk_round_nearest_ties_to_away(); break; + case BV_RM_TIES_TO_EVEN: fp_val_e = fu.mk_round_nearest_ties_to_even(); break; + case BV_RM_TO_NEGATIVE: fp_val_e = fu.mk_round_toward_negative(); break; + case BV_RM_TO_POSITIVE: fp_val_e = fu.mk_round_toward_positive(); break; + case BV_RM_TO_ZERO: + default: fp_val_e = fu.mk_round_toward_zero(); + } + + TRACE("fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); + res = alloc(expr_wrapper_proc, fp_val_e); + m.inc_ref(fp_val_e); + } + } + else { + expr * bv_sgn, *bv_sig, *bv_exp; + split_triple(bv_e, bv_sgn, bv_sig, bv_exp); + + SASSERT(ctx.e_internalized(bv_sgn)); + SASSERT(ctx.e_internalized(bv_sig)); + SASSERT(ctx.e_internalized(bv_exp)); + + enode * e_sgn = ctx.get_enode(bv_sgn); + enode * e_sig = ctx.get_enode(bv_sig); + enode * e_exp = ctx.get_enode(bv_exp); + + sort * s = m.get_sort(e_sgn->get_owner()); + family_id fid = s->get_family_id(); + theory * bv_th = ctx.get_theory(fid); + + expr_wrapper_proc * mv_sgn = (expr_wrapper_proc*)bv_th->mk_value(e_sgn, mg); + expr_wrapper_proc * mv_sig = (expr_wrapper_proc*)bv_th->mk_value(e_sig, mg); + expr_wrapper_proc * mv_exp = (expr_wrapper_proc*)bv_th->mk_value(e_exp, mg); + + ptr_vector pve; + app_ref bvm_sgn(m), bvm_sig(m), bvm_exp(m); + bvm_sgn = mv_sgn->mk_value(mg, pve); + bvm_sig = mv_sig->mk_value(mg, pve); + bvm_exp = mv_exp->mk_value(mg, pve); + + TRACE("fpa", tout << "bv model: [" << mk_ismt2_pp(bvm_sgn, get_manager()) << " " + << mk_ismt2_pp(bvm_sig, get_manager()) << " " + << mk_ismt2_pp(bvm_exp, get_manager()) << "]\n";); + + unsigned sgn_sz, sig_sz, exp_sz; + rational sgn_q(0), sig_q(0), exp_q(0); + if (bvm_sgn) bu.is_numeral(bvm_sgn, sgn_q, sgn_sz); + if (bvm_sig) bu.is_numeral(bvm_sig, sig_q, sig_sz); + if (bvm_exp) bu.is_numeral(bvm_exp, exp_q, exp_sz); + + // un-bias exponent + rational exp_unbiased_q; + exp_unbiased_q = exp_q - fu.fm().m_powers2.m1(exp_sz - 1); + + mpz sig_z; mpf_exp_t exp_z; + mpzm.set(sig_z, sig_q.to_mpq().numerator()); + exp_z = mpzm.get_int64(exp_unbiased_q.to_mpq().numerator()); + + mpf fp_val; + fu.fm().set(fp_val, exp_sz, sig_sz+1, !mpqm.is_zero(sgn_q.to_mpq()), sig_z, exp_z); + + app_ref fp_val_e(m); + fp_val_e = fu.mk_value(fp_val); + mpzm.del(sig_z); + + TRACE("fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); + + res = alloc(expr_wrapper_proc, fp_val_e); + m.inc_ref(fp_val_e); + } + + return res; } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index bb3a8b786..51e0ff0d5 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -25,20 +25,37 @@ Revision History: namespace smt { class theory_fpa : public theory { + typedef trail_stack th_trail_stack; + fpa2bv_converter m_converter; fpa2bv_rewriter m_rw; + expr_map m_trans_map; + th_trail_stack m_trail_stack; virtual final_check_status final_check_eh() { return FC_DONE; } - virtual bool internalize_atom(app * a, bool); - virtual bool internalize_term(app * a) { return internalize_atom(a, false); } + virtual bool internalize_atom(app * atom, bool gate_ctx); + virtual bool internalize_term(app * term); + virtual void apply_sort_cnstr(enode * n, sort * s); virtual void new_eq_eh(theory_var, theory_var); virtual void new_diseq_eh(theory_var, theory_var); virtual void push_scope_eh(); virtual void pop_scope_eh(unsigned num_scopes); virtual theory* mk_fresh(context*) { return alloc(theory_fpa, get_manager()); } - virtual char const * get_name() const { return "fpa"; } + virtual char const * get_name() const { return "fpa"; } + + virtual model_value_proc * mk_value(enode * n, model_generator & mg); + public: theory_fpa(ast_manager& m); + + protected: + void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { + SASSERT(is_app_of(e, get_family_id(), OP_TO_FLOAT)); + SASSERT(to_app(e)->get_num_args() == 3); + sgn = to_app(e)->get_arg(0); + sig = to_app(e)->get_arg(1); + exp = to_app(e)->get_arg(2); + } }; }; From c2a2d2d0dfdccccc9e611d8556014fdff774be3f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 11 Jun 2014 13:27:21 +0100 Subject: [PATCH 045/507] Renamed Z3_mk_double to Z3_mk_fpa_double for consistency Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 4 ++-- src/api/z3_fpa.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 278a0556a..374e3d344 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -121,9 +121,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_double(Z3_context c, double v, Z3_sort ty) { + Z3_ast Z3_API Z3_mk_fpa_double(Z3_context c, double v, Z3_sort ty) { Z3_TRY; - LOG_Z3_mk_double(c, v, ty); + LOG_Z3_mk_fpa_double(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->float_util().fm()); diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 93268b821..81cfff591 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -131,7 +131,7 @@ extern "C" { def_API('Z3_mk_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) */ - Z3_ast Z3_API Z3_mk_double(__in Z3_context c, __in double v, __in Z3_sort ty); + Z3_ast Z3_API Z3_mk_fpa_double(__in Z3_context c, __in double v, __in Z3_sort ty); /** \brief Floating-point absolute value From ca89b120d3b2c1ebb83eb996f022425c701768db Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 11 Jun 2014 16:44:12 +0100 Subject: [PATCH 046/507] improve FPA theory implementation Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 239 ++++++++++++++++++++++++++++------------- src/smt/theory_fpa.h | 7 +- 2 files changed, 170 insertions(+), 76 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index bd95d78f1..e606857e5 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -19,27 +19,32 @@ Revision History: #include"ast_smt2_pp.h" #include"smt_context.h" #include"theory_fpa.h" +#include"theory_bv.h" #include"smt_model_generator.h" namespace smt { - theory_fpa::theory_fpa(ast_manager & m) : - theory(m.mk_family_id("float")), - m_converter(m), + theory_fpa::theory_fpa(ast_manager & m) : + theory(m.mk_family_id("float")), + m_converter(m), m_rw(m, m_converter, params_ref()), m_trans_map(m), m_trail_stack(*this) { } + theory_fpa::~theory_fpa() + { + } + bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { - TRACE("fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); + TRACE("t_fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); NOT_IMPLEMENTED_YET(); } bool theory_fpa::internalize_term(app * term) { - TRACE("fpa", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); + TRACE("t_fpa", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); SASSERT(term->get_family_id() == get_family_id()); SASSERT(!get_context().e_internalized(term)); @@ -55,7 +60,7 @@ namespace smt { m_rw(term, res); SASSERT(is_app(res) && to_app(res)->get_num_args() == 3); app * a = to_app(res); - TRACE("fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); + TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); expr_ref sgn(m), sig(m), exp(m); proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); @@ -63,20 +68,34 @@ namespace smt { simp(a->get_arg(1), sig, pr_sig); simp(a->get_arg(2), exp, pr_exp); - ctx.internalize(sgn, false); - ctx.internalize(sig, false); - ctx.internalize(exp, false); + expr_ref bv_v_sgn(m), bv_v_sig(m), bv_v_exp(m); + bv_v_sgn = m.mk_fresh_const("fpa2bv", m.get_sort(sgn)); + bv_v_sig = m.mk_fresh_const("fpa2bv", m.get_sort(sig)); + bv_v_exp = m.mk_fresh_const("fpa2bv", m.get_sort(exp)); + expr_ref e1(m), e2(m), e3(m); + e1 = m.mk_eq(bv_v_sgn, sgn); + e2 = m.mk_eq(bv_v_sig, sig); + e3 = m.mk_eq(bv_v_exp, exp); + ctx.internalize(e1, false); + ctx.internalize(e2, false); + ctx.internalize(e3, false); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e1)); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e2)); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); + ctx.mark_as_relevant(e1); + ctx.mark_as_relevant(e2); + ctx.mark_as_relevant(e3); expr_ref s_term(m); - m_converter.mk_triple(sgn, sig, exp, s_term); + m_converter.mk_triple(bv_v_sgn, bv_v_sig, bv_v_exp, s_term); SASSERT(!m_trans_map.contains(term)); m_trans_map.insert(term, s_term, 0); enode * e = ctx.mk_enode(term, false, false, true); - theory_var v = mk_var(e); + theory_var v = mk_var(e); ctx.attach_th_var(e, this, v); - TRACE("fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); + TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); SASSERT(e->get_th_var(get_id()) != null_theory_var); return v != null_theory_var; @@ -84,6 +103,7 @@ namespace smt { void theory_fpa::apply_sort_cnstr(enode * n, sort * s) { if (!is_attached_to_var(n)) { + TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); context & ctx = get_context(); ast_manager & m = get_manager(); simplifier & simp = ctx.get_simplifier(); @@ -96,7 +116,12 @@ namespace smt { m_trans_map.insert(owner, converted, 0); if (m_converter.is_rm_sort(m.get_sort(owner))) { - ctx.internalize(converted, false); + expr_ref bv_v(m), eq(m); + bv_v = m.mk_fresh_const("fpa2bv", m.get_sort(converted)); + eq = m.mk_eq(bv_v, converted); + ctx.internalize(eq, false); + literal l = ctx.get_literal(eq); + ctx.mk_th_axiom(get_id(), 1, &l); } else { app * a = to_app(converted); @@ -109,14 +134,32 @@ namespace smt { ctx.internalize(sgn, false); ctx.internalize(sig, false); ctx.internalize(exp, false); + + expr_ref bv_v_sgn(m), bv_v_sig(m), bv_v_exp(m); + bv_v_sgn = m.mk_fresh_const("fpa2bv", m.get_sort(sgn)); + bv_v_sig = m.mk_fresh_const("fpa2bv", m.get_sort(sig)); + bv_v_exp = m.mk_fresh_const("fpa2bv", m.get_sort(exp)); + expr_ref e1(m), e2(m), e3(m); + e1 = m.mk_eq(bv_v_sgn, sgn); + e2 = m.mk_eq(bv_v_sig, sig); + e3 = m.mk_eq(bv_v_exp, exp); + ctx.internalize(e1, true); + ctx.internalize(e2, true); + ctx.internalize(e3, true); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e1)); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e2)); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); + ctx.mark_as_relevant(e1); + ctx.mark_as_relevant(e2); + ctx.mark_as_relevant(e3); } - TRACE("fpa", tout << "new const: " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); + TRACE("t_fpa", tout << "new theory var (const): " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); } } void theory_fpa::new_eq_eh(theory_var x, theory_var y) { - TRACE("fpa", tout << "new eq: " << x << " = " << y << "\n";); + TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); app * ax = get_enode(x)->get_owner(); @@ -132,9 +175,6 @@ namespace smt { split_triple(ex, sgn_x, sig_x, exp_x); split_triple(ey, sgn_y, sig_y, exp_y); - literal_vector lits; - lits.push_back(mk_eq(ax, ay, true)); - expr_ref e1(m), e2(m), e3(m); e1 = m.mk_eq(sgn_x, sgn_y); e2 = m.mk_eq(sig_x, sig_y); @@ -142,15 +182,16 @@ namespace smt { ctx.internalize(e1, true); ctx.internalize(e2, true); ctx.internalize(e3, true); - lits.push_back(ctx.get_literal(e1)); - lits.push_back(ctx.get_literal(e2)); - lits.push_back(ctx.get_literal(e3)); - - ctx.mk_th_axiom(get_id(), lits.size(), lits.c_ptr()); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e1)); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e2)); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); + ctx.mark_as_relevant(e1); + ctx.mark_as_relevant(e2); + ctx.mark_as_relevant(e3); } void theory_fpa::new_diseq_eh(theory_var x, theory_var y) { - TRACE("fpa", tout << "new eq: " << x << " = " << y << "\n";); + TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); app * ax = get_enode(x)->get_owner(); @@ -166,9 +207,13 @@ namespace smt { split_triple(ex, sgn_x, sig_x, exp_x); split_triple(ex, sgn_y, sig_y, exp_y); - ctx.internalize(m.mk_not(m.mk_eq(sgn_x, sgn_y)), true); - ctx.internalize(m.mk_not(m.mk_eq(sig_x, sig_y)), true); - ctx.internalize(m.mk_not(m.mk_eq(exp_x, exp_y)), true); + expr_ref e1(m), e2(m), e3(m); + e1 = m.mk_not(m.mk_eq(sgn_x, sgn_y)); + e2 = m.mk_or(e1, m.mk_not(m.mk_eq(sig_x, sig_y))); + e3 = m.mk_or(e2, m.mk_not(m.mk_eq(exp_x, exp_y))); + ctx.internalize(e3, true); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); + ctx.mark_as_relevant(e3); } void theory_fpa::push_scope_eh() { @@ -186,13 +231,14 @@ namespace smt { context & ctx = get_context(); bv_util & bu = m_converter.bu(); float_util & fu = m_converter.fu(); - unsynch_mpz_manager & mpzm = fu.fm().mpz_manager(); - unsynch_mpq_manager & mpqm = fu.fm().mpq_manager(); + mpf_manager & mpfm = fu.fm(); + unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); theory_var v = n->get_th_var(get_id()); SASSERT(v != null_theory_var); expr * fpa_e = get_enode(v)->get_owner(); - TRACE("fpa", tout << "mk_value for: " << mk_ismt2_pp(fpa_e, m) << "\n";); + TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(fpa_e, m) << "\n";); expr * bv_e; proof * bv_pr; @@ -204,17 +250,14 @@ namespace smt { SASSERT(ctx.e_internalized(bv_e)); sort * s = m.get_sort(bv_e); family_id fid = s->get_family_id(); - theory * bv_th = ctx.get_theory(fid); - - enode * ev = ctx.get_enode(bv_e); - ptr_vector pve; - app_ref mv(m); - mv = ((expr_wrapper_proc*)bv_th->mk_value(ev, mg))->mk_value(mg, pve); - - rational val(0); - unsigned sz = 0; - if (bu.is_numeral(mv, val, sz)) { - app_ref fp_val_e(m); + theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); + rational val; + if (!bv_th->get_fixed_value(ctx.get_enode(bv_e)->get_owner(), val)) { + NOT_IMPLEMENTED_YET(); + } + else + { + app * fp_val_e; SASSERT(val.is_uint64()); switch (val.get_uint64()) { @@ -226,9 +269,8 @@ namespace smt { default: fp_val_e = fu.mk_round_toward_zero(); } - TRACE("fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); + TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); res = alloc(expr_wrapper_proc, fp_val_e); - m.inc_ref(fp_val_e); } } else { @@ -241,53 +283,100 @@ namespace smt { enode * e_sgn = ctx.get_enode(bv_sgn); enode * e_sig = ctx.get_enode(bv_sig); - enode * e_exp = ctx.get_enode(bv_exp); + enode * e_exp = ctx.get_enode(bv_exp); + + TRACE("t_fpa", tout << "bv rep: [" << mk_ismt2_pp(e_sgn->get_owner(), m) << " " + << mk_ismt2_pp(e_sig->get_owner(), m) << " " + << mk_ismt2_pp(e_exp->get_owner(), m) << "]\n";); sort * s = m.get_sort(e_sgn->get_owner()); family_id fid = s->get_family_id(); - theory * bv_th = ctx.get_theory(fid); + theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); - expr_wrapper_proc * mv_sgn = (expr_wrapper_proc*)bv_th->mk_value(e_sgn, mg); - expr_wrapper_proc * mv_sig = (expr_wrapper_proc*)bv_th->mk_value(e_sig, mg); - expr_wrapper_proc * mv_exp = (expr_wrapper_proc*)bv_th->mk_value(e_exp, mg); + SASSERT(bv_th->is_attached_to_var(e_sgn)); + SASSERT(bv_th->is_attached_to_var(e_sig)); + SASSERT(bv_th->is_attached_to_var(e_exp)); - ptr_vector pve; - app_ref bvm_sgn(m), bvm_sig(m), bvm_exp(m); - bvm_sgn = mv_sgn->mk_value(mg, pve); - bvm_sig = mv_sig->mk_value(mg, pve); - bvm_exp = mv_exp->mk_value(mg, pve); + unsigned sig_sz, exp_sz; + sig_sz = bu.get_bv_size(e_sig->get_owner()); + exp_sz = bu.get_bv_size(e_exp->get_owner()); - TRACE("fpa", tout << "bv model: [" << mk_ismt2_pp(bvm_sgn, get_manager()) << " " - << mk_ismt2_pp(bvm_sig, get_manager()) << " " - << mk_ismt2_pp(bvm_exp, get_manager()) << "]\n";); + rational sgn_r(0), sig_r(0), exp_r(0); + + if (!bv_th->get_fixed_value(e_sgn->get_owner(), sgn_r) || + !bv_th->get_fixed_value(e_sig->get_owner(), sig_r) || + !bv_th->get_fixed_value(e_exp->get_owner(), exp_r)) { + NOT_IMPLEMENTED_YET(); + } + else { + TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " + << sig_r.to_string() << " " + << exp_r.to_string() << "]\n";); - unsigned sgn_sz, sig_sz, exp_sz; - rational sgn_q(0), sig_q(0), exp_q(0); - if (bvm_sgn) bu.is_numeral(bvm_sgn, sgn_q, sgn_sz); - if (bvm_sig) bu.is_numeral(bvm_sig, sig_q, sig_sz); - if (bvm_exp) bu.is_numeral(bvm_exp, exp_q, exp_sz); + // un-bias exponent + rational exp_unbiased_r; + exp_unbiased_r = exp_r - mpfm.m_powers2.m1(exp_sz - 1); - // un-bias exponent - rational exp_unbiased_q; - exp_unbiased_q = exp_q - fu.fm().m_powers2.m1(exp_sz - 1); + mpz sig_z; mpf_exp_t exp_z; + mpq sig_q, exp_q; + mpz sig_num, exp_num; + mpqm.set(sig_q, sig_r.to_mpq()); + mpzm.set(sig_num, sig_q.numerator()); + mpqm.set(exp_q, exp_unbiased_r.to_mpq()); + mpzm.set(exp_num, exp_q.numerator()); + mpzm.set(sig_z, sig_num); + exp_z = mpzm.get_int64(exp_num); - mpz sig_z; mpf_exp_t exp_z; - mpzm.set(sig_z, sig_q.to_mpq().numerator()); - exp_z = mpzm.get_int64(exp_unbiased_q.to_mpq().numerator()); + mpf fp_val; + mpfm.set(fp_val, exp_sz, sig_sz + 1, !sgn_r.is_zero(), sig_z, exp_z); - mpf fp_val; - fu.fm().set(fp_val, exp_sz, sig_sz+1, !mpqm.is_zero(sgn_q.to_mpq()), sig_z, exp_z); + app * fp_val_e; + fp_val_e = fu.mk_value(fp_val); - app_ref fp_val_e(m); - fp_val_e = fu.mk_value(fp_val); - mpzm.del(sig_z); + TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); - TRACE("fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); + mpfm.del(fp_val); + mpzm.del(sig_num); + mpzm.del(exp_num); + mpqm.del(sig_q); + mpqm.del(exp_q); + mpzm.del(sig_z); - res = alloc(expr_wrapper_proc, fp_val_e); - m.inc_ref(fp_val_e); + res = alloc(expr_wrapper_proc, fp_val_e); + } } return res; } + + void theory_fpa::assign_eh(bool_var v, bool is_true) { + TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << ")\n";); + UNREACHABLE(); + } + + void theory_fpa::relevant_eh(app * n) { + ast_manager & m = get_manager(); + context & ctx = get_context(); + float_util & fu = m_converter.fu(); + if (ctx.e_internalized(n)) { + SASSERT(m_trans_map.contains(n)); + expr * ex; + proof * px; + m_trans_map.get(n, ex, px); + + if (fu.is_rm(m.get_sort(n))) { + ctx.mark_as_relevant(ex); + } + else { + expr * bv_sgn, *bv_sig, *bv_exp; + split_triple(ex, bv_sgn, bv_sig, bv_exp); + + ctx.mark_as_relevant(bv_sgn); + ctx.mark_as_relevant(bv_sig); + ctx.mark_as_relevant(bv_exp); + } + } + else + NOT_IMPLEMENTED_YET(); + } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 51e0ff0d5..4a465ada2 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -44,9 +44,12 @@ namespace smt { virtual char const * get_name() const { return "fpa"; } virtual model_value_proc * mk_value(enode * n, model_generator & mg); - + + void assign_eh(bool_var v, bool is_true); + virtual void relevant_eh(app * n); public: theory_fpa(ast_manager& m); + virtual ~theory_fpa(); protected: void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { @@ -56,6 +59,8 @@ namespace smt { sig = to_app(e)->get_arg(1); exp = to_app(e)->get_arg(2); } + + void ensure_bv_var(expr_ref const & n); }; }; From 129e2f5e238daf2bb37d2e1e9dcc425a741fbf75 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 11 Jun 2014 17:55:31 +0100 Subject: [PATCH 047/507] FPA API fixes and examples Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 55 +++++++++++++++++++++++++++------------ src/api/dotnet/Context.cs | 2 +- src/api/z3_fpa.h | 2 +- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 4363ee382..578c563b7 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2604,29 +2604,49 @@ void fpa_example() { printf("\nFPA-example\n"); LOG_MSG("FPA-example"); - - enable_trace("fpa"); - cfg = Z3_mk_config(); - ctx = Z3_mk_context(cfg); + cfg = Z3_mk_config(); + ctx = Z3_mk_context(cfg); Z3_del_config(cfg); - double_sort = Z3_mk_fpa_sort(ctx, 11, 53); - rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); + double_sort = Z3_mk_fpa_sort(ctx, 11, 53); + rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); - symbol_rm = Z3_mk_string_symbol(ctx, "rm"); - rm = Z3_mk_const(ctx, symbol_rm, rm_sort); - symbol_x = Z3_mk_string_symbol(ctx, "x"); - symbol_y = Z3_mk_string_symbol(ctx, "y"); - x = Z3_mk_const(ctx, symbol_x, double_sort); - y = Z3_mk_const(ctx, symbol_y, double_sort); - n = Z3_mk_double(ctx, 42.0, double_sort); + symbol_rm = Z3_mk_string_symbol(ctx, "rm"); + rm = Z3_mk_const(ctx, symbol_rm, rm_sort); + symbol_x = Z3_mk_string_symbol(ctx, "x"); + symbol_y = Z3_mk_string_symbol(ctx, "y"); + x = Z3_mk_const(ctx, symbol_x, double_sort); + y = Z3_mk_const(ctx, symbol_y, double_sort); + n = Z3_mk_fpa_double(ctx, 42.0, double_sort); + + Z3_symbol q_s = Z3_mk_string_symbol(ctx, "q"); + Z3_ast q = Z3_mk_const(ctx, q_s, double_sort); + c = Z3_mk_eq(ctx, q, Z3_mk_fpa_add(ctx, rm, x, y)); + + Z3_ast args[2] = { c, Z3_mk_eq(ctx, q, n) }; + c = Z3_mk_and(ctx, 2, (Z3_ast*)&args); + + printf("c = %s\n", Z3_ast_to_string(ctx, c)); - c = Z3_mk_eq(ctx, Z3_mk_fpa_add(ctx, rm, x, y), n); - Z3_assert_cnstr(ctx, c); - if (Z3_check(ctx) != Z3_L_TRUE) - printf("FPA-example not satisfied!\n"); + + Z3_model m = 0; + Z3_lbool result = Z3_check_and_get_model(ctx, &m); + switch (result) { + case Z3_L_FALSE: + printf("unsat\n"); + break; + case Z3_L_UNDEF: + printf("unknown\n"); + break; + case Z3_L_TRUE: + printf("sat\n%s\n", Z3_model_to_string(ctx, m)); + break; + } + + if (m) + Z3_del_model(ctx, m); Z3_del_context(ctx); } @@ -2676,5 +2696,6 @@ int main() { smt2parser_example(); substitute_example(); substitute_vars_example(); + fpa_example(); return 0; } diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index b654feb7e..e60c93fba 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3533,7 +3533,7 @@ namespace Microsoft.Z3 public FPNum MkFP(double v, FPSort s) { Contract.Ensures(Contract.Result() != null); - return new FPNum(this, Native.Z3_mk_double(this.nCtx, v, s.NativeObject)); + return new FPNum(this, Native.Z3_mk_fpa_double(this.nCtx, v, s.NativeObject)); } /// diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 81cfff591..93cfb8dd5 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -129,7 +129,7 @@ extern "C" { \sa Z3_mk_numeral - def_API('Z3_mk_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) + def_API('Z3_mk_fpa_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) */ Z3_ast Z3_API Z3_mk_fpa_double(__in Z3_context c, __in double v, __in Z3_sort ty); From 8b8cee7f6484ff0dfaa466c29c5f7f318b780101 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 12 Jun 2014 15:14:06 +0100 Subject: [PATCH 048/507] FPA theory improvements Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 221 +++++++++++++++++++++-------------------- src/smt/theory_fpa.h | 5 +- 2 files changed, 119 insertions(+), 107 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index e606857e5..3a52b2590 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -37,6 +37,25 @@ namespace smt { { } + void theory_fpa::mk_bv_eq(expr * x, expr * y) { + ast_manager & m = get_manager(); + context & ctx = get_context(); + expr_ref eq(m); + eq = m.mk_eq(x, y); + ctx.internalize(eq, false); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(eq)); + ctx.mark_as_relevant(eq); + } + + expr_ref theory_fpa::mk_eq_bv_const(expr_ref const & e) { + ast_manager & m = get_manager(); + context & ctx = get_context(); + expr_ref bv_const(m); + bv_const = m.mk_fresh_const(0, m.get_sort(e)); + mk_bv_eq(bv_const, e); + return bv_const; + } + bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { TRACE("t_fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); @@ -51,53 +70,60 @@ namespace smt { ast_manager & m = get_manager(); context & ctx = get_context(); simplifier & simp = ctx.get_simplifier(); - + unsigned num_args = term->get_num_args(); for (unsigned i = 0; i < num_args; i++) ctx.internalize(term->get_arg(i), false); + + if (m_converter.is_float(m.get_sort(term))) { + expr_ref res(m); + m_rw(term, res); + SASSERT(is_app(res) && to_app(res)->get_num_args() == 3); + TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); + + app * a = to_app(res); + expr_ref sgn(m), sig(m), exp(m); + proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); + simp(a->get_arg(0), sgn, pr_sgn); + simp(a->get_arg(1), sig, pr_sig); + simp(a->get_arg(2), exp, pr_exp); - expr_ref res(m); - m_rw(term, res); - SASSERT(is_app(res) && to_app(res)->get_num_args() == 3); - app * a = to_app(res); - TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); + expr_ref bv_v_sgn = mk_eq_bv_const(sgn); + expr_ref bv_v_sig = mk_eq_bv_const(sig); + expr_ref bv_v_exp = mk_eq_bv_const(exp); - expr_ref sgn(m), sig(m), exp(m); - proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); - simp(a->get_arg(0), sgn, pr_sgn); - simp(a->get_arg(1), sig, pr_sig); - simp(a->get_arg(2), exp, pr_exp); + expr_ref s_term(m); + m_converter.mk_triple(bv_v_sgn, bv_v_sig, bv_v_exp, s_term); - expr_ref bv_v_sgn(m), bv_v_sig(m), bv_v_exp(m); - bv_v_sgn = m.mk_fresh_const("fpa2bv", m.get_sort(sgn)); - bv_v_sig = m.mk_fresh_const("fpa2bv", m.get_sort(sig)); - bv_v_exp = m.mk_fresh_const("fpa2bv", m.get_sort(exp)); - expr_ref e1(m), e2(m), e3(m); - e1 = m.mk_eq(bv_v_sgn, sgn); - e2 = m.mk_eq(bv_v_sig, sig); - e3 = m.mk_eq(bv_v_exp, exp); - ctx.internalize(e1, false); - ctx.internalize(e2, false); - ctx.internalize(e3, false); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e1)); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e2)); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); - ctx.mark_as_relevant(e1); - ctx.mark_as_relevant(e2); - ctx.mark_as_relevant(e3); + SASSERT(!m_trans_map.contains(term)); + m_trans_map.insert(term, s_term, 0); + } + else if (m_converter.is_rm_sort(m.get_sort(term))) { + expr_ref res(m); + m_rw(term, res); + SASSERT(is_app(res)); + TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); + + app * a = to_app(res); + expr_ref bv_rm(m); + proof_ref bv_pr(m); + simp(res, bv_rm, bv_pr); - expr_ref s_term(m); - m_converter.mk_triple(bv_v_sgn, bv_v_sig, bv_v_exp, s_term); + expr_ref bv_v = mk_eq_bv_const(bv_rm); - SASSERT(!m_trans_map.contains(term)); - m_trans_map.insert(term, s_term, 0); + SASSERT(!m_trans_map.contains(term)); + m_trans_map.insert(term, bv_v, 0); + + + } + else + UNREACHABLE(); enode * e = ctx.mk_enode(term, false, false, true); - theory_var v = mk_var(e); + theory_var v = mk_var(e); ctx.attach_th_var(e, this, v); TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); SASSERT(e->get_th_var(get_id()) != null_theory_var); - return v != null_theory_var; } @@ -116,12 +142,7 @@ namespace smt { m_trans_map.insert(owner, converted, 0); if (m_converter.is_rm_sort(m.get_sort(owner))) { - expr_ref bv_v(m), eq(m); - bv_v = m.mk_fresh_const("fpa2bv", m.get_sort(converted)); - eq = m.mk_eq(bv_v, converted); - ctx.internalize(eq, false); - literal l = ctx.get_literal(eq); - ctx.mk_th_axiom(get_id(), 1, &l); + mk_eq_bv_const(converted); } else { app * a = to_app(converted); @@ -131,89 +152,77 @@ namespace smt { simp(a->get_arg(1), sig, pr_sig); simp(a->get_arg(2), exp, pr_exp); - ctx.internalize(sgn, false); - ctx.internalize(sig, false); - ctx.internalize(exp, false); - - expr_ref bv_v_sgn(m), bv_v_sig(m), bv_v_exp(m); - bv_v_sgn = m.mk_fresh_const("fpa2bv", m.get_sort(sgn)); - bv_v_sig = m.mk_fresh_const("fpa2bv", m.get_sort(sig)); - bv_v_exp = m.mk_fresh_const("fpa2bv", m.get_sort(exp)); - expr_ref e1(m), e2(m), e3(m); - e1 = m.mk_eq(bv_v_sgn, sgn); - e2 = m.mk_eq(bv_v_sig, sig); - e3 = m.mk_eq(bv_v_exp, exp); - ctx.internalize(e1, true); - ctx.internalize(e2, true); - ctx.internalize(e3, true); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e1)); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e2)); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); - ctx.mark_as_relevant(e1); - ctx.mark_as_relevant(e2); - ctx.mark_as_relevant(e3); + mk_eq_bv_const(sgn); + mk_eq_bv_const(sig); + mk_eq_bv_const(exp); } TRACE("t_fpa", tout << "new theory var (const): " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); } } - void theory_fpa::new_eq_eh(theory_var x, theory_var y) { + void theory_fpa::new_eq_eh(theory_var x, theory_var y) { TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); + app * ax = get_enode(x)->get_owner(); app * ay = get_enode(y)->get_owner(); - - expr * ex, * ey; - proof * px, * py; + expr * ex, *ey; + proof * px, *py; m_trans_map.get(ax, ex, px); m_trans_map.get(ay, ey, py); - expr * sgn_x, * sig_x, * exp_x; - expr * sgn_y, * sig_y, * exp_y; - split_triple(ex, sgn_x, sig_x, exp_x); - split_triple(ey, sgn_y, sig_y, exp_y); - - expr_ref e1(m), e2(m), e3(m); - e1 = m.mk_eq(sgn_x, sgn_y); - e2 = m.mk_eq(sig_x, sig_y); - e3 = m.mk_eq(exp_x, exp_y); - ctx.internalize(e1, true); - ctx.internalize(e2, true); - ctx.internalize(e3, true); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e1)); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e2)); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); - ctx.mark_as_relevant(e1); - ctx.mark_as_relevant(e2); - ctx.mark_as_relevant(e3); + if (m_converter.fu().is_float(m.get_sort(get_enode(x)->get_owner()))) { + expr * sgn_x, *sig_x, *exp_x; + expr * sgn_y, *sig_y, *exp_y; + split_triple(ex, sgn_x, sig_x, exp_x); + split_triple(ey, sgn_y, sig_y, exp_y); + + mk_bv_eq(sgn_x, sgn_y); + mk_bv_eq(sig_x, sig_y); + mk_bv_eq(exp_x, exp_y); + } + else if (m_converter.fu().is_rm(m.get_sort(get_enode(x)->get_owner()))) { + mk_bv_eq(ex, ey); + } + else + UNREACHABLE(); } void theory_fpa::new_diseq_eh(theory_var x, theory_var y) { TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); + app * ax = get_enode(x)->get_owner(); app * ay = get_enode(y)->get_owner(); - expr * ex, *ey; proof * px, *py; m_trans_map.get(ax, ex, px); m_trans_map.get(ay, ey, py); - expr * sgn_x, *sig_x, *exp_x; - expr * sgn_y, *sig_y, *exp_y; - split_triple(ex, sgn_x, sig_x, exp_x); - split_triple(ex, sgn_y, sig_y, exp_y); + expr_ref deq(m); - expr_ref e1(m), e2(m), e3(m); - e1 = m.mk_not(m.mk_eq(sgn_x, sgn_y)); - e2 = m.mk_or(e1, m.mk_not(m.mk_eq(sig_x, sig_y))); - e3 = m.mk_or(e2, m.mk_not(m.mk_eq(exp_x, exp_y))); - ctx.internalize(e3, true); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(e3)); - ctx.mark_as_relevant(e3); + if (m_converter.fu().is_float(m.get_sort(get_enode(x)->get_owner()))) { + expr * sgn_x, *sig_x, *exp_x; + expr * sgn_y, *sig_y, *exp_y; + split_triple(ex, sgn_x, sig_x, exp_x); + split_triple(ex, sgn_y, sig_y, exp_y); + + deq = m.mk_or(m.mk_not(m.mk_eq(sgn_x, sgn_y)), + m.mk_not(m.mk_eq(sig_x, sig_y)), + m.mk_not(m.mk_eq(exp_x, exp_y))); + } + else if (m_converter.fu().is_rm(m.get_sort(get_enode(x)->get_owner()))) { + deq = m.mk_not(m.mk_eq(ex, ey)); + } + else + UNREACHABLE(); + + ctx.internalize(deq, true); + ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(deq)); + ctx.mark_as_relevant(deq); } void theory_fpa::push_scope_eh() { @@ -273,7 +282,7 @@ namespace smt { res = alloc(expr_wrapper_proc, fp_val_e); } } - else { + else if (fu.is_float(m.get_sort(fpa_e))) { expr * bv_sgn, *bv_sig, *bv_exp; split_triple(bv_e, bv_sgn, bv_sig, bv_exp); @@ -283,15 +292,15 @@ namespace smt { enode * e_sgn = ctx.get_enode(bv_sgn); enode * e_sig = ctx.get_enode(bv_sig); - enode * e_exp = ctx.get_enode(bv_exp); + enode * e_exp = ctx.get_enode(bv_exp); TRACE("t_fpa", tout << "bv rep: [" << mk_ismt2_pp(e_sgn->get_owner(), m) << " " - << mk_ismt2_pp(e_sig->get_owner(), m) << " " - << mk_ismt2_pp(e_exp->get_owner(), m) << "]\n";); + << mk_ismt2_pp(e_sig->get_owner(), m) << " " + << mk_ismt2_pp(e_exp->get_owner(), m) << "]\n";); sort * s = m.get_sort(e_sgn->get_owner()); family_id fid = s->get_family_id(); - theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); + theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); SASSERT(bv_th->is_attached_to_var(e_sgn)); SASSERT(bv_th->is_attached_to_var(e_sig)); @@ -301,8 +310,8 @@ namespace smt { sig_sz = bu.get_bv_size(e_sig->get_owner()); exp_sz = bu.get_bv_size(e_exp->get_owner()); - rational sgn_r(0), sig_r(0), exp_r(0); - + rational sgn_r(0), sig_r(0), exp_r(0); + if (!bv_th->get_fixed_value(e_sgn->get_owner(), sgn_r) || !bv_th->get_fixed_value(e_sig->get_owner(), sig_r) || !bv_th->get_fixed_value(e_exp->get_owner(), exp_r)) { @@ -310,8 +319,8 @@ namespace smt { } else { TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " - << sig_r.to_string() << " " - << exp_r.to_string() << "]\n";); + << sig_r.to_string() << " " + << exp_r.to_string() << "]\n";); // un-bias exponent rational exp_unbiased_r; @@ -345,6 +354,8 @@ namespace smt { res = alloc(expr_wrapper_proc, fp_val_e); } } + else + UNREACHABLE(); return res; } @@ -377,6 +388,6 @@ namespace smt { } } else - NOT_IMPLEMENTED_YET(); + UNREACHABLE(); } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 4a465ada2..ea09df27b 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -59,8 +59,9 @@ namespace smt { sig = to_app(e)->get_arg(1); exp = to_app(e)->get_arg(2); } - - void ensure_bv_var(expr_ref const & n); + + void mk_bv_eq(expr * x, expr * y); + expr_ref mk_eq_bv_const(expr_ref const & e); }; }; From 4a915f6528f33802f9b271be53a8fcf158384231 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 12 Jun 2014 21:16:11 +0100 Subject: [PATCH 049/507] FPA theory additions Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 163 ++++++++++++++++++++++++++++------------- src/smt/theory_fpa.h | 28 ++++++- 2 files changed, 139 insertions(+), 52 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 3a52b2590..7082a9582 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -24,6 +24,18 @@ Revision History: namespace smt { + class mk_atom_trail : public trail { + bool_var m_var; + public: + mk_atom_trail(bool_var v) : m_var(v) {} + virtual ~mk_atom_trail() {} + virtual void undo(theory_fpa & th) { + theory_fpa::atom * a = th.get_bv2a(m_var); + a->~atom(); + th.erase_bv2a(m_var); + } + }; + theory_fpa::theory_fpa(ast_manager & m) : theory(m.mk_family_id("float")), m_converter(m), @@ -38,13 +50,13 @@ namespace smt { } void theory_fpa::mk_bv_eq(expr * x, expr * y) { + SASSERT(get_sort(x)->get_family_id() == m_converter.bu().get_family_id()); ast_manager & m = get_manager(); - context & ctx = get_context(); - expr_ref eq(m); - eq = m.mk_eq(x, y); - ctx.internalize(eq, false); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(eq)); - ctx.mark_as_relevant(eq); + context & ctx = get_context(); + theory_id bv_tid = ctx.get_theory(m.get_sort(x)->get_family_id())->get_id(); + literal l = mk_eq(x, y, false); + ctx.mk_th_axiom(get_id(), 1, &l); + ctx.mark_as_relevant(l); } expr_ref theory_fpa::mk_eq_bv_const(expr_ref const & e) { @@ -59,7 +71,33 @@ namespace smt { bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { TRACE("t_fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); - NOT_IMPLEMENTED_YET(); + + ast_manager & m = get_manager(); + context & ctx = get_context(); + simplifier & simp = ctx.get_simplifier(); + bv_util & bu = m_converter.bu(); + expr_ref bv_atom(m); + + unsigned num_args = atom->get_num_args(); + for (unsigned i = 0; i < num_args; i++) + ctx.internalize(atom->get_arg(i), false); + + m_rw(atom, bv_atom); + + ctx.internalize(bv_atom, gate_ctx); + literal def = ctx.get_literal(bv_atom); + literal l(ctx.mk_bool_var(atom)); + ctx.set_var_theory(l.var(), get_id()); + pred_atom * a = new (get_region()) pred_atom(l, def); + insert_bv2a(l.var(), a); + m_trail_stack.push(mk_atom_trail(l.var())); + + if (!ctx.relevancy()) { + ctx.mk_th_axiom(get_id(), l, ~def); + ctx.mk_th_axiom(get_id(), ~l, def); + } + + return true; } bool theory_fpa::internalize_term(app * term) { @@ -69,19 +107,28 @@ namespace smt { ast_manager & m = get_manager(); context & ctx = get_context(); - simplifier & simp = ctx.get_simplifier(); + simplifier & simp = ctx.get_simplifier(); + bv_util & bu = m_converter.bu(); + sort * term_sort = m.get_sort(term); + expr_ref t(m), bv_term(m); unsigned num_args = term->get_num_args(); for (unsigned i = 0; i < num_args; i++) ctx.internalize(term->get_arg(i), false); - - if (m_converter.is_float(m.get_sort(term))) { - expr_ref res(m); - m_rw(term, res); - SASSERT(is_app(res) && to_app(res)->get_num_args() == 3); - TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); - - app * a = to_app(res); + + m_rw(term, t); + + if (m_converter.is_rm_sort(term_sort)) { + SASSERT(is_app(t)); + expr_ref bv_rm(m); + proof_ref bv_pr(m); + simp(t, bv_rm, bv_pr); + + bv_term = mk_eq_bv_const(bv_rm); + } + else if (m_converter.is_float(term_sort)) { + SASSERT(is_app(t) && to_app(t)->get_num_args() == 3); + app * a = to_app(t); expr_ref sgn(m), sig(m), exp(m); proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); simp(a->get_arg(0), sgn, pr_sgn); @@ -92,34 +139,25 @@ namespace smt { expr_ref bv_v_sig = mk_eq_bv_const(sig); expr_ref bv_v_exp = mk_eq_bv_const(exp); - expr_ref s_term(m); - m_converter.mk_triple(bv_v_sgn, bv_v_sig, bv_v_exp, s_term); - - SASSERT(!m_trans_map.contains(term)); - m_trans_map.insert(term, s_term, 0); + m_converter.mk_triple(bv_v_sgn, bv_v_sig, bv_v_exp, bv_term); } - else if (m_converter.is_rm_sort(m.get_sort(term))) { - expr_ref res(m); - m_rw(term, res); - SASSERT(is_app(res)); - TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(res, get_manager()) << "\n";); - - app * a = to_app(res); - expr_ref bv_rm(m); + else if (term->get_decl_kind() == OP_TO_IEEE_BV) { + SASSERT(is_app(t)); + expr_ref bv_e(m); proof_ref bv_pr(m); - simp(res, bv_rm, bv_pr); + simp(t, bv_e, bv_pr); - expr_ref bv_v = mk_eq_bv_const(bv_rm); - - SASSERT(!m_trans_map.contains(term)); - m_trans_map.insert(term, bv_v, 0); - - + bv_term = mk_eq_bv_const(bv_e); } else - UNREACHABLE(); + NOT_IMPLEMENTED_YET(); - enode * e = ctx.mk_enode(term, false, false, true); + TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(bv_term, get_manager()) << "\n";); + + SASSERT(!m_trans_map.contains(term)); + m_trans_map.insert(term, bv_term, 0); + + enode * e = ctx.mk_enode(term, false, false, true); theory_var v = mk_var(e); ctx.attach_th_var(e, this, v); TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); @@ -191,7 +229,7 @@ namespace smt { } void theory_fpa::new_diseq_eh(theory_var x, theory_var y) { - TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); + TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); @@ -219,7 +257,7 @@ namespace smt { } else UNREACHABLE(); - + ctx.internalize(deq, true); ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(deq)); ctx.mark_as_relevant(deq); @@ -252,17 +290,17 @@ namespace smt { expr * bv_e; proof * bv_pr; m_trans_map.get(fpa_e, bv_e, bv_pr); - + sort * fpa_e_srt = m.get_sort(fpa_e); expr_wrapper_proc * res = 0; - if (fu.is_rm(m.get_sort(fpa_e))) { + if (fu.is_rm(fpa_e_srt)) { SASSERT(ctx.e_internalized(bv_e)); sort * s = m.get_sort(bv_e); family_id fid = s->get_family_id(); theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); rational val; if (!bv_th->get_fixed_value(ctx.get_enode(bv_e)->get_owner(), val)) { - NOT_IMPLEMENTED_YET(); + UNREACHABLE(); } else { @@ -282,7 +320,7 @@ namespace smt { res = alloc(expr_wrapper_proc, fp_val_e); } } - else if (fu.is_float(m.get_sort(fpa_e))) { + else if (fu.is_float(fpa_e_srt)) { expr * bv_sgn, *bv_sig, *bv_exp; split_triple(bv_e, bv_sgn, bv_sig, bv_exp); @@ -315,7 +353,7 @@ namespace smt { if (!bv_th->get_fixed_value(e_sgn->get_owner(), sgn_r) || !bv_th->get_fixed_value(e_sig->get_owner(), sig_r) || !bv_th->get_fixed_value(e_exp->get_owner(), exp_r)) { - NOT_IMPLEMENTED_YET(); + UNREACHABLE(); } else { TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " @@ -362,23 +400,35 @@ namespace smt { void theory_fpa::assign_eh(bool_var v, bool is_true) { TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << ")\n";); - UNREACHABLE(); + /* CMW: okay to ignore? */ } void theory_fpa::relevant_eh(app * n) { + TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, get_manager()) << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); float_util & fu = m_converter.fu(); - if (ctx.e_internalized(n)) { + bv_util & bu = m_converter.bu(); + + if (m.is_bool(n)) { + bool_var v = ctx.get_bool_var(n); + atom * a = get_bv2a(v); + pred_atom * pa = static_cast(a); + ctx.mark_as_relevant(pa->m_def); + ctx.mk_th_axiom(get_id(), pa->m_var, ~pa->m_def); + ctx.mk_th_axiom(get_id(), ~pa->m_var, pa->m_def); + } + else if (ctx.e_internalized(n)) { SASSERT(m_trans_map.contains(n)); expr * ex; proof * px; m_trans_map.get(n, ex, px); + sort * n_srt = m.get_sort(n); - if (fu.is_rm(m.get_sort(n))) { - ctx.mark_as_relevant(ex); + if (fu.is_rm(n_srt)) { + ctx.mark_as_relevant(ex); } - else { + else if (fu.is_float(n_srt)) { expr * bv_sgn, *bv_sig, *bv_exp; split_triple(ex, bv_sgn, bv_sig, bv_exp); @@ -386,8 +436,21 @@ namespace smt { ctx.mark_as_relevant(bv_sig); ctx.mark_as_relevant(bv_exp); } + else if (n->get_decl()->get_decl_kind() == OP_TO_IEEE_BV) { + literal l = mk_eq(n, ex, false); + ctx.mark_as_relevant(l); + ctx.mk_th_axiom(get_id(), 1, &l); + } + else + NOT_IMPLEMENTED_YET(); } else UNREACHABLE(); } + + void theory_fpa::reset_eh() { + pop_scope_eh(m_trail_stack.get_num_scopes()); + m_bool_var2atom.reset(); + theory::reset_eh(); + } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index ea09df27b..2039e34df 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -20,17 +20,40 @@ Revision History: #define _THEORY_FPA_H_ #include"smt_theory.h" +#include"trail.h" #include"fpa2bv_converter.h" #include"fpa2bv_rewriter.h" namespace smt { + class theory_fpa : public theory { typedef trail_stack th_trail_stack; - + + public: + class atom { + public: + virtual ~atom() {} + }; + + struct pred_atom : public atom { + literal m_var; + literal m_def; + pred_atom(literal v, literal d) : m_var(v), m_def(d) {} + virtual ~pred_atom() {} + }; + + typedef ptr_vector bool_var2atom; + void insert_bv2a(bool_var bv, pred_atom * a) { m_bool_var2atom.setx(bv, a, 0); } + void erase_bv2a(bool_var bv) { m_bool_var2atom[bv] = 0; } + pred_atom * get_bv2a(bool_var bv) const { return m_bool_var2atom.get(bv, 0); } + region & get_region() { return m_trail_stack.get_region(); } + + protected: fpa2bv_converter m_converter; fpa2bv_rewriter m_rw; expr_map m_trans_map; th_trail_stack m_trail_stack; + bool_var2atom m_bool_var2atom; virtual final_check_status final_check_eh() { return FC_DONE; } virtual bool internalize_atom(app * atom, bool gate_ctx); @@ -40,6 +63,7 @@ namespace smt { virtual void new_diseq_eh(theory_var, theory_var); virtual void push_scope_eh(); virtual void pop_scope_eh(unsigned num_scopes); + virtual void reset_eh(); virtual theory* mk_fresh(context*) { return alloc(theory_fpa, get_manager()); } virtual char const * get_name() const { return "fpa"; } @@ -47,6 +71,7 @@ namespace smt { void assign_eh(bool_var v, bool is_true); virtual void relevant_eh(app * n); + public: theory_fpa(ast_manager& m); virtual ~theory_fpa(); @@ -67,4 +92,3 @@ namespace smt { }; #endif /* _THEORY_FPA_H_ */ - From 2cd4edf1a23a3978851c83338f01d0ea775dabb6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 31 Jul 2014 17:56:18 +0100 Subject: [PATCH 050/507] FPA API bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.h | 2 +- src/smt/theory_fpa.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 4dedbc2e2..2b6b7fd64 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -221,7 +221,7 @@ public: app * mk_value(mpf const & v) { return m_plugin->mk_value(v); } bool is_value(expr * n) { return m_plugin->is_value(n); } - bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); } + bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); } bool is_rm_value(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm_value(n, v); } app * mk_pzero(unsigned ebits, unsigned sbits); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index f44447b8f..9c03cb76c 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -122,7 +122,7 @@ namespace smt { m_rw(term, t); - if (m_converter.is_rm_sort(term_sort)) { + if (m_converter.is_rm(term_sort)) { SASSERT(is_app(t)); expr_ref bv_rm(m); proof_ref bv_pr(m); @@ -183,7 +183,7 @@ namespace smt { m_rw(owner, converted); m_trans_map.insert(owner, converted, 0); - if (m_converter.is_rm_sort(m.get_sort(owner))) { + if (m_converter.is_rm(m.get_sort(owner))) { mk_eq_bv_const(converted); } else { From 8b40d4a7357cbe13a3aaefb1b848a7b710cdd30d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 4 Aug 2014 17:00:04 +0100 Subject: [PATCH 051/507] FPA theory bug fixes. Also removed unnecessary intermediate variables. Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 73 ++++++++++++++++++++++++++++++++--------- src/api/api_numeral.cpp | 2 +- src/smt/theory_fpa.cpp | 68 +++++++++++++++----------------------- src/smt/theory_fpa.h | 2 +- 4 files changed, 85 insertions(+), 60 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 578c563b7..6eb7a2e11 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2599,11 +2599,11 @@ void fpa_example() { Z3_config cfg; Z3_context ctx; Z3_sort double_sort, rm_sort; - Z3_symbol symbol_rm, symbol_x, symbol_y; - Z3_ast rm, x, y, n, c; - - printf("\nFPA-example\n"); - LOG_MSG("FPA-example"); + Z3_symbol symbol_rm, symbol_x, symbol_y, symbol_q; + Z3_ast rm, x, y, n, q, c1, c2, c3, c4, c5, c6; + + printf("\nfpa_example\n"); + LOG_MSG("fpa_example"); cfg = Z3_mk_config(); ctx = Z3_mk_context(cfg); @@ -2620,16 +2620,32 @@ void fpa_example() { y = Z3_mk_const(ctx, symbol_y, double_sort); n = Z3_mk_fpa_double(ctx, 42.0, double_sort); - Z3_symbol q_s = Z3_mk_string_symbol(ctx, "q"); - Z3_ast q = Z3_mk_const(ctx, q_s, double_sort); - c = Z3_mk_eq(ctx, q, Z3_mk_fpa_add(ctx, rm, x, y)); + symbol_q = Z3_mk_string_symbol(ctx, "q"); + q = Z3_mk_const(ctx, symbol_q, double_sort); + c1 = Z3_mk_eq(ctx, q, Z3_mk_fpa_add(ctx, rm, x, y)); - Z3_ast args[2] = { c, Z3_mk_eq(ctx, q, n) }; - c = Z3_mk_and(ctx, 2, (Z3_ast*)&args); + Z3_ast args[2] = { c1, Z3_mk_eq(ctx, q, n) }; + c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); - printf("c = %s\n", Z3_ast_to_string(ctx, c)); + Z3_ast args2[2] = { c2, Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_round_nearest_ties_to_away(ctx))) }; + c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); - Z3_assert_cnstr(ctx, c); + Z3_ast and_args[3] = { + Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)), + Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)), + Z3_mk_not(ctx, Z3_mk_fpa_is_inf(ctx, y)) }; + Z3_ast args3[2] = { c3, Z3_mk_and(ctx, 3, and_args) }; + c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); + + + Z3_assert_cnstr(ctx, c4); + Z3_push(ctx); + + // c5 := (IEEEBV(x) == 7.0). + c5 = Z3_mk_eq(ctx, Z3_mk_fpa_to_ieee_bv(ctx, x), + Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64))); + + Z3_assert_cnstr(ctx, c5); Z3_model m = 0; Z3_lbool result = Z3_check_and_get_model(ctx, &m); @@ -2639,19 +2655,44 @@ void fpa_example() { break; case Z3_L_UNDEF: printf("unknown\n"); + printf("potential model:\n%s\n", Z3_model_to_string(ctx, m)); + break; + case Z3_L_TRUE: + printf("sat\n%s\n", Z3_model_to_string(ctx, m)); + Z3_del_model(ctx, m); + break; + } + + Z3_pop(ctx, 1); + + // c6 := (IEEEBV(x) == 28.0). + c6 = Z3_mk_eq(ctx, Z3_mk_fpa_to_ieee_bv(ctx, x), + Z3_mk_numeral(ctx, "4628574517030027264", Z3_mk_bv_sort(ctx, 64))); + + Z3_assert_cnstr(ctx, c6); + Z3_push(ctx); + + m = 0; + result = Z3_check_and_get_model(ctx, &m); + switch (result) { + case Z3_L_FALSE: + printf("unsat\n"); + break; + case Z3_L_UNDEF: + printf("unknown\n"); + printf("potential model:\n%s\n", Z3_model_to_string(ctx, m)); break; case Z3_L_TRUE: - printf("sat\n%s\n", Z3_model_to_string(ctx, m)); + printf("sat\n%s\n", Z3_model_to_string(ctx, m)); + Z3_del_model(ctx, m); break; } - if (m) - Z3_del_model(ctx, m); + Z3_pop(ctx, 1); Z3_del_context(ctx); } - /*@}*/ /*@}*/ diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 740fef2ac..d2829e990 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -193,7 +193,7 @@ extern "C" { // floats are separated from all others to avoid huge rationals. float_util & fu = mk_c(c)->float_util(); scoped_mpf tmp(fu.fm()); - if (mk_c(c)->float_util().is_numeral(to_expr(a), tmp)) { + if (mk_c(c)->float_util().is_value(to_expr(a), tmp)) { return mk_c(c)->mk_external_string(fu.fm().to_string(tmp)); } else { diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 9c03cb76c..a228ec4a5 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -60,15 +60,6 @@ namespace smt { ctx.mark_as_relevant(l); } - app_ref theory_fpa::mk_eq_bv_const(expr_ref const & e) { - ast_manager & m = get_manager(); - context & ctx = get_context(); - app_ref bv_const(m); - bv_const = m.mk_fresh_const(0, m.get_sort(e)); - mk_bv_eq(bv_const, e); - return bv_const; - } - bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { TRACE("t_fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); @@ -128,7 +119,7 @@ namespace smt { proof_ref bv_pr(m); simp(t, bv_rm, bv_pr); - bv_term = mk_eq_bv_const(bv_rm); + bv_term = bv_rm; } else if (m_converter.is_float(term_sort)) { SASSERT(is_app(t) && to_app(t)->get_num_args() == 3); @@ -139,19 +130,13 @@ namespace smt { simp(a->get_arg(1), sig, pr_sig); simp(a->get_arg(2), exp, pr_exp); - app_ref bv_v_sgn = mk_eq_bv_const(sgn); - app_ref bv_v_sig = mk_eq_bv_const(sig); - app_ref bv_v_exp = mk_eq_bv_const(exp); - - m_converter.mk_triple(bv_v_sgn, bv_v_sig, bv_v_exp, bv_term); + m_converter.mk_triple(sgn, sig, exp, bv_term); } else if (term->get_decl_kind() == OP_TO_IEEE_BV) { SASSERT(is_app(t)); expr_ref bv_e(m); proof_ref bv_pr(m); - simp(t, bv_e, bv_pr); - - bv_term = mk_eq_bv_const(bv_e); + simp(t, bv_term, bv_pr); } else NOT_IMPLEMENTED_YET(); @@ -159,11 +144,12 @@ namespace smt { TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(bv_term, get_manager()) << "\n";); SASSERT(!m_trans_map.contains(term)); - m_trans_map.insert(term, bv_term, 0); + m_trans_map.insert(term, bv_term, 0); enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : ctx.mk_enode(term, false, false, true); theory_var v = mk_var(e); ctx.attach_th_var(e, this, v); + m_tvars.push_back(v); TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); SASSERT(e->get_th_var(get_id()) != null_theory_var); return v != null_theory_var; @@ -180,23 +166,14 @@ namespace smt { theory_var v = mk_var(n); ctx.attach_th_var(n, this, v); + m_tvars.push_back(v); m_rw(owner, converted); m_trans_map.insert(owner, converted, 0); - if (m_converter.is_rm(m.get_sort(owner))) { - mk_eq_bv_const(converted); - } - else { - app * a = to_app(converted); - expr_ref sgn(m), sig(m), exp(m); - proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); - simp(a->get_arg(0), sgn, pr_sgn); - simp(a->get_arg(1), sig, pr_sig); - simp(a->get_arg(2), exp, pr_exp); - - mk_eq_bv_const(sgn); - mk_eq_bv_const(sig); - mk_eq_bv_const(exp); + sort * owner_sort = m.get_sort(owner); + if (m_converter.is_rm(owner_sort)) { + bv_util & bu = m_converter.bu(); + bu.mk_ule(converted, bu.mk_numeral(4, bu.get_bv_size(converted))); } TRACE("t_fpa", tout << "new theory var (const): " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); @@ -215,7 +192,7 @@ namespace smt { m_trans_map.get(ax, ex, px); m_trans_map.get(ay, ey, py); - if (m_converter.fu().is_float(m.get_sort(get_enode(x)->get_owner()))) { + if (m_converter.fu().is_float(get_enode(x)->get_owner())) { expr * sgn_x, *sig_x, *exp_x; expr * sgn_y, *sig_y, *exp_y; split_triple(ex, sgn_x, sig_x, exp_x); @@ -225,7 +202,7 @@ namespace smt { mk_bv_eq(sig_x, sig_y); mk_bv_eq(exp_x, exp_y); } - else if (m_converter.fu().is_rm(m.get_sort(get_enode(x)->get_owner()))) { + else if (m_converter.fu().is_rm(get_enode(x)->get_owner())) { mk_bv_eq(ex, ey); } else @@ -273,7 +250,13 @@ namespace smt { } void theory_fpa::pop_scope_eh(unsigned num_scopes) { + TRACE("bv", tout << num_scopes << "\n";); m_trail_stack.pop_scope(num_scopes); + unsigned num_old_vars = get_old_num_vars(num_scopes); + for (unsigned i = num_old_vars; i < get_num_vars(); i++) { + m_trans_map.erase(get_enode(m_tvars[i])->get_owner()); + } + m_tvars.shrink(num_old_vars); theory::pop_scope_eh(num_scopes); } @@ -405,6 +388,7 @@ namespace smt { void theory_fpa::assign_eh(bool_var v, bool is_true) { TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << ")\n";); /* CMW: okay to ignore? */ + theory::assign_eh(v, is_true); } void theory_fpa::relevant_eh(app * n) { @@ -441,14 +425,10 @@ namespace smt { ctx.mark_as_relevant(bv_exp); } else if (n->get_decl()->get_decl_kind() == OP_TO_IEEE_BV) { - //literal l = mk_eq(n, ex, false); - //ctx.mark_as_relevant(l); - //ctx.mk_th_axiom(get_id(), 1, &l); - + expr_ref eq(m); app * ex_a = to_app(ex); if (n->get_id() > ex_a->get_id()) - std::swap(n, ex_a); - expr_ref eq(m); + std::swap(n, ex_a); eq = m.mk_eq(n, ex_a); ctx.internalize(eq, false); literal l = ctx.get_literal(eq); @@ -464,7 +444,11 @@ namespace smt { void theory_fpa::reset_eh() { pop_scope_eh(m_trail_stack.get_num_scopes()); - m_bool_var2atom.reset(); + m_rw.reset(); + m_trans_map.reset(); + m_bool_var2atom.reset(); + m_temporaries.reset(); + m_tvars.reset(); theory::reset_eh(); } diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 998cc17e8..5c0d2acca 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -55,6 +55,7 @@ namespace smt { th_trail_stack m_trail_stack; bool_var2atom m_bool_var2atom; enode_vector m_temporaries; + int_vector m_tvars; virtual final_check_status final_check_eh() { return FC_DONE; } virtual bool internalize_atom(app * atom, bool gate_ctx); @@ -88,7 +89,6 @@ namespace smt { } void mk_bv_eq(expr * x, expr * y); - app_ref mk_eq_bv_const(expr_ref const & e); }; }; From 4610acca0f4e7761be73f7a6851f3169c9a49ff2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 4 Aug 2014 17:10:56 +0100 Subject: [PATCH 052/507] FPA: reduced number of temporary variables. Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index d6f362902..07f0cdc8a 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -136,12 +136,13 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { unsigned sbits = m_util.get_sbits(srt); expr_ref sgn(m), s(m), e(m); - sort_ref s_sgn(m), s_sig(m), s_exp(m); - s_sgn = m_bv_util.mk_sort(1); - s_sig = m_bv_util.mk_sort(sbits-1); - s_exp = m_bv_util.mk_sort(ebits); #ifdef Z3DEBUG + sort_ref s_sgn(m), s_sig(m), s_exp(m); + s_sgn = m_bv_util.mk_sort(1); + s_sig = m_bv_util.mk_sort(sbits - 1); + s_exp = m_bv_util.mk_sort(ebits); + std::string p("fpa2bv"); std::string name = f->get_name().str(); @@ -149,9 +150,17 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { s = m.mk_fresh_const((p + "_sig_" + name).c_str(), s_sig); e = m.mk_fresh_const((p + "_exp_" + name).c_str(), s_exp); #else - sgn = m.mk_fresh_const(0, s_sgn); - s = m.mk_fresh_const(0, s_sig); - e = m.mk_fresh_const(0, s_exp); + expr_ref bv(m); + unsigned bv_sz = 1 + ebits + (sbits - 1); + bv = m.mk_fresh_const(0, m_bv_util.mk_sort(bv_sz)); + + sgn = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv); + e = m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv); + s = m_bv_util.mk_extract(sbits - 2, 0, bv); + + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(s) == sbits-1); + SASSERT(m_bv_util.get_bv_size(e) == ebits); #endif mk_triple(sgn, s, e, result); From 6b37b847a0e3717fe718e97e0b2f9d49320edc91 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 11 Sep 2014 00:27:37 +0100 Subject: [PATCH 053/507] merge fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tactic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 7ddf1a53d..9bbed20bb 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -79,10 +79,10 @@ public: } virtual void cleanup() { - imp * d = alloc(imp, m, m_params, m_stats); + sls_engine * d = alloc(sls_engine, m, m_params); #pragma omp critical (tactic_cancel) { - std::swap(d, m_imp); + std::swap(d, m_engine); } dealloc(d); } From 7af410e6d668674fab67019941995dad603fa736 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 18 Oct 2014 13:42:28 +0100 Subject: [PATCH 054/507] FPA updates and bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 12 +- src/api/z3_fpa.h | 33 ++- src/ast/float_decl_plugin.cpp | 326 ++++++++++++++++------------ src/ast/float_decl_plugin.h | 42 ++-- src/ast/fpa/fpa2bv_converter.cpp | 14 +- src/ast/fpa/fpa2bv_converter.h | 3 +- src/ast/fpa/fpa2bv_rewriter.h | 14 +- src/ast/rewriter/float_rewriter.cpp | 37 ++-- src/ast/rewriter/float_rewriter.h | 11 +- src/smt/theory_fpa.cpp | 4 +- 10 files changed, 308 insertions(+), 188 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 374e3d344..8bcc4c1af 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -121,6 +121,16 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_zero(Z3_context c, Z3_sort s, Z3_bool negative) { + Z3_TRY; + LOG_Z3_mk_fpa_inf(c, s, negative); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(negative != 0 ? ctx->float_util().mk_nzero(to_sort(s)) : ctx->float_util().mk_pzero(to_sort(s))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_double(Z3_context c, double v, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_fpa_double(c, v, ty); @@ -361,7 +371,7 @@ extern "C" { LOG_Z3_mk_fpa_to_ieee_bv(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_to_ieee_bv(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_float_to_ieee_bv(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 93cfb8dd5..265657bf4 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -109,12 +109,25 @@ extern "C" { \param s target sort \param negative indicates whether the result should be negative - When \c negative is true, -Inf will be generated instead of +Inf. + When \c negative is true, -oo will be generated instead of +oo. def_API('Z3_mk_fpa_inf', AST, (_in(CONTEXT),_in(SORT),_in(BOOL))) */ Z3_ast Z3_API Z3_mk_fpa_inf(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); + /** + \brief Create a floating point zero of sort s. + + \param c logical context. + \param s target sort + \param negative indicates whether the result should be negative + + When \c negative is true, -zero will be generated instead of +zero. + + def_API('Z3_mk_fpa_zero', AST, (_in(CONTEXT),_in(SORT),_in(BOOL))) + */ + Z3_ast Z3_API Z3_mk_fpa_zero(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); + /** \brief Create a numeral of floating point sort. @@ -133,6 +146,24 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_double(__in Z3_context c, __in double v, __in Z3_sort ty); + /** + \brief Create a numeral of floating point sort. + + This function can be use to create numerals that fit in a double value. + It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. + + \params c logical context. + \params v value. + \params ty sort. + + ty must be a floating point sort + + \sa Z3_mk_numeral + + def_API('Z3_mk_fpa_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_double(__in Z3_context c, __in double v, __in Z3_sort ty); + /** \brief Floating-point absolute value diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index df26422c8..c31c0b89b 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -40,11 +40,10 @@ void float_decl_plugin::set_manager(ast_manager * m, family_id id) { SASSERT(m_int_sort != 0); // arith_decl_plugin must be installed before float_decl_plugin. m_manager->inc_ref(m_int_sort); - if (m_manager->has_plugin(symbol("bv"))) { - // bv plugin is optional, so m_bv_plugin may be 0 - m_bv_fid = m_manager->mk_family_id("bv"); - m_bv_plugin = static_cast(m_manager->get_plugin(m_bv_fid)); - } + // BV is not optional anymore. + SASSERT(m_manager->has_plugin(symbol("bv"))); + m_bv_fid = m_manager->mk_family_id("bv"); + m_bv_plugin = static_cast(m_manager->get_plugin(m_bv_fid)); } float_decl_plugin::~float_decl_plugin() { @@ -103,6 +102,18 @@ bool float_decl_plugin::is_value(expr * n, mpf & val) { m_fm.mk_nan(ebits, sbits, val); return true; } + else if (is_app_of(n, m_family_id, OP_FLOAT_PLUS_ZERO)) { + unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); + unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); + m_fm.mk_pzero(ebits, sbits, val); + return true; + } + else if (is_app_of(n, m_family_id, OP_FLOAT_MINUS_ZERO)) { + unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); + unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); + m_fm.mk_nzero(ebits, sbits, val); + return true; + } return false; } @@ -156,7 +167,7 @@ sort * float_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) { parameter ps[2] = { p1, p2 }; sort_size sz; sz = sort_size::mk_very_big(); // TODO: refine - return m_manager->mk_sort(symbol("FP"), sort_info(m_family_id, FLOAT_SORT, sz, 2, ps)); + return m_manager->mk_sort(symbol("FloatingPoint"), sort_info(m_family_id, FLOAT_SORT, sz, 2, ps)); } sort * float_decl_plugin::mk_rm_sort() { @@ -176,6 +187,14 @@ sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, paramete return mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); case ROUNDING_MODE_SORT: return mk_rm_sort(); + case FLOAT16_SORT: + return mk_float_sort(5, 11); + case FLOAT32_SORT: + return mk_float_sort(8, 24); + case FLOAT64_SORT: + return mk_float_sort(11, 53); + case FLOAT128_SORT: + return mk_float_sort(15, 133); default: m_manager->raise_exception("unknown floating point theory sort"); return 0; @@ -229,17 +248,18 @@ func_decl * float_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_par unsigned ebits = s->get_parameter(0).get_int(); unsigned sbits = s->get_parameter(1).get_int(); scoped_mpf val(m_fm); - if (k == OP_FLOAT_NAN) { - m_fm.mk_nan(ebits, sbits, val); + + switch (k) + { + case OP_FLOAT_NAN: m_fm.mk_nan(ebits, sbits, val); SASSERT(m_fm.is_nan(val)); + break; + case OP_FLOAT_MINUS_INF: m_fm.mk_ninf(ebits, sbits, val); break; + case OP_FLOAT_PLUS_INF: m_fm.mk_pinf(ebits, sbits, val); break; + case OP_FLOAT_MINUS_ZERO: m_fm.mk_nzero(ebits, sbits, val); break; + case OP_FLOAT_PLUS_ZERO: m_fm.mk_pzero(ebits, sbits, val); break; } - else if (k == OP_FLOAT_MINUS_INF) { - m_fm.mk_ninf(ebits, sbits, val); - } - else { - SASSERT(k == OP_FLOAT_PLUS_INF); - m_fm.mk_pinf(ebits, sbits, val); - } + return mk_value_decl(val); } @@ -251,11 +271,11 @@ func_decl * float_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_paramet m_manager->raise_exception("sort mismatch"); symbol name; switch (k) { - case OP_FLOAT_EQ: name = "=="; break; - case OP_FLOAT_LT: name = "<"; break; - case OP_FLOAT_GT: name = ">"; break; - case OP_FLOAT_LE: name = "<="; break; - case OP_FLOAT_GE: name = ">="; break; + case OP_FLOAT_EQ: name = "fp.eq"; break; + case OP_FLOAT_LT: name = "fp.lt"; break; + case OP_FLOAT_GT: name = "fp.gt"; break; + case OP_FLOAT_LE: name = "fp.lte"; break; + case OP_FLOAT_GE: name = "fp.gte"; break; default: UNREACHABLE(); break; @@ -273,14 +293,15 @@ func_decl * float_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_param m_manager->raise_exception("sort mismatch"); symbol name; switch (k) { - case OP_FLOAT_IS_ZERO: name = "isZero"; break; - case OP_FLOAT_IS_NZERO: name = "isNZero"; break; - case OP_FLOAT_IS_PZERO: name = "isPZero"; break; - case OP_FLOAT_IS_SIGN_MINUS: name = "isSignMinus"; break; - case OP_FLOAT_IS_NAN: name = "isNaN"; break; - case OP_FLOAT_IS_INF: name = "isInfinite"; break; - case OP_FLOAT_IS_NORMAL: name = "isNormal"; break; - case OP_FLOAT_IS_SUBNORMAL: name = "isSubnormal"; break; + case OP_FLOAT_IS_ZERO: name = "fp.isZero"; break; + case OP_FLOAT_IS_NZERO: name = "fp.isNZero"; break; + case OP_FLOAT_IS_PZERO: name = "fp.isPZero"; break; + case OP_FLOAT_IS_NEGATIVE: name = "fp.isNegative"; break; + case OP_FLOAT_IS_POSITIVE: name = "fp.isPositive"; break; + case OP_FLOAT_IS_NAN: name = "fp.isNaN"; break; + case OP_FLOAT_IS_INF: name = "fp.isInfinite"; break; + case OP_FLOAT_IS_NORMAL: name = "fp.isNormal"; break; + case OP_FLOAT_IS_SUBNORMAL: name = "fp.isSubnormal"; break; default: UNREACHABLE(); break; @@ -296,8 +317,8 @@ func_decl * float_decl_plugin::mk_unary_decl(decl_kind k, unsigned num_parameter m_manager->raise_exception("sort mismatch"); symbol name; switch (k) { - case OP_FLOAT_ABS: name = "abs"; break; - case OP_FLOAT_UMINUS: name = "-"; break; + case OP_FLOAT_ABS: name = "fp.abs"; break; + case OP_FLOAT_NEG: name = "fp.neg"; break; default: UNREACHABLE(); break; @@ -313,9 +334,9 @@ func_decl * float_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_paramete m_manager->raise_exception("sort mismatch"); symbol name; switch (k) { - case OP_FLOAT_REM: name = "remainder"; break; - case OP_FLOAT_MIN: name = "min"; break; - case OP_FLOAT_MAX: name = "max"; break; + case OP_FLOAT_REM: name = "fp.rem"; break; + case OP_FLOAT_MIN: name = "fp.min"; break; + case OP_FLOAT_MAX: name = "fp.max"; break; default: UNREACHABLE(); break; @@ -331,10 +352,10 @@ func_decl * float_decl_plugin::mk_rm_binary_decl(decl_kind k, unsigned num_param m_manager->raise_exception("sort mismatch"); symbol name; switch (k) { - case OP_FLOAT_ADD: name = "+"; break; - case OP_FLOAT_SUB: name = "-"; break; - case OP_FLOAT_MUL: name = "*"; break; - case OP_FLOAT_DIV: name = "/"; break; + case OP_FLOAT_ADD: name = "fp.add"; break; + case OP_FLOAT_SUB: name = "fp.sub"; break; + case OP_FLOAT_MUL: name = "fp.mul"; break; + case OP_FLOAT_DIV: name = "fp.div"; break; default: UNREACHABLE(); break; @@ -350,8 +371,8 @@ func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parame m_manager->raise_exception("sort mismatch"); symbol name; switch (k) { - case OP_FLOAT_SQRT: name = "squareRoot"; break; - case OP_FLOAT_ROUND_TO_INTEGRAL: name = "roundToIntegral"; break; + case OP_FLOAT_SQRT: name = "fp.sqrt"; break; + case OP_FLOAT_ROUND_TO_INTEGRAL: name = "fp.roundToIntegral"; break; default: UNREACHABLE(); break; @@ -359,13 +380,13 @@ func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parame return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_fused_ma(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * float_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 4) m_manager->raise_exception("invalid number of arguments to fused_ma operator"); if (!is_rm_sort(domain[0]) || domain[1] != domain[2] || domain[1] != domain[3] || !is_float_sort(domain[1])) m_manager->raise_exception("sort mismatch"); - symbol name("fusedMA"); + symbol name("fp.fma"); return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k)); } @@ -375,12 +396,13 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, is_sort_of(domain[0], m_bv_fid, BV_SORT) && is_sort_of(domain[1], m_bv_fid, BV_SORT) && is_sort_of(domain[2], m_bv_fid, BV_SORT)) { - // When the bv_decl_plugin is installed, then we know how to convert 3 bit-vectors into a float! + // 3 BVs -> 1 FP sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1); - symbol name("asFloat"); + symbol name("fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } else if (m_bv_plugin && arity == 1 && is_sort_of(domain[0], m_bv_fid, BV_SORT)) { + // 1 BV -> 1 FP if (num_parameters != 2) m_manager->raise_exception("invalid number of parameters to to_fp"); if (!parameters[0].is_int() || !parameters[1].is_int()) @@ -389,28 +411,56 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, int sbits = parameters[1].get_int(); sort * fp = mk_float_sort(ebits, sbits); - symbol name("asFloat"); + symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } - else { - // .. Otherwise we only know how to convert rationals/reals. - if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) - m_manager->raise_exception("expecting two integer parameters to asFloat"); - if (arity != 2 && arity != 3) - m_manager->raise_exception("invalid number of arguments to asFloat operator"); - if (arity == 3 && domain[2] != m_int_sort) - m_manager->raise_exception("sort mismatch"); + else if (m_bv_plugin && arity == 2 && + is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && + is_sort_of(domain[1], m_bv_fid, BV_SORT)) { + // Rounding + 1 BV -> 1 FP + if (num_parameters != 2) + m_manager->raise_exception("invalid number of parameters to to_fp"); + if (!parameters[0].is_int() || !parameters[1].is_int()) + m_manager->raise_exception("invalid parameter type to to_fp"); + int ebits = parameters[0].get_int(); + int sbits = parameters[1].get_int(); + + sort * fp = mk_float_sort(ebits, sbits); + symbol name("to_fp"); + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); + } + else if (arity == 2 && + is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && + is_sort_of(domain[1], m_family_id, FLOAT_SORT)) { + // Rounding + 1 FP -> 1 FP + if (num_parameters != 2) + m_manager->raise_exception("invalid number of parameters to to_fp"); + if (!parameters[0].is_int() || !parameters[1].is_int()) + m_manager->raise_exception("invalid parameter type to to_fp"); + int ebits = parameters[0].get_int(); + int sbits = parameters[1].get_int(); if (!is_rm_sort(domain[0]) || - !(domain[1] == m_real_sort || is_sort_of(domain[1], m_family_id, FLOAT_SORT))) + !is_sort_of(domain[1], m_family_id, FLOAT_SORT)) + m_manager->raise_exception("sort mismatch"); + } + else { + // 1 Real -> 1 FP + if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) + m_manager->raise_exception("expecting two integer parameters to to_fp"); + if (arity != 2 && arity != 3) + m_manager->raise_exception("invalid number of arguments to to_fp operator"); + if (arity == 3 && domain[2] != m_int_sort) + m_manager->raise_exception("sort mismatch"); + if (domain[1] != m_real_sort) m_manager->raise_exception("sort mismatch"); sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); - symbol name("asFloat"); + symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } } -func_decl * float_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (!m_bv_plugin) m_manager->raise_exception("asIEEEBV unsupported; use a logic with BV support"); @@ -443,7 +493,7 @@ func_decl * float_decl_plugin::mk_from3bv(decl_kind k, unsigned num_parameters, return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (!m_bv_plugin) m_manager->raise_exception("to_fp_unsigned unsupported; use a logic with BV support"); @@ -455,15 +505,10 @@ func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_param m_manager->raise_exception("sort mismtach"); sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); - symbol name("to_fp_unsigned"); + symbol name("fp.t_ubv"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - NOT_IMPLEMENTED_YET(); -} - func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { NOT_IMPLEMENTED_YET(); @@ -498,14 +543,15 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters case OP_FLOAT_IS_ZERO: case OP_FLOAT_IS_NZERO: case OP_FLOAT_IS_PZERO: - case OP_FLOAT_IS_SIGN_MINUS: + case OP_FLOAT_IS_NEGATIVE: + case OP_FLOAT_IS_POSITIVE: case OP_FLOAT_IS_NAN: case OP_FLOAT_IS_INF: case OP_FLOAT_IS_NORMAL: case OP_FLOAT_IS_SUBNORMAL: return mk_unary_rel_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_ABS: - case OP_FLOAT_UMINUS: + case OP_FLOAT_NEG: return mk_unary_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_REM: case OP_FLOAT_MIN: @@ -517,20 +563,18 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters return mk_rm_binary_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_SUB: if (arity == 1) - return mk_unary_decl(OP_FLOAT_UMINUS, num_parameters, parameters, arity, domain, range); + return mk_unary_decl(OP_FLOAT_NEG, num_parameters, parameters, arity, domain, range); else return mk_rm_binary_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_SQRT: case OP_FLOAT_ROUND_TO_INTEGRAL: return mk_rm_unary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_FUSED_MA: - return mk_fused_ma(k, num_parameters, parameters, arity, domain, range); - case OP_TO_IEEE_BV: - return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_FMA: + return mk_fma(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_TO_IEEE_BV: + return mk_float_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_FP: return mk_from3bv(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_FP_UNSIGNED: - return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_UBV: return mk_to_ubv(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_SBV: @@ -544,8 +588,11 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters } void float_decl_plugin::get_op_names(svector & op_names, symbol const & logic) { - op_names.push_back(builtin_name("plusInfinity", OP_FLOAT_PLUS_INF)); - op_names.push_back(builtin_name("minusInfinity", OP_FLOAT_MINUS_INF)); + // These are the operators from the final draft of the SMT FloatingPoint standard + op_names.push_back(builtin_name("+oo", OP_FLOAT_PLUS_INF)); + op_names.push_back(builtin_name("-oo", OP_FLOAT_MINUS_INF)); + op_names.push_back(builtin_name("+zero", OP_FLOAT_PLUS_ZERO)); + op_names.push_back(builtin_name("-zero", OP_FLOAT_MINUS_ZERO)); op_names.push_back(builtin_name("NaN", OP_FLOAT_NAN)); op_names.push_back(builtin_name("roundNearestTiesToEven", OP_RM_NEAREST_TIES_TO_EVEN)); @@ -553,22 +600,66 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("roundTowardPositive", OP_RM_TOWARD_POSITIVE)); op_names.push_back(builtin_name("roundTowardNegative", OP_RM_TOWARD_NEGATIVE)); op_names.push_back(builtin_name("roundTowardZero", OP_RM_TOWARD_ZERO)); - - op_names.push_back(builtin_name("+", OP_FLOAT_ADD)); - op_names.push_back(builtin_name("-", OP_FLOAT_SUB)); - op_names.push_back(builtin_name("/", OP_FLOAT_DIV)); - op_names.push_back(builtin_name("*", OP_FLOAT_MUL)); - op_names.push_back(builtin_name("abs", OP_FLOAT_ABS)); - op_names.push_back(builtin_name("remainder", OP_FLOAT_REM)); - op_names.push_back(builtin_name("fusedMA", OP_FLOAT_FUSED_MA)); - op_names.push_back(builtin_name("squareRoot", OP_FLOAT_SQRT)); - op_names.push_back(builtin_name("roundToIntegral", OP_FLOAT_ROUND_TO_INTEGRAL)); + op_names.push_back(builtin_name("RNE", OP_RM_NEAREST_TIES_TO_EVEN)); + op_names.push_back(builtin_name("RNA", OP_RM_NEAREST_TIES_TO_AWAY)); + op_names.push_back(builtin_name("RTP", OP_RM_TOWARD_POSITIVE)); + op_names.push_back(builtin_name("RTN", OP_RM_TOWARD_NEGATIVE)); + op_names.push_back(builtin_name("RTZ", OP_RM_TOWARD_ZERO)); + + op_names.push_back(builtin_name("fp.abs", OP_FLOAT_ABS)); + op_names.push_back(builtin_name("fp.neg", OP_FLOAT_NEG)); + op_names.push_back(builtin_name("fp.add", OP_FLOAT_ADD)); + op_names.push_back(builtin_name("fp.sub", OP_FLOAT_SUB)); + op_names.push_back(builtin_name("fp.mul", OP_FLOAT_MUL)); + op_names.push_back(builtin_name("fp.div", OP_FLOAT_DIV)); + op_names.push_back(builtin_name("fp.fma", OP_FLOAT_FMA)); + op_names.push_back(builtin_name("fp.sqrt", OP_FLOAT_SQRT)); + op_names.push_back(builtin_name("fp.rem", OP_FLOAT_REM)); + op_names.push_back(builtin_name("fp.roundToIntegral", OP_FLOAT_ROUND_TO_INTEGRAL)); + op_names.push_back(builtin_name("fp.min", OP_FLOAT_MIN)); + op_names.push_back(builtin_name("fp.max", OP_FLOAT_MAX)); + op_names.push_back(builtin_name("fp.leq", OP_FLOAT_LE)); + op_names.push_back(builtin_name("fp.lt", OP_FLOAT_LT)); + op_names.push_back(builtin_name("fp.geq", OP_FLOAT_GE)); + op_names.push_back(builtin_name("fp.gt", OP_FLOAT_GT)); + op_names.push_back(builtin_name("fp.eq", OP_FLOAT_EQ)); + + op_names.push_back(builtin_name("fp.isNormal", OP_FLOAT_IS_NORMAL)); + op_names.push_back(builtin_name("fp.isSubnormal", OP_FLOAT_IS_SUBNORMAL)); + op_names.push_back(builtin_name("fp.isZero", OP_FLOAT_IS_ZERO)); + op_names.push_back(builtin_name("fp.isInfinite", OP_FLOAT_IS_INF)); + op_names.push_back(builtin_name("fp.isNaN", OP_FLOAT_IS_NAN)); + op_names.push_back(builtin_name("fp.isNegative", OP_FLOAT_IS_NEGATIVE)); + op_names.push_back(builtin_name("fp.isPositive", OP_FLOAT_IS_POSITIVE)); + op_names.push_back(builtin_name("to_fp", OP_FLOAT_FP)); + + if (m_bv_plugin) { + op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); + op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); + op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); + } + + // We also support the names of operators in older drafts. + op_names.push_back(builtin_name("plusInfinity", OP_FLOAT_PLUS_INF)); + op_names.push_back(builtin_name("minusInfinity", OP_FLOAT_MINUS_INF)); + + op_names.push_back(builtin_name("+", OP_FLOAT_ADD)); + op_names.push_back(builtin_name("-", OP_FLOAT_SUB)); + op_names.push_back(builtin_name("/", OP_FLOAT_DIV)); + op_names.push_back(builtin_name("*", OP_FLOAT_MUL)); + + op_names.push_back(builtin_name("abs", OP_FLOAT_ABS)); + op_names.push_back(builtin_name("remainder", OP_FLOAT_REM)); + op_names.push_back(builtin_name("fusedMA", OP_FLOAT_FMA)); + op_names.push_back(builtin_name("squareRoot", OP_FLOAT_SQRT)); + op_names.push_back(builtin_name("roundToIntegral", OP_FLOAT_ROUND_TO_INTEGRAL)); + op_names.push_back(builtin_name("==", OP_FLOAT_EQ)); - - op_names.push_back(builtin_name("<", OP_FLOAT_LT)); - op_names.push_back(builtin_name(">", OP_FLOAT_GT)); + + op_names.push_back(builtin_name("<", OP_FLOAT_LT)); + op_names.push_back(builtin_name(">", OP_FLOAT_GT)); op_names.push_back(builtin_name("<=", OP_FLOAT_LE)); op_names.push_back(builtin_name(">=", OP_FLOAT_GE)); @@ -579,65 +670,30 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("isPZero", OP_FLOAT_IS_PZERO)); op_names.push_back(builtin_name("isNormal", OP_FLOAT_IS_NORMAL)); op_names.push_back(builtin_name("isSubnormal", OP_FLOAT_IS_SUBNORMAL)); - op_names.push_back(builtin_name("isSignMinus", OP_FLOAT_IS_SIGN_MINUS)); + op_names.push_back(builtin_name("isSignMinus", OP_FLOAT_IS_NEGATIVE)); - op_names.push_back(builtin_name("min", OP_FLOAT_MIN)); - op_names.push_back(builtin_name("max", OP_FLOAT_MAX)); + // Disabled min/max, clashes with user-defined min/max functions + // op_names.push_back(builtin_name("min", OP_FLOAT_MIN)); + // op_names.push_back(builtin_name("max", OP_FLOAT_MAX)); - op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT)); - - if (m_bv_plugin) - op_names.push_back(builtin_name("asIEEEBV", OP_TO_IEEE_BV)); - - // These are the operators from the final draft of the SMT FloatingPoints standard - op_names.push_back(builtin_name("+oo", OP_FLOAT_PLUS_INF)); - op_names.push_back(builtin_name("-oo", OP_FLOAT_MINUS_INF)); - - op_names.push_back(builtin_name("RNE", OP_RM_NEAREST_TIES_TO_EVEN)); - op_names.push_back(builtin_name("RNA", OP_RM_NEAREST_TIES_TO_AWAY)); - op_names.push_back(builtin_name("RTP", OP_RM_TOWARD_POSITIVE)); - op_names.push_back(builtin_name("RTN", OP_RM_TOWARD_NEGATIVE)); - op_names.push_back(builtin_name("RTZ", OP_RM_TOWARD_ZERO)); - - op_names.push_back(builtin_name("fp.abs", OP_FLOAT_ABS)); - op_names.push_back(builtin_name("fp.neg", OP_FLOAT_UMINUS)); - op_names.push_back(builtin_name("fp.add", OP_FLOAT_ADD)); - op_names.push_back(builtin_name("fp.sub", OP_FLOAT_SUB)); - op_names.push_back(builtin_name("fp.mul", OP_FLOAT_MUL)); - op_names.push_back(builtin_name("fp.div", OP_FLOAT_DIV)); - op_names.push_back(builtin_name("fp.fma", OP_FLOAT_FUSED_MA)); - op_names.push_back(builtin_name("fp.sqrt", OP_FLOAT_SQRT)); - op_names.push_back(builtin_name("fp.rem", OP_FLOAT_REM)); - op_names.push_back(builtin_name("fp.eq", OP_FLOAT_EQ)); - op_names.push_back(builtin_name("fp.leq", OP_FLOAT_LE)); - op_names.push_back(builtin_name("fp.lt", OP_FLOAT_LT)); - op_names.push_back(builtin_name("fp.geq", OP_FLOAT_GE)); - op_names.push_back(builtin_name("fp.gt", OP_FLOAT_GT)); - op_names.push_back(builtin_name("fp.isNormal", OP_FLOAT_IS_NORMAL)); - op_names.push_back(builtin_name("fp.isSubnormal", OP_FLOAT_IS_SUBNORMAL)); - op_names.push_back(builtin_name("fp.isZero", OP_FLOAT_IS_ZERO)); - op_names.push_back(builtin_name("fp.isInfinite", OP_FLOAT_IS_INF)); - op_names.push_back(builtin_name("fp.isNaN", OP_FLOAT_IS_NAN)); - op_names.push_back(builtin_name("fp.min", OP_FLOAT_MIN)); - op_names.push_back(builtin_name("fp.max", OP_FLOAT_MAX)); op_names.push_back(builtin_name("to_fp", OP_TO_FLOAT)); - if (m_bv_plugin) { - op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); - op_names.push_back(builtin_name("to_fp_unsigned", OP_FLOAT_TO_FP_UNSIGNED)); - op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); - op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); - } - - // op_names.push_back(builtin_name("fp.toReal", ?)); + if (m_bv_plugin) + op_names.push_back(builtin_name("asIEEEBV", OP_FLOAT_TO_IEEE_BV)); } void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { + // Old draft sort names. sort_names.push_back(builtin_name("FP", FLOAT_SORT)); sort_names.push_back(builtin_name("RoundingMode", ROUNDING_MODE_SORT)); - // In the SMT FPA final draft, FP is called FloatingPoint + // In the final draft, FP is called FloatingPoint ... sort_names.push_back(builtin_name("FloatingPoint", FLOAT_SORT)); + // ... and it supports three common FloatingPoint sorts + sort_names.push_back(builtin_name("Float16", FLOAT16_SORT)); + sort_names.push_back(builtin_name("Float32", FLOAT32_SORT)); + sort_names.push_back(builtin_name("Float64", FLOAT64_SORT)); + sort_names.push_back(builtin_name("Float128", FLOAT128_SORT)); } expr * float_decl_plugin::get_some_value(sort * s) { @@ -661,6 +717,8 @@ bool float_decl_plugin::is_value(app * e) const { case OP_FLOAT_VALUE: case OP_FLOAT_PLUS_INF: case OP_FLOAT_MINUS_INF: + case OP_FLOAT_PLUS_ZERO: + case OP_FLOAT_MINUS_ZERO: case OP_FLOAT_NAN: return true; case OP_TO_FLOAT: diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 2b6b7fd64..8a77b63cc 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -27,7 +27,11 @@ Revision History: enum float_sort_kind { FLOAT_SORT, - ROUNDING_MODE_SORT + ROUNDING_MODE_SORT, + FLOAT16_SORT, + FLOAT32_SORT, + FLOAT64_SORT, + FLOAT128_SORT }; enum float_op_kind { @@ -37,22 +41,23 @@ enum float_op_kind { OP_RM_TOWARD_NEGATIVE, OP_RM_TOWARD_ZERO, - OP_FLOAT_VALUE, OP_FLOAT_PLUS_INF, OP_FLOAT_MINUS_INF, OP_FLOAT_NAN, + OP_FLOAT_PLUS_ZERO, + OP_FLOAT_MINUS_ZERO, OP_FLOAT_ADD, OP_FLOAT_SUB, - OP_FLOAT_UMINUS, + OP_FLOAT_NEG, OP_FLOAT_MUL, OP_FLOAT_DIV, OP_FLOAT_REM, OP_FLOAT_ABS, OP_FLOAT_MIN, OP_FLOAT_MAX, - OP_FLOAT_FUSED_MA, // x*y + z + OP_FLOAT_FMA, // x*y + z OP_FLOAT_SQRT, OP_FLOAT_ROUND_TO_INTEGRAL, @@ -68,13 +73,14 @@ enum float_op_kind { OP_FLOAT_IS_SUBNORMAL, OP_FLOAT_IS_PZERO, OP_FLOAT_IS_NZERO, - OP_FLOAT_IS_SIGN_MINUS, + OP_FLOAT_IS_NEGATIVE, + OP_FLOAT_IS_POSITIVE, OP_TO_FLOAT, - OP_TO_IEEE_BV, + OP_FLOAT_TO_IEEE_BV, OP_FLOAT_FP, - OP_FLOAT_TO_FP_UNSIGNED, + OP_FLOAT_TO_FP, OP_FLOAT_TO_UBV, OP_FLOAT_TO_SBV, OP_FLOAT_TO_REAL, @@ -125,16 +131,14 @@ class float_decl_plugin : public decl_plugin { unsigned arity, sort * const * domain, sort * range); func_decl * mk_rm_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_fused_ma(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + func_decl * mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + func_decl * mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); func_decl * mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -243,7 +247,7 @@ public: app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); } app * mk_div(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_DIV, arg1, arg2, arg3); } - app * mk_uminus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_UMINUS, arg1); } + app * mk_uminus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_NEG, arg1); } app * mk_rem(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_REM, arg1, arg2); } app * mk_max(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MAX, arg1, arg2); } app * mk_min(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MIN, arg1, arg2); } @@ -252,7 +256,7 @@ public: app * mk_round(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ROUND_TO_INTEGRAL, arg1, arg2); } app * mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4) { expr * args[4] = { arg1, arg2, arg3, arg4 }; - return m().mk_app(m_fid, OP_FLOAT_FUSED_MA, 4, args); + return m().mk_app(m_fid, OP_FLOAT_FMA, 4, args); } app * mk_float_eq(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_EQ, arg1, arg2); } @@ -268,11 +272,13 @@ public: app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SUBNORMAL, arg1); } app * mk_is_nzero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NZERO, arg1); } app * mk_is_pzero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_PZERO, arg1); } - app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SIGN_MINUS, arg1); } + app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); } + app * mk_is_positive(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_POSITIVE, arg1); } + app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); } - bool is_uminus(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_UMINUS); } + bool is_uminus(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); } - app * mk_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_TO_IEEE_BV, arg1); } + app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_TO_IEEE_BV, arg1); } }; #endif diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 07f0cdc8a..8564777f2 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1844,11 +1844,19 @@ void fpa2bv_converter::mk_is_subnormal(func_decl * f, unsigned num, expr * const mk_is_denormal(args[0], result); } -void fpa2bv_converter::mk_is_sign_minus(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { +void fpa2bv_converter::mk_is_negative(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); mk_is_neg(args[0], result); } +void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + SASSERT(num == 1); + expr_ref t1(m), t2(m); + mk_is_nan(args[0], t1); + mk_is_pos(args[0], t2); + result = m.mk_and(m.mk_not(t1), t2); +} + void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_float", for (unsigned i=0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl; ); @@ -2141,10 +2149,6 @@ void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, e mk_triple(args[0], args[2], args[1], result); } -void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - NOT_IMPLEMENTED_YET(); -} - void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { NOT_IMPLEMENTED_YET(); } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index dcb508ffd..31ff0f7c9 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -114,7 +114,8 @@ public: void mk_is_zero(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_nzero(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_pzero(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_is_sign_minus(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_is_negative(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_is_positive(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_nan(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_inf(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_normal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 9a0f2564f..bb2506be0 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -115,17 +115,19 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE; case OP_FLOAT_PLUS_INF: m_conv.mk_plus_inf(f, result); return BR_DONE; case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE; + case OP_FLOAT_PLUS_ZERO: m_conv.mk_pzero(f, result); return BR_DONE; + case OP_FLOAT_MINUS_ZERO: m_conv.mk_nzero(f, result); return BR_DONE; case OP_FLOAT_NAN: m_conv.mk_nan(f, result); return BR_DONE; case OP_FLOAT_ADD: m_conv.mk_add(f, num, args, result); return BR_DONE; case OP_FLOAT_SUB: m_conv.mk_sub(f, num, args, result); return BR_DONE; - case OP_FLOAT_UMINUS: m_conv.mk_uminus(f, num, args, result); return BR_DONE; + case OP_FLOAT_NEG: m_conv.mk_uminus(f, num, args, result); return BR_DONE; case OP_FLOAT_MUL: m_conv.mk_mul(f, num, args, result); return BR_DONE; case OP_FLOAT_DIV: m_conv.mk_div(f, num, args, result); return BR_DONE; case OP_FLOAT_REM: m_conv.mk_remainder(f, num, args, result); return BR_DONE; case OP_FLOAT_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE; case OP_FLOAT_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE; case OP_FLOAT_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE; - case OP_FLOAT_FUSED_MA: m_conv.mk_fusedma(f, num, args, result); return BR_DONE; + case OP_FLOAT_FMA: m_conv.mk_fusedma(f, num, args, result); return BR_DONE; case OP_FLOAT_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE; case OP_FLOAT_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE; case OP_FLOAT_EQ: m_conv.mk_float_eq(f, num, args, result); return BR_DONE; @@ -140,11 +142,11 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_IS_INF: m_conv.mk_is_inf(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_NORMAL: m_conv.mk_is_normal(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_SIGN_MINUS: m_conv.mk_is_sign_minus(f, num, args, result); return BR_DONE; + case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; + case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; case OP_TO_FLOAT: m_conv.mk_to_float(f, num, args, result); return BR_DONE; - case OP_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_FP_UNSIGNED: m_conv.mk_to_fp_unsigned(f, num, args, result); return BR_DONE; + case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; + case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index a4212d579..e44540290 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -36,17 +36,17 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c br_status st = BR_FAILED; SASSERT(f->get_family_id() == get_fid()); switch (f->get_decl_kind()) { - case OP_TO_FLOAT: st = mk_to_float(f, num_args, args, result); break; + case OP_TO_FLOAT: st = mk_to_fp(f, num_args, args, result); break; case OP_FLOAT_ADD: SASSERT(num_args == 3); st = mk_add(args[0], args[1], args[2], result); break; case OP_FLOAT_SUB: SASSERT(num_args == 3); st = mk_sub(args[0], args[1], args[2], result); break; - case OP_FLOAT_UMINUS: SASSERT(num_args == 1); st = mk_uminus(args[0], result); break; + case OP_FLOAT_NEG: SASSERT(num_args == 1); st = mk_neg(args[0], result); break; case OP_FLOAT_MUL: SASSERT(num_args == 3); st = mk_mul(args[0], args[1], args[2], result); break; case OP_FLOAT_DIV: SASSERT(num_args == 3); st = mk_div(args[0], args[1], args[2], result); break; case OP_FLOAT_REM: SASSERT(num_args == 2); st = mk_rem(args[0], args[1], result); break; case OP_FLOAT_ABS: SASSERT(num_args == 1); st = mk_abs(args[0], result); break; case OP_FLOAT_MIN: SASSERT(num_args == 2); st = mk_min(args[0], args[1], result); break; case OP_FLOAT_MAX: SASSERT(num_args == 2); st = mk_max(args[0], args[1], result); break; - case OP_FLOAT_FUSED_MA: SASSERT(num_args == 4); st = mk_fused_ma(args[0], args[1], args[2], args[3], result); break; + case OP_FLOAT_FMA: SASSERT(num_args == 4); st = mk_fma(args[0], args[1], args[2], args[3], result); break; case OP_FLOAT_SQRT: SASSERT(num_args == 2); st = mk_sqrt(args[0], args[1], result); break; case OP_FLOAT_ROUND_TO_INTEGRAL: SASSERT(num_args == 2); st = mk_round(args[0], args[1], result); break; @@ -62,10 +62,10 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c case OP_FLOAT_IS_INF: SASSERT(num_args == 1); st = mk_is_inf(args[0], result); break; case OP_FLOAT_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break; case OP_FLOAT_IS_SUBNORMAL: SASSERT(num_args == 1); st = mk_is_subnormal(args[0], result); break; - case OP_FLOAT_IS_SIGN_MINUS: SASSERT(num_args == 1); st = mk_is_sign_minus(args[0], result); break; - case OP_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; - case OP_FLOAT_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break; - case OP_FLOAT_TO_FP_UNSIGNED: SASSERT(num_args == 2); st = mk_to_fp_unsigned(args[0], args[1], result); break; + case OP_FLOAT_IS_NEGATIVE: SASSERT(num_args == 1); st = mk_is_negative(args[0], result); break; + case OP_FLOAT_IS_POSITIVE: SASSERT(num_args == 1); st = mk_is_positive(args[0], result); break; + case OP_FLOAT_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; + case OP_FLOAT_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break; case OP_FLOAT_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(args[0], args[1], result); break; case OP_FLOAT_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(args[0], args[1], result); break; case OP_FLOAT_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; @@ -73,7 +73,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c return st; } -br_status float_rewriter::mk_to_float(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { +br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); SASSERT(f->get_parameter(1).is_int()); @@ -188,7 +188,7 @@ br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref return BR_FAILED; } -br_status float_rewriter::mk_uminus(expr * arg1, expr_ref & result) { +br_status float_rewriter::mk_neg(expr * arg1, expr_ref & result) { if (m_util.is_nan(arg1)) { // -nan --> nan result = arg1; @@ -284,7 +284,7 @@ br_status float_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { return BR_REWRITE_FULL; } -br_status float_rewriter::mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { +br_status float_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm()); @@ -480,7 +480,7 @@ br_status float_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_sign_minus(expr * arg1, expr_ref & result) { +br_status float_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_neg(v)) ? m().mk_true() : m().mk_false(); @@ -490,6 +490,17 @@ br_status float_rewriter::mk_is_sign_minus(expr * arg1, expr_ref & result) { return BR_FAILED; } +br_status float_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { + scoped_mpf v(m_util.fm()); + if (m_util.is_value(arg1, v)) { + result = (m_util.fm().is_neg(v) || m_util.fm().is_nan(v)) ? m().mk_false() : m().mk_true(); + return BR_DONE; + } + + return BR_FAILED; +} + + // This the SMT = br_status float_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); @@ -532,10 +543,6 @@ br_status float_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref return BR_FAILED; } -br_status float_rewriter::mk_to_fp_unsigned(expr * arg1, expr * arg2, expr_ref & result) { - return BR_FAILED; -} - br_status float_rewriter::mk_to_ubv(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } diff --git a/src/ast/rewriter/float_rewriter.h b/src/ast/rewriter/float_rewriter.h index 0f44d227c..16ac766a9 100644 --- a/src/ast/rewriter/float_rewriter.h +++ b/src/ast/rewriter/float_rewriter.h @@ -44,18 +44,17 @@ public: br_status mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); br_status mk_eq_core(expr * arg1, expr * arg2, expr_ref & result); - - br_status mk_to_float(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); + br_status mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); br_status mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); br_status mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); br_status mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); - br_status mk_uminus(expr * arg1, expr_ref & result); + br_status mk_neg(expr * arg1, expr_ref & result); br_status mk_rem(expr * arg1, expr * arg2, expr_ref & result); br_status mk_abs(expr * arg1, expr_ref & result); br_status mk_min(expr * arg1, expr * arg2, expr_ref & result); br_status mk_max(expr * arg1, expr * arg2, expr_ref & result); - br_status mk_fused_ma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result); + br_status mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result); br_status mk_sqrt(expr * arg1, expr * arg2, expr_ref & result); br_status mk_round(expr * arg1, expr * arg2, expr_ref & result); br_status mk_float_eq(expr * arg1, expr * arg2, expr_ref & result); @@ -70,10 +69,12 @@ public: br_status mk_is_inf(expr * arg1, expr_ref & result); br_status mk_is_normal(expr * arg1, expr_ref & result); br_status mk_is_subnormal(expr * arg1, expr_ref & result); - br_status mk_is_sign_minus(expr * arg1, expr_ref & result); + br_status mk_is_negative(expr * arg1, expr_ref & result); + br_status mk_is_positive(expr * arg1, expr_ref & result); br_status mk_to_ieee_bv(expr * arg1, expr_ref & result); + br_status mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); br_status mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); br_status mk_to_fp_unsigned(expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ubv(expr * arg1, expr * arg2, expr_ref & result); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index a228ec4a5..ad353c3d0 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -132,7 +132,7 @@ namespace smt { m_converter.mk_triple(sgn, sig, exp, bv_term); } - else if (term->get_decl_kind() == OP_TO_IEEE_BV) { + else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { SASSERT(is_app(t)); expr_ref bv_e(m); proof_ref bv_pr(m); @@ -424,7 +424,7 @@ namespace smt { ctx.mark_as_relevant(bv_sig); ctx.mark_as_relevant(bv_exp); } - else if (n->get_decl()->get_decl_kind() == OP_TO_IEEE_BV) { + else if (n->get_decl()->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { expr_ref eq(m); app * ex_a = to_app(ex); if (n->get_id() > ex_a->get_id()) From b3f569574c46837209f8b38b8234924307deed1b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 22 Oct 2014 19:28:54 +0100 Subject: [PATCH 055/507] FPA API consistency Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 57 +++++------------------------------ 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index c31c0b89b..eb53403f6 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -635,61 +635,18 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("to_fp", OP_FLOAT_FP)); - if (m_bv_plugin) { - op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); - op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); - op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); - } - - // We also support the names of operators in older drafts. - op_names.push_back(builtin_name("plusInfinity", OP_FLOAT_PLUS_INF)); - op_names.push_back(builtin_name("minusInfinity", OP_FLOAT_MINUS_INF)); + op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); + op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); + op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); - op_names.push_back(builtin_name("+", OP_FLOAT_ADD)); - op_names.push_back(builtin_name("-", OP_FLOAT_SUB)); - op_names.push_back(builtin_name("/", OP_FLOAT_DIV)); - op_names.push_back(builtin_name("*", OP_FLOAT_MUL)); - - op_names.push_back(builtin_name("abs", OP_FLOAT_ABS)); - op_names.push_back(builtin_name("remainder", OP_FLOAT_REM)); - op_names.push_back(builtin_name("fusedMA", OP_FLOAT_FMA)); - op_names.push_back(builtin_name("squareRoot", OP_FLOAT_SQRT)); - op_names.push_back(builtin_name("roundToIntegral", OP_FLOAT_ROUND_TO_INTEGRAL)); - - op_names.push_back(builtin_name("==", OP_FLOAT_EQ)); - - op_names.push_back(builtin_name("<", OP_FLOAT_LT)); - op_names.push_back(builtin_name(">", OP_FLOAT_GT)); - op_names.push_back(builtin_name("<=", OP_FLOAT_LE)); - op_names.push_back(builtin_name(">=", OP_FLOAT_GE)); - - op_names.push_back(builtin_name("isNaN", OP_FLOAT_IS_NAN)); - op_names.push_back(builtin_name("isInfinite", OP_FLOAT_IS_INF)); - op_names.push_back(builtin_name("isZero", OP_FLOAT_IS_ZERO)); - op_names.push_back(builtin_name("isNZero", OP_FLOAT_IS_NZERO)); - op_names.push_back(builtin_name("isPZero", OP_FLOAT_IS_PZERO)); - op_names.push_back(builtin_name("isNormal", OP_FLOAT_IS_NORMAL)); - op_names.push_back(builtin_name("isSubnormal", OP_FLOAT_IS_SUBNORMAL)); - op_names.push_back(builtin_name("isSignMinus", OP_FLOAT_IS_NEGATIVE)); - - // Disabled min/max, clashes with user-defined min/max functions - // op_names.push_back(builtin_name("min", OP_FLOAT_MIN)); - // op_names.push_back(builtin_name("max", OP_FLOAT_MAX)); - - op_names.push_back(builtin_name("to_fp", OP_TO_FLOAT)); - - if (m_bv_plugin) - op_names.push_back(builtin_name("asIEEEBV", OP_FLOAT_TO_IEEE_BV)); + op_names.push_back(builtin_name("to_fp", OP_TO_FLOAT)); } -void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { - // Old draft sort names. - sort_names.push_back(builtin_name("FP", FLOAT_SORT)); +void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { + sort_names.push_back(builtin_name("FloatingPoint", FLOAT_SORT)); sort_names.push_back(builtin_name("RoundingMode", ROUNDING_MODE_SORT)); - // In the final draft, FP is called FloatingPoint ... - sort_names.push_back(builtin_name("FloatingPoint", FLOAT_SORT)); - // ... and it supports three common FloatingPoint sorts + // The final theory supports three common FloatingPoint sorts sort_names.push_back(builtin_name("Float16", FLOAT16_SORT)); sort_names.push_back(builtin_name("Float32", FLOAT32_SORT)); sort_names.push_back(builtin_name("Float64", FLOAT64_SORT)); From 60478b7022b31ada3c5cbfb48c58bb37c3cca579 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 22 Oct 2014 19:29:03 +0100 Subject: [PATCH 056/507] FPA API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_rewriter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index bb2506be0..89aaf4e12 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -142,8 +142,8 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_IS_INF: m_conv.mk_is_inf(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_NORMAL: m_conv.mk_is_normal(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; + case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; + case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; case OP_TO_FLOAT: m_conv.mk_to_float(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; From 261fe01ceadae0f5a387fdaf0f2af4f3147f0c6d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Nov 2014 12:38:59 +0000 Subject: [PATCH 057/507] FPA API bug and consistency fixes Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 2 +- src/api/api_fpa.cpp | 26 +++++++-- src/api/dotnet/Context.cs | 2 +- src/api/z3_fpa.h | 94 ++++++++++++++++++++++++-------- src/ast/fpa/fpa2bv_converter.cpp | 8 --- 5 files changed, 95 insertions(+), 37 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 6eb7a2e11..1aef9eb1b 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2618,7 +2618,7 @@ void fpa_example() { symbol_y = Z3_mk_string_symbol(ctx, "y"); x = Z3_mk_const(ctx, symbol_x, double_sort); y = Z3_mk_const(ctx, symbol_y, double_sort); - n = Z3_mk_fpa_double(ctx, 42.0, double_sort); + n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); symbol_q = Z3_mk_string_symbol(ctx, "q"); q = Z3_mk_const(ctx, symbol_q, double_sort); diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 8bcc4c1af..df0dd232a 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -99,7 +99,23 @@ extern "C" { Z3_sort r = of_sort(ctx->float_util().mk_float_sort(ebits, sbits)); RETURN_Z3(r); Z3_CATCH_RETURN(0); - } + } + + Z3_sort Z3_API Z3_mk_fpa_sort_half(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 5, 11); + } + + Z3_sort Z3_API Z3_mk_fpa_sort_single(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 8, 24); + } + + Z3_sort Z3_API Z3_mk_fpa_sort_double(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 11, 53); + } + + Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 15, 113); + } Z3_ast Z3_API Z3_mk_fpa_nan(Z3_context c, Z3_sort s) { Z3_TRY; @@ -131,9 +147,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_double(Z3_context c, double v, Z3_sort ty) { + Z3_ast Z3_API Z3_mk_fpa_numeral_double(Z3_context c, double v, Z3_sort ty) { Z3_TRY; - LOG_Z3_mk_fpa_double(c, v, ty); + LOG_Z3_mk_fpa_numeral_double(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->float_util().fm()); @@ -158,7 +174,7 @@ extern "C" { LOG_Z3_mk_fpa_neg(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_uminus(to_expr(t))); + Z3_ast r = of_ast(ctx->float_util().mk_neg(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -208,7 +224,7 @@ extern "C" { LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_fused_ma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); + Z3_ast r = of_ast(ctx->float_util().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index b1e60d34f..19f6d582c 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3533,7 +3533,7 @@ namespace Microsoft.Z3 public FPNum MkFP(double v, FPSort s) { Contract.Ensures(Contract.Result() != null); - return new FPNum(this, Native.Z3_mk_fpa_double(this.nCtx, v, s.NativeObject)); + return new FPNum(this, Native.Z3_mk_fpa_numeral_double(this.nCtx, v, s.NativeObject)); } /// diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 265657bf4..63b489c83 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -23,6 +23,18 @@ Notes: extern "C" { #endif // __cplusplus + /** + \defgroup capi C API + + */ + + /*@{*/ + + /** + @name Floating-Point API + */ + /*@{*/ + /** \brief Create a rounding mode sort. @@ -92,6 +104,59 @@ extern "C" { */ Z3_sort Z3_API Z3_mk_fpa_sort(__in Z3_context c, __in unsigned ebits, __in unsigned sbits); + /** + \brief Create the half-precision (16-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_half', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_half(__in Z3_context c); + + /** + \brief Create the single-precision (32-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_single', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_single(__in Z3_context c); + + /** + \brief Create the double-precision (64-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_double', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_double(__in Z3_context c); + + /** + \brief Create the quadruple-precision (128-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_quadruple', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(__in Z3_context c); + + /** \brief Create a NaN of sort s. @@ -129,7 +194,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_zero(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); /** - \brief Create a numeral of floating point sort. + \brief Create a numeral of floating point sort from a double. This function can be use to create numerals that fit in a double value. It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. @@ -142,27 +207,9 @@ extern "C" { \sa Z3_mk_numeral - def_API('Z3_mk_fpa_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) + def_API('Z3_mk_fpa_numeral_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_double(__in Z3_context c, __in double v, __in Z3_sort ty); - - /** - \brief Create a numeral of floating point sort. - - This function can be use to create numerals that fit in a double value. - It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. - - \params c logical context. - \params v value. - \params ty sort. - - ty must be a floating point sort - - \sa Z3_mk_numeral - - def_API('Z3_mk_fpa_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) - */ - Z3_ast Z3_API Z3_mk_fpa_double(__in Z3_context c, __in double v, __in Z3_sort ty); + Z3_ast Z3_API Z3_mk_fpa_numeral_double(__in Z3_context c, __in double v, __in Z3_sort ty); /** \brief Floating-point absolute value @@ -468,7 +515,10 @@ extern "C" { def_API('Z3_mk_fpa_to_ieee_bv', AST, (_in(CONTEXT),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t); - + + /*@}*/ + /*@}*/ + #ifdef __cplusplus }; #endif // __cplusplus diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 20d8a00e1..de4797f80 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1858,14 +1858,6 @@ void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const result = m.mk_and(m.mk_not(t1), t2); } -void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 1); - expr_ref t1(m), t2(m); - mk_is_nan(args[0], t1); - mk_is_pos(args[0], t2); - result = m.mk_and(m.mk_not(t1), t2); -} - void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_float", for (unsigned i=0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl; ); From 62d4542f83c4f314e94c1deaf1d4007e6d73aa6d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Nov 2014 13:05:48 +0000 Subject: [PATCH 058/507] FPA API bug fix for RoundingMode values in models Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/fpa2bv_model_converter.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 53fa2405b..3de869e15 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -167,14 +167,15 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { it++) { func_decl * var = it->m_key; - app * a = to_app(it->m_value); + expr * v = it->m_value; + expr_ref eval_v(m); SASSERT(fu.is_rm(var->get_range())); - rational val(0); + rational bv_val(0); unsigned sz = 0; - if (a && bu.is_numeral(a, val, sz)) { - TRACE("fpa2bv_mc", tout << var->get_name() << " == " << val.to_string() << std::endl;); - SASSERT(val.is_uint64()); - switch (val.get_uint64()) + if (v && bv_mdl->eval(v, eval_v, true) && bu.is_numeral(eval_v, bv_val, sz)) { + TRACE("fpa2bv_mc", tout << var->get_name() << " == " << bv_val.to_string() << std::endl;); + SASSERT(bv_val.is_uint64()); + switch (bv_val.get_uint64()) { case BV_RM_TIES_TO_AWAY: float_mdl->register_decl(var, fu.mk_round_nearest_ties_to_away()); break; case BV_RM_TIES_TO_EVEN: float_mdl->register_decl(var, fu.mk_round_nearest_ties_to_even()); break; @@ -183,7 +184,8 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { case BV_RM_TO_ZERO: default: float_mdl->register_decl(var, fu.mk_round_toward_zero()); } - seen.insert(var); + SASSERT(v->get_kind() == AST_APP); + seen.insert(to_app(v)->get_decl()); } } From 9503d955f9d0b4597fc1623e70df942e03dcabe0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Nov 2014 13:16:28 +0000 Subject: [PATCH 059/507] FPA API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 9bf2d5c81..f11389024 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -194,7 +194,7 @@ sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, paramete case FLOAT64_SORT: return mk_float_sort(11, 53); case FLOAT128_SORT: - return mk_float_sort(15, 133); + return mk_float_sort(15, 113); default: m_manager->raise_exception("unknown floating point theory sort"); return 0; From c9c11f3b3ae5299ec2975e4c96171d20c8a277b8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Nov 2014 16:20:19 +0000 Subject: [PATCH 060/507] FPA API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index f11389024..20078f73f 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -454,20 +454,6 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } - else if (arity == 2 && - is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && - is_sort_of(domain[1], m_family_id, FLOAT_SORT)) { - // Rounding + 1 FP -> 1 FP - if (num_parameters != 2) - m_manager->raise_exception("invalid number of parameters to to_fp"); - if (!parameters[0].is_int() || !parameters[1].is_int()) - m_manager->raise_exception("invalid parameter type to to_fp"); - int ebits = parameters[0].get_int(); - int sbits = parameters[1].get_int(); - if (!is_rm_sort(domain[0]) || - !is_sort_of(domain[1], m_family_id, FLOAT_SORT)) - m_manager->raise_exception("sort mismatch"); - } else { // 1 Real -> 1 FP if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) @@ -481,7 +467,7 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); symbol name("to_fp"); - return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } } From b7c5a295705f10114e84d0d457a06ef27bda87b8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Nov 2014 18:36:18 +0000 Subject: [PATCH 061/507] FPA theory bug fixes Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 128 ++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 66 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index ad353c3d0..a7e1c7bf1 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -53,7 +53,7 @@ namespace smt { SASSERT(get_sort(x)->get_family_id() == m_converter.bu().get_family_id()); SASSERT(get_sort(y)->get_family_id() == m_converter.bu().get_family_id()); ast_manager & m = get_manager(); - context & ctx = get_context(); + context & ctx = get_context(); theory_id bv_tid = ctx.get_theory(m.get_sort(x)->get_family_id())->get_id(); literal l = mk_eq(x, y, false); ctx.mk_th_axiom(bv_tid, 1, &l); @@ -69,6 +69,7 @@ namespace smt { simplifier & simp = ctx.get_simplifier(); bv_util & bu = m_converter.bu(); expr_ref bv_atom(m); + proof_ref pr(m); if (ctx.b_internalized(atom)) return true; @@ -78,6 +79,7 @@ namespace smt { ctx.internalize(atom->get_arg(i), false); m_rw(atom, bv_atom); + simp(bv_atom, bv_atom, pr); ctx.internalize(bv_atom, gate_ctx); literal def = ctx.get_literal(bv_atom); @@ -106,12 +108,14 @@ namespace smt { bv_util & bu = m_converter.bu(); sort * term_sort = m.get_sort(term); expr_ref t(m), bv_term(m); + proof_ref pr(m); unsigned num_args = term->get_num_args(); for (unsigned i = 0; i < num_args; i++) ctx.internalize(term->get_arg(i), false); m_rw(term, t); + simp(t, t, pr); if (m_converter.is_rm(term_sort)) { SASSERT(is_app(t)); @@ -163,11 +167,13 @@ namespace smt { simplifier & simp = ctx.get_simplifier(); app * owner = n->get_owner(); expr_ref converted(m); + proof_ref pr(m); theory_var v = mk_var(n); ctx.attach_th_var(n, this, v); m_tvars.push_back(v); m_rw(owner, converted); + simp(converted, converted, pr); m_trans_map.insert(owner, converted, 0); sort * owner_sort = m.get_sort(owner); @@ -260,7 +266,7 @@ namespace smt { theory::pop_scope_eh(num_scopes); } - model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { + model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { ast_manager & m = get_manager(); context & ctx = get_context(); bv_util & bu = m_converter.bu(); @@ -268,12 +274,12 @@ namespace smt { mpf_manager & mpfm = fu.fm(); unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); - + theory_var v = n->get_th_var(get_id()); SASSERT(v != null_theory_var); expr * fpa_e = get_enode(v)->get_owner(); TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(fpa_e, m) << "\n";); - + expr * bv_e; proof * bv_pr; m_trans_map.get(fpa_e, bv_e, bv_pr); @@ -281,16 +287,14 @@ namespace smt { expr_wrapper_proc * res = 0; if (fu.is_rm(fpa_e_srt)) { - SASSERT(ctx.e_internalized(bv_e)); - sort * s = m.get_sort(bv_e); - family_id fid = s->get_family_id(); - theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); - rational val; - if (!bv_th->get_fixed_value(ctx.get_enode(bv_e)->get_owner(), val)) { - UNREACHABLE(); - } + if (!ctx.e_internalized(bv_e)) + res = alloc(expr_wrapper_proc, fu.mk_round_nearest_ties_to_away()); else { + theory_bv * bv_th = (theory_bv*)ctx.get_theory(m.get_family_id("bv")); + rational val; + + bv_th->get_fixed_value(ctx.get_enode(bv_e)->get_owner(), val); // OK to fail app * fp_val_e; SASSERT(val.is_uint64()); switch (val.get_uint64()) @@ -301,8 +305,8 @@ namespace smt { case BV_RM_TO_POSITIVE: fp_val_e = fu.mk_round_toward_positive(); break; case BV_RM_TO_ZERO: default: fp_val_e = fu.mk_round_toward_zero(); - } - + } + TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); res = alloc(expr_wrapper_proc, fp_val_e); } @@ -311,73 +315,65 @@ namespace smt { expr * bv_sgn, *bv_sig, *bv_exp; split_triple(bv_e, bv_sgn, bv_sig, bv_exp); - SASSERT(ctx.e_internalized(bv_sgn)); - SASSERT(ctx.e_internalized(bv_sig)); - SASSERT(ctx.e_internalized(bv_exp)); - - enode * e_sgn = ctx.get_enode(bv_sgn); - enode * e_sig = ctx.get_enode(bv_sig); - enode * e_exp = ctx.get_enode(bv_exp); - - TRACE("t_fpa", tout << "bv rep: [" << mk_ismt2_pp(e_sgn->get_owner(), m) << " " - << mk_ismt2_pp(e_sig->get_owner(), m) << " " - << mk_ismt2_pp(e_exp->get_owner(), m) << "]\n";); - - sort * s = m.get_sort(e_sgn->get_owner()); - family_id fid = s->get_family_id(); + family_id fid = m.get_family_id("bv"); theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); - SASSERT(bv_th->is_attached_to_var(e_sgn)); - SASSERT(bv_th->is_attached_to_var(e_sig)); - SASSERT(bv_th->is_attached_to_var(e_exp)); + app * e_sgn, *e_sig, *e_exp; + unsigned exp_sz = fpa_e_srt->get_parameter(0).get_int(); + unsigned sig_sz = fpa_e_srt->get_parameter(1).get_int() - 1; - unsigned sig_sz, exp_sz; - sig_sz = bu.get_bv_size(e_sig->get_owner()); - exp_sz = bu.get_bv_size(e_exp->get_owner()); + e_sgn = (ctx.e_internalized(bv_sgn)) ? ctx.get_enode(bv_sgn)->get_owner() : + m_converter.bu().mk_numeral(0, 1); + e_sig = (ctx.e_internalized(bv_sig)) ? ctx.get_enode(bv_sig)->get_owner() : + m_converter.bu().mk_numeral(0, sig_sz); + e_exp = (ctx.e_internalized(bv_exp)) ? ctx.get_enode(bv_exp)->get_owner() : + m_converter.bu().mk_numeral(0, exp_sz); + + TRACE("t_fpa", tout << "bv rep: [" + << mk_ismt2_pp(e_sgn, m) << "\n" + << mk_ismt2_pp(e_sig, m) << "\n" + << mk_ismt2_pp(e_exp, m) << "]\n";); rational sgn_r(0), sig_r(0), exp_r(0); - if (!bv_th->get_fixed_value(e_sgn->get_owner(), sgn_r) || - !bv_th->get_fixed_value(e_sig->get_owner(), sig_r) || - !bv_th->get_fixed_value(e_exp->get_owner(), exp_r)) { - UNREACHABLE(); - } - else { - TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " + bv_th->get_fixed_value(e_sgn, sgn_r); // OK to fail + bv_th->get_fixed_value(e_sig, sig_r); // OK to fail + bv_th->get_fixed_value(e_exp, exp_r); // OK to fail + + TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " << sig_r.to_string() << " " << exp_r.to_string() << "]\n";); - // un-bias exponent - rational exp_unbiased_r; - exp_unbiased_r = exp_r - mpfm.m_powers2.m1(exp_sz - 1); + // un-bias exponent + rational exp_unbiased_r; + exp_unbiased_r = exp_r - mpfm.m_powers2.m1(exp_sz - 1); - mpz sig_z; mpf_exp_t exp_z; - mpq sig_q, exp_q; - mpz sig_num, exp_num; - mpqm.set(sig_q, sig_r.to_mpq()); - mpzm.set(sig_num, sig_q.numerator()); - mpqm.set(exp_q, exp_unbiased_r.to_mpq()); - mpzm.set(exp_num, exp_q.numerator()); - mpzm.set(sig_z, sig_num); - exp_z = mpzm.get_int64(exp_num); + mpz sig_z; mpf_exp_t exp_z; + mpq sig_q, exp_q; + mpz sig_num, exp_num; + mpqm.set(sig_q, sig_r.to_mpq()); + mpzm.set(sig_num, sig_q.numerator()); + mpqm.set(exp_q, exp_unbiased_r.to_mpq()); + mpzm.set(exp_num, exp_q.numerator()); + mpzm.set(sig_z, sig_num); + exp_z = mpzm.get_int64(exp_num); - mpf fp_val; - mpfm.set(fp_val, exp_sz, sig_sz + 1, !sgn_r.is_zero(), sig_z, exp_z); + mpf fp_val; + mpfm.set(fp_val, exp_sz, sig_sz + 1, !sgn_r.is_zero(), sig_z, exp_z); - app * fp_val_e; - fp_val_e = fu.mk_value(fp_val); + app * fp_val_e; + fp_val_e = fu.mk_value(fp_val); - TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); + TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); - mpfm.del(fp_val); - mpzm.del(sig_num); - mpzm.del(exp_num); - mpqm.del(sig_q); - mpqm.del(exp_q); - mpzm.del(sig_z); + mpfm.del(fp_val); + mpzm.del(sig_num); + mpzm.del(exp_num); + mpqm.del(sig_q); + mpqm.del(exp_q); + mpzm.del(sig_z); - res = alloc(expr_wrapper_proc, fp_val_e); - } + res = alloc(expr_wrapper_proc, fp_val_e); } else UNREACHABLE(); From 657595818ee97233bd47955630e63ef9a6d62d6e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 10 Dec 2014 18:45:44 +0000 Subject: [PATCH 062/507] FPA API: Renaming for consistency with final SMT standard. Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 31 +++++---- src/api/z3_fpa.h | 63 +++++++++++++---- src/ast/float_decl_plugin.cpp | 85 ++++++++++------------- src/ast/float_decl_plugin.h | 36 ++++------ src/ast/fpa/fpa2bv_converter.cpp | 26 +++---- src/ast/fpa/fpa2bv_converter.h | 2 +- src/ast/fpa/fpa2bv_rewriter.h | 13 ++-- src/ast/rewriter/float_rewriter.cpp | 5 +- src/smt/theory_fpa.cpp | 19 +---- src/smt/theory_fpa.h | 2 +- src/tactic/fpa/fpa2bv_model_converter.cpp | 2 +- 11 files changed, 146 insertions(+), 138 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index df0dd232a..12d32c04a 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -88,6 +88,7 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_sort Z3_API Z3_mk_fpa_sort(Z3_context c, unsigned ebits, unsigned sbits) { Z3_TRY; LOG_Z3_mk_fpa_sort(c, ebits, sbits); @@ -105,18 +106,34 @@ extern "C" { return Z3_mk_fpa_sort(c, 5, 11); } + Z3_sort Z3_API Z3_mk_fpa_sort_16(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 5, 11); + } + Z3_sort Z3_API Z3_mk_fpa_sort_single(__in Z3_context c) { return Z3_mk_fpa_sort(c, 8, 24); } + Z3_sort Z3_API Z3_mk_fpa_sort_32(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 8, 24); + } + Z3_sort Z3_API Z3_mk_fpa_sort_double(__in Z3_context c) { return Z3_mk_fpa_sort(c, 11, 53); } + Z3_sort Z3_API Z3_mk_fpa_sort_64(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 11, 53); + } + Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(__in Z3_context c) { return Z3_mk_fpa_sort(c, 15, 113); } + Z3_sort Z3_API Z3_mk_fpa_sort_128(__in Z3_context c) { + return Z3_mk_fpa_sort(c, 15, 113); + } + Z3_ast Z3_API Z3_mk_fpa_nan(Z3_context c, Z3_sort s) { Z3_TRY; LOG_Z3_mk_fpa_nan(c, s); @@ -373,22 +390,12 @@ extern "C" { Z3_TRY; LOG_Z3_mk_fpa_convert(c, s, rm, t); RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); + api::context * ctx = mk_c(c); expr * args [2] = { to_expr(rm), to_expr(t) }; - Z3_ast r = of_ast(ctx->m().mk_app(ctx->float_util().get_family_id(), OP_TO_FLOAT, + Z3_ast r = of_ast(ctx->m().mk_app(ctx->float_util().get_family_id(), OP_FLOAT_TO_FP, to_sort(s)->get_num_parameters(), to_sort(s)->get_parameters(), 2, args)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } - - Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t) { - Z3_TRY; - LOG_Z3_mk_fpa_to_ieee_bv(c, t); - RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_float_to_ieee_bv(to_expr(t))); - RETURN_Z3(r); - Z3_CATCH_RETURN(0); - } }; diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 63b489c83..f04b87ea3 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -117,6 +117,19 @@ extern "C" { */ Z3_sort Z3_API Z3_mk_fpa_sort_half(__in Z3_context c); + /** + \brief Create the half-precision (16-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_16', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_16(__in Z3_context c); + /** \brief Create the single-precision (32-bit) floating point sort. @@ -130,6 +143,19 @@ extern "C" { */ Z3_sort Z3_API Z3_mk_fpa_sort_single(__in Z3_context c); + /** + \brief Create the single-precision (32-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_32', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_32(__in Z3_context c); + /** \brief Create the double-precision (64-bit) floating point sort. @@ -143,6 +169,19 @@ extern "C" { */ Z3_sort Z3_API Z3_mk_fpa_sort_double(__in Z3_context c); + /** + \brief Create the double-precision (64-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_64', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort__64(__in Z3_context c); + /** \brief Create the quadruple-precision (128-bit) floating point sort. @@ -156,6 +195,18 @@ extern "C" { */ Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(__in Z3_context c); + /** + \brief Create the quadruple-precision (128-bit) floating point sort. + + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits + + \remark ebits must be larger than 1 and sbits must be larger than 2. + + def_API('Z3_mk_fpa_sort_128', SORT, (_in(CONTEXT),)) + */ + Z3_sort Z3_API Z3_mk_fpa_sort_128(__in Z3_context c); /** \brief Create a NaN of sort s. @@ -504,18 +555,6 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_convert(__in Z3_context c, __in Z3_sort s, __in Z3_ast rm, __in Z3_ast t); - /** - \brief Conversion of a floating point term to a bit-vector term in IEEE754 format. - - \param c logical context. - \param t floating-point term. - - t must have floating point sort. The size of the resulting bit-vector is automatically determined. - - def_API('Z3_mk_fpa_to_ieee_bv', AST, (_in(CONTEXT),_in(AST))) - */ - Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t); - /*@}*/ /*@}*/ diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 20078f73f..4f8650610 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -118,23 +118,23 @@ bool float_decl_plugin::is_value(expr * n, mpf & val) { } bool float_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) { - if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_AWAY)) { + if (is_app_of(n, m_family_id, OP_FLOAT_RM_NEAREST_TIES_TO_AWAY)) { val = MPF_ROUND_NEAREST_TAWAY; return true; } - else if (is_app_of(n, m_family_id, OP_RM_NEAREST_TIES_TO_EVEN)) { + else if (is_app_of(n, m_family_id, OP_FLOAT_RM_NEAREST_TIES_TO_EVEN)) { val = MPF_ROUND_NEAREST_TEVEN; return true; } - else if (is_app_of(n, m_family_id, OP_RM_TOWARD_NEGATIVE)) { + else if (is_app_of(n, m_family_id, OP_FLOAT_RM_TOWARD_NEGATIVE)) { val = MPF_ROUND_TOWARD_NEGATIVE; return true; } - else if (is_app_of(n, m_family_id, OP_RM_TOWARD_POSITIVE)) { + else if (is_app_of(n, m_family_id, OP_FLOAT_RM_TOWARD_POSITIVE)) { val = MPF_ROUND_TOWARD_POSITIVE; return true; } - else if (is_app_of(n, m_family_id, OP_RM_TOWARD_ZERO)) { + else if (is_app_of(n, m_family_id, OP_FLOAT_RM_TOWARD_ZERO)) { val = MPF_ROUND_TOWARD_ZERO; return true; } @@ -210,15 +210,15 @@ func_decl * float_decl_plugin::mk_rm_const_decl(decl_kind k, unsigned num_parame sort * s = mk_rm_sort(); func_decl_info finfo(m_family_id, k); switch (k) { - case OP_RM_NEAREST_TIES_TO_EVEN: + case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: return m_manager->mk_const_decl(symbol("roundNearestTiesToEven"), s, finfo); - case OP_RM_NEAREST_TIES_TO_AWAY: + case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: return m_manager->mk_const_decl(symbol("roundNearestTiesToAway"), s, finfo); - case OP_RM_TOWARD_POSITIVE: + case OP_FLOAT_RM_TOWARD_POSITIVE: return m_manager->mk_const_decl(symbol("roundTowardPositive"), s, finfo); - case OP_RM_TOWARD_NEGATIVE: + case OP_FLOAT_RM_TOWARD_NEGATIVE: return m_manager->mk_const_decl(symbol("roundTowardNegative"), s, finfo); - case OP_RM_TOWARD_ZERO: + case OP_FLOAT_RM_TOWARD_ZERO: return m_manager->mk_const_decl(symbol("roundTowardZero"), s, finfo); default: UNREACHABLE(); @@ -471,20 +471,6 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, } } -func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (arity != 1) - m_manager->raise_exception("invalid number of arguments to asIEEEBV"); - if (!is_float_sort(domain[0])) - m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort"); - - unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int(); - parameter ps[] = { parameter(float_sz) }; - sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps); - symbol name("asIEEEBV"); - return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); -} - func_decl * float_decl_plugin::mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 3) @@ -528,17 +514,19 @@ func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { switch (k) { - case OP_TO_FLOAT: + case OP_FLOAT_TO_FP: return mk_to_float(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_MINUS_INF: case OP_FLOAT_PLUS_INF: case OP_FLOAT_NAN: + case OP_FLOAT_MINUS_ZERO: + case OP_FLOAT_PLUS_ZERO: return mk_float_const_decl(k, num_parameters, parameters, arity, domain, range); - case OP_RM_NEAREST_TIES_TO_EVEN: - case OP_RM_NEAREST_TIES_TO_AWAY: - case OP_RM_TOWARD_POSITIVE: - case OP_RM_TOWARD_NEGATIVE: - case OP_RM_TOWARD_ZERO: + case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: + case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: + case OP_FLOAT_RM_TOWARD_POSITIVE: + case OP_FLOAT_RM_TOWARD_NEGATIVE: + case OP_FLOAT_RM_TOWARD_ZERO: return mk_rm_const_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_EQ: case OP_FLOAT_LT: @@ -577,8 +565,6 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters return mk_rm_unary_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_FMA: return mk_fma(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_IEEE_BV: - return mk_float_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_FP: return mk_from3bv(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_UBV: @@ -601,17 +587,17 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("-zero", OP_FLOAT_MINUS_ZERO)); op_names.push_back(builtin_name("NaN", OP_FLOAT_NAN)); - op_names.push_back(builtin_name("roundNearestTiesToEven", OP_RM_NEAREST_TIES_TO_EVEN)); - op_names.push_back(builtin_name("roundNearestTiesToAway", OP_RM_NEAREST_TIES_TO_AWAY)); - op_names.push_back(builtin_name("roundTowardPositive", OP_RM_TOWARD_POSITIVE)); - op_names.push_back(builtin_name("roundTowardNegative", OP_RM_TOWARD_NEGATIVE)); - op_names.push_back(builtin_name("roundTowardZero", OP_RM_TOWARD_ZERO)); + op_names.push_back(builtin_name("roundNearestTiesToEven", OP_FLOAT_RM_NEAREST_TIES_TO_EVEN)); + op_names.push_back(builtin_name("roundNearestTiesToAway", OP_FLOAT_RM_NEAREST_TIES_TO_AWAY)); + op_names.push_back(builtin_name("roundTowardPositive", OP_FLOAT_RM_TOWARD_POSITIVE)); + op_names.push_back(builtin_name("roundTowardNegative", OP_FLOAT_RM_TOWARD_NEGATIVE)); + op_names.push_back(builtin_name("roundTowardZero", OP_FLOAT_RM_TOWARD_ZERO)); - op_names.push_back(builtin_name("RNE", OP_RM_NEAREST_TIES_TO_EVEN)); - op_names.push_back(builtin_name("RNA", OP_RM_NEAREST_TIES_TO_AWAY)); - op_names.push_back(builtin_name("RTP", OP_RM_TOWARD_POSITIVE)); - op_names.push_back(builtin_name("RTN", OP_RM_TOWARD_NEGATIVE)); - op_names.push_back(builtin_name("RTZ", OP_RM_TOWARD_ZERO)); + op_names.push_back(builtin_name("RNE", OP_FLOAT_RM_NEAREST_TIES_TO_EVEN)); + op_names.push_back(builtin_name("RNA", OP_FLOAT_RM_NEAREST_TIES_TO_AWAY)); + op_names.push_back(builtin_name("RTP", OP_FLOAT_RM_TOWARD_POSITIVE)); + op_names.push_back(builtin_name("RTN", OP_FLOAT_RM_TOWARD_NEGATIVE)); + op_names.push_back(builtin_name("RTZ", OP_FLOAT_RM_TOWARD_ZERO)); op_names.push_back(builtin_name("fp.abs", OP_FLOAT_ABS)); op_names.push_back(builtin_name("fp.neg", OP_FLOAT_NEG)); @@ -643,7 +629,8 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); - op_names.push_back(builtin_name("to_fp", OP_TO_FLOAT)); + op_names.push_back(builtin_name("to_fp", OP_FLOAT_TO_FP)); + op_names.push_back(builtin_name("to_fp_unsigned", OP_FLOAT_TO_FP_UNSIGNED)); } void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { @@ -670,11 +657,11 @@ bool float_decl_plugin::is_value(app * e) const { if (e->get_family_id() != m_family_id) return false; switch (e->get_decl_kind()) { - case OP_RM_NEAREST_TIES_TO_EVEN: - case OP_RM_NEAREST_TIES_TO_AWAY: - case OP_RM_TOWARD_POSITIVE: - case OP_RM_TOWARD_NEGATIVE: - case OP_RM_TOWARD_ZERO: + case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: + case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: + case OP_FLOAT_RM_TOWARD_POSITIVE: + case OP_FLOAT_RM_TOWARD_NEGATIVE: + case OP_FLOAT_RM_TOWARD_ZERO: case OP_FLOAT_VALUE: case OP_FLOAT_PLUS_INF: case OP_FLOAT_MINUS_INF: @@ -682,7 +669,7 @@ bool float_decl_plugin::is_value(app * e) const { case OP_FLOAT_MINUS_ZERO: case OP_FLOAT_NAN: return true; - case OP_TO_FLOAT: + case OP_FLOAT_TO_FP: return m_manager->is_value(e->get_arg(0)); default: return false; diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 93ff2e664..98b87f6c9 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -35,11 +35,11 @@ enum float_sort_kind { }; enum float_op_kind { - OP_RM_NEAREST_TIES_TO_EVEN, - OP_RM_NEAREST_TIES_TO_AWAY, - OP_RM_TOWARD_POSITIVE, - OP_RM_TOWARD_NEGATIVE, - OP_RM_TOWARD_ZERO, + OP_FLOAT_RM_NEAREST_TIES_TO_EVEN, + OP_FLOAT_RM_NEAREST_TIES_TO_AWAY, + OP_FLOAT_RM_TOWARD_POSITIVE, + OP_FLOAT_RM_TOWARD_NEGATIVE, + OP_FLOAT_RM_TOWARD_ZERO, OP_FLOAT_VALUE, OP_FLOAT_PLUS_INF, @@ -76,11 +76,9 @@ enum float_op_kind { OP_FLOAT_IS_NEGATIVE, OP_FLOAT_IS_POSITIVE, - OP_TO_FLOAT, - OP_FLOAT_TO_IEEE_BV, - OP_FLOAT_FP, - OP_FLOAT_TO_FP, + OP_FLOAT_TO_FP, + OP_FLOAT_TO_FP_UNSIGNED, OP_FLOAT_TO_UBV, OP_FLOAT_TO_SBV, OP_FLOAT_TO_REAL, @@ -134,9 +132,7 @@ class float_decl_plugin : public decl_plugin { func_decl * mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + unsigned arity, sort * const * domain, sort * range); func_decl * mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -210,11 +206,11 @@ public: unsigned get_ebits(sort * s); unsigned get_sbits(sort * s); - app * mk_round_nearest_ties_to_even() { return m().mk_const(m_fid, OP_RM_NEAREST_TIES_TO_EVEN); } - app * mk_round_nearest_ties_to_away() { return m().mk_const(m_fid, OP_RM_NEAREST_TIES_TO_AWAY); } - app * mk_round_toward_positive() { return m().mk_const(m_fid, OP_RM_TOWARD_POSITIVE); } - app * mk_round_toward_negative() { return m().mk_const(m_fid, OP_RM_TOWARD_NEGATIVE); } - app * mk_round_toward_zero() { return m().mk_const(m_fid, OP_RM_TOWARD_ZERO); } + app * mk_round_nearest_ties_to_even() { return m().mk_const(m_fid, OP_FLOAT_RM_NEAREST_TIES_TO_EVEN); } + app * mk_round_nearest_ties_to_away() { return m().mk_const(m_fid, OP_FLOAT_RM_NEAREST_TIES_TO_AWAY); } + app * mk_round_toward_positive() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_POSITIVE); } + app * mk_round_toward_negative() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_NEGATIVE); } + app * mk_round_toward_zero() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_ZERO); } app * mk_nan(unsigned ebits, unsigned sbits); app * mk_plus_inf(unsigned ebits, unsigned sbits); @@ -240,9 +236,9 @@ public: bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } - bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_TO_FLOAT); } + bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_FLOAT_TO_FP); } - app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); } + app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_TO_FP, arg1, arg2); } app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); } app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); } @@ -277,8 +273,6 @@ public: app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); } bool is_neg(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); } - - app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_TO_IEEE_BV, arg1); } }; #endif diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index de4797f80..3fbb7ccf8 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -53,8 +53,8 @@ fpa2bv_converter::~fpa2bv_converter() { } void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { - SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_TO_FLOAT)); - SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); expr_ref sgn(m), s(m), e(m); m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), sgn); @@ -73,8 +73,8 @@ void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { } void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { - SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_TO_FLOAT)); - SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); expr_ref sgn(m), s(m), e(m); m_simp.mk_ite(c, to_app(t)->get_arg(0), to_app(f)->get_arg(0), sgn); @@ -2203,7 +2203,7 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar } void fpa2bv_converter::split(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); sgn = to_app(e)->get_arg(0); @@ -2252,7 +2252,7 @@ void fpa2bv_converter::mk_is_ninf(expr * e, expr_ref & result) { } void fpa2bv_converter::mk_is_pos(expr * e, expr_ref & result) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr * a0 = to_app(e)->get_arg(0); expr_ref zero(m); @@ -2261,7 +2261,7 @@ void fpa2bv_converter::mk_is_pos(expr * e, expr_ref & result) { } void fpa2bv_converter::mk_is_neg(expr * e, expr_ref & result) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr * a0 = to_app(e)->get_arg(0); expr_ref one(m); @@ -2424,7 +2424,7 @@ void fpa2bv_converter::mk_unbias(expr * e, expr_ref & result) { } void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & lz, bool normalize) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); sort * srt = to_app(e)->get_decl()->get_range(); @@ -2519,11 +2519,11 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) { switch(f->get_decl_kind()) { - case OP_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; - case OP_RM_NEAREST_TIES_TO_EVEN: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); break; - case OP_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; - case OP_RM_TOWARD_POSITIVE: result = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); break; - case OP_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; + case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; + case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); break; + case OP_FLOAT_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; + case OP_FLOAT_RM_TOWARD_POSITIVE: result = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); break; + case OP_FLOAT_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; default: UNREACHABLE(); } } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index eb539d8ae..d033890be 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -73,7 +73,7 @@ public: SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); SASSERT(m_bv_util.is_bv(significand)); SASSERT(m_bv_util.is_bv(exponent)); - result = m.mk_app(m_util.get_family_id(), OP_TO_FLOAT, sign, significand, exponent); + result = m.mk_app(m_util.get_family_id(), OP_FLOAT_FP, sign, significand, exponent); } void mk_eq(expr * a, expr * b, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 7a245b71a..62554e06e 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -107,11 +107,11 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { if (m_conv.is_float_family(f)) { switch (f->get_decl_kind()) { - case OP_RM_NEAREST_TIES_TO_AWAY: - case OP_RM_NEAREST_TIES_TO_EVEN: - case OP_RM_TOWARD_NEGATIVE: - case OP_RM_TOWARD_POSITIVE: - case OP_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE; + case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: + case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: + case OP_FLOAT_RM_TOWARD_NEGATIVE: + case OP_FLOAT_RM_TOWARD_POSITIVE: + case OP_FLOAT_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE; case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE; case OP_FLOAT_PLUS_INF: m_conv.mk_plus_inf(f, result); return BR_DONE; case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE; @@ -144,8 +144,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; - case OP_TO_FLOAT: m_conv.mk_to_float(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; + case OP_FLOAT_TO_FP: m_conv.mk_to_float(f, num, args, result); return BR_DONE; case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index 04546bb4b..436194844 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -36,7 +36,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c br_status st = BR_FAILED; SASSERT(f->get_family_id() == get_fid()); switch (f->get_decl_kind()) { - case OP_TO_FLOAT: st = mk_to_fp(f, num_args, args, result); break; + case OP_FLOAT_TO_FP: st = mk_to_fp(f, num_args, args, result); break; case OP_FLOAT_ADD: SASSERT(num_args == 3); st = mk_add(args[0], args[1], args[2], result); break; case OP_FLOAT_SUB: SASSERT(num_args == 3); st = mk_sub(args[0], args[1], args[2], result); break; case OP_FLOAT_NEG: SASSERT(num_args == 1); st = mk_neg(args[0], result); break; @@ -63,8 +63,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c case OP_FLOAT_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break; case OP_FLOAT_IS_SUBNORMAL: SASSERT(num_args == 1); st = mk_is_subnormal(args[0], result); break; case OP_FLOAT_IS_NEGATIVE: SASSERT(num_args == 1); st = mk_is_negative(args[0], result); break; - case OP_FLOAT_IS_POSITIVE: SASSERT(num_args == 1); st = mk_is_positive(args[0], result); break; - case OP_FLOAT_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; + case OP_FLOAT_IS_POSITIVE: SASSERT(num_args == 1); st = mk_is_positive(args[0], result); break; case OP_FLOAT_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break; case OP_FLOAT_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(args[0], args[1], result); break; case OP_FLOAT_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(args[0], args[1], result); break; diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index a7e1c7bf1..b1947ceb5 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -135,13 +135,7 @@ namespace smt { simp(a->get_arg(2), exp, pr_exp); m_converter.mk_triple(sgn, sig, exp, bv_term); - } - else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { - SASSERT(is_app(t)); - expr_ref bv_e(m); - proof_ref bv_pr(m); - simp(t, bv_term, bv_pr); - } + } else NOT_IMPLEMENTED_YET(); @@ -420,17 +414,6 @@ namespace smt { ctx.mark_as_relevant(bv_sig); ctx.mark_as_relevant(bv_exp); } - else if (n->get_decl()->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { - expr_ref eq(m); - app * ex_a = to_app(ex); - if (n->get_id() > ex_a->get_id()) - std::swap(n, ex_a); - eq = m.mk_eq(n, ex_a); - ctx.internalize(eq, false); - literal l = ctx.get_literal(eq); - ctx.mk_th_axiom(get_id(), 1, &l); - ctx.mark_as_relevant(l); - } else NOT_IMPLEMENTED_YET(); } diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 5c0d2acca..c833f2be3 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -81,7 +81,7 @@ namespace smt { protected: void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { - SASSERT(is_app_of(e, get_family_id(), OP_TO_FLOAT)); + SASSERT(is_app_of(e, get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); sgn = to_app(e)->get_arg(0); sig = to_app(e)->get_arg(1); diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 3de869e15..23809d265 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -116,7 +116,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { bv_mdl->eval(a->get_arg(1), sig, true); bv_mdl->eval(a->get_arg(2), exp, true); - SASSERT(a->is_app_of(fu.get_family_id(), OP_TO_FLOAT)); + SASSERT(a->is_app_of(fu.get_family_id(), OP_FLOAT_TO_FP)); #ifdef Z3DEBUG SASSERT(to_app(a->get_arg(0))->get_decl()->get_arity() == 0); From 7965d24df8a37f26b5f4d722d3c51ba7df4cc124 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 10 Dec 2014 19:36:58 +0000 Subject: [PATCH 063/507] FPA API: added conversion functions to float_decl_plugin Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 118 +++++++++++++++++++++++++--------- src/ast/float_decl_plugin.h | 13 ++-- 2 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 4f8650610..3941d3a97 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -31,12 +31,12 @@ float_decl_plugin::float_decl_plugin(): void float_decl_plugin::set_manager(ast_manager * m, family_id id) { decl_plugin::set_manager(m, id); - family_id aid = m_manager->mk_family_id("arith"); - m_real_sort = m_manager->mk_sort(aid, REAL_SORT); + m_arith_fid = m_manager->mk_family_id("arith"); + m_real_sort = m_manager->mk_sort(m_arith_fid, REAL_SORT); SASSERT(m_real_sort != 0); // arith_decl_plugin must be installed before float_decl_plugin. m_manager->inc_ref(m_real_sort); - m_int_sort = m_manager->mk_sort(aid, INT_SORT); + m_int_sort = m_manager->mk_sort(m_arith_fid, INT_SORT); SASSERT(m_int_sort != 0); // arith_decl_plugin must be installed before float_decl_plugin. m_manager->inc_ref(m_int_sort); @@ -396,8 +396,8 @@ func_decl * float_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, para return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { +func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { if (m_bv_plugin && arity == 3 && is_sort_of(domain[0], m_bv_fid, BV_SORT) && is_sort_of(domain[1], m_bv_fid, BV_SORT) && @@ -423,7 +423,7 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, else if (m_bv_plugin && arity == 2 && is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && is_sort_of(domain[1], m_bv_fid, BV_SORT)) { - // Rounding + 1 BV -> 1 FP + // RoundingMode + 1 BV -> 1 FP if (num_parameters != 2) m_manager->raise_exception("invalid number of parameters to to_fp"); if (!parameters[0].is_int() || !parameters[1].is_int()) @@ -471,51 +471,103 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, } } -func_decl * float_decl_plugin::mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { +func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + SASSERT(m_bv_plugin); + if (arity != 2) + m_manager->raise_exception("invalid number of arguments to to_fp_unsigned"); + if (!is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT)) + m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); + if (!is_sort_of(domain[1], m_bv_fid, BV_SORT)) + m_manager->raise_exception("sort mismatch, expected second argument of bit-vector sort"); + + // RoundingMode + 1 BV -> 1 FP + if (num_parameters != 2) + m_manager->raise_exception("invalid number of parameters to to_fp_unsigned"); + if (!parameters[0].is_int() || !parameters[1].is_int()) + m_manager->raise_exception("invalid parameter type to to_fp_unsigned"); + + int ebits = parameters[0].get_int(); + int sbits = parameters[1].get_int(); + + sort * fp = mk_float_sort(ebits, sbits); + symbol name("to_fp_unsigned"); + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + +func_decl * float_decl_plugin::mk_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { if (arity != 3) m_manager->raise_exception("invalid number of arguments to fp"); - if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) || + if (!is_sort_of(domain[0], m_bv_fid, BV_SORT) || + (domain[0]->get_parameter(0).get_int() != 1) || !is_sort_of(domain[1], m_bv_fid, BV_SORT) || !is_sort_of(domain[2], m_bv_fid, BV_SORT)) - m_manager->raise_exception("sort mismatch"); - - sort * fp = mk_float_sort(domain[1]->get_parameter(0).get_int(), domain[2]->get_parameter(0).get_int() + 1); - symbol name("fp"); + m_manager->raise_exception("sort mismatch, expected three bit-vectors, the first one of size 1."); + + int eb = (domain[1])->get_parameter(0).get_int(); + int sb = (domain[2])->get_parameter(0).get_int() + 1; + symbol name("fp"); + sort * fp = mk_float_sort(eb, sb); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k)); } func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - if (!m_bv_plugin) - m_manager->raise_exception("to_fp_unsigned unsupported; use a logic with BV support"); + unsigned arity, sort * const * domain, sort * range) { + SASSERT(m_bv_plugin); if (arity != 2) - m_manager->raise_exception("invalid number of arguments to to_fp_unsigned"); + m_manager->raise_exception("invalid number of arguments to fp.to_ubv"); + if (num_parameters != 1) + m_manager->raise_exception("invalid number of parameters to fp.to_ubv"); + if (parameters[0].is_int()) + m_manager->raise_exception("invalid parameter type; fp.to_ubv expects an int parameter"); if (is_rm_sort(domain[0])) m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); - if (!is_sort_of(domain[1], m_bv_fid, BV_SORT)) - m_manager->raise_exception("sort mismatch, expected second argument of BV sort"); + if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) + m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); + if (parameters[0].get_int() <= 0) + m_manager->raise_exception("invalid parameter value; fp.to_ubv expects a parameter larger than 0"); - sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); - symbol name("fp.t_ubv"); - return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k)); + symbol name("fp.to_ubv"); + sort * bvs = m_bv_plugin->mk_sort(BV_SORT, 1, parameters); + return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k)); } func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - NOT_IMPLEMENTED_YET(); + unsigned arity, sort * const * domain, sort * range) { + SASSERT(m_bv_plugin); + if (arity != 2) + m_manager->raise_exception("invalid number of arguments to fp.to_sbv"); + if (parameters[0].is_int()) + m_manager->raise_exception("invalid parameter type; fp.to_sbv expects an int parameter"); + if (num_parameters != 1) + m_manager->raise_exception("invalid number of parameters to fp.to_sbv"); + if (is_rm_sort(domain[0])) + m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); + if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) + m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); + if (parameters[0].get_int() <= 0) + m_manager->raise_exception("invalid parameter value; fp.to_ubv expects a parameter larger than 0"); + + symbol name("fp.to_sbv"); + sort * bvs = m_bv_plugin->mk_sort(BV_SORT, 1, parameters); + return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k)); } func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range) { - NOT_IMPLEMENTED_YET(); + unsigned arity, sort * const * domain, sort * range) { + if (arity != 1) + m_manager->raise_exception("invalid number of arguments to fp.to_real"); + if (!is_float_sort(domain[0])) + m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort"); + + symbol name("fp.to_real"); + return m_manager->mk_func_decl(name, 1, domain, m_real_sort, func_decl_info(m_family_id, k)); } func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { - switch (k) { - case OP_FLOAT_TO_FP: - return mk_to_float(k, num_parameters, parameters, arity, domain, range); + switch (k) { case OP_FLOAT_MINUS_INF: case OP_FLOAT_PLUS_INF: case OP_FLOAT_NAN: @@ -566,13 +618,17 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters case OP_FLOAT_FMA: return mk_fma(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_FP: - return mk_from3bv(k, num_parameters, parameters, arity, domain, range); + return mk_fp(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_UBV: return mk_to_ubv(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_SBV: return mk_to_sbv(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_REAL: return mk_to_real(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_TO_FP: + return mk_to_fp(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_TO_FP_UNSIGNED: + return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; @@ -628,7 +684,7 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); - + op_names.push_back(builtin_name("to_fp", OP_FLOAT_TO_FP)); op_names.push_back(builtin_name("to_fp_unsigned", OP_FLOAT_TO_FP_UNSIGNED)); } diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 98b87f6c9..92610444a 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -108,6 +108,7 @@ class float_decl_plugin : public decl_plugin { value_table m_value_table; sort * m_real_sort; sort * m_int_sort; + family_id m_arith_fid; family_id m_bv_fid; bv_decl_plugin * m_bv_plugin; @@ -130,11 +131,13 @@ class float_decl_plugin : public decl_plugin { func_decl * mk_rm_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - func_decl * mk_from3bv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_to_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, From c2b5b6a36b1b20a8d729b8ca53678324dd2f59c6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 10 Dec 2014 19:45:18 +0000 Subject: [PATCH 064/507] typo Signed-off-by: Christoph M. Wintersteiger --- src/api/z3_fpa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index f04b87ea3..6042fc044 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -180,7 +180,7 @@ extern "C" { def_API('Z3_mk_fpa_sort_64', SORT, (_in(CONTEXT),)) */ - Z3_sort Z3_API Z3_mk_fpa_sort__64(__in Z3_context c); + Z3_sort Z3_API Z3_mk_fpa_sort_64(__in Z3_context c); /** \brief Create the quadruple-precision (128-bit) floating point sort. From 72dbb2a51315e729cf6cadb515acad3b00359edc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 10 Dec 2014 20:04:24 +0000 Subject: [PATCH 065/507] FPA API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 13 ------------- src/ast/fpa/fpa2bv_converter.h | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 19f6d582c..87090dcc9 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3788,19 +3788,6 @@ namespace Microsoft.Z3 return new FPExpr(this, Native.Z3_mk_fpa_convert(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); } - /// - /// Conversion of a floating point term to a bit-vector term in IEEE754 format. - /// - /// - /// The size of the resulting bit-vector is automatically determined. - /// - /// floating point term - public FPExpr MkFPToIEEEBV(FPExpr t) - { - Contract.Ensures(Contract.Result() != null); - return new FPExpr(this, Native.Z3_mk_fpa_to_ieee_bv(this.nCtx, t.NativeObject)); - } - #endregion #region Miscellaneous diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index d033890be..08542cd40 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -73,7 +73,7 @@ public: SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); SASSERT(m_bv_util.is_bv(significand)); SASSERT(m_bv_util.is_bv(exponent)); - result = m.mk_app(m_util.get_family_id(), OP_FLOAT_FP, sign, significand, exponent); + result = m.mk_app(m_util.get_family_id(), OP_FLOAT_TO_FP, sign, significand, exponent); } void mk_eq(expr * a, expr * b, expr_ref & result); From d6ac98a494fc6b5e3d6fa9e82250b53ad1027051 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 11 Dec 2014 12:05:52 +0000 Subject: [PATCH 066/507] FPA API: reintroduced to_ieee_bv Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 11 +++++++++++ src/api/z3_fpa.h | 13 +++++++++++++ src/ast/float_decl_plugin.cpp | 20 ++++++++++++++++++++ src/ast/float_decl_plugin.h | 15 +++++++++++---- src/ast/rewriter/float_rewriter.cpp | 1 + src/smt/theory_fpa.cpp | 19 ++++++++++++++++++- 6 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 12d32c04a..876e3cff5 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -398,4 +398,15 @@ extern "C" { RETURN_Z3(r); Z3_CATCH_RETURN(0); } + + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_to_ieee_bv(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_float_to_ieee_bv(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + }; diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 6042fc044..50ad49590 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -555,6 +555,19 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_convert(__in Z3_context c, __in Z3_sort s, __in Z3_ast rm, __in Z3_ast t); + /** + \brief Conversion of a floating point term to a bit-vector term in IEEE754 format. + + \param c logical context. + \param t floating-point term. + + t must have floating point sort. The size of the resulting bit-vector is automatically determined. + + def_API('Z3_mk_fpa_to_ieee_bv', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t); + + /*@}*/ /*@}*/ diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 3941d3a97..231d826b2 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -565,6 +565,21 @@ func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, return m_manager->mk_func_decl(name, 1, domain, m_real_sort, func_decl_info(m_family_id, k)); } +func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 1) + m_manager->raise_exception("invalid number of arguments to asIEEEBV"); + if (!is_float_sort(domain[0])) + m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort"); + + unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int(); + parameter ps[] = { parameter(float_sz) }; + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps); + symbol name("to_ieee_bv"); + return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + + func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { switch (k) { @@ -629,6 +644,8 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters return mk_to_fp(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_FP_UNSIGNED: return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_TO_IEEE_BV: + return mk_float_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; @@ -687,6 +704,9 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("to_fp", OP_FLOAT_TO_FP)); op_names.push_back(builtin_name("to_fp_unsigned", OP_FLOAT_TO_FP_UNSIGNED)); + + /* Extensions */ + op_names.push_back(builtin_name("to_ieee_bv", OP_FLOAT_TO_IEEE_BV)); } void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 92610444a..dbd3dda2e 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -82,6 +82,9 @@ enum float_op_kind { OP_FLOAT_TO_UBV, OP_FLOAT_TO_SBV, OP_FLOAT_TO_REAL, + + /* Extensions */ + OP_FLOAT_TO_IEEE_BV, LAST_FLOAT_OP }; @@ -139,12 +142,14 @@ class float_decl_plugin : public decl_plugin { func_decl * mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_real(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); - + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + virtual void set_manager(ast_manager * m, family_id id); unsigned mk_id(mpf const & v); void recycled_id(unsigned id); @@ -276,6 +281,8 @@ public: app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); } bool is_neg(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); } + + app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_TO_IEEE_BV, arg1); } }; #endif diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index 436194844..d1e1ab00e 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -68,6 +68,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c case OP_FLOAT_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(args[0], args[1], result); break; case OP_FLOAT_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(args[0], args[1], result); break; case OP_FLOAT_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; + case OP_FLOAT_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; } return st; } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index b1947ceb5..5efac6596 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -135,7 +135,13 @@ namespace smt { simp(a->get_arg(2), exp, pr_exp); m_converter.mk_triple(sgn, sig, exp, bv_term); - } + } + else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { + SASSERT(is_app(t)); + expr_ref bv_e(m); + proof_ref bv_pr(m); + simp(t, bv_term, bv_pr); + } else NOT_IMPLEMENTED_YET(); @@ -414,6 +420,17 @@ namespace smt { ctx.mark_as_relevant(bv_sig); ctx.mark_as_relevant(bv_exp); } + else if (n->get_decl()->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { + expr_ref eq(m); + app * ex_a = to_app(ex); + if (n->get_id() > ex_a->get_id()) + std::swap(n, ex_a); + eq = m.mk_eq(n, ex_a); + ctx.internalize(eq, false); + literal l = ctx.get_literal(eq); + ctx.mk_th_axiom(get_id(), 1, &l); + ctx.mark_as_relevant(l); + } else NOT_IMPLEMENTED_YET(); } From b30e61e528b819c18831b903a37ed98291b7db90 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 13 Dec 2014 19:34:55 +0000 Subject: [PATCH 067/507] FPA: bugfixes, leakfixes, added fp.to_real Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 7 +- src/ast/fpa/fpa2bv_converter.cpp | 136 ++++++++++++++++++++++------ src/ast/fpa/fpa2bv_converter.h | 2 +- src/ast/fpa/fpa2bv_rewriter.h | 3 +- src/ast/rewriter/float_rewriter.cpp | 9 ++ src/smt/theory_fpa.cpp | 6 +- src/util/mpf.cpp | 76 ++++++++++------ 7 files changed, 177 insertions(+), 62 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 231d826b2..9b6af92ff 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -413,9 +413,13 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa m_manager->raise_exception("invalid number of parameters to to_fp"); if (!parameters[0].is_int() || !parameters[1].is_int()) m_manager->raise_exception("invalid parameter type to to_fp"); + int ebits = parameters[0].get_int(); int sbits = parameters[1].get_int(); + if (domain[0]->get_parameter(0).get_int() != (ebits + sbits)) + m_manager->raise_exception("sort mismtach; invalid bit-vector size, expected bitvector of size (ebits+sbits)"); + sort * fp = mk_float_sort(ebits, sbits); symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); @@ -461,7 +465,7 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa if (arity != 2 && arity != 3) m_manager->raise_exception("invalid number of arguments to to_fp operator"); if (arity == 3 && domain[2] != m_int_sort) - m_manager->raise_exception("sort mismatch, expected second argument of Int sort"); + m_manager->raise_exception("sort mismatch, expected third argument of Int sort"); if (domain[1] != m_real_sort) m_manager->raise_exception("sort mismatch, expected second argument of Real sort"); @@ -701,6 +705,7 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); + op_names.push_back(builtin_name("fp.to_real", OP_FLOAT_TO_REAL)); op_names.push_back(builtin_name("to_fp", OP_FLOAT_TO_FP)); op_names.push_back(builtin_name("to_fp_unsigned", OP_FLOAT_TO_FP_UNSIGNED)); diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 3fbb7ccf8..5fd96eace 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1858,9 +1858,9 @@ void fpa2bv_converter::mk_is_positive(func_decl * f, unsigned num, expr * const result = m.mk_and(m.mk_not(t1), t2); } -void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - TRACE("fpa2bv_to_float", for (unsigned i=0; i < num; i++) - tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl; ); +void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_to_fp", for (unsigned i=0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl; ); if (num == 3 && m_bv_util.is_bv(args[0]) && @@ -1884,16 +1884,16 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a rational q; if (!m_arith_util.is_numeral(args[1], q)) - NOT_IMPLEMENTED_YET(); + UNREACHABLE(); rational e; if (!m_arith_util.is_numeral(args[2], e)) - NOT_IMPLEMENTED_YET(); + UNREACHABLE(); SASSERT(e.is_int64()); SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1)); - mpf nte, nta, tp, tn, tz; + scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager); m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator()); m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator()); m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator()); @@ -1914,21 +1914,26 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a mk_value(a_tn->get_decl(), 0, 0, bv_tn); mk_value(a_tz->get_decl(), 0, 0, bv_tz); - mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)), bv_tn, bv_tz, result); - mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)), bv_tp, result, result); - mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)), bv_nta, result, result); - mk_ite(m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)), bv_nte, result, result); + expr_ref c1(m), c2(m), c3(m), c4(m); + c1 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); + c2 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); + c3 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)); + c4 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)); + + mk_ite(c1, bv_tn, bv_tz, result); + mk_ite(c2, bv_tp, result, result); + mk_ite(c3, bv_nta, result, result); + mk_ite(c4, bv_nte, result, result); } else if (num == 1 && m_bv_util.is_bv(args[0])) { sort * s = f->get_range(); unsigned to_sbits = m_util.get_sbits(s); - unsigned to_ebits = m_util.get_ebits(s); + unsigned to_ebits = m_util.get_ebits(s); expr * bv = args[0]; int sz = m_bv_util.get_bv_size(bv); SASSERT((unsigned)sz == to_sbits + to_ebits); - - m_bv_util.mk_extract(sz - 1, sz - 1, bv); + mk_triple(m_bv_util.mk_extract(sz - 1, sz - 1, bv), m_bv_util.mk_extract(sz - to_ebits - 2, 0, bv), m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), @@ -2093,8 +2098,8 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a else if (num == 2 && m_util.is_rm(args[0]), m_arith_util.is_real(args[1])) { - // .. other than that, we only support rationals for asFloat - SASSERT(m_util.is_float(f->get_range())); + // .. other than that, we only support rationals for to_fp + SASSERT(m_util.is_float(f->get_range())); unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); @@ -2121,16 +2126,16 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a rational q; m_util.au().is_numeral(args[1], q); - mpf v; + scoped_mpf v(m_mpf_manager); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq()); - expr * sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1); - expr * s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1); - expr * e = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits); + expr_ref sgn(m), s(m), e(m), unbiased_exp(m); + sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1); + s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1); + unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits); + mk_bias(unbiased_exp, e); mk_triple(sgn, s, e, result); - - m_util.fm().del(v); } else UNREACHABLE(); @@ -2187,19 +2192,92 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg } void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); SASSERT(num == 1); + SASSERT(f->get_num_parameters() == 0); + SASSERT(is_app_of(args[0], m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + + expr * x = args[0]; + sort * s = m.get_sort(x); + unsigned ebits = m_util.get_ebits(s); + unsigned sbits = m_util.get_sbits(s); - //unsigned ebits = m_util.get_ebits(f->get_range()); - //unsigned sbits = m_util.get_sbits(f->get_range()); - //int width = f->get_parameter(0).get_int(); + sort * rs = m_arith_util.mk_real(); + expr_ref x_is_nan(m), x_is_inf(m), x_is_zero(m); + mk_is_nan(x, x_is_nan); + mk_is_inf(x, x_is_inf); + mk_is_zero(x, x_is_zero); - //expr * rm = args[0]; - //expr * x = args[1]; + expr_ref sgn(m), sig(m), exp(m), lz(m); + unpack(x, sgn, sig, exp, lz, true); + // sig is of the form [1].[sigbits] - //expr * sgn, *s, *e; - //split(x, sgn, s, e); + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(sig) == sbits); + SASSERT(m_bv_util.get_bv_size(exp) == ebits); - NOT_IMPLEMENTED_YET(); + expr_ref rsig(m), bit(m), zero(m), one(m), two(m), bv0(m), bv1(m); + zero = m_arith_util.mk_numeral(rational(0), rs); + one = m_arith_util.mk_numeral(rational(1), rs); + two = m_arith_util.mk_numeral(rational(2), rs); + bv0 = m_bv_util.mk_numeral(0, 1); + bv1 = m_bv_util.mk_numeral(1, 1); + rsig = one; + for (unsigned i = sbits-2; i != (unsigned)-1; i--) + { + bit = m_bv_util.mk_extract(i, i, sig); + rsig = m_arith_util.mk_mul(rsig, two); + rsig = m_arith_util.mk_add(rsig, m.mk_ite(m.mk_eq(bit, bv1), one, zero)); + } + + const mpz & p2 = fu().fm().m_powers2(sbits-1); + expr_ref ep2(m); + ep2 = m_arith_util.mk_numeral(rational(p2), false); + rsig = m_arith_util.mk_div(rsig, ep2); + dbg_decouple("fpa2bv_to_real_ep2", ep2); + dbg_decouple("fpa2bv_to_real_rsig", rsig); + + expr_ref exp_n(m), exp_p(m), exp_is_neg(m), exp_abs(m); + exp_is_neg = m.mk_eq(m_bv_util.mk_extract(ebits - 1, ebits - 1, exp), bv1); + dbg_decouple("fpa2bv_to_real_exp_is_neg", exp_is_neg); + exp_p = m_bv_util.mk_sign_extend(1, exp); + exp_n = m_bv_util.mk_bv_not(m_bv_util.mk_sign_extend(1, exp)); + exp_abs = m.mk_ite(exp_is_neg, exp_n, exp_p); + dbg_decouple("fpa2bv_to_real_exp_abs", exp); + SASSERT(m_bv_util.get_bv_size(exp_abs) == ebits + 1); + + expr_ref exp2(m), prev_bit(m); + exp2 = zero; + prev_bit = bv0; + for (unsigned i = ebits; i != (unsigned)-1; i--) + { + bit = m_bv_util.mk_extract(i, i, exp_abs); + exp2 = m_arith_util.mk_mul(exp2, two); + exp2 = m_arith_util.mk_add(exp2, m.mk_ite(m.mk_eq(bit, prev_bit), zero, one)); + prev_bit = bit; + } + + exp2 = m.mk_ite(exp_is_neg, m_arith_util.mk_div(one, exp2), exp2); + dbg_decouple("fpa2bv_to_real_exp2", exp2); + + expr_ref res(m), two_exp2(m); + two_exp2 = m_arith_util.mk_power(two, exp2); + res = m_arith_util.mk_mul(rsig, two_exp2); + res = m.mk_ite(m.mk_eq(sgn, bv1), m_arith_util.mk_uminus(res), res); + dbg_decouple("fpa2bv_to_real_sig_times_exp2", res); + + TRACE("fpa2bv_to_real", tout << "rsig = " << mk_ismt2_pp(rsig, m) << std::endl; + tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;); + + expr_ref undef(m); + undef = m.mk_fresh_const(0, rs); + + result = m.mk_ite(x_is_zero, zero, res); + result = m.mk_ite(x_is_inf, undef, result); + result = m.mk_ite(x_is_nan, undef, result); + + SASSERT(is_well_sorted(m, result)); } void fpa2bv_converter::split(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 08542cd40..caad0875c 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -121,7 +121,7 @@ public: void mk_is_normal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_subnormal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 62554e06e..a5ff8f5ca 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -144,11 +144,12 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_FP: m_conv.mk_to_float(f, num, args, result); return BR_DONE; + case OP_FLOAT_TO_FP: m_conv.mk_to_fp(f, num, args, result); return BR_DONE; case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; + case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; default: TRACE("fpa2bv", tout << "unsupported operator: " << f->get_name() << "\n"; for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << std::endl;); diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index d1e1ab00e..42a4e5660 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -552,5 +552,14 @@ br_status float_rewriter::mk_to_sbv(expr * arg1, expr * arg2, expr_ref & result) } br_status float_rewriter::mk_to_real(expr * arg1, expr_ref & result) { + scoped_mpf fv(m_util.fm()); + + if (m_util.is_value(arg1, fv)) { + scoped_mpq r(m_fm.mpq_manager()); + m_fm.to_rational(fv, r); + result = m_util.au().mk_numeral(r.get(), false); + return BR_DONE; + } + return BR_FAILED; } \ No newline at end of file diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 5efac6596..ba53dc20f 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -136,7 +136,8 @@ namespace smt { m_converter.mk_triple(sgn, sig, exp, bv_term); } - else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { + else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV || + term->get_decl_kind() == OP_FLOAT_TO_REAL) { SASSERT(is_app(t)); expr_ref bv_e(m); proof_ref bv_pr(m); @@ -420,7 +421,8 @@ namespace smt { ctx.mark_as_relevant(bv_sig); ctx.mark_as_relevant(bv_exp); } - else if (n->get_decl()->get_decl_kind() == OP_FLOAT_TO_IEEE_BV) { + else if (n->get_decl()->get_decl_kind() == OP_FLOAT_TO_IEEE_BV || + n->get_decl()->get_decl_kind() == OP_FLOAT_TO_REAL) { expr_ref eq(m); app * ex_a = to_app(ex); if (n->get_id() > ex_a->get_id()) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index f5785c072..c4fa17d9a 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -199,35 +199,59 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode o.sign = m_mpq_manager.is_neg(value); m_mpz_manager.set(o.significand, 0); - const mpz & p = m_powers2(sbits+2); - signed lz = 0; - - o.exponent = sbits+2; + const mpz & p = m_powers2(sbits+3); + + scoped_mpq v(m_mpq_manager); + m_mpq_manager.set(v, value); + o.exponent = 0; - // CMW: This could be optimized considerably. - scoped_mpz t(m_mpz_manager); - retry: - m_mpz_manager.mul2k(value.numerator(), lz, t); - m_mpz_manager.machine_div(t, value.denominator(), o.significand); - m_mpz_manager.abs(o.significand); - if (m_mpz_manager.lt(o.significand, p)) { - lz++; - goto retry; - } - o.exponent -= lz; - - bool sticky = false; - while (m_mpz_manager.ge(o.significand, m_powers2(sbits+3))) { - sticky = sticky || !m_mpz_manager.is_even(o.significand); - m_mpz_manager.machine_div2k(o.significand, 1); + // Normalize + while (m_mpq_manager.ge(v, mpq(2))) + { + m_mpq_manager.div(v, mpq(2), v); o.exponent++; } - if (sticky && m_mpz_manager.is_even(o.significand)) - m_mpz_manager.inc(o.significand); - TRACE("mpf_dbg", tout << "QUOTIENT = " << m_mpz_manager.to_string(o.significand) << " shift=" << lz << std::endl;); + while (m_mpq_manager.lt(v, mpq(1))) + { + m_mpq_manager.mul(v, mpq(2), v); + o.exponent--; + } - SASSERT(m_mpz_manager.ge(o.significand, m_powers2(sbits+2))); + m_mpz_manager.set(o.significand, 0); + // o.exponent += sbits ; + + SASSERT(m_mpq_manager.lt(v, mpq(2))); + SASSERT(m_mpq_manager.ge(v, mpq(1))); + + // 1.0 <= v < 2.0 (* 2^o.exponent) + // (and v != 0.0) + for (unsigned i = 0; i < sbits + 3 ; i++) + { + m_mpz_manager.mul(o.significand, mpz(2), o.significand); + if (m_mpq_manager.ge(v, mpq(1))) + m_mpz_manager.add(o.significand, mpz(1), o.significand); + m_mpq_manager.sub(v, mpq(1), v); // v := v - 1.0 + m_mpq_manager.mul(mpq(2), v, v); // v := 2.0 * v + } + + // Sticky + // m_mpz_manager.mul(o.significand, mpz(2), o.significand); + /*if (!m_mpq_manager.is_zero(v)) + m_mpz_manager.add(o.significand, mpz(1), o.significand);*/ + + // bias? + // o.exponent += m_mpz_manager.get_int64(m_powers2.m1(ebits - 1, false)); + + // mpq pow; + // m_mpq_manager.power(mpq(2), sbits + 3, pow); + // m_mpq_manager.div(o.significand, pow, o.significand); + // SASSERT(m_mpz_manager.ge(o.significand, mpq(1.0))); + // SASSERT(m_mpz_manager.lt(o.significand, mpq(2.0))); + + TRACE("mpf_dbg", tout << "sig=" << m_mpz_manager.to_string(o.significand) << " exp=" << o.exponent << + " sticky=" << (!m_mpq_manager.is_zero(v)) << std::endl;); + round(rm, o); } @@ -253,7 +277,6 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode TRACE("mpf_dbg", tout << " f = " << f << " e = " << e << std::endl;); - // [Leo]: potential memory leak. moving q and ex to scoped versions scoped_mpq q(m_mpq_manager); m_mpq_manager.set(q, f.c_str()); @@ -276,9 +299,6 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode if (m_mpq_manager.is_zero(significand)) mk_zero(ebits, sbits, o.sign, o); else { - // [Leo]: The following two lines may produce a memory leak. Moving to scoped version - // mpq sig; - // mpz exp; scoped_mpq sig(m_mpq_manager); scoped_mpz exp(m_mpq_manager); From 4e913bb18c561e47fef33a831cfcd568ad100e19 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 14 Dec 2014 17:34:18 +0000 Subject: [PATCH 068/507] FPA bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 6 ++++-- src/smt/theory_fpa.cpp | 10 +++++----- src/smt/theory_fpa.h | 6 +++++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 9b6af92ff..1ae8a2a2c 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -750,8 +750,10 @@ bool float_decl_plugin::is_value(app * e) const { case OP_FLOAT_MINUS_ZERO: case OP_FLOAT_NAN: return true; - case OP_FLOAT_TO_FP: - return m_manager->is_value(e->get_arg(0)); + case OP_FLOAT_FP: + return m_manager->is_value(e->get_arg(0)) && + m_manager->is_value(e->get_arg(1)) && + m_manager->is_value(e->get_arg(2)); default: return false; } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index ba53dc20f..3c6b18349 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -24,11 +24,11 @@ Revision History: namespace smt { - class mk_atom_trail : public trail { + class fpa_atom_trail : public trail { bool_var m_var; public: - mk_atom_trail(bool_var v) : m_var(v) {} - virtual ~mk_atom_trail() {} + fpa_atom_trail(bool_var v) : m_var(v) {} + virtual ~fpa_atom_trail() {} virtual void undo(theory_fpa & th) { theory_fpa::atom * a = th.get_bv2a(m_var); a->~atom(); @@ -87,7 +87,7 @@ namespace smt { ctx.set_var_theory(l.var(), get_id()); pred_atom * a = new (get_region()) pred_atom(l, def); insert_bv2a(l.var(), a); - m_trail_stack.push(mk_atom_trail(l.var())); + m_trail_stack.push(fpa_atom_trail(l.var())); if (!ctx.relevancy()) { ctx.mk_th_axiom(get_id(), l, ~def); @@ -257,7 +257,7 @@ namespace smt { } void theory_fpa::pop_scope_eh(unsigned num_scopes) { - TRACE("bv", tout << num_scopes << "\n";); + TRACE("t_fpa", tout << num_scopes << "\n";); m_trail_stack.pop_scope(num_scopes); unsigned num_old_vars = get_old_num_vars(num_scopes); for (unsigned i = num_old_vars; i < get_num_vars(); i++) { diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index c833f2be3..41374fd8f 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -27,7 +27,11 @@ Revision History: namespace smt { class theory_fpa : public theory { - typedef trail_stack th_trail_stack; + class th_trail_stack : public trail_stack { + public: + th_trail_stack(theory_fpa & th) : trail_stack(th) {} + virtual ~th_trail_stack() {} + }; public: class atom { From f11ee40c38928d84e54ca5fcee404a8cc619f6aa Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 14 Dec 2014 19:09:17 +0000 Subject: [PATCH 069/507] FPA: bug and leak fixes Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 75 ++++++++++++++++++++++++----- src/ast/float_decl_plugin.h | 2 +- src/ast/fpa/fpa2bv_converter.cpp | 50 +++++++++++++++++++ src/ast/fpa/fpa2bv_converter.h | 8 +-- src/ast/rewriter/float_rewriter.cpp | 19 ++++++-- src/ast/rewriter/float_rewriter.h | 1 + src/smt/theory_fpa.cpp | 11 +++-- 7 files changed, 142 insertions(+), 24 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 1ae8a2a2c..625ed9ade 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -457,22 +457,47 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa sort * fp = mk_float_sort(ebits, sbits); symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); - } - else { - // 1 Real -> 1 FP - if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) - m_manager->raise_exception("expecting two integer parameters to to_fp"); - if (arity != 2 && arity != 3) - m_manager->raise_exception("invalid number of arguments to to_fp operator"); - if (arity == 3 && domain[2] != m_int_sort) - m_manager->raise_exception("sort mismatch, expected third argument of Int sort"); - if (domain[1] != m_real_sort) - m_manager->raise_exception("sort mismatch, expected second argument of Real sort"); - + } + else if (arity == 3 && + is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && + is_sort_of(domain[1], m_arith_fid, REAL_SORT) && + is_sort_of(domain[2], m_arith_fid, INT_SORT)) + { + // Rounding + 1 Real + 1 Int -> 1 FP + if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) + m_manager->raise_exception("expecting two integer parameters to to_fp"); + sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } + else if (arity == 1 && + is_sort_of(domain[0], m_arith_fid, REAL_SORT)) + { + // 1 Real -> 1 FP + if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) + m_manager->raise_exception("expecting two integer parameters to to_fp"); + if (domain[1] != m_real_sort) + m_manager->raise_exception("sort mismatch, expected one argument of Real sort"); + + sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); + symbol name("to_fp"); + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); + } + else if (arity == 2 && + is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && + is_sort_of(domain[1], m_arith_fid, REAL_SORT)) + { + // Rounding + 1 Real -> 1 FP + if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) + m_manager->raise_exception("expecting two integer parameters to to_fp"); + + sort * fp = mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); + symbol name("to_fp"); + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); + } + else + NOT_IMPLEMENTED_YET(); } func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -759,6 +784,32 @@ bool float_decl_plugin::is_value(app * e) const { } } +bool float_decl_plugin::is_unique_value(app* e) const { + if (e->get_family_id() != m_family_id) + return false; + switch (e->get_decl_kind()) { + case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: + case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: + case OP_FLOAT_RM_TOWARD_POSITIVE: + case OP_FLOAT_RM_TOWARD_NEGATIVE: + case OP_FLOAT_RM_TOWARD_ZERO: + return true; + case OP_FLOAT_PLUS_INF: /* No; +oo == fp(#b0 #b11 #b00) */ + case OP_FLOAT_MINUS_INF: /* Nol -oo == fp #b1 #b11 #b00) */ + case OP_FLOAT_PLUS_ZERO: /* No; +zero == fp #b0 #b00 #b000) */ + case OP_FLOAT_MINUS_ZERO: /* No; -zero == fp #b1 #b00 #b000) */ + case OP_FLOAT_NAN: /* No; NaN == (fp #b0 #b111111 #b0000001) */ + case OP_FLOAT_VALUE: /* above */ + return false; + case OP_FLOAT_FP: + return m_manager->is_unique_value(e->get_arg(0)) && + m_manager->is_unique_value(e->get_arg(1)) && + m_manager->is_unique_value(e->get_arg(2)); + default: + return false; + } +} + float_util::float_util(ast_manager & m): m_manager(m), m_fid(m.mk_family_id("float")), diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index dbd3dda2e..bd180c45c 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -170,7 +170,7 @@ public: virtual void get_sort_names(svector & sort_names, symbol const & logic); virtual expr * get_some_value(sort * s); virtual bool is_value(app* e) const; - virtual bool is_unique_value(app* e) const { return is_value(e); } + virtual bool is_unique_value(app* e) const; mpf_manager & fm() { return m_fm; } func_decl * mk_value_decl(mpf const & v); diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 5fd96eace..afad59dff 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1870,6 +1870,12 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args // Just keep it here, as there will be something else that uses it. mk_triple(args[0], args[1], args[2], result); } + else if (num == 2 && + m_bv_util.is_bv(args[0]) && + m_bv_util.is_bv(args[1])) + { + mk_to_fp_signed(f, num, args, result); + } else if (num == 3 && m_bv_util.is_bv(args[0]) && m_arith_util.is_numeral(args[1]) && @@ -2143,6 +2149,50 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args SASSERT(is_well_sorted(m, result)); } +void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_to_fp_signed", for (unsigned i = 0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); + + // This is meant to be a conversion from signed bitvector to float: + // ; from signed machine integer, represented as a 2's complement bit vector + // ((_ to_fp eb sb) RoundingMode(_ BitVec m) (_ FloatingPoint eb sb)) + + + // Semantics: + //((_ to_fp eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb)): + // Let b in[[(_ BitVec m)]] and let n be the signed integer represented by b (in 2's complement format). + // [[(_ to_fp eb sb)]](r, b) = +/ -infinity if n is too large / too small to be represented as a finite + // number of [[(_ FloatingPoint eb sb)]]; [[(_ to_fp eb sb)]](r, x) = y otherwise, where y is the finite + // number such that [[fp.to_real]](y) is closest to n according to rounding mode r. + + NOT_IMPLEMENTED_YET(); + + SASSERT(m_util.is_float(f->get_range())); + unsigned ebits = m_util.get_ebits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); + unsigned sz = sbits + ebits; + SASSERT(m_bv_util.get_bv_size(args[0]) == 3); + SASSERT(m_bv_util.get_bv_size(args[1]) == sz); + + expr_ref rm(m), x(m); + rm = args[0]; + x = args[1]; + + expr_ref sgn(m), sig(m), exp(m); + sgn = m_bv_util.mk_extract(sz - 1, sz - 1, x); + sig = m_bv_util.mk_extract(sz - ebits - 2, 0, x); + exp = m_bv_util.mk_extract(sz - 2, sz - ebits - 1, x); + + round(f->get_range(), rm, sgn, sig, exp, result); +} + +void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_to_fp_unsigned", for (unsigned i = 0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); + + NOT_IMPLEMENTED_YET(); +} + void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index caad0875c..e83754e38 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -121,11 +121,13 @@ public: void mk_is_normal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_subnormal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + + void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result); diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index 42a4e5660..583268c34 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -37,6 +37,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c SASSERT(f->get_family_id() == get_fid()); switch (f->get_decl_kind()) { case OP_FLOAT_TO_FP: st = mk_to_fp(f, num_args, args, result); break; + case OP_FLOAT_TO_FP_UNSIGNED: st = mk_to_fp_unsigned(f, num_args, args, result); break; case OP_FLOAT_ADD: SASSERT(num_args == 3); st = mk_add(args[0], args[1], args[2], result); break; case OP_FLOAT_SUB: SASSERT(num_args == 3); st = mk_sub(args[0], args[1], args[2], result); break; case OP_FLOAT_NEG: SASSERT(num_args == 1); st = mk_neg(args[0], result); break; @@ -86,10 +87,10 @@ br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * cons return BR_FAILED; rational q; - mpf q_mpf; + scoped_mpf q_mpf(m_util.fm()); if (m_util.au().is_numeral(args[1], q)) { TRACE("fp_rewriter", tout << "q: " << q << std::endl; ); - mpf v; + scoped_mpf v(m_util.fm()); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq()); result = m_util.mk_value(v); m_util.fm().del(v); @@ -98,7 +99,7 @@ br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * cons } else if (m_util.is_value(args[1], q_mpf)) { TRACE("fp_rewriter", tout << "q: " << m_util.fm().to_string(q_mpf) << std::endl; ); - mpf v; + scoped_mpf v(m_util.fm()); m_util.fm().set(v, ebits, sbits, rm, q_mpf); result = m_util.mk_value(v); m_util.fm().del(v); @@ -126,7 +127,7 @@ br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * cons return BR_FAILED; TRACE("fp_rewriter", tout << "q: " << q << ", e: " << e << "\n";); - mpf v; + scoped_mpf v(m_util.fm()); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator()); result = m_util.mk_value(v); m_util.fm().del(v); @@ -137,6 +138,16 @@ br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * cons } } +br_status float_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { + SASSERT(f->get_num_parameters() == 2); + SASSERT(f->get_parameter(0).is_int()); + SASSERT(f->get_parameter(1).is_int()); + unsigned ebits = f->get_parameter(0).get_int(); + unsigned sbits = f->get_parameter(1).get_int(); + + return BR_FAILED; +} + br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { diff --git a/src/ast/rewriter/float_rewriter.h b/src/ast/rewriter/float_rewriter.h index 4d8cec856..31c571f32 100644 --- a/src/ast/rewriter/float_rewriter.h +++ b/src/ast/rewriter/float_rewriter.h @@ -75,6 +75,7 @@ public: br_status mk_to_ieee_bv(expr * arg1, expr_ref & result); br_status mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); + br_status mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); br_status mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result); br_status mk_to_fp_unsigned(expr * arg1, expr * arg2, expr_ref & result); br_status mk_to_ubv(expr * arg1, expr * arg2, expr_ref & result); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 3c6b18349..26ee88226 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -336,10 +336,13 @@ namespace smt { << mk_ismt2_pp(e_exp, m) << "]\n";); rational sgn_r(0), sig_r(0), exp_r(0); - - bv_th->get_fixed_value(e_sgn, sgn_r); // OK to fail - bv_th->get_fixed_value(e_sig, sig_r); // OK to fail - bv_th->get_fixed_value(e_exp, exp_r); // OK to fail + + if (ctx.e_internalized(bv_sgn) && ctx.get_enode(bv_sgn)->get_num_th_vars() > 0) + bv_th->get_fixed_value(e_sgn, sgn_r); // OK to fail + if (ctx.e_internalized(bv_sig) && ctx.get_enode(bv_sig)->get_num_th_vars() > 0) + bv_th->get_fixed_value(e_sig, sig_r); // OK to fail + if (ctx.e_internalized(bv_exp) && ctx.get_enode(bv_exp)->get_num_th_vars() > 0) + bv_th->get_fixed_value(e_exp, exp_r); // OK to fail TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " << sig_r.to_string() << " " From 47325c5fd3f8bee823a8a9a6a89930309cf2999f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 16 Dec 2014 23:59:27 +0000 Subject: [PATCH 070/507] FPA: bugfixes, naming convention, core theory additions Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 2 +- src/ast/float_decl_plugin.cpp | 9 +- src/ast/float_decl_plugin.h | 12 +- src/ast/fpa/fpa2bv_converter.cpp | 184 ++++++++++++++++++++++------ src/ast/fpa/fpa2bv_converter.h | 4 +- src/ast/fpa/fpa2bv_rewriter.h | 4 +- src/ast/rewriter/float_rewriter.cpp | 16 +-- src/qe/nlarith_util.cpp | 8 +- src/smt/theory_fpa.cpp | 128 +++++++++++-------- src/smt/theory_fpa.h | 34 ++++- 10 files changed, 287 insertions(+), 114 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 876e3cff5..bbf27d25d 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -149,7 +149,7 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->float_util().mk_minus_inf(to_sort(s)) : ctx->float_util().mk_plus_inf(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->float_util().mk_ninf(to_sort(s)) : ctx->float_util().mk_pinf(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 625ed9ade..816df906e 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -163,6 +163,11 @@ decl_plugin * float_decl_plugin::mk_fresh() { } sort * float_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) { + if (ebits > sbits) + m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported"); + if (ebits <= 2) + m_manager->raise_exception("floating point sorts with ebits <= 2 are currently not supported"); + parameter p1(ebits), p2(sbits); parameter ps[2] = { p1, p2 }; sort_size sz; @@ -841,13 +846,13 @@ app * float_util::mk_nan(unsigned ebits, unsigned sbits) { return mk_value(v); } -app * float_util::mk_plus_inf(unsigned ebits, unsigned sbits) { +app * float_util::mk_pinf(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_pinf(ebits, sbits, v); return mk_value(v); } -app * float_util::mk_minus_inf(unsigned ebits, unsigned sbits) { +app * float_util::mk_ninf(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_ninf(ebits, sbits, v); return mk_value(v); diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index bd180c45c..ebf424578 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -221,11 +221,11 @@ public: app * mk_round_toward_zero() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_ZERO); } app * mk_nan(unsigned ebits, unsigned sbits); - app * mk_plus_inf(unsigned ebits, unsigned sbits); - app * mk_minus_inf(unsigned ebits, unsigned sbits); + app * mk_pinf(unsigned ebits, unsigned sbits); + app * mk_ninf(unsigned ebits, unsigned sbits); app * mk_nan(sort * s) { return mk_nan(get_ebits(s), get_sbits(s)); } - app * mk_plus_inf(sort * s) { return mk_plus_inf(get_ebits(s), get_sbits(s)); } - app * mk_minus_inf(sort * s) { return mk_minus_inf(get_ebits(s), get_sbits(s)); } + app * mk_pinf(sort * s) { return mk_pinf(get_ebits(s), get_sbits(s)); } + app * mk_ninf(sort * s) { return mk_ninf(get_ebits(s), get_sbits(s)); } app * mk_value(mpf const & v) { return m_plugin->mk_value(v); } bool is_value(expr * n) { return m_plugin->is_value(n); } @@ -238,8 +238,8 @@ public: app * mk_nzero(sort * s) { return mk_nzero(get_ebits(s), get_sbits(s)); } bool is_nan(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nan(v); } - bool is_plus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pinf(v); } - bool is_minus_inf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); } + bool is_pinf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pinf(v); } + bool is_ninf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); } bool is_zero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_zero(v); } bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index afad59dff..be951098a 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -103,9 +103,9 @@ void fpa2bv_converter::mk_value(func_decl * f, unsigned num, expr * const * args mk_nan(f, result); else if (m_util.fm().is_inf(v)) { if (m_util.fm().sgn(v)) - mk_minus_inf(f, result); + mk_ninf(f, result); else - mk_plus_inf(f, result); + mk_pinf(f, result); } else { expr_ref bv_sgn(m), bv_sig(m), e(m), biased_exp(m); @@ -298,7 +298,7 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) { } } -void fpa2bv_converter::mk_plus_inf(func_decl * f, expr_ref & result) { +void fpa2bv_converter::mk_pinf(func_decl * f, expr_ref & result) { sort * srt = f->get_range(); SASSERT(is_float(srt)); unsigned sbits = m_util.get_sbits(srt); @@ -311,7 +311,7 @@ void fpa2bv_converter::mk_plus_inf(func_decl * f, expr_ref & result) { result); } -void fpa2bv_converter::mk_minus_inf(func_decl * f, expr_ref & result) { +void fpa2bv_converter::mk_ninf(func_decl * f, expr_ref & result) { sort * srt = f->get_range(); SASSERT(is_float(srt)); unsigned sbits = m_util.get_sbits(srt); @@ -633,8 +633,8 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, mk_nan(f, nan); mk_nzero(f, nzero); mk_pzero(f, pzero); - mk_minus_inf(f, ninf); - mk_plus_inf(f, pinf); + mk_ninf(f, ninf); + mk_pinf(f, pinf); expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m); expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_inf(m); @@ -781,8 +781,8 @@ void fpa2bv_converter::mk_div(func_decl * f, unsigned num, expr * const * args, mk_nan(f, nan); mk_nzero(f, nzero); mk_pzero(f, pzero); - mk_minus_inf(f, ninf); - mk_plus_inf(f, pinf); + mk_ninf(f, ninf); + mk_pinf(f, pinf); expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m); expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_inf(m); @@ -927,8 +927,8 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, mk_nan(f, nan); mk_nzero(f, nzero); mk_pzero(f, pzero); - mk_minus_inf(f, ninf); - mk_plus_inf(f, pinf); + mk_ninf(f, ninf); + mk_pinf(f, pinf); expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m); expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_inf(m); @@ -1137,8 +1137,8 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, mk_nan(f, nan); mk_nzero(f, nzero); mk_pzero(f, pzero); - mk_minus_inf(f, ninf); - mk_plus_inf(f, pinf); + mk_ninf(f, ninf); + mk_pinf(f, pinf); expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_neg(m), x_is_inf(m); expr_ref y_is_nan(m), y_is_zero(m), y_is_pos(m), y_is_neg(m), y_is_inf(m); @@ -1447,8 +1447,8 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, mk_nan(f, nan); mk_nzero(f, nzero); mk_pzero(f, pzero); - mk_minus_inf(f, ninf); - mk_plus_inf(f, pinf); + mk_ninf(f, ninf); + mk_pinf(f, pinf); expr_ref x_is_nan(m), x_is_zero(m), x_is_pos(m), x_is_inf(m); mk_is_nan(x, x_is_nan); @@ -1871,9 +1871,11 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args mk_triple(args[0], args[1], args[2], result); } else if (num == 2 && - m_bv_util.is_bv(args[0]) && + m_bv_util.is_bv(args[0]) && + m_bv_util.get_bv_size(args[0]) == 3 && m_bv_util.is_bv(args[1])) { + mk_to_fp_signed(f, num, args, result); } else if (num == 3 && @@ -1968,8 +1970,8 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args one1 = m_bv_util.mk_numeral(1, 1); expr_ref ninf(m), pinf(m); - mk_plus_inf(f, pinf); - mk_minus_inf(f, ninf); + mk_pinf(f, pinf); + mk_ninf(f, ninf); // NaN -> NaN mk_is_nan(x, c1); @@ -2152,38 +2154,146 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_fp_signed", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); - - // This is meant to be a conversion from signed bitvector to float: + + // This is a conversion from signed bitvector to float: // ; from signed machine integer, represented as a 2's complement bit vector // ((_ to_fp eb sb) RoundingMode(_ BitVec m) (_ FloatingPoint eb sb)) - - - // Semantics: - //((_ to_fp eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb)): + // Semantics: // Let b in[[(_ BitVec m)]] and let n be the signed integer represented by b (in 2's complement format). // [[(_ to_fp eb sb)]](r, b) = +/ -infinity if n is too large / too small to be represented as a finite // number of [[(_ FloatingPoint eb sb)]]; [[(_ to_fp eb sb)]](r, x) = y otherwise, where y is the finite - // number such that [[fp.to_real]](y) is closest to n according to rounding mode r. - - NOT_IMPLEMENTED_YET(); + // number such that [[fp.to_real]](y) is closest to n according to rounding mode r. + SASSERT(num == 2); SASSERT(m_util.is_float(f->get_range())); - unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); - unsigned sz = sbits + ebits; - SASSERT(m_bv_util.get_bv_size(args[0]) == 3); - SASSERT(m_bv_util.get_bv_size(args[1]) == sz); + SASSERT(m_bv_util.is_bv(args[0])); + SASSERT(m_bv_util.is_bv(args[1])); expr_ref rm(m), x(m); rm = args[0]; x = args[1]; - expr_ref sgn(m), sig(m), exp(m); - sgn = m_bv_util.mk_extract(sz - 1, sz - 1, x); - sig = m_bv_util.mk_extract(sz - ebits - 2, 0, x); - exp = m_bv_util.mk_extract(sz - 2, sz - ebits - 1, x); + dbg_decouple("fpa2bv_to_fp_signed_x", x); - round(f->get_range(), rm, sgn, sig, exp, result); + unsigned ebits = m_util.get_ebits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); + unsigned f_sz = sbits + ebits; + unsigned bv_sz = m_bv_util.get_bv_size(x); + SASSERT(m_bv_util.get_bv_size(rm) == 3); + + //if (bv_sz < f_sz) { + // x = m_bv_util.mk_zero_extend(f_sz - bv_sz, x); + // bv_sz = f_sz; + //} + + expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m); + bv0_1 = m_bv_util.mk_numeral(0, 1); + bv1_1 = m_bv_util.mk_numeral(1, 1); + bv0_sz = m_bv_util.mk_numeral(0, bv_sz); + bv1_sz = m_bv_util.mk_numeral(1, bv_sz); + + expr_ref is_zero(m), nzero(m), pzero(m), ninf(m), pinf(m); + is_zero = m.mk_eq(x, bv0_sz); + mk_nzero(f, nzero); + mk_pzero(f, pzero); + mk_ninf(f, ninf); + mk_pinf(f, pinf); + + // Special case: x == 0 -> p/n zero + expr_ref c1(m), v1(m), rm_is_to_neg(m); + c1 = is_zero; + mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_ite(rm_is_to_neg, nzero, pzero, v1); + + // Special case: x != 0 + expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m); + expr_ref is_neg(m), x_abs(m); + is_neg_bit = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, x); + is_neg = m.mk_eq(is_neg_bit, bv1_1); + x_abs = m.mk_ite(is_neg, m_bv_util.mk_bv_neg(x), x); + dbg_decouple("fpa2bv_to_fp_signed_is_neg", is_neg); + // x_abs has an extra bit in the front. + // x_abs is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2) + // bv_sz-2 is the "1.0" bit for the rounder. + + expr_ref lz(m), e_bv_sz(m), e_rest_sz(m); + mk_leading_zeros(x_abs, bv_sz, lz); + e_bv_sz = m_bv_util.mk_numeral(bv_sz, bv_sz); + e_rest_sz = m_bv_util.mk_bv_sub(e_bv_sz, lz); + SASSERT(m_bv_util.get_bv_size(lz) == m_bv_util.get_bv_size(e_bv_sz)); + dbg_decouple("fpa2bv_to_fp_signed_lz", lz); + expr_ref shifted_sig(m); + shifted_sig = m_bv_util.mk_bv_shl(x_abs, lz); + + expr_ref sticky(m); + // shifted_sig is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2) * 2^(-lz) + unsigned sig_sz = sbits + 4; // we want extra rounding bits. + if (sig_sz <= bv_sz) { + expr_ref sig_rest(m); + sig_4 = m_bv_util.mk_extract(bv_sz - 1, bv_sz - sig_sz + 1, shifted_sig); // one short + sig_rest = m_bv_util.mk_extract(bv_sz - sig_sz, 0, shifted_sig); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest); + sig_4 = m_bv_util.mk_concat(sig_4, sticky); + } + else { + unsigned extra_bits = sig_sz - bv_sz; + expr_ref extra_zeros(m); + extra_zeros = m_bv_util.mk_numeral(0, extra_bits); + sig_4 = m_bv_util.mk_concat(shifted_sig, extra_zeros); + lz = m_bv_util.mk_bv_add(m_bv_util.mk_concat(extra_zeros, lz), + m_bv_util.mk_numeral(extra_bits, sig_sz)); + bv_sz = bv_sz + extra_bits; + SASSERT(is_well_sorted(m, lz)); + } + SASSERT(m_bv_util.get_bv_size(sig_4) == sig_sz); + + expr_ref s_exp(m), exp_rest(m); + s_exp = m_bv_util.mk_bv_sub(m_bv_util.mk_numeral(bv_sz - 2, bv_sz), lz); + // s_exp = (bv_sz-2) + (-lz) signed + SASSERT(m_bv_util.get_bv_size(s_exp) == bv_sz); + + unsigned exp_sz = ebits + 2; // (+2 for rounder) + exp_2 = m_bv_util.mk_extract(exp_sz - 1, 0, s_exp); + // the remaining bits are 0 if ebits is large enough. + exp_too_large = m.mk_false(); // This is always in range. + + // The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits. + // exp < bv_sz (+sign bit which is [0]) + unsigned exp_worst_case_sz = (unsigned)((log(bv_sz) / log(2)) + 1); + + if (exp_sz < exp_worst_case_sz) { + // exp_sz < exp_worst_case_sz and exp >= 0. + // Take the maximum legal exponent; this + // allows us to keep the most precision. + expr_ref max_exp(m), max_exp_bvsz(m); + mk_max_exp(exp_sz, max_exp); + max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp); + + exp_too_large = m_bv_util.mk_ule(m_bv_util.mk_bv_add( + max_exp_bvsz, + m_bv_util.mk_numeral(1, bv_sz)), + s_exp); + sig_4 = m.mk_ite(exp_too_large, m_bv_util.mk_numeral(0, sig_sz), sig_4); + exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2); + } + dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large); + + expr_ref sgn(m), sig(m), exp(m); + sgn = is_neg_bit; + sig = sig_4; + exp = exp_2; + + dbg_decouple("fpa2bv_to_fp_signed_sgn", sgn); + dbg_decouple("fpa2bv_to_fp_signed_sig", sig); + dbg_decouple("fpa2bv_to_fp_signed_exp", exp); + + SASSERT(m_bv_util.get_bv_size(sig) == sbits + 4); + SASSERT(m_bv_util.get_bv_size(exp) == ebits + 2); + + expr_ref v2(m); + round(f->get_range(), rm, sgn, sig, exp, v2); + + mk_ite(c1, v1, v2, result); } void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -2538,7 +2648,7 @@ void fpa2bv_converter::mk_bias(expr * e, expr_ref & result) { void fpa2bv_converter::mk_unbias(expr * e, expr_ref & result) { unsigned ebits = m_bv_util.get_bv_size(e); - SASSERT(ebits >= 3); + SASSERT(ebits >= 2); expr_ref e_plus_one(m); e_plus_one = m_bv_util.mk_bv_add(e, m_bv_util.mk_numeral(1, ebits)); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index e83754e38..eb4435132 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -86,8 +86,8 @@ public: void mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_var(unsigned base_inx, sort * srt, expr_ref & result); - void mk_plus_inf(func_decl * f, expr_ref & result); - void mk_minus_inf(func_decl * f, expr_ref & result); + void mk_pinf(func_decl * f, expr_ref & result); + void mk_ninf(func_decl * f, expr_ref & result); void mk_nan(func_decl * f, expr_ref & result); void mk_nzero(func_decl *f, expr_ref & result); void mk_pzero(func_decl *f, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index a5ff8f5ca..bb42bdf5d 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -113,8 +113,8 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_RM_TOWARD_POSITIVE: case OP_FLOAT_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE; case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE; - case OP_FLOAT_PLUS_INF: m_conv.mk_plus_inf(f, result); return BR_DONE; - case OP_FLOAT_MINUS_INF: m_conv.mk_minus_inf(f, result); return BR_DONE; + case OP_FLOAT_PLUS_INF: m_conv.mk_pinf(f, result); return BR_DONE; + case OP_FLOAT_MINUS_INF: m_conv.mk_ninf(f, result); return BR_DONE; case OP_FLOAT_PLUS_ZERO: m_conv.mk_pzero(f, result); return BR_DONE; case OP_FLOAT_MINUS_ZERO: m_conv.mk_nzero(f, result); return BR_DONE; case OP_FLOAT_NAN: m_conv.mk_nan(f, result); return BR_DONE; diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index 583268c34..3c1f51990 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -205,14 +205,14 @@ br_status float_rewriter::mk_neg(expr * arg1, expr_ref & result) { result = arg1; return BR_DONE; } - if (m_util.is_plus_inf(arg1)) { + if (m_util.is_pinf(arg1)) { // - +oo --> -oo - result = m_util.mk_minus_inf(m().get_sort(arg1)); + result = m_util.mk_ninf(m().get_sort(arg1)); return BR_DONE; } - if (m_util.is_minus_inf(arg1)) { + if (m_util.is_ninf(arg1)) { // - -oo -> +oo - result = m_util.mk_plus_inf(m().get_sort(arg1)); + result = m_util.mk_pinf(m().get_sort(arg1)); return BR_DONE; } if (m_util.is_neg(arg1)) { @@ -366,22 +366,22 @@ br_status float_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { result = m().mk_false(); return BR_DONE; } - if (m_util.is_minus_inf(arg1)) { + if (m_util.is_ninf(arg1)) { // -oo < arg2 --> not(arg2 = -oo) and not(arg2 = NaN) result = m().mk_and(m().mk_not(m().mk_eq(arg2, arg1)), mk_neq_nan(arg2)); return BR_REWRITE3; } - if (m_util.is_minus_inf(arg2)) { + if (m_util.is_ninf(arg2)) { // arg1 < -oo --> false result = m().mk_false(); return BR_DONE; } - if (m_util.is_plus_inf(arg1)) { + if (m_util.is_pinf(arg1)) { // +oo < arg2 --> false result = m().mk_false(); return BR_DONE; } - if (m_util.is_plus_inf(arg2)) { + if (m_util.is_pinf(arg2)) { // arg1 < +oo --> not(arg1 = +oo) and not(arg1 = NaN) result = m().mk_and(m().mk_not(m().mk_eq(arg1, arg2)), mk_neq_nan(arg1)); return BR_REWRITE3; diff --git a/src/qe/nlarith_util.cpp b/src/qe/nlarith_util.cpp index c555b71f1..fce54aaa4 100644 --- a/src/qe/nlarith_util.cpp +++ b/src/qe/nlarith_util.cpp @@ -1492,11 +1492,11 @@ namespace nlarith { } fml = mk_and(equivs.size(), equivs.c_ptr()); } - void mk_plus_inf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { + void mk_pinf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { plus_inf_subst sub(*this); mk_inf_sign(sub, literals, fml, new_atoms); } - void mk_minus_inf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { + void mk_ninf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { minus_inf_subst sub(*this); mk_inf_sign(sub, literals, fml, new_atoms); } @@ -1704,10 +1704,10 @@ namespace nlarith { app_ref fml(m()); app_ref_vector new_atoms(m()); if (is_pos) { - mk_plus_inf_sign(literals, fml, new_atoms); + mk_pinf_sign(literals, fml, new_atoms); } else { - mk_minus_inf_sign(literals, fml, new_atoms); + mk_ninf_sign(literals, fml, new_atoms); } simple_branch* br = alloc(simple_branch, m(), fml); swap_atoms(br, literals.lits(), new_atoms); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 26ee88226..7552e276b 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -49,6 +49,24 @@ namespace smt { { } + void theory_fpa::add_extra_assertions() + { + ast_manager & m = get_manager(); + context & ctx = get_context(); + simplifier & simp = ctx.get_simplifier(); + + expr_ref_vector::iterator it = m_converter.extra_assertions.begin(); + expr_ref_vector::iterator end = m_converter.extra_assertions.end(); + for (; it != end; it++) { + expr_ref t(m); + proof_ref t_pr(m); + simp(*it, t, t_pr); + TRACE("t_fpa", tout << "extra: " << mk_ismt2_pp(t, m) << "\n";); + ctx.internalize_assertion(t, t_pr, 0); + } + m_converter.extra_assertions.reset(); + } + void theory_fpa::mk_bv_eq(expr * x, expr * y) { SASSERT(get_sort(x)->get_family_id() == m_converter.bu().get_family_id()); SASSERT(get_sort(y)->get_family_id() == m_converter.bu().get_family_id()); @@ -94,6 +112,8 @@ namespace smt { ctx.mk_th_axiom(get_id(), ~l, def); } + add_extra_assertions(); + return true; } @@ -134,7 +154,7 @@ namespace smt { simp(a->get_arg(1), sig, pr_sig); simp(a->get_arg(2), exp, pr_exp); - m_converter.mk_triple(sgn, sig, exp, bv_term); + m_converter.mk_triple(sgn, sig, exp, bv_term); } else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV || term->get_decl_kind() == OP_FLOAT_TO_REAL) { @@ -149,7 +169,9 @@ namespace smt { TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(bv_term, get_manager()) << "\n";); SASSERT(!m_trans_map.contains(term)); - m_trans_map.insert(term, bv_term, 0); + m_trans_map.insert(term, bv_term, 0); + + add_extra_assertions(); enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : ctx.mk_enode(term, false, false, true); theory_var v = mk_var(e); @@ -176,11 +198,15 @@ namespace smt { m_rw(owner, converted); simp(converted, converted, pr); m_trans_map.insert(owner, converted, 0); + + add_extra_assertions(); sort * owner_sort = m.get_sort(owner); if (m_converter.is_rm(owner_sort)) { bv_util & bu = m_converter.bu(); - bu.mk_ule(converted, bu.mk_numeral(4, bu.get_bv_size(converted))); + expr_ref t(m); + t = bu.mk_ule(converted, bu.mk_numeral(4, bu.get_bv_size(converted))); + ctx.internalize_assertion(t, proof_ref(m), 0); } TRACE("t_fpa", tout << "new theory var (const): " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); @@ -191,7 +217,8 @@ namespace smt { TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); - + float_util & fu = m_converter.fu(); + app * ax = get_enode(x)->get_owner(); app * ay = get_enode(y)->get_owner(); expr * ex, *ey; @@ -199,7 +226,7 @@ namespace smt { m_trans_map.get(ax, ex, px); m_trans_map.get(ay, ey, py); - if (m_converter.fu().is_float(get_enode(x)->get_owner())) { + if (fu.is_float(get_enode(x)->get_owner())) { expr * sgn_x, *sig_x, *exp_x; expr * sgn_y, *sig_y, *exp_y; split_triple(ex, sgn_x, sig_x, exp_x); @@ -209,7 +236,7 @@ namespace smt { mk_bv_eq(sig_x, sig_y); mk_bv_eq(exp_x, exp_y); } - else if (m_converter.fu().is_rm(get_enode(x)->get_owner())) { + else if (fu.is_rm(get_enode(x)->get_owner())) { mk_bv_eq(ex, ey); } else @@ -220,7 +247,8 @@ namespace smt { TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << "\n";); ast_manager & m = get_manager(); context & ctx = get_context(); - + float_util & fu = m_converter.fu(); + app * ax = get_enode(x)->get_owner(); app * ay = get_enode(y)->get_owner(); expr * ex, *ey; @@ -230,7 +258,7 @@ namespace smt { expr_ref deq(m); - if (m_converter.fu().is_float(m.get_sort(get_enode(x)->get_owner()))) { + if (fu.is_float(m.get_sort(get_enode(x)->get_owner()))) { expr * sgn_x, *sig_x, *exp_x; expr * sgn_y, *sig_y, *exp_y; split_triple(ex, sgn_x, sig_x, exp_x); @@ -240,7 +268,7 @@ namespace smt { m.mk_not(m.mk_eq(sig_x, sig_y)), m.mk_not(m.mk_eq(exp_x, exp_y))); } - else if (m_converter.fu().is_rm(m.get_sort(get_enode(x)->get_owner()))) { + else if (fu.is_rm(m.get_sort(get_enode(x)->get_owner()))) { deq = m.mk_not(m.mk_eq(ex, ey)); } else @@ -317,67 +345,65 @@ namespace smt { split_triple(bv_e, bv_sgn, bv_sig, bv_exp); family_id fid = m.get_family_id("bv"); - theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); + theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); app * e_sgn, *e_sig, *e_exp; - unsigned exp_sz = fpa_e_srt->get_parameter(0).get_int(); + unsigned ebits = fpa_e_srt->get_parameter(0).get_int(); + unsigned sbits = fpa_e_srt->get_parameter(1).get_int(); unsigned sig_sz = fpa_e_srt->get_parameter(1).get_int() - 1; + rational bias = mpfm.m_powers2.m1(ebits - 1); + rational sgn_r(0), sig_r(0), exp_r(bias); + e_sgn = (ctx.e_internalized(bv_sgn)) ? ctx.get_enode(bv_sgn)->get_owner() : - m_converter.bu().mk_numeral(0, 1); + bu.mk_numeral(0, 1); e_sig = (ctx.e_internalized(bv_sig)) ? ctx.get_enode(bv_sig)->get_owner() : - m_converter.bu().mk_numeral(0, sig_sz); + bu.mk_numeral(0, sig_sz); e_exp = (ctx.e_internalized(bv_exp)) ? ctx.get_enode(bv_exp)->get_owner() : - m_converter.bu().mk_numeral(0, exp_sz); + bu.mk_numeral(bias, ebits); TRACE("t_fpa", tout << "bv rep: [" << mk_ismt2_pp(e_sgn, m) << "\n" << mk_ismt2_pp(e_sig, m) << "\n" - << mk_ismt2_pp(e_exp, m) << "]\n";); - - rational sgn_r(0), sig_r(0), exp_r(0); + << mk_ismt2_pp(e_exp, m) << "]\n";); - if (ctx.e_internalized(bv_sgn) && ctx.get_enode(bv_sgn)->get_num_th_vars() > 0) - bv_th->get_fixed_value(e_sgn, sgn_r); // OK to fail - if (ctx.e_internalized(bv_sig) && ctx.get_enode(bv_sig)->get_num_th_vars() > 0) - bv_th->get_fixed_value(e_sig, sig_r); // OK to fail - if (ctx.e_internalized(bv_exp) && ctx.get_enode(bv_exp)->get_num_th_vars() > 0) - bv_th->get_fixed_value(e_exp, exp_r); // OK to fail - - TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " - << sig_r.to_string() << " " - << exp_r.to_string() << "]\n";); + if (!ctx.e_internalized(bv_sgn) || + ctx.get_enode(bv_sgn)->get_num_th_vars() == 0 || + !bv_th->get_fixed_value(e_sgn, sgn_r)) + sgn_r = rational(0); + if (!ctx.e_internalized(bv_sig) || + ctx.get_enode(bv_sig)->get_num_th_vars() == 0 || + !bv_th->get_fixed_value(e_sig, sig_r)) + sig_r = rational(0); + if (!ctx.e_internalized(bv_exp) || + ctx.get_enode(bv_exp)->get_num_th_vars() == 0 || + !bv_th->get_fixed_value(e_exp, exp_r)) + exp_r = bias; // un-bias exponent rational exp_unbiased_r; - exp_unbiased_r = exp_r - mpfm.m_powers2.m1(exp_sz - 1); + exp_unbiased_r = exp_r - bias; - mpz sig_z; mpf_exp_t exp_z; - mpq sig_q, exp_q; - mpz sig_num, exp_num; + TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " + << sig_r.to_string() << " " + << exp_unbiased_r.to_string() << "(" << exp_r.to_string() << ")]\n"; ); + + scoped_mpz sig_z(mpzm); + mpf_exp_t exp_z; + scoped_mpq sig_q(mpqm), exp_q(mpqm); + scoped_mpz sig_num(mpzm), exp_num(mpzm); mpqm.set(sig_q, sig_r.to_mpq()); - mpzm.set(sig_num, sig_q.numerator()); + mpzm.set(sig_num, sig_q.get().numerator()); mpqm.set(exp_q, exp_unbiased_r.to_mpq()); - mpzm.set(exp_num, exp_q.numerator()); + mpzm.set(exp_num, exp_q.get().numerator()); mpzm.set(sig_z, sig_num); exp_z = mpzm.get_int64(exp_num); - mpf fp_val; - mpfm.set(fp_val, exp_sz, sig_sz + 1, !sgn_r.is_zero(), sig_z, exp_z); + scoped_mpf fp_val(mpfm); + mpfm.set(fp_val, ebits, sbits, !sgn_r.is_zero(), sig_z, exp_z); - app * fp_val_e; - fp_val_e = fu.mk_value(fp_val); - - TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); - - mpfm.del(fp_val); - mpzm.del(sig_num); - mpzm.del(exp_num); - mpqm.del(sig_q); - mpqm.del(exp_q); - mpzm.del(sig_z); - - res = alloc(expr_wrapper_proc, fp_val_e); + TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mpfm.to_string(fp_val) << std::endl;); + res = alloc(expr_wrapper_proc, m_factory->mk_value(fp_val)); } else UNREACHABLE(); @@ -445,7 +471,7 @@ namespace smt { void theory_fpa::reset_eh() { pop_scope_eh(m_trail_stack.get_num_scopes()); - m_rw.reset(); + m_rw.reset(); m_trans_map.reset(); m_bool_var2atom.reset(); m_temporaries.reset(); @@ -453,6 +479,8 @@ namespace smt { theory::reset_eh(); } - void theory_fpa::init_model(model_generator & m) { + void theory_fpa::init_model(model_generator & m) { + m_factory = alloc(fpa_factory, get_manager(), get_family_id()); + m.register_factory(m_factory); } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 41374fd8f..7b29b82de 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -23,9 +23,38 @@ Revision History: #include"trail.h" #include"fpa2bv_converter.h" #include"fpa2bv_rewriter.h" +#include"value_factory.h" namespace smt { + class fpa_factory : public value_factory { + float_util m_util; + + virtual app * mk_value_core(mpf const & val, sort * s) { + SASSERT(m_util.get_ebits(s) == val.get_ebits()); + SASSERT(m_util.get_sbits(s) == val.get_sbits()); + return m_util.mk_value(val); + } + + public: + fpa_factory(ast_manager & m, family_id fid) : + value_factory(m, fid), + m_util(m) { + } + + virtual ~fpa_factory() {} + + virtual expr * get_some_value(sort * s) { NOT_IMPLEMENTED_YET(); } + virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { NOT_IMPLEMENTED_YET(); } + virtual expr * get_fresh_value(sort * s) { NOT_IMPLEMENTED_YET(); } + virtual void register_value(expr * n) { /* Ignore */ } + + app * mk_value(mpf const & x) { + return m_util.mk_value(x); + } + }; + + class theory_fpa : public theory { class th_trail_stack : public trail_stack { public: @@ -60,6 +89,7 @@ namespace smt { bool_var2atom m_bool_var2atom; enode_vector m_temporaries; int_vector m_tvars; + fpa_factory * m_factory; virtual final_check_status final_check_eh() { return FC_DONE; } virtual bool internalize_atom(app * atom, bool gate_ctx); @@ -78,7 +108,6 @@ namespace smt { void assign_eh(bool_var v, bool is_true); virtual void relevant_eh(app * n); virtual void init_model(model_generator & m); - public: theory_fpa(ast_manager& m); virtual ~theory_fpa(); @@ -91,7 +120,8 @@ namespace smt { sig = to_app(e)->get_arg(1); exp = to_app(e)->get_arg(2); } - + + void add_extra_assertions(); void mk_bv_eq(expr * x, expr * y); }; From 75bae1b00c507dc4a85d7e9046063611b611507a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 19 Dec 2014 12:32:57 +0000 Subject: [PATCH 071/507] BV-SLS optimization Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 73355197a..89ef57871 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -89,6 +89,7 @@ private: unsigned m_track_unsat; obj_map m_weights; double m_top_sum; + obj_hashtable m_temp_seen; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -440,6 +441,7 @@ public: } } + m_temp_seen.reset(); for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; @@ -630,7 +632,14 @@ public: app * a = to_app(n); expr * const * args = a->get_args(); for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); + { + expr * child = args[i]; + if (!m_temp_seen.contains(child)) + { + setup_occs(child, false); + m_temp_seen.insert(child); + } + } } else if (m_manager.is_not(n)) { @@ -638,8 +647,7 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); + SASSERT(!m_manager.is_and(child) && !m_manager.is_or(child)); setup_occs(child, true); } else From d5fef38c00ca42dbe91818f16f85ba239e1afb5f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 21 Dec 2014 18:43:22 +0000 Subject: [PATCH 072/507] FPA: Switched default value representation to 3-bitvector Signed-off-by: Christoph M. Wintersteiger --- src/ast/ast_smt2_pp.cpp | 51 +++++++++++++++++++++++++++++------------ src/ast/ast_smt2_pp.h | 2 +- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 77c8ac58f..00ce6aa8f 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -222,34 +222,55 @@ format * smt2_pp_environment::pp_bv_literal(app * t, bool use_bv_lits, bool bv_n return vf; } -format * smt2_pp_environment::pp_float_literal(app * t) { +format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits) { mpf_manager & fm = get_futil().fm(); scoped_mpf v(fm); + ast_manager & m = get_manager(); format * body = 0; + string_buffer<> buf; VERIFY(get_futil().is_value(t, v)); if (fm.is_nan(v)) { - body = mk_string(get_manager(), "NaN"); + buf << "(_ NaN " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; + return mk_string(get_manager(), buf.c_str()); } else if (fm.is_pinf(v)) { - body = mk_string(get_manager(), "plusInfinity"); + buf << "(_ +oo " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; + return mk_string(get_manager(), buf.c_str()); } else if (fm.is_ninf(v)) { - body = mk_string(get_manager(), "minusInfinity"); + buf << "(_ -oo " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; + return mk_string(get_manager(), buf.c_str()); } - else if (fm.is_pzero(v)) { - // TODO: make it SMT 2.0 compatible - body = mk_string(get_manager(), "+0.0"); + else if (fm.is_pzero(v)) { + buf << "(_ +zero " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; + return mk_string(get_manager(), buf.c_str()); } else if (fm.is_nzero(v)) { - // TODO: make it SMT 2.0 compatible - body = mk_string(get_manager(), "-0.0"); + buf << "(_ -zero " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; + return mk_string(get_manager(), buf.c_str()); } - else { - // TODO: make it SMT 2.0 compatible - std::string val = fm.to_string(v); - body = mk_string(get_manager(), val.c_str()); + else { + buf << "(fp #b" << (fm.sgn(v) ? 1 : 0); + body = mk_string(get_manager(), buf.c_str()); + body = mk_compose(m, body, mk_string(get_manager(), " ")); + + mpf_exp_t exp = fm.exp(v); + const mpz & bias = fm.m_powers2.m1(v.get().get_ebits() - 1); + mpf_exp_t biased_exp = exp + fm.mpz_manager().get_int64(bias); + app_ref e_biased_exp(m); + e_biased_exp = get_bvutil().mk_numeral(biased_exp, v.get().get_ebits()); + body = mk_compose(m, body, pp_bv_literal(e_biased_exp, use_bv_lits, false)); + body = mk_compose(m, body, mk_string(get_manager(), " ")); + + scoped_mpz sig(fm.mpz_manager()); + sig = fm.sig(v); + app_ref e_sig(m); + e_sig = get_bvutil().mk_numeral(rational(sig), v.get().get_sbits() - 1); + body = mk_compose(m, body, pp_bv_literal(e_sig, use_bv_lits, false)); + + body = mk_compose(m, body, mk_string(get_manager(), ")")); + return body; } - return pp_as(body, get_manager().get_sort(t)); } // generate (- f) @@ -544,7 +565,7 @@ class smt2_printer { f = m_env.pp_bv_literal(c, m_pp_bv_lits, m_pp_bv_neg); } else if (m_env.get_futil().is_value(c)) { - f = m_env.pp_float_literal(c); + f = m_env.pp_float_literal(c, m_pp_bv_lits); } else if (m_env.get_dlutil().is_numeral(c)) { f = m_env.pp_datalog_literal(c); diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index aa84d6e03..93feec8d5 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -52,7 +52,7 @@ public: virtual format_ns::format * pp_fdecl(func_decl * f, unsigned & len); virtual format_ns::format * pp_bv_literal(app * t, bool use_bv_lits, bool bv_neg); virtual format_ns::format * pp_arith_literal(app * t, bool decimal, unsigned prec); - virtual format_ns::format * pp_float_literal(app * t); + virtual format_ns::format * pp_float_literal(app * t, bool use_bv_lits); virtual format_ns::format * pp_datalog_literal(app * t); virtual format_ns::format * pp_sort(sort * s); virtual format_ns::format * pp_fdecl_ref(func_decl * f); From a1b4ef9e1b7dcdf85eea923aab907bec5debf560 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 21 Dec 2014 18:44:12 +0000 Subject: [PATCH 073/507] fpa2bv refactoring Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 69 ++++++++++---- src/ast/float_decl_plugin.h | 9 ++ src/ast/fpa/fpa2bv_converter.cpp | 152 +++++++++++++++++++------------ src/ast/fpa/fpa2bv_converter.h | 18 ++-- src/ast/fpa/fpa2bv_rewriter.h | 2 + 5 files changed, 169 insertions(+), 81 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 816df906e..d775523ec 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -163,10 +163,10 @@ decl_plugin * float_decl_plugin::mk_fresh() { } sort * float_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) { - if (ebits > sbits) - m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported"); - if (ebits <= 2) - m_manager->raise_exception("floating point sorts with ebits <= 2 are currently not supported"); + if (sbits < 2) + m_manager->raise_exception("minimum number of significand bits is 1"); + if (ebits < 2) + m_manager->raise_exception("minimum number of exponent bits is 2"); parameter p1(ebits), p2(sbits); parameter ps[2] = { p1, p2 }; @@ -182,13 +182,8 @@ sort * float_decl_plugin::mk_rm_sort() { sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { switch (k) { case FLOAT_SORT: - if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) { - m_manager->raise_exception("expecting two integer parameters to floating point sort"); - } - if (parameters[0].get_int() <= 1 || parameters[1].get_int() <= 1) - m_manager->raise_exception("floating point sorts need parameters > 1"); - if (parameters[0].get_int() > parameters[1].get_int()) - m_manager->raise_exception("floating point sorts with ebits > sbits are currently not supported"); + if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) + m_manager->raise_exception("expecting two integer parameters to floating point sort (ebits, sbits)"); return mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); case ROUNDING_MODE_SORT: return mk_rm_sort(); @@ -279,8 +274,8 @@ func_decl * float_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_paramet case OP_FLOAT_EQ: name = "fp.eq"; break; case OP_FLOAT_LT: name = "fp.lt"; break; case OP_FLOAT_GT: name = "fp.gt"; break; - case OP_FLOAT_LE: name = "fp.lte"; break; - case OP_FLOAT_GE: name = "fp.gte"; break; + case OP_FLOAT_LE: name = "fp.leq"; break; + case OP_FLOAT_GE: name = "fp.geq"; break; default: UNREACHABLE(); break; @@ -408,9 +403,12 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa is_sort_of(domain[1], m_bv_fid, BV_SORT) && is_sort_of(domain[2], m_bv_fid, BV_SORT)) { // 3 BVs -> 1 FP - sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1); - symbol name("fp"); - return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); + unsigned ebits = domain[1]->get_parameter(0).get_int(); + unsigned sbits = domain[2]->get_parameter(0).get_int() + 1; + parameter ps[] = { parameter(ebits), parameter(sbits) }; + sort * fp = mk_float_sort(ebits, sbits); + symbol name("to_fp"); + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, 2, ps)); } else if (m_bv_plugin && arity == 1 && is_sort_of(domain[0], m_bv_fid, BV_SORT)) { // 1 BV -> 1 FP @@ -423,7 +421,7 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa int sbits = parameters[1].get_int(); if (domain[0]->get_parameter(0).get_int() != (ebits + sbits)) - m_manager->raise_exception("sort mismtach; invalid bit-vector size, expected bitvector of size (ebits+sbits)"); + m_manager->raise_exception("sort mismatch; invalid bit-vector size, expected bitvector of size (ebits+sbits)"); sort * fp = mk_float_sort(ebits, sbits); symbol name("to_fp"); @@ -613,6 +611,39 @@ func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_par return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } +func_decl * float_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 1) + m_manager->raise_exception("invalid number of arguments to internal_bv_wrap"); + if (!is_float_sort(domain[0]) && !is_rm_sort(domain[0])) + m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint or RoundingMode sort"); + + if (is_float_sort(domain[0])) + { + unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int(); + parameter ps[] = { parameter(float_sz) }; + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps); + return m_manager->mk_func_decl(symbol("bv_wrap"), 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); + } + else { + parameter ps[] = { parameter(3) }; + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps); + return m_manager->mk_func_decl(symbol("bv_wrap"), 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); + } +} + +func_decl * float_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 1) + m_manager->raise_exception("invalid number of arguments to internal_bv_unwrap"); + if (!is_sort_of(domain[0], m_bv_fid, BV_SORT)) + m_manager->raise_exception("sort mismatch, expected argument of bitvector sort"); + if (!is_float_sort(range) && !is_rm_sort(range)) + m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); + + return m_manager->mk_func_decl(symbol("bv_unwrap"), 1, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { @@ -680,6 +711,10 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_TO_IEEE_BV: return mk_float_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_INTERNAL_BVWRAP: + return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_INTERNAL_BVUNWRAP: + return mk_internal_bv_unwrap(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index ebf424578..e4bf633a5 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -86,6 +86,10 @@ enum float_op_kind { /* Extensions */ OP_FLOAT_TO_IEEE_BV, + /* Internal use only */ + OP_FLOAT_INTERNAL_BVWRAP, + OP_FLOAT_INTERNAL_BVUNWRAP, + LAST_FLOAT_OP }; @@ -150,6 +154,11 @@ class float_decl_plugin : public decl_plugin { func_decl * mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); + func_decl * mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + virtual void set_manager(ast_manager * m, family_id id); unsigned mk_id(mpf const & v); void recycled_id(unsigned id); diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index be951098a..f4b4e7951 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -32,7 +32,7 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_arith_util(m), m_mpf_manager(m_util.fm()), m_mpz_manager(m_mpf_manager.mpz_manager()), - extra_assertions(m) { + m_extra_assertions(m) { m_plugin = static_cast(m.get_plugin(m.mk_family_id("float"))); } @@ -76,10 +76,15 @@ void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + expr *t_sgn, *t_sig, *t_exp; + expr *f_sgn, *f_sig, *f_exp; + split_triple(t, t_sgn, t_sig, t_exp); + split_triple(f, f_sgn, f_sig, f_exp); + expr_ref sgn(m), s(m), e(m); - m_simp.mk_ite(c, to_app(t)->get_arg(0), to_app(f)->get_arg(0), sgn); - m_simp.mk_ite(c, to_app(t)->get_arg(1), to_app(f)->get_arg(1), s); - m_simp.mk_ite(c, to_app(t)->get_arg(2), to_app(f)->get_arg(2), e); + m_simp.mk_ite(c, t_sgn, f_sgn, sgn); + m_simp.mk_ite(c, t_sig, f_sig, s); + m_simp.mk_ite(c, t_exp, f_exp, e); mk_triple(sgn, s, e, result); } @@ -122,6 +127,10 @@ void fpa2bv_converter::mk_value(func_decl * f, unsigned num, expr * const * args } } +app * fpa2bv_converter::mk_fresh_const(char const * prefix, unsigned sz) { + return m.mk_fresh_const(prefix, m_bv_util.mk_sort(sz)); +} + void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { SASSERT(f->get_family_id() == null_family_id); SASSERT(f->get_arity() == 0); @@ -134,25 +143,21 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { SASSERT(is_float(srt)); unsigned ebits = m_util.get_ebits(srt); unsigned sbits = m_util.get_sbits(srt); - - expr_ref sgn(m), s(m), e(m); + + app_ref sgn(m), s(m), e(m); #ifdef Z3DEBUG - sort_ref s_sgn(m), s_sig(m), s_exp(m); - s_sgn = m_bv_util.mk_sort(1); - s_sig = m_bv_util.mk_sort(sbits - 1); - s_exp = m_bv_util.mk_sort(ebits); - std::string p("fpa2bv"); std::string name = f->get_name().str(); - - sgn = m.mk_fresh_const((p + "_sgn_" + name).c_str(), s_sgn); - s = m.mk_fresh_const((p + "_sig_" + name).c_str(), s_sig); - e = m.mk_fresh_const((p + "_exp_" + name).c_str(), s_exp); + + sgn = mk_fresh_const((p + "_sgn_" + name).c_str(), 1); + s = mk_fresh_const((p + "_sig_" + name).c_str(), sbits - 1); + e = mk_fresh_const((p + "_exp_" + name).c_str(), ebits); #else - expr_ref bv(m); + app_ref bv(m); unsigned bv_sz = 1 + ebits + (sbits - 1); - bv = m.mk_fresh_const(0, m_bv_util.mk_sort(bv_sz)); + bv = mk_fresh_const(0, bv_sz); + m_fresh_bv_variables.insert(bv); sgn = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv); e = m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv); @@ -196,7 +201,7 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex if (is_float(args[i])) { expr * sgn, * sig, * exp; - split(args[i], sgn, sig, exp); + split_triple(args[i], sgn, sig, exp); new_args.push_back(sgn); new_args.push_back(sig); new_args.push_back(exp); @@ -294,7 +299,7 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) { expr_ref rcc(m); rcc = bu().mk_ule(result, bu().mk_numeral(4, 3)); - extra_assertions.push_back(rcc); + m_extra_assertions.push_back(rcc); } } @@ -612,7 +617,7 @@ void fpa2bv_converter::mk_sub(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_neg(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; - split(args[0], sgn, s, e); + split_triple(args[0], sgn, s, e); expr_ref c(m), nsgn(m); mk_is_nan(args[0], c); nsgn = m_bv_util.mk_bv_not(sgn); @@ -695,8 +700,7 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, // else comes the actual multiplication. unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); - SASSERT(ebits <= sbits); + unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m), b_sgn(m), b_sig(m), b_exp(m), b_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); @@ -1033,7 +1037,7 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_abs(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; - split(args[0], sgn, s, e); + split_triple(args[0], sgn, s, e); mk_triple(m_bv_util.mk_numeral(0, 1), s, e, result); } @@ -1044,8 +1048,8 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split(x, x_sgn, x_sig, x_exp); - split(y, y_sgn, y_sig, y_exp); + split_triple(x, x_sgn, x_sig, x_exp); + split_triple(y, y_sgn, y_sig, y_exp); expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), c1_and(m); mk_is_zero(x, x_is_zero); @@ -1087,8 +1091,8 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split(x, x_sgn, x_sig, x_exp); - split(y, y_sgn, y_sig, y_exp); + split_triple(x, x_sgn, x_sig, x_exp); + split_triple(y, y_sgn, y_sig, y_exp); expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), y_is_zero(m), x_is_zero(m), c1_and(m); mk_is_zero(y, y_is_zero); @@ -1225,11 +1229,9 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, m_simp.mk_and(z_is_zero, m.mk_not(rm_is_to_neg), ite_c); mk_ite(ite_c, pzero, z, v7); - // else comes the fused multiplication. unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); - SASSERT(ebits <= sbits); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m); expr_ref b_sgn(m), b_sig(m), b_exp(m), b_lz(m); @@ -1482,7 +1484,6 @@ void fpa2bv_converter::mk_sqrt(func_decl * f, unsigned num, expr * const * args, // else comes the actual square root. unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); - SASSERT(ebits <= sbits); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m); unpack(x, a_sgn, a_sig, a_exp, a_lz, true); @@ -1698,8 +1699,8 @@ void fpa2bv_converter::mk_float_eq(func_decl * f, unsigned num, expr * const * a expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split(x, x_sgn, x_sig, x_exp); - split(y, y_sgn, y_sig, y_exp); + split_triple(x, x_sgn, x_sig, x_exp); + split_triple(y, y_sgn, y_sig, y_exp); expr_ref x_eq_y_sgn(m), x_eq_y_exp(m), x_eq_y_sig(m); m_simp.mk_eq(x_sgn, y_sgn, x_eq_y_sgn); @@ -1734,8 +1735,8 @@ void fpa2bv_converter::mk_float_lt(func_decl * f, unsigned num, expr * const * a expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split(x, x_sgn, x_sig, x_exp); - split(y, y_sgn, y_sig, y_exp); + split_triple(x, x_sgn, x_sig, x_exp); + split_triple(y, y_sgn, y_sig, y_exp); expr_ref c3(m), t3(m), t4(m), one_1(m), nil_1(m); one_1 = m_bv_util.mk_numeral(1, 1); @@ -1865,10 +1866,11 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args if (num == 3 && m_bv_util.is_bv(args[0]) && m_bv_util.is_bv(args[1]) && - m_bv_util.is_bv(args[2])) { - // Theoretically, the user could have thrown in it's own triple of bit-vectors. - // Just keep it here, as there will be something else that uses it. - mk_triple(args[0], args[1], args[2], result); + m_bv_util.is_bv(args[2])) { + SASSERT(m_bv_util.get_bv_size(args[0]) == 1); + SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); + SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); + mk_triple(args[0], args[2], args[1], result); } else if (num == 2 && m_bv_util.is_bv(args[0]) && @@ -2148,7 +2150,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args else UNREACHABLE(); - SASSERT(is_well_sorted(m, result)); + SASSERT(is_well_sorted(m, result)); } void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -2306,13 +2308,40 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; - split(args[0], sgn, s, e); + split_triple(args[0], sgn, s, e); result = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s); } +void fpa2bv_converter::mk_internal_bvwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_internal", tout << "wrap "; + for (unsigned i = 0; i < num; i++) + tout << " " << mk_ismt2_pp(args[i], m); + tout << std::endl;); + SASSERT(num == 1); + result = m.mk_app(f, num, args); +} + +void fpa2bv_converter::mk_internal_bvunwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_internal", tout << "unwrap "; + for (unsigned i = 0; i < num; i++) + tout << " " << mk_ismt2_pp(args[i], m); + tout << std::endl;); + SASSERT(num == 1); + app * a0 = to_app(args[0]); + SASSERT(a0->get_kind() == AST_APP); + SASSERT(is_float_family(a0->get_decl())); + decl_kind k = a0->get_decl_kind(); + SASSERT(k == OP_FLOAT_INTERNAL_BVWRAP); + SASSERT(a0->get_num_args() == 1); + result = a0->get_arg(0); +} void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 3); + SASSERT(m_bv_util.get_bv_size(args[0]) == 1); + SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); + SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); mk_triple(args[0], args[2], args[1], result); + TRACE("fpa2bv_mk_fp", tout << "mk_fp result = " << mk_ismt2_pp(result, m) << std::endl;); } void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -2328,7 +2357,7 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg //expr * x = args[1]; //expr * sgn, *s, *e; - //split(x, sgn, s, e); + //split_triple(x, sgn, s, e); NOT_IMPLEMENTED_YET(); } @@ -2346,7 +2375,7 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg //expr * x = args[1]; //expr * sgn, *s, *e; - //split(x, sgn, s, e); + //split_triple(x, sgn, s, e); NOT_IMPLEMENTED_YET(); } @@ -2440,18 +2469,28 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar SASSERT(is_well_sorted(m, result)); } -void fpa2bv_converter::split(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { +void fpa2bv_converter::split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); sgn = to_app(e)->get_arg(0); - sig = to_app(e)->get_arg(1); - exp = to_app(e)->get_arg(2); + sig = to_app(e)->get_arg(2); + exp = to_app(e)->get_arg(1); +} + +void fpa2bv_converter::split_triple(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp) const { + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(to_app(e)->get_num_args() == 3); + expr *e_sgn, *e_sig, *e_exp; + split_triple(e, e_sgn, e_sig, e_exp); + sgn = e_sgn; + sig = e_sig; + exp = e_exp; } void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); // exp == 1^n , sig != 0 expr_ref sig_is_zero(m), sig_is_not_zero(m), exp_is_top(m), top_exp(m), zero(m); @@ -2466,7 +2505,7 @@ void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_inf(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); expr_ref eq1(m), eq2(m), top_exp(m), zero(m); mk_top_exp(m_bv_util.get_bv_size(exp), top_exp); zero = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(sig)); @@ -2509,7 +2548,7 @@ void fpa2bv_converter::mk_is_neg(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_zero(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); expr_ref eq1(m), eq2(m), bot_exp(m), zero(m); mk_bot_exp(m_bv_util.get_bv_size(exp), bot_exp); zero = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(sig)); @@ -2520,7 +2559,7 @@ void fpa2bv_converter::mk_is_zero(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_nzero(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); expr_ref e_is_zero(m), eq(m), one_1(m); mk_is_zero(e, e_is_zero); one_1 = m_bv_util.mk_numeral(1, 1); @@ -2530,7 +2569,7 @@ void fpa2bv_converter::mk_is_nzero(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_pzero(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); expr_ref e_is_zero(m), eq(m), nil_1(m); mk_is_zero(e, e_is_zero); nil_1 = m_bv_util.mk_numeral(0, 1); @@ -2540,7 +2579,7 @@ void fpa2bv_converter::mk_is_pzero(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_denormal(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); expr_ref zero(m); zero = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(exp)); m_simp.mk_eq(exp, zero, result); @@ -2548,7 +2587,7 @@ void fpa2bv_converter::mk_is_denormal(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_normal(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split(e, sgn, sig, exp); + split_triple(e, sgn, sig, exp); expr_ref is_special(m), is_denormal(m), p(m); mk_is_denormal(e, is_denormal); @@ -2670,9 +2709,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref unsigned sbits = m_util.get_sbits(srt); unsigned ebits = m_util.get_ebits(srt); - sgn = to_app(e)->get_arg(0); - sig = to_app(e)->get_arg(1); - exp = to_app(e)->get_arg(2); + split_triple(e, sgn, sig, exp); expr_ref is_normal(m); mk_is_normal(e, is_normal); @@ -2684,7 +2721,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref expr_ref denormal_sig(m), denormal_exp(m); denormal_sig = m_bv_util.mk_zero_extend(1, sig); - SASSERT(ebits >= 3); // Note: when ebits=2 there is no 1-exponent, so mk_unbias will produce a 0. + // SASSERT(ebits >= 3); // Note: when ebits=2 there is no 1-exponent, so mk_unbias will produce a 0. denormal_exp = m_bv_util.mk_numeral(1, ebits); mk_unbias(denormal_exp, denormal_exp); dbg_decouple("fpa2bv_unpack_denormal_exp", denormal_exp); @@ -2772,7 +2809,7 @@ void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { // CMW: This works only for quantifier-free formulas. expr_ref new_e(m); new_e = m.mk_fresh_const(prefix, m.get_sort(e)); - extra_assertions.push_back(m.mk_eq(new_e, e)); + m_extra_assertions.push_back(m.mk_eq(new_e, e)); e = new_e; #endif } @@ -2802,7 +2839,6 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & // i.e., it has 2 + (sbits-1) + 3 = sbits + 4 bits, where the first one is in sgn. // Furthermore, note that sig is an unsigned bit-vector, while exp is signed. - SASSERT(ebits <= sbits); SASSERT(m_bv_util.is_bv(rm) && m_bv_util.get_bv_size(rm) == 3); SASSERT(m_bv_util.is_bv(sgn) && m_bv_util.get_bv_size(sgn) == 1); SASSERT(m_bv_util.is_bv(sig) && m_bv_util.get_bv_size(sig) >= 5); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index eb4435132..5da0ca463 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -42,6 +42,7 @@ struct func_decl_triple { }; class fpa2bv_converter { +protected: ast_manager & m; basic_simplifier_plugin m_simp; float_util m_util; @@ -73,16 +74,19 @@ public: SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); SASSERT(m_bv_util.is_bv(significand)); SASSERT(m_bv_util.is_bv(exponent)); - result = m.mk_app(m_util.get_family_id(), OP_FLOAT_TO_FP, sign, significand, exponent); + result = m.mk_app(m_util.get_family_id(), OP_FLOAT_TO_FP, sign, exponent, significand); } + void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const; + void split_triple(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp) const; + void mk_eq(expr * a, expr * b, expr_ref & result); void mk_ite(expr * c, expr * t, expr * f, expr_ref & result); void mk_rounding_mode(func_decl * f, expr_ref & result); void mk_value(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_const(func_decl * f, expr_ref & result); - void mk_rm_const(func_decl * f, expr_ref & result); + virtual void mk_const(func_decl * f, expr_ref & result); + virtual void mk_rm_const(func_decl * f, expr_ref & result); void mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_var(unsigned base_inx, sort * srt, expr_ref & result); @@ -138,11 +142,11 @@ public: obj_map const & uf23bvuf() const { return m_uf23bvuf; } void dbg_decouple(const char * prefix, expr_ref & e); - expr_ref_vector extra_assertions; + expr_ref_vector m_extra_assertions; + void mk_internal_bvwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_internal_bvunwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); protected: - void split(expr * e, expr * & sgn, expr * & sig, expr * & exp) const; - void mk_is_nan(expr * e, expr_ref & result); void mk_is_inf(expr * e, expr_ref & result); void mk_is_pinf(expr * e, expr_ref & result); @@ -173,6 +177,8 @@ protected: void add_core(unsigned sbits, unsigned ebits, expr_ref & rm, expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp, expr_ref & res_sgn, expr_ref & res_sig, expr_ref & res_exp); + + app * mk_fresh_const(char const * prefix, unsigned sz); }; #endif diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index bb42bdf5d..17ee924ad 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -150,6 +150,8 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; + case OP_FLOAT_INTERNAL_BVWRAP: m_conv.mk_internal_bvwrap(f, num, args, result); return BR_DONE; + case OP_FLOAT_INTERNAL_BVUNWRAP: m_conv.mk_internal_bvunwrap(f, num, args, result); return BR_DONE; default: TRACE("fpa2bv", tout << "unsupported operator: " << f->get_name() << "\n"; for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << std::endl;); From d394b9579fd658afa26968251123392d095d5d92 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 21 Dec 2014 18:45:05 +0000 Subject: [PATCH 074/507] FPA: new conversion Signed-off-by: Christoph M. Wintersteiger --- src/ast/rewriter/float_rewriter.cpp | 67 +++++++++++++++++++---------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index 3c1f51990..522fad678 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -109,33 +109,54 @@ br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * cons else return BR_FAILED; } - else if (num_args == 3 && - m_util.is_rm(args[0]) && - m_util.au().is_real(args[1]) && - m_util.au().is_int(args[2])) { + else if (num_args == 3) { + bv_util bu(m()); + rational r1, r2, r3; + unsigned bvs1, bvs2, bvs3; - mpf_rounding_mode rm; - if (!m_util.is_rm_value(args[0], rm)) + if (m_util.is_rm(args[0]) && + m_util.au().is_real(args[1]) && + m_util.au().is_int(args[2])) { + mpf_rounding_mode rm; + if (!m_util.is_rm_value(args[0], rm)) + return BR_FAILED; + + rational q; + if (!m_util.au().is_numeral(args[1], q)) + return BR_FAILED; + + rational e; + if (!m_util.au().is_numeral(args[2], e)) + return BR_FAILED; + + TRACE("fp_rewriter", tout << "q: " << q << ", e: " << e << "\n";); + scoped_mpf v(m_util.fm()); + m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator()); + result = m_util.mk_value(v); + m_util.fm().del(v); + return BR_DONE; + } + else if (bu.is_numeral(args[0], r1, bvs1) && + bu.is_numeral(args[1], r2, bvs2) && + bu.is_numeral(args[2], r3, bvs3)) { + SASSERT(m_util.fm().mpz_manager().is_one(r2.to_mpq().denominator())); + SASSERT(m_util.fm().mpz_manager().is_one(r3.to_mpq().denominator())); + SASSERT(m_util.fm().mpz_manager().is_int64(r3.to_mpq().numerator())); + scoped_mpf v(m_util.fm()); + mpf_exp_t biased_exp = m_util.fm().mpz_manager().get_int64(r2.to_mpq().numerator()); + m_util.fm().set(v, bvs2, bvs3 + 1, + r1.is_one(), + r3.to_mpq().numerator(), + m_util.fm().unbias_exp(bvs2, biased_exp)); + TRACE("fp_rewriter", tout << "v = " << m_util.fm().to_string(v) << std::endl;); + result = m_util.mk_value(v); + return BR_DONE; + } + else return BR_FAILED; - - rational q; - if (!m_util.au().is_numeral(args[1], q)) - return BR_FAILED; - - rational e; - if (!m_util.au().is_numeral(args[2], e)) - return BR_FAILED; - - TRACE("fp_rewriter", tout << "q: " << q << ", e: " << e << "\n";); - scoped_mpf v(m_util.fm()); - m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator()); - result = m_util.mk_value(v); - m_util.fm().del(v); - return BR_DONE; } - else { + else return BR_FAILED; - } } br_status float_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { From cf4b7219e10c4fdb1a6533eaab0fe6b7ec892afc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 21 Dec 2014 18:45:36 +0000 Subject: [PATCH 075/507] new theory_fpa. plenty of bugs remain. Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 824 +++++++++++++++++++++++++---------------- src/smt/theory_fpa.h | 86 ++++- 2 files changed, 563 insertions(+), 347 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 7552e276b..354dc7596 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -22,7 +22,7 @@ Revision History: #include"theory_bv.h" #include"smt_model_generator.h" -namespace smt { +namespace smt { class fpa_atom_trail : public trail { bool_var m_var; @@ -36,11 +36,60 @@ namespace smt { } }; + void theory_fpa::fpa2bv_converter_wrapped::mk_const(func_decl * f, expr_ref & result) { + SASSERT(f->get_family_id() == null_family_id); + SASSERT(f->get_arity() == 0); + expr * r; + if (m_const2bv.find(f, r)) { + result = r; + } + else { + sort * s = f->get_range(); + func_decl *w, *u; + m_th.get_wrap(s, w, u); + expr_ref bv(m); + bv = m.mk_app(w, m.mk_const(f)); + unsigned bv_sz = m_th.m_converter.bu().get_bv_size(bv); + unsigned ebits = m_th.m_converter.fu().get_ebits(f->get_range()); + unsigned sbits = m_th.m_converter.fu().get_sbits(f->get_range()); + SASSERT(bv_sz == ebits + sbits); + m_th.m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), + m_bv_util.mk_extract(sbits - 2, 0, bv), + m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), + result); + + m_const2bv.insert(f, result); + m.inc_ref(f); + m.inc_ref(result); + } + } + + void theory_fpa::fpa2bv_converter_wrapped::mk_rm_const(func_decl * f, expr_ref & result) { + SASSERT(f->get_family_id() == null_family_id); + SASSERT(f->get_arity() == 0); + expr * r; + if (m_rm_const2bv.find(f, r)) { + result = r; + } + else { + SASSERT(is_rm(f->get_range())); + + sort * s = f->get_range(); + func_decl *w, *u; + m_th.get_wrap(s, w, u); + result = m.mk_app(w, m.mk_const(f)); + + m_rm_const2bv.insert(f, result); + m.inc_ref(f); + m.inc_ref(result); + } + } + theory_fpa::theory_fpa(ast_manager & m) : theory(m.mk_family_id("float")), - m_converter(m), + m_converter(m, this), m_rw(m, m_converter, params_ref()), - m_trans_map(m), + m_th_rw(m), m_trail_stack(*this) { } @@ -49,45 +98,277 @@ namespace smt { { } - void theory_fpa::add_extra_assertions() + app * theory_fpa::fpa_value_proc::mk_value(model_generator & mg, ptr_vector & values) { + TRACE("t_fpa", tout << "fpa_value_proc::mk_value for: " << mk_ismt2_pp(m_a, m_th.get_manager()) << "\n";); + ast_manager & m = m_th.get_manager(); + context & ctx = m_th.get_context(); + theory_id bv_id = m.mk_family_id("bv"); + theory_bv * th_bv = dynamic_cast(ctx.get_theory(bv_id)); + SASSERT(th_bv != 0); + + float_util & fu = m_th.m_converter.fu(); + bv_util & bu = m_th.m_converter.bu(); + mpf_manager & mpfm = fu.fm(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); + + sort * s = m.get_sort(m_a); + unsigned ebits = fu.get_ebits(s); + unsigned sbits = fu.get_sbits(s); + + scoped_mpz bias(mpzm); + mpzm.power(mpz(2), ebits - 1, bias); + mpzm.dec(bias); + + app * result; + float_op_kind k = (float_op_kind) to_app(m_a)->get_decl_kind(); + switch (k) + { + case -1: { + func_decl *w, *u; + m_th.get_wrap(s, w, u); + rational bv_val(0); + scoped_mpz sgn(mpzm), sig(mpzm), exp(bias); + app_ref bv_w(m); + bv_w = m.mk_app(w, m_a); + + if (!th_bv->get_fixed_value(bv_w, bv_val)) + result = fu.mk_nan(ebits, sbits); + else { + scoped_mpz all_bits(mpzm); + all_bits = bv_val.to_mpq().numerator(); + SASSERT(mpzm.is_one(bv_val.to_mpq().denominator())); + + mpzm.machine_div2k(all_bits, ebits + sbits - 1, sgn); + + scoped_mpz tmp_p(mpzm); + mpzm.power(mpz(2), ebits + sbits - 1, tmp_p); + + if (mpzm.is_one(sgn)) mpzm.sub(all_bits, tmp_p, all_bits); + + mpzm.machine_div2k(all_bits, sbits - 1, exp); + scoped_mpz exp_u(mpzm); + mpzm.sub(exp, bias, exp_u); + SASSERT(mpzm.is_int64(exp_u)); + + mpzm.power(mpz(2), sbits - 1, tmp_p); + mpzm.mod(all_bits, tmp_p, sig); + + scoped_mpf f(mpfm); + mpfm.set(f, ebits, sbits, mpzm.is_one(sgn), sig, mpzm.get_int64(exp_u)); + result = fu.mk_value(f); + } + break; + } + case OP_FLOAT_FP: { + bool is_internalized = ctx.e_internalized(m_a); + if (is_internalized) { + SASSERT(m_a->get_num_args() == 3); + app_ref a_sgn(m), a_sig(m), a_exp(m); + a_sgn = to_app(m_a->get_arg(0)); + a_exp = to_app(m_a->get_arg(1)); + a_sig = to_app(m_a->get_arg(2)); + + scoped_mpz bias(mpzm); + mpzm.power(mpz(2), ebits - 1, bias); + mpzm.dec(bias); + + rational sgn(0), sig(0), exp(bias); + th_bv->get_fixed_value(a_sgn, sgn); + th_bv->get_fixed_value(a_sig, sig); + th_bv->get_fixed_value(a_exp, exp); + + TRACE("t_fpa", tout << "sgn=" << sgn.to_string() << " ; " << + "sig=" << sig.to_string() << " ; " << + "exp=" << exp.to_string() << std::endl;); + + rational exp_u = exp - rational(bias); + SASSERT(exp_u.is_int64()); + + scoped_mpf f(mpfm); + scoped_mpq sig_q(mpqm); + sig_q = sig.to_mpq(); + mpfm.set(f, ebits, sbits, sgn.is_one(), sig_q.get().numerator(), exp_u.get_int64()); + result = fu.mk_value(f); + } + else { + result = fu.mk_nan(ebits, sbits); + } + break; + } + default: + NOT_IMPLEMENTED_YET(); + } + + TRACE("t_fpa", tout << "fpa_value_proc::mk_value result: " << mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + return result; + } + + app * theory_fpa::fpa_rm_value_proc::mk_value(model_generator & mg, ptr_vector & values) { + TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value for: " << mk_ismt2_pp(m_a, m_th.get_manager()) << "\n";); + ast_manager & m = m_th.get_manager(); + context & ctx = m_th.get_context(); + theory_id bv_id = m.mk_family_id("bv"); + theory_bv * th_bv = dynamic_cast(ctx.get_theory(bv_id)); + + app * result = 0; + mpf_rounding_mode rm; + if (m_th.m_converter.fu().is_rm_value(m_a, rm)) { + result = m_a.get(); + } + else { + sort * s = m.get_sort(m_a); + func_decl *w, *u; + m_th.get_wrap(s, w, u); + + app_ref bv_w(m); + bv_w = m.mk_app(w, m_a); + + rational val(0); + if (ctx.e_internalized(bv_w)) + if (!th_bv->get_fixed_value(bv_w, val)) + val = rational(0); + + switch (val.get_uint64()) + { + case BV_RM_TIES_TO_AWAY: result = m_fu.mk_round_nearest_ties_to_away(); break; + case BV_RM_TIES_TO_EVEN: result = m_fu.mk_round_nearest_ties_to_even(); break; + case BV_RM_TO_NEGATIVE: result = m_fu.mk_round_toward_negative(); break; + case BV_RM_TO_POSITIVE: result = m_fu.mk_round_toward_positive(); break; + case BV_RM_TO_ZERO: + default: result = m_fu.mk_round_toward_zero(); + } + } + + TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value result: " << mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + return result; + } + + void theory_fpa::get_wrap(sort * s, func_decl *& wrap, func_decl *& unwrap) + { + if (!m_wraps.find(s, wrap) || !m_unwraps.find(s, unwrap)) { + SASSERT(!m_wraps.contains(s)); + ast_manager & m = get_manager(); + sort * bv_srt = 0; + + if (m_converter.is_rm(s)) + bv_srt = m_converter.bu().mk_sort(3); + else { + SASSERT(m_converter.is_float(s)); + unsigned ebits = m_converter.fu().get_ebits(s); + unsigned sbits = m_converter.fu().get_sbits(s); + bv_srt = m_converter.bu().mk_sort(ebits + sbits); + } + + wrap = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVWRAP, 0, 0, 1, &s, bv_srt); + unwrap = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); + m_wraps.insert(s, wrap); + m_unwraps.insert(s, unwrap); + get_context().push_trail(insert_obj_map(m_wraps, s)); + get_context().push_trail(insert_obj_map(m_unwraps, s)); + } + } + + expr_ref theory_fpa::convert_atom(expr * e) { + ast_manager & m = get_manager(); + expr_ref res(m); + proof_ref pr(m); + m_rw(e, res); + + TRACE("t_fpa", tout << "converted atom:" << std::endl; + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); + return res; + } + + expr_ref theory_fpa::convert_term(expr * e) { + ast_manager & m = get_manager(); + expr_ref res(m); + proof_ref pr(m); + m_rw(e, res); + + SASSERT(is_app(res)); + + if (m_converter.fu().is_rm(e)) { + SASSERT(is_sort_of(m.get_sort(res), m_converter.bu().get_family_id(), BV_SORT)); + SASSERT(m_converter.bu().get_bv_size(res) == 3); + } + else { + SASSERT(to_app(res)->get_family_id() == get_family_id()); + decl_kind k = to_app(res)->get_decl_kind(); + if (k == OP_FLOAT_TO_FP) { + SASSERT(to_app(res)->get_num_args() == 3); + SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(0)), m_converter.bu().get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(1)), m_converter.bu().get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(2)), m_converter.bu().get_family_id(), BV_SORT)); + + expr *sgn, *sig, *exp; + expr_ref s_sgn(m), s_sig(m), s_exp(m); + m_converter.split_triple(res, sgn, sig, exp); + m_th_rw(sgn, s_sgn); + m_th_rw(sig, s_sig); + m_th_rw(exp, s_exp); + + m_converter.mk_triple(s_sgn, s_sig, s_exp, res); + } + else { + SASSERT(is_sort_of(m.get_sort(e), get_family_id(), ROUNDING_MODE_SORT)); + SASSERT(is_sort_of(m.get_sort(res), m_converter.bu().get_family_id(), BV_SORT)); + } + } + + TRACE("t_fpa", tout << "converted term:" << std::endl; + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); + return res; + } + + expr_ref theory_fpa::mk_side_conditions() { ast_manager & m = get_manager(); context & ctx = get_context(); simplifier & simp = ctx.get_simplifier(); + + expr_ref res(m), t(m); + proof_ref t_pr(m); + res = m.mk_true(); - expr_ref_vector::iterator it = m_converter.extra_assertions.begin(); - expr_ref_vector::iterator end = m_converter.extra_assertions.end(); + expr_ref_vector::iterator it = m_converter.m_extra_assertions.begin(); + expr_ref_vector::iterator end = m_converter.m_extra_assertions.end(); for (; it != end; it++) { - expr_ref t(m); - proof_ref t_pr(m); - simp(*it, t, t_pr); - TRACE("t_fpa", tout << "extra: " << mk_ismt2_pp(t, m) << "\n";); - ctx.internalize_assertion(t, t_pr, 0); + simp(*it, t, t_pr); + res = m.mk_and(res, t); } - m_converter.extra_assertions.reset(); + m_converter.m_extra_assertions.reset(); + + TRACE("t_fpa", if (!m.is_true(res)) tout << "side condition: " << mk_ismt2_pp(res, m) << "\n";); + return res; } - void theory_fpa::mk_bv_eq(expr * x, expr * y) { - SASSERT(get_sort(x)->get_family_id() == m_converter.bu().get_family_id()); - SASSERT(get_sort(y)->get_family_id() == m_converter.bu().get_family_id()); - ast_manager & m = get_manager(); + void theory_fpa::assert_cnstr(expr * e) { + if (get_manager().is_true(e)) return; + TRACE("t_fpa", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); + context& ctx = get_context(); + ctx.internalize(e, false); + literal lit(ctx.get_literal(e)); + ctx.mark_as_relevant(lit); + ctx.mk_th_axiom(get_id(), 1, &lit); + } + + void theory_fpa::attach_new_th_var(enode * n) { context & ctx = get_context(); - theory_id bv_tid = ctx.get_theory(m.get_sort(x)->get_family_id())->get_id(); - literal l = mk_eq(x, y, false); - ctx.mk_th_axiom(bv_tid, 1, &l); - ctx.mark_as_relevant(l); + theory_var v = mk_var(n); + ctx.attach_th_var(n, this, v); + m_tvars.push_back(v); + TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), get_manager()) << " := " << v << "\n";); } bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { - TRACE("t_fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); - SASSERT(atom->get_family_id() == get_family_id()); + TRACE("t_fpa_detail", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); + SASSERT(atom->get_family_id() == get_family_id()); ast_manager & m = get_manager(); context & ctx = get_context(); - simplifier & simp = ctx.get_simplifier(); - bv_util & bu = m_converter.bu(); - expr_ref bv_atom(m); - proof_ref pr(m); if (ctx.b_internalized(atom)) return true; @@ -96,187 +377,157 @@ namespace smt { for (unsigned i = 0; i < num_args; i++) ctx.internalize(atom->get_arg(i), false); - m_rw(atom, bv_atom); - simp(bv_atom, bv_atom, pr); - - ctx.internalize(bv_atom, gate_ctx); - literal def = ctx.get_literal(bv_atom); literal l(ctx.mk_bool_var(atom)); ctx.set_var_theory(l.var(), get_id()); - pred_atom * a = new (get_region()) pred_atom(l, def); - insert_bv2a(l.var(), a); - m_trail_stack.push(fpa_atom_trail(l.var())); + + expr_ref bv_atom(m); + bv_atom = convert_atom(atom); + bv_atom = m.mk_and(bv_atom, mk_side_conditions()); - if (!ctx.relevancy()) { - ctx.mk_th_axiom(get_id(), l, ~def); - ctx.mk_th_axiom(get_id(), ~l, def); - } - - add_extra_assertions(); - + expr_ref atom_iff(m); + assert_cnstr(m.mk_iff(atom, bv_atom)); return true; } bool theory_fpa::internalize_term(app * term) { - TRACE("t_fpa", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); + TRACE("t_fpa_detail", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); SASSERT(term->get_family_id() == get_family_id()); SASSERT(!get_context().e_internalized(term)); - + ast_manager & m = get_manager(); context & ctx = get_context(); - simplifier & simp = ctx.get_simplifier(); - bv_util & bu = m_converter.bu(); - sort * term_sort = m.get_sort(term); - expr_ref t(m), bv_term(m); - proof_ref pr(m); unsigned num_args = term->get_num_args(); for (unsigned i = 0; i < num_args; i++) ctx.internalize(term->get_arg(i), false); + + enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : + ctx.mk_enode(term, false, false, true); - m_rw(term, t); - simp(t, t, pr); + if (is_attached_to_var(e)) + return false; - if (m_converter.is_rm(term_sort)) { - SASSERT(is_app(t)); - expr_ref bv_rm(m); - proof_ref bv_pr(m); - simp(t, bv_rm, bv_pr); + attach_new_th_var(e); + TRACE("t_fpa", tout << "internalized? " << (ctx.e_internalized(term)?"yes":"no") << std::endl;); + return true; + } - bv_term = bv_rm; - } - else if (m_converter.is_float(term_sort)) { - SASSERT(is_app(t) && to_app(t)->get_num_args() == 3); - app * a = to_app(t); - expr_ref sgn(m), sig(m), exp(m); - proof_ref pr_sgn(m), pr_sig(m), pr_exp(m); - simp(a->get_arg(0), sgn, pr_sgn); - simp(a->get_arg(1), sig, pr_sig); - simp(a->get_arg(2), exp, pr_exp); + void theory_fpa::apply_sort_cnstr(enode * n, sort * s) { + TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); + SASSERT(n->get_owner()->get_family_id() == get_family_id() || + n->get_owner()->get_family_id() == null_theory_id); + SASSERT(s->get_family_id() == get_family_id()); + ast_manager & m = get_manager(); - m_converter.mk_triple(sgn, sig, exp, bv_term); - } - else if (term->get_decl_kind() == OP_FLOAT_TO_IEEE_BV || - term->get_decl_kind() == OP_FLOAT_TO_REAL) { - SASSERT(is_app(t)); - expr_ref bv_e(m); - proof_ref bv_pr(m); - simp(t, bv_term, bv_pr); - } - else - NOT_IMPLEMENTED_YET(); - - TRACE("t_fpa", tout << "converted: " << mk_ismt2_pp(bv_term, get_manager()) << "\n";); - - SASSERT(!m_trans_map.contains(term)); - m_trans_map.insert(term, bv_term, 0); - - add_extra_assertions(); - - enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : ctx.mk_enode(term, false, false, true); - theory_var v = mk_var(e); - ctx.attach_th_var(e, this, v); - m_tvars.push_back(v); - TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(term, get_manager()) << " := " << v << "\n";); - SASSERT(e->get_th_var(get_id()) != null_theory_var); - return v != null_theory_var; - } - - void theory_fpa::apply_sort_cnstr(enode * n, sort * s) { - if (!is_attached_to_var(n)) { - TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); - context & ctx = get_context(); - ast_manager & m = get_manager(); - simplifier & simp = ctx.get_simplifier(); - app * owner = n->get_owner(); - expr_ref converted(m); - proof_ref pr(m); - - theory_var v = mk_var(n); - ctx.attach_th_var(n, this, v); - m_tvars.push_back(v); - m_rw(owner, converted); - simp(converted, converted, pr); - m_trans_map.insert(owner, converted, 0); - - add_extra_assertions(); + if (!is_attached_to_var(n)) + attach_new_th_var(n); - sort * owner_sort = m.get_sort(owner); - if (m_converter.is_rm(owner_sort)) { - bv_util & bu = m_converter.bu(); - expr_ref t(m); - t = bu.mk_ule(converted, bu.mk_numeral(4, bu.get_bv_size(converted))); - ctx.internalize_assertion(t, proof_ref(m), 0); + app * owner = n->get_owner(); + sort * owner_sort = m.get_sort(owner); + if (m_converter.is_rm(owner_sort)) { + bv_util & bu = m_converter.bu(); + func_decl *wrap, *unwrap; + get_wrap(owner_sort, wrap, unwrap); + if (owner->get_decl() != unwrap) + { + expr_ref converted(m), t(m); + m_rw(owner, converted); + t = bu.mk_ule(converted, bu.mk_numeral(4, 3)); + assert_cnstr(t); } - - TRACE("t_fpa", tout << "new theory var (const): " << mk_ismt2_pp(owner, get_manager()) << " := " << v << "\n";); } } void theory_fpa::new_eq_eh(theory_var x, theory_var y) { - TRACE("t_fpa", tout << "new eq: " << x << " = " << y << "\n";); ast_manager & m = get_manager(); + + TRACE("t_fpa", tout << "new eq: " << x << " = " << y << std::endl; + tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " = " << + mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl; ); + context & ctx = get_context(); float_util & fu = m_converter.fu(); + bv_util & bu = m_converter.bu(); + mpf_manager & mpfm = fu.fm(); - app * ax = get_enode(x)->get_owner(); - app * ay = get_enode(y)->get_owner(); - expr * ex, *ey; - proof * px, *py; - m_trans_map.get(ax, ex, px); - m_trans_map.get(ay, ey, py); + app * xe = get_enode(x)->get_owner(); + app * ye = get_enode(y)->get_owner(); - if (fu.is_float(get_enode(x)->get_owner())) { - expr * sgn_x, *sig_x, *exp_x; - expr * sgn_y, *sig_y, *exp_y; - split_triple(ex, sgn_x, sig_x, exp_x); - split_triple(ey, sgn_y, sig_y, exp_y); + if (fu.is_float(xe) && fu.is_float(ye)) + { + expr_ref xc(m), yc(m); + xc = convert_term(xe); + yc = convert_term(ye); - mk_bv_eq(sgn_x, sgn_y); - mk_bv_eq(sig_x, sig_y); - mk_bv_eq(exp_x, exp_y); + expr *x_sgn, *x_sig, *x_exp; + m_converter.split_triple(xc, x_sgn, x_sig, x_exp); + expr *y_sgn, *y_sig, *y_exp; + m_converter.split_triple(yc, y_sgn, y_sig, y_exp); + + expr_ref c(m); + c = m.mk_and(m.mk_eq(x_sgn, y_sgn), + m.mk_eq(x_sig, y_sig), + m.mk_eq(x_exp, y_exp)); + assert_cnstr(c); + assert_cnstr(mk_side_conditions()); } - else if (fu.is_rm(get_enode(x)->get_owner())) { - mk_bv_eq(ex, ey); + else if (fu.is_rm(xe) && fu.is_rm(ye)) { + expr_ref xc(m), yc(m); + xc = convert_term(xe); + yc = convert_term(ye); + expr_ref c(m); + c = m.mk_eq(xc, yc); + assert_cnstr(c); + assert_cnstr(mk_side_conditions()); } - else - UNREACHABLE(); + + return; } void theory_fpa::new_diseq_eh(theory_var x, theory_var y) { - TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << "\n";); ast_manager & m = get_manager(); + + TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << std::endl; + tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " != " << + mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); + context & ctx = get_context(); float_util & fu = m_converter.fu(); + bv_util & bu = m_converter.bu(); + mpf_manager & mpfm = fu.fm(); - app * ax = get_enode(x)->get_owner(); - app * ay = get_enode(y)->get_owner(); - expr * ex, *ey; - proof * px, *py; - m_trans_map.get(ax, ex, px); - m_trans_map.get(ay, ey, py); + app * xe = get_enode(x)->get_owner(); + app * ye = get_enode(y)->get_owner(); - expr_ref deq(m); + if (fu.is_float(xe) && fu.is_float(ye)) + { + expr_ref xc(m), yc(m); + xc = convert_term(xe); + yc = convert_term(ye); - if (fu.is_float(m.get_sort(get_enode(x)->get_owner()))) { - expr * sgn_x, *sig_x, *exp_x; - expr * sgn_y, *sig_y, *exp_y; - split_triple(ex, sgn_x, sig_x, exp_x); - split_triple(ex, sgn_y, sig_y, exp_y); - - deq = m.mk_or(m.mk_not(m.mk_eq(sgn_x, sgn_y)), - m.mk_not(m.mk_eq(sig_x, sig_y)), - m.mk_not(m.mk_eq(exp_x, exp_y))); - } - else if (fu.is_rm(m.get_sort(get_enode(x)->get_owner()))) { - deq = m.mk_not(m.mk_eq(ex, ey)); + expr *x_sgn, *x_sig, *x_exp; + m_converter.split_triple(xc, x_sgn, x_sig, x_exp); + expr *y_sgn, *y_sig, *y_exp; + m_converter.split_triple(yc, y_sgn, y_sig, y_exp); + + expr_ref c(m); + c = m.mk_or(m.mk_not(m.mk_eq(x_sgn, y_sgn)), + m.mk_not(m.mk_eq(x_sig, y_sig)), + m.mk_not(m.mk_eq(x_exp, y_exp))); + assert_cnstr(c); + assert_cnstr(mk_side_conditions()); } - else - UNREACHABLE(); - - ctx.internalize(deq, true); - ctx.mk_th_axiom(get_id(), 1, &ctx.get_literal(deq)); - ctx.mark_as_relevant(deq); + else if (fu.is_rm(xe) && fu.is_rm(ye)) { + expr_ref xc(m), yc(m); + xc = convert_term(xe); + yc = convert_term(ye); + expr_ref c(m); + c = m.mk_not(m.mk_eq(xc, yc)); + assert_cnstr(c); + assert_cnstr(mk_side_conditions()); + } + + return; } void theory_fpa::push_scope_eh() { @@ -289,198 +540,117 @@ namespace smt { m_trail_stack.pop_scope(num_scopes); unsigned num_old_vars = get_old_num_vars(num_scopes); for (unsigned i = num_old_vars; i < get_num_vars(); i++) { - m_trans_map.erase(get_enode(m_tvars[i])->get_owner()); + // m_trans_map.erase(get_enode(m_tvars[i])->get_owner()); } m_tvars.shrink(num_old_vars); theory::pop_scope_eh(num_scopes); - } - - model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { - ast_manager & m = get_manager(); - context & ctx = get_context(); - bv_util & bu = m_converter.bu(); - float_util & fu = m_converter.fu(); - mpf_manager & mpfm = fu.fm(); - unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); - unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); - - theory_var v = n->get_th_var(get_id()); - SASSERT(v != null_theory_var); - expr * fpa_e = get_enode(v)->get_owner(); - TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(fpa_e, m) << "\n";); - - expr * bv_e; - proof * bv_pr; - m_trans_map.get(fpa_e, bv_e, bv_pr); - sort * fpa_e_srt = m.get_sort(fpa_e); - expr_wrapper_proc * res = 0; - - if (fu.is_rm(fpa_e_srt)) { - if (!ctx.e_internalized(bv_e)) - res = alloc(expr_wrapper_proc, fu.mk_round_nearest_ties_to_away()); - else - { - theory_bv * bv_th = (theory_bv*)ctx.get_theory(m.get_family_id("bv")); - rational val; - - bv_th->get_fixed_value(ctx.get_enode(bv_e)->get_owner(), val); // OK to fail - app * fp_val_e; - SASSERT(val.is_uint64()); - switch (val.get_uint64()) - { - case BV_RM_TIES_TO_AWAY: fp_val_e = fu.mk_round_nearest_ties_to_away(); break; - case BV_RM_TIES_TO_EVEN: fp_val_e = fu.mk_round_nearest_ties_to_even(); break; - case BV_RM_TO_NEGATIVE: fp_val_e = fu.mk_round_toward_negative(); break; - case BV_RM_TO_POSITIVE: fp_val_e = fu.mk_round_toward_positive(); break; - case BV_RM_TO_ZERO: - default: fp_val_e = fu.mk_round_toward_zero(); - } - - TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mk_ismt2_pp(fp_val_e, m) << std::endl;); - res = alloc(expr_wrapper_proc, fp_val_e); - } - } - else if (fu.is_float(fpa_e_srt)) { - expr * bv_sgn, *bv_sig, *bv_exp; - split_triple(bv_e, bv_sgn, bv_sig, bv_exp); - - family_id fid = m.get_family_id("bv"); - theory_bv * bv_th = (theory_bv*)ctx.get_theory(fid); - - app * e_sgn, *e_sig, *e_exp; - unsigned ebits = fpa_e_srt->get_parameter(0).get_int(); - unsigned sbits = fpa_e_srt->get_parameter(1).get_int(); - unsigned sig_sz = fpa_e_srt->get_parameter(1).get_int() - 1; - - rational bias = mpfm.m_powers2.m1(ebits - 1); - rational sgn_r(0), sig_r(0), exp_r(bias); - - e_sgn = (ctx.e_internalized(bv_sgn)) ? ctx.get_enode(bv_sgn)->get_owner() : - bu.mk_numeral(0, 1); - e_sig = (ctx.e_internalized(bv_sig)) ? ctx.get_enode(bv_sig)->get_owner() : - bu.mk_numeral(0, sig_sz); - e_exp = (ctx.e_internalized(bv_exp)) ? ctx.get_enode(bv_exp)->get_owner() : - bu.mk_numeral(bias, ebits); - - TRACE("t_fpa", tout << "bv rep: [" - << mk_ismt2_pp(e_sgn, m) << "\n" - << mk_ismt2_pp(e_sig, m) << "\n" - << mk_ismt2_pp(e_exp, m) << "]\n";); - - if (!ctx.e_internalized(bv_sgn) || - ctx.get_enode(bv_sgn)->get_num_th_vars() == 0 || - !bv_th->get_fixed_value(e_sgn, sgn_r)) - sgn_r = rational(0); - if (!ctx.e_internalized(bv_sig) || - ctx.get_enode(bv_sig)->get_num_th_vars() == 0 || - !bv_th->get_fixed_value(e_sig, sig_r)) - sig_r = rational(0); - if (!ctx.e_internalized(bv_exp) || - ctx.get_enode(bv_exp)->get_num_th_vars() == 0 || - !bv_th->get_fixed_value(e_exp, exp_r)) - exp_r = bias; - - // un-bias exponent - rational exp_unbiased_r; - exp_unbiased_r = exp_r - bias; - - TRACE("t_fpa", tout << "bv model: [" << sgn_r.to_string() << " " - << sig_r.to_string() << " " - << exp_unbiased_r.to_string() << "(" << exp_r.to_string() << ")]\n"; ); - - scoped_mpz sig_z(mpzm); - mpf_exp_t exp_z; - scoped_mpq sig_q(mpqm), exp_q(mpqm); - scoped_mpz sig_num(mpzm), exp_num(mpzm); - mpqm.set(sig_q, sig_r.to_mpq()); - mpzm.set(sig_num, sig_q.get().numerator()); - mpqm.set(exp_q, exp_unbiased_r.to_mpq()); - mpzm.set(exp_num, exp_q.get().numerator()); - mpzm.set(sig_z, sig_num); - exp_z = mpzm.get_int64(exp_num); - - scoped_mpf fp_val(mpfm); - mpfm.set(fp_val, ebits, sbits, !sgn_r.is_zero(), sig_z, exp_z); - - TRACE("t_fpa", tout << mk_ismt2_pp(fpa_e, m) << " := " << mpfm.to_string(fp_val) << std::endl;); - res = alloc(expr_wrapper_proc, m_factory->mk_value(fp_val)); - } - else - UNREACHABLE(); - - return res; - } + } void theory_fpa::assign_eh(bool_var v, bool is_true) { - TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << ")\n";); - /* CMW: okay to ignore? */ - theory::assign_eh(v, is_true); + ast_manager & m = get_manager(); + context & ctx = get_context(); + expr * e = ctx.bool_var2expr(v); + + TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << "):\n" << mk_ismt2_pp(e, m) << "\n";); + + expr_ref converted(m); + m_rw(e, converted); + converted = m.mk_and(converted, mk_side_conditions()); + if (!is_true) converted = m.mk_not(converted); + assert_cnstr(converted); } void theory_fpa::relevant_eh(app * n) { TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, get_manager()) << "\n";); + + NOT_IMPLEMENTED_YET(); + ast_manager & m = get_manager(); - context & ctx = get_context(); + + if (m.is_bool(n)) + return; + float_util & fu = m_converter.fu(); bv_util & bu = m_converter.bu(); + mpf_manager & mpfm = fu.fm(); - if (m.is_bool(n)) { - bool_var v = ctx.get_bool_var(n); - atom * a = get_bv2a(v); - pred_atom * pa = static_cast(a); - ctx.mark_as_relevant(pa->m_def); - ctx.mk_th_axiom(get_id(), pa->m_var, ~pa->m_def); - ctx.mk_th_axiom(get_id(), ~pa->m_var, pa->m_def); - } - else if (ctx.e_internalized(n)) { - SASSERT(m_trans_map.contains(n)); - expr * ex; - proof * px; - m_trans_map.get(n, ex, px); - sort * n_srt = m.get_sort(n); + if (bu.is_bv(n)) + return; - if (fu.is_rm(n_srt)) { - ctx.mark_as_relevant(ex); - } - else if (fu.is_float(n_srt)) { - expr * bv_sgn, *bv_sig, *bv_exp; - split_triple(ex, bv_sgn, bv_sig, bv_exp); + sort * s = m.get_sort(n); + func_decl *wrap, *unwrap; + get_wrap(s, wrap, unwrap); - ctx.mark_as_relevant(bv_sgn); - ctx.mark_as_relevant(bv_sig); - ctx.mark_as_relevant(bv_exp); - } - else if (n->get_decl()->get_decl_kind() == OP_FLOAT_TO_IEEE_BV || - n->get_decl()->get_decl_kind() == OP_FLOAT_TO_REAL) { - expr_ref eq(m); - app * ex_a = to_app(ex); - if (n->get_id() > ex_a->get_id()) - std::swap(n, ex_a); - eq = m.mk_eq(n, ex_a); - ctx.internalize(eq, false); - literal l = ctx.get_literal(eq); - ctx.mk_th_axiom(get_id(), 1, &l); - ctx.mark_as_relevant(l); + if (n->get_decl() != unwrap) { + expr * wrapped = m.mk_app(wrap, n); + mpf_rounding_mode rm; + scoped_mpf val(mpfm); + if (fu.is_rm_value(n, rm)) + assert_cnstr(m.mk_eq(wrapped, bu.mk_numeral(rm, 3))); + else if (fu.is_value(n, val)) { + unsigned sz = val.get().get_ebits() + val.get().get_sbits(); + scoped_mpq q(fu.fm().mpq_manager()); + mpfm.to_rational(val, q); + assert_cnstr(m.mk_eq(wrapped, bu.mk_numeral(rational(q), sz))); } else - NOT_IMPLEMENTED_YET(); + assert_cnstr(m.mk_eq(m.mk_app(unwrap, wrapped), n)); } - else - UNREACHABLE(); } void theory_fpa::reset_eh() { + TRACE("t_fpa", tout << "reset_eh for: " << "\n";); pop_scope_eh(m_trail_stack.get_num_scopes()); m_rw.reset(); - m_trans_map.reset(); m_bool_var2atom.reset(); m_temporaries.reset(); m_tvars.reset(); theory::reset_eh(); } - void theory_fpa::init_model(model_generator & m) { + void theory_fpa::init_model(model_generator & mg) { + TRACE("t_fpa", tout << "initializing model" << std::endl;); m_factory = alloc(fpa_factory, get_manager(), get_family_id()); - m.register_factory(m_factory); + mg.register_factory(m_factory); + TRACE("t_fpa", display(tout);); + } + + model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { + TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); + + ast_manager & m = get_manager(); + float_util & fu = m_converter.fu(); + + expr * owner = n->get_owner(); + sort * o_srt = m.get_sort(owner); + + mpf_rounding_mode rm; + + if (fu.is_rm_value(n->get_owner(), rm)) + return alloc(expr_wrapper_proc, n->get_owner()); + else if (fu.is_value(n->get_owner())) + return alloc(expr_wrapper_proc, n->get_owner()); + else if (fu.is_rm(owner)) + return alloc(fpa_rm_value_proc, this, app_ref(to_app(owner), m)); + else if (fu.is_float(owner)) + return alloc(fpa_value_proc, this, app_ref(to_app(owner), m)); + + UNREACHABLE(); + return 0; + } + + void theory_fpa::finalize_model(model_generator & mg) {} + + void theory_fpa::display(std::ostream & out) const + { + ast_manager & m = get_manager(); + context & ctx = get_context(); + + out << "theory variables:" << std::endl; + ptr_vector::const_iterator it = ctx.begin_enodes(); + ptr_vector::const_iterator end = ctx.end_enodes(); + for (; it != end; it++) + out << (*it)->get_th_var(get_family_id()) << " -> " << + mk_ismt2_pp((*it)->get_owner(), m) << std::endl; } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 7b29b82de..0c472be33 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -23,7 +23,9 @@ Revision History: #include"trail.h" #include"fpa2bv_converter.h" #include"fpa2bv_rewriter.h" +#include"th_rewriter.h" #include"value_factory.h" +#include"smt_model_generator.h" namespace smt { @@ -52,8 +54,7 @@ namespace smt { app * mk_value(mpf const & x) { return m_util.mk_value(x); } - }; - + }; class theory_fpa : public theory { class th_trail_stack : public trail_stack { @@ -62,6 +63,45 @@ namespace smt { virtual ~th_trail_stack() {} }; + class fpa2bv_converter_wrapped : public fpa2bv_converter { + public: + theory_fpa & m_th; + fpa2bv_converter_wrapped(ast_manager & m, theory_fpa * th) : + fpa2bv_converter(m), + m_th(*th) {} + virtual ~fpa2bv_converter_wrapped() {} + virtual void mk_const(func_decl * f, expr_ref & result); + virtual void mk_rm_const(func_decl * f, expr_ref & result); + }; + + class fpa_value_proc : public model_value_proc { + protected: + theory_fpa & m_th; + app_ref m_a; + svector m_dependencies; + public: + fpa_value_proc(theory_fpa * th, app_ref & a) : m_th(*th), m_a(a) {} + void add_dependency(enode * n) { m_dependencies.push_back(model_value_dependency(n)); } + virtual ~fpa_value_proc() {} + virtual void get_dependencies(buffer & result) { + result.append(m_dependencies.size(), m_dependencies.c_ptr()); + } + virtual app * mk_value(model_generator & mg, ptr_vector & values); + }; + + class fpa_rm_value_proc : public fpa_value_proc { + float_util & m_fu; + bv_util & m_bu; + public: + fpa_rm_value_proc(theory_fpa * th, app_ref & a) : + fpa_value_proc(th, a), + m_fu(th->m_converter.fu()), + m_bu(th->m_converter.bu()) {} + void add_dependency(enode * n) { fpa_value_proc::add_dependency(n); } + virtual ~fpa_rm_value_proc() {} + virtual app * mk_value(model_generator & mg, ptr_vector & values); + }; + public: class atom { public: @@ -79,17 +119,20 @@ namespace smt { void insert_bv2a(bool_var bv, pred_atom * a) { m_bool_var2atom.setx(bv, a, 0); } void erase_bv2a(bool_var bv) { m_bool_var2atom[bv] = 0; } pred_atom * get_bv2a(bool_var bv) const { return m_bool_var2atom.get(bv, 0); } - region & get_region() { return m_trail_stack.get_region(); } + region & get_region() { return m_trail_stack.get_region(); } protected: - fpa2bv_converter m_converter; - fpa2bv_rewriter m_rw; - expr_map m_trans_map; - th_trail_stack m_trail_stack; - bool_var2atom m_bool_var2atom; - enode_vector m_temporaries; - int_vector m_tvars; - fpa_factory * m_factory; + fpa2bv_converter_wrapped m_converter; + fpa2bv_rewriter m_rw; + th_rewriter m_th_rw; + th_trail_stack m_trail_stack; + bool_var2atom m_bool_var2atom; + enode_vector m_temporaries; + vector m_tvars; + fpa_factory * m_factory; + obj_map m_wraps; + obj_map m_unwraps; + float_decl_plugin m_flt_plugin; virtual final_check_status final_check_eh() { return FC_DONE; } virtual bool internalize_atom(app * atom, bool gate_ctx); @@ -108,21 +151,24 @@ namespace smt { void assign_eh(bool_var v, bool is_true); virtual void relevant_eh(app * n); virtual void init_model(model_generator & m); + virtual void finalize_model(model_generator & mg); + public: theory_fpa(ast_manager& m); virtual ~theory_fpa(); - protected: - void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { - SASSERT(is_app_of(e, get_family_id(), OP_FLOAT_TO_FP)); - SASSERT(to_app(e)->get_num_args() == 3); - sgn = to_app(e)->get_arg(0); - sig = to_app(e)->get_arg(1); - exp = to_app(e)->get_arg(2); - } + virtual void display(std::ostream & out) const; + + protected: + expr_ref mk_side_conditions(); + expr_ref convert_atom(expr * e); + expr_ref convert_term(expr * e); + void get_wrap(sort * s, func_decl *& wrap, func_decl *& unwrap); + void add_trail(ast * a); - void add_extra_assertions(); void mk_bv_eq(expr * x, expr * y); + void attach_new_th_var(enode * n); + void assert_cnstr(expr * e); }; }; From b8c373bbce423f861cb1583dbc73d53fa987e3d6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 22 Dec 2014 14:25:23 +0000 Subject: [PATCH 076/507] fpa2bv tactic bugfix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/fpa2bv_tactic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_tactic.cpp b/src/tactic/fpa/fpa2bv_tactic.cpp index 4a3a01b6f..5fb35d972 100644 --- a/src/tactic/fpa/fpa2bv_tactic.cpp +++ b/src/tactic/fpa/fpa2bv_tactic.cpp @@ -96,8 +96,8 @@ class fpa2bv_tactic : public tactic { g->inc_depth(); result.push_back(g.get()); - for (unsigned i = 0; i < m_conv.extra_assertions.size(); i++) - result.back()->assert_expr(m_conv.extra_assertions[i].get()); + for (unsigned i = 0; i < m_conv.m_extra_assertions.size(); i++) + result.back()->assert_expr(m_conv.m_extra_assertions[i].get()); SASSERT(g->is_well_sorted()); TRACE("fpa2bv", tout << "AFTER: " << std::endl; g->display(tout); From 7f8a34d2e11e99ff5272de113bfbe382b16bb0cd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 13:31:30 +0000 Subject: [PATCH 077/507] Adjusted default model display for float literals. Signed-off-by: Christoph M. Wintersteiger --- src/ast/ast_smt2_pp.cpp | 38 +++++++++++++++++++++++++------------- src/ast/ast_smt2_pp.h | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 00ce6aa8f..a9e223c55 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -222,7 +222,7 @@ format * smt2_pp_environment::pp_bv_literal(app * t, bool use_bv_lits, bool bv_n return vf; } -format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits) { +format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits, bool use_float_real_lits) { mpf_manager & fm = get_futil().fm(); scoped_mpf v(fm); ast_manager & m = get_manager(); @@ -231,28 +231,38 @@ format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits) { VERIFY(get_futil().is_value(t, v)); if (fm.is_nan(v)) { buf << "(_ NaN " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; - return mk_string(get_manager(), buf.c_str()); + return mk_string(m, buf.c_str()); } else if (fm.is_pinf(v)) { buf << "(_ +oo " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; - return mk_string(get_manager(), buf.c_str()); + return mk_string(m, buf.c_str()); } else if (fm.is_ninf(v)) { buf << "(_ -oo " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; - return mk_string(get_manager(), buf.c_str()); + return mk_string(m, buf.c_str()); } else if (fm.is_pzero(v)) { buf << "(_ +zero " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; - return mk_string(get_manager(), buf.c_str()); + return mk_string(m, buf.c_str()); } else if (fm.is_nzero(v)) { buf << "(_ -zero " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; - return mk_string(get_manager(), buf.c_str()); + return mk_string(m, buf.c_str()); } - else { - buf << "(fp #b" << (fm.sgn(v) ? 1 : 0); - body = mk_string(get_manager(), buf.c_str()); - body = mk_compose(m, body, mk_string(get_manager(), " ")); + else if (use_float_real_lits) + { + buf << "((_ to_fp " << v.get().get_ebits() << " " << + v.get().get_sbits() << ") RTZ " << + fm.to_string(v).c_str() << ")"; + return mk_string(m, buf.c_str()); + } + else { + if (use_bv_lits) + buf << "(fp #b" << (fm.sgn(v) ? 1 : 0); + else + buf << "(fp (_ bv" << (fm.sgn(v) ? 1 : 0) << " 1)"; + body = mk_string(m, buf.c_str()); + body = mk_compose(m, body, mk_string(m, " ")); mpf_exp_t exp = fm.exp(v); const mpz & bias = fm.m_powers2.m1(v.get().get_ebits() - 1); @@ -260,7 +270,7 @@ format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits) { app_ref e_biased_exp(m); e_biased_exp = get_bvutil().mk_numeral(biased_exp, v.get().get_ebits()); body = mk_compose(m, body, pp_bv_literal(e_biased_exp, use_bv_lits, false)); - body = mk_compose(m, body, mk_string(get_manager(), " ")); + body = mk_compose(m, body, mk_string(m, " ")); scoped_mpz sig(fm.mpz_manager()); sig = fm.sig(v); @@ -268,7 +278,7 @@ format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits) { e_sig = get_bvutil().mk_numeral(rational(sig), v.get().get_sbits() - 1); body = mk_compose(m, body, pp_bv_literal(e_sig, use_bv_lits, false)); - body = mk_compose(m, body, mk_string(get_manager(), ")")); + body = mk_compose(m, body, mk_string(m, ")")); return body; } } @@ -446,6 +456,7 @@ class smt2_printer { bool m_pp_decimal; unsigned m_pp_decimal_precision; bool m_pp_bv_lits; + bool m_pp_float_real_lits; bool m_pp_bv_neg; unsigned m_pp_max_depth; unsigned m_pp_min_alias_size; @@ -565,7 +576,7 @@ class smt2_printer { f = m_env.pp_bv_literal(c, m_pp_bv_lits, m_pp_bv_neg); } else if (m_env.get_futil().is_value(c)) { - f = m_env.pp_float_literal(c, m_pp_bv_lits); + f = m_env.pp_float_literal(c, m_pp_bv_lits, m_pp_float_real_lits); } else if (m_env.get_dlutil().is_numeral(c)) { f = m_env.pp_datalog_literal(c); @@ -1008,6 +1019,7 @@ public: m_pp_decimal = p.decimal(); m_pp_decimal_precision = p.decimal_precision(); m_pp_bv_lits = p.bv_literals(); + m_pp_float_real_lits = p.fp_real_literals(); m_pp_bv_neg = p.bv_neg(); m_pp_max_depth = p.max_depth(); m_pp_min_alias_size = p.min_alias_size(); diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index 93feec8d5..37d13e57a 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -52,7 +52,7 @@ public: virtual format_ns::format * pp_fdecl(func_decl * f, unsigned & len); virtual format_ns::format * pp_bv_literal(app * t, bool use_bv_lits, bool bv_neg); virtual format_ns::format * pp_arith_literal(app * t, bool decimal, unsigned prec); - virtual format_ns::format * pp_float_literal(app * t, bool use_bv_lits); + virtual format_ns::format * pp_float_literal(app * t, bool use_bv_lits, bool use_float_real_lits); virtual format_ns::format * pp_datalog_literal(app * t); virtual format_ns::format * pp_sort(sort * s); virtual format_ns::format * pp_fdecl_ref(func_decl * f); From 6ebeebde509d23b597889f3dc2078c79d964beb8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 13:32:34 +0000 Subject: [PATCH 078/507] Added parameter to display floating point numerals as reals Signed-off-by: Christoph M. Wintersteiger --- src/ast/pp_params.pyg | 1 + src/util/mpf.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ast/pp_params.pyg b/src/ast/pp_params.pyg index 75b2baddd..7424b516f 100644 --- a/src/ast/pp_params.pyg +++ b/src/ast/pp_params.pyg @@ -10,6 +10,7 @@ def_module_params('pp', ('decimal', BOOL, False, 'pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a ? if the value is not precise'), ('decimal_precision', UINT, 10, 'maximum number of decimal places to be used when pp.decimal=true'), ('bv_literals', BOOL, True, 'use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing'), + ('fp_real_literals', BOOL, False, 'use real-numbered floating point literals (e.g, +1.0p-1) during pretty printing'), ('bv_neg', BOOL, False, 'use bvneg when displaying Bit-Vector literals where the most significant bit is 1'), ('flat_assoc', BOOL, True, 'flat associative operators (when pretty printing SMT2 terms/formulas)'), ('fixed_indent', BOOL, False, 'use a fixed indentation for applications'), diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index c4fa17d9a..ac2eb3096 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -1223,7 +1223,9 @@ std::string mpf_manager::to_string(mpf const & x) { std::stringstream ss; m_mpq_manager.display_decimal(ss, r, x.sbits); - ss << "p" << exponent; // "p" means 2^exp + if (m_mpq_manager.is_int(r)) + ss << ".0"; + ss << " " << exponent; res += ss.str(); } } From 55662bcf6b62d835878ebd4404f428a2b6ab4dbc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 13:33:19 +0000 Subject: [PATCH 079/507] fpa2bv: added reset(), adjustments for consistency Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 43 +++++++++++++++++++------------- src/ast/fpa/fpa2bv_converter.h | 4 +++ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f4b4e7951..0de267d2f 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -37,19 +37,7 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : } fpa2bv_converter::~fpa2bv_converter() { - dec_ref_map_key_values(m, m_const2bv); - dec_ref_map_key_values(m, m_rm_const2bv); - dec_ref_map_key_values(m, m_uf2bvuf); - - obj_map::iterator it = m_uf23bvuf.begin(); - obj_map::iterator end = m_uf23bvuf.end(); - for (; it != end; ++it) { - m.dec_ref(it->m_key); - m.dec_ref(it->m_value.f_sgn); - m.dec_ref(it->m_value.f_sig); - m.dec_ref(it->m_value.f_exp); - } - m_uf23bvuf.reset(); + reset(); } void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { @@ -58,8 +46,8 @@ void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { expr_ref sgn(m), s(m), e(m); m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), sgn); - m_simp.mk_eq(to_app(a)->get_arg(1), to_app(b)->get_arg(1), s); - m_simp.mk_eq(to_app(a)->get_arg(2), to_app(b)->get_arg(2), e); + m_simp.mk_eq(to_app(a)->get_arg(1), to_app(b)->get_arg(1), e); + m_simp.mk_eq(to_app(a)->get_arg(2), to_app(b)->get_arg(2), s); // The SMT FPA theory asks for _one_ NaN value, but the bit-blasting // has many, like IEEE754. This encoding of equality makes it look like @@ -2261,7 +2249,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const // The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits. // exp < bv_sz (+sign bit which is [0]) - unsigned exp_worst_case_sz = (unsigned)((log(bv_sz) / log(2)) + 1); + unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); if (exp_sz < exp_worst_case_sz) { // exp_sz < exp_worst_case_sz and exp >= 0. @@ -2473,9 +2461,9 @@ void fpa2bv_converter::split_triple(expr * e, expr * & sgn, expr * & sig, expr * SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); - sgn = to_app(e)->get_arg(0); - sig = to_app(e)->get_arg(2); + sgn = to_app(e)->get_arg(0); exp = to_app(e)->get_arg(1); + sig = to_app(e)->get_arg(2); } void fpa2bv_converter::split_triple(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp) const { @@ -3140,3 +3128,22 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & TRACE("fpa2bv_round", tout << "ROUND = " << mk_ismt2_pp(result, m) << std::endl; ); } + + +void fpa2bv_converter::reset(void) { + dec_ref_map_key_values(m, m_const2bv); + dec_ref_map_key_values(m, m_rm_const2bv); + dec_ref_map_key_values(m, m_uf2bvuf); + + obj_map::iterator it = m_uf23bvuf.begin(); + obj_map::iterator end = m_uf23bvuf.end(); + for (; it != end; ++it) { + m.dec_ref(it->m_key); + m.dec_ref(it->m_value.f_sgn); + m.dec_ref(it->m_value.f_sig); + m.dec_ref(it->m_value.f_exp); + } + m_uf23bvuf.reset(); + + m_extra_assertions.reset(); +} \ No newline at end of file diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 5da0ca463..cd92a6ab2 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -63,6 +63,7 @@ public: float_util & fu() { return m_util; } bv_util & bu() { return m_bv_util; } + arith_util & au() { return m_arith_util; } bool is_float(sort * s) { return m_util.is_float(s); } bool is_float(expr * e) { return is_app(e) && m_util.is_float(to_app(e)->get_decl()->get_range()); } @@ -141,11 +142,14 @@ public: obj_map const & uf2bvuf() const { return m_uf2bvuf; } obj_map const & uf23bvuf() const { return m_uf23bvuf; } + void reset(void); + void dbg_decouple(const char * prefix, expr_ref & e); expr_ref_vector m_extra_assertions; void mk_internal_bvwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_internal_bvunwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + protected: void mk_is_nan(expr * e, expr_ref & result); void mk_is_inf(expr * e, expr_ref & result); From d1cb2566e4e45239000d82b703ea66585e317285 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 13:33:48 +0000 Subject: [PATCH 080/507] fpa2bv: adjustments for consistency Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/fpa2bv_model_converter.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 23809d265..989ad64ff 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -112,16 +112,16 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { unsigned sbits = fu.get_sbits(var->get_range()); expr_ref sgn(m), sig(m), exp(m); - bv_mdl->eval(a->get_arg(0), sgn, true); - bv_mdl->eval(a->get_arg(1), sig, true); - bv_mdl->eval(a->get_arg(2), exp, true); + bv_mdl->eval(a->get_arg(0), sgn, true); + bv_mdl->eval(a->get_arg(1), exp, true); + bv_mdl->eval(a->get_arg(2), sig, true); SASSERT(a->is_app_of(fu.get_family_id(), OP_FLOAT_TO_FP)); #ifdef Z3DEBUG SASSERT(to_app(a->get_arg(0))->get_decl()->get_arity() == 0); SASSERT(to_app(a->get_arg(1))->get_decl()->get_arity() == 0); - SASSERT(to_app(a->get_arg(1))->get_decl()->get_arity() == 0); + SASSERT(to_app(a->get_arg(2))->get_decl()->get_arity() == 0); seen.insert(to_app(a->get_arg(0))->get_decl()); seen.insert(to_app(a->get_arg(1))->get_decl()); seen.insert(to_app(a->get_arg(2))->get_decl()); @@ -134,9 +134,9 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { if (!sgn && !sig && !exp) continue; - unsigned sgn_sz = bu.get_bv_size(m.get_sort(a->get_arg(0))); - unsigned sig_sz = bu.get_bv_size(m.get_sort(a->get_arg(1))) - 1; - unsigned exp_sz = bu.get_bv_size(m.get_sort(a->get_arg(2))); + unsigned sgn_sz = bu.get_bv_size(m.get_sort(a->get_arg(0))); + unsigned exp_sz = bu.get_bv_size(m.get_sort(a->get_arg(1))); + unsigned sig_sz = bu.get_bv_size(m.get_sort(a->get_arg(2))) - 1; rational sgn_q(0), sig_q(0), exp_q(0); From 7a15c41c473152ffd6d83e48133c3dd30b3e67be Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 13:40:36 +0000 Subject: [PATCH 081/507] FPA: improved error messages for to_fp Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 15 +++++++++++++-- src/ast/float_decl_plugin.h | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index d775523ec..846d6ddb7 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -499,8 +499,19 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa symbol name("to_fp"); return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } - else - NOT_IMPLEMENTED_YET(); + else { + m_manager->raise_exception("Unexpected argument combination for (_ to_fp eb sb). Supported argument combinations are: " + "((_ BitVec 1) (_ BitVec eb) (_ BitVec sb-1))," + "(_ BitVec (eb+sb))," + "(Real)," + "(RoundingMode (_ BitVec (eb+sb)))," + "(RoundingMode (_ FloatingPoint eb' sb'))," + "(RoundingMode Real Int), and" + "(RoundingMode Real)." + ); + } + + return 0; } func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index e4bf633a5..01daab8e3 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -239,6 +239,7 @@ public: app * mk_value(mpf const & v) { return m_plugin->mk_value(v); } bool is_value(expr * n) { return m_plugin->is_value(n); } bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); } + bool is_rm_value(expr * n) { return m_plugin->is_rm_value(n); } bool is_rm_value(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm_value(n, v); } app * mk_pzero(unsigned ebits, unsigned sbits); @@ -254,8 +255,7 @@ public: bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_FLOAT_TO_FP); } - - app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_TO_FP, arg1, arg2); } + app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); } app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); } From 23aa614d55994518ac9079badd8027839edf0e99 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 13:44:29 +0000 Subject: [PATCH 082/507] FPA: New theory implementation with support for "hidden" variables, relevancy, and eq/diseq. Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 638 ++++++++++++++++++++++------------------- src/smt/theory_fpa.h | 82 ++---- 2 files changed, 366 insertions(+), 354 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 354dc7596..ec22e3ebb 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -22,17 +22,46 @@ Revision History: #include"theory_bv.h" #include"smt_model_generator.h" -namespace smt { +namespace smt { + + class fpa_factory : public value_factory { + float_util m_util; + + virtual app * mk_value_core(mpf const & val, sort * s) { + SASSERT(m_util.get_ebits(s) == val.get_ebits()); + SASSERT(m_util.get_sbits(s) == val.get_sbits()); + return m_util.mk_value(val); + } - class fpa_atom_trail : public trail { - bool_var m_var; public: - fpa_atom_trail(bool_var v) : m_var(v) {} - virtual ~fpa_atom_trail() {} + fpa_factory(ast_manager & m, family_id fid) : + value_factory(m, fid), + m_util(m) { + } + + virtual ~fpa_factory() {} + + virtual expr * get_some_value(sort * s) { NOT_IMPLEMENTED_YET(); } + virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { NOT_IMPLEMENTED_YET(); } + virtual expr * get_fresh_value(sort * s) { NOT_IMPLEMENTED_YET(); } + virtual void register_value(expr * n) { /* Ignore */ } + + app * mk_value(mpf const & x) { + return m_util.mk_value(x); + } + }; + + class fpa_conv_trail : public trail { + ast_manager & m; + obj_map & m_conversions; + expr * m_e; + public: + fpa_conv_trail(ast_manager & m, obj_map & c, expr * e) : m(m), m_conversions(c), m_e(e) {} + virtual ~fpa_conv_trail() {} virtual void undo(theory_fpa & th) { - theory_fpa::atom * a = th.get_bv2a(m_var); - a->~atom(); - th.erase_bv2a(m_var); + expr * v = m_conversions.find(m_e); + m_conversions.remove(m_e); + m.dec_ref(v); } }; @@ -43,15 +72,15 @@ namespace smt { if (m_const2bv.find(f, r)) { result = r; } - else { + else { sort * s = f->get_range(); - func_decl *w, *u; + func_decl_ref w(m), u(m); m_th.get_wrap(s, w, u); expr_ref bv(m); bv = m.mk_app(w, m.mk_const(f)); - unsigned bv_sz = m_th.m_converter.bu().get_bv_size(bv); - unsigned ebits = m_th.m_converter.fu().get_ebits(f->get_range()); - unsigned sbits = m_th.m_converter.fu().get_sbits(f->get_range()); + unsigned bv_sz = m_th.m_bv_util.get_bv_size(bv); + unsigned ebits = m_th.m_float_util.get_ebits(f->get_range()); + unsigned sbits = m_th.m_float_util.get_sbits(f->get_range()); SASSERT(bv_sz == ebits + sbits); m_th.m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), m_bv_util.mk_extract(sbits - 2, 0, bv), @@ -75,7 +104,7 @@ namespace smt { SASSERT(is_rm(f->get_range())); sort * s = f->get_range(); - func_decl *w, *u; + func_decl_ref w(m), u(m); m_th.get_wrap(s, w, u); result = m.mk_app(w, m.mk_const(f)); @@ -87,186 +116,134 @@ namespace smt { theory_fpa::theory_fpa(ast_manager & m) : theory(m.mk_family_id("float")), - m_converter(m, this), + m_converter(m, this), m_rw(m, m_converter, params_ref()), m_th_rw(m), - m_trail_stack(*this) + m_trail_stack(*this), + m_float_util(m_converter.fu()), + m_bv_util(m_converter.bu()), + m_arith_util(m_converter.au()) { } theory_fpa::~theory_fpa() - { + { + ast_manager & m = get_manager(); + dec_ref_map_values(m, m_conversions); + dec_ref_map_values(m, m_wraps); + dec_ref_map_values(m, m_unwraps); } app * theory_fpa::fpa_value_proc::mk_value(model_generator & mg, ptr_vector & values) { - TRACE("t_fpa", tout << "fpa_value_proc::mk_value for: " << mk_ismt2_pp(m_a, m_th.get_manager()) << "\n";); + SASSERT(values.size() == 3); ast_manager & m = m_th.get_manager(); - context & ctx = m_th.get_context(); - theory_id bv_id = m.mk_family_id("bv"); - theory_bv * th_bv = dynamic_cast(ctx.get_theory(bv_id)); - SASSERT(th_bv != 0); - - float_util & fu = m_th.m_converter.fu(); - bv_util & bu = m_th.m_converter.bu(); - mpf_manager & mpfm = fu.fm(); - unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); - unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); - - sort * s = m.get_sort(m_a); - unsigned ebits = fu.get_ebits(s); - unsigned sbits = fu.get_sbits(s); + TRACE("t_fpa", tout << "fpa_value_proc::mk_value for: [" << + mk_ismt2_pp(values[0], m) << " " << + mk_ismt2_pp(values[1], m) << " " << + mk_ismt2_pp(values[2], m) << "]" << std::endl;); + + mpf_manager & mpfm = m_fu.fm(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); + + unsigned ebits = m_bu.get_bv_size(values[2]); + unsigned sbits = m_bu.get_bv_size(values[1]) + 1; + app * result; + + scoped_mpz sgn_z(mpzm), sig_z(mpzm), exp_z(mpzm); scoped_mpz bias(mpzm); mpzm.power(mpz(2), ebits - 1, bias); mpzm.dec(bias); - app * result; - float_op_kind k = (float_op_kind) to_app(m_a)->get_decl_kind(); - switch (k) - { - case -1: { - func_decl *w, *u; - m_th.get_wrap(s, w, u); - rational bv_val(0); - scoped_mpz sgn(mpzm), sig(mpzm), exp(bias); - app_ref bv_w(m); - bv_w = m.mk_app(w, m_a); + rational sgn_q(0), sig_q(0), exp_q(bias); + unsigned bv_sz; - if (!th_bv->get_fixed_value(bv_w, bv_val)) - result = fu.mk_nan(ebits, sbits); - else { - scoped_mpz all_bits(mpzm); - all_bits = bv_val.to_mpq().numerator(); - SASSERT(mpzm.is_one(bv_val.to_mpq().denominator())); - - mpzm.machine_div2k(all_bits, ebits + sbits - 1, sgn); + bool r; + r = m_bu.is_numeral(values[0], sgn_q, bv_sz); SASSERT(r); SASSERT(bv_sz == 1); + r = m_bu.is_numeral(values[1], sig_q, bv_sz); SASSERT(r); SASSERT(bv_sz == sbits - 1); + r = m_bu.is_numeral(values[2], exp_q, bv_sz); SASSERT(r); SASSERT(bv_sz == ebits); - scoped_mpz tmp_p(mpzm); - mpzm.power(mpz(2), ebits + sbits - 1, tmp_p); + TRACE("t_fpa", tout << "sgn=" << sgn_q.to_string() << " ; " << + "sig=" << sig_q.to_string() << " ; " << + "exp=" << exp_q.to_string() << std::endl;); - if (mpzm.is_one(sgn)) mpzm.sub(all_bits, tmp_p, all_bits); + rational exp_u = exp_q - rational(bias); + SASSERT(exp_u.is_int64()); - mpzm.machine_div2k(all_bits, sbits - 1, exp); - scoped_mpz exp_u(mpzm); - mpzm.sub(exp, bias, exp_u); - SASSERT(mpzm.is_int64(exp_u)); - - mpzm.power(mpz(2), sbits - 1, tmp_p); - mpzm.mod(all_bits, tmp_p, sig); + scoped_mpf f(mpfm); + scoped_mpq sig_mpq(mpqm); + sig_mpq = sig_q.to_mpq(); + mpfm.set(f, ebits, sbits, sgn_q.is_one(), sig_mpq.get().numerator(), exp_u.get_int64()); + result = m_fu.mk_value(f); - scoped_mpf f(mpfm); - mpfm.set(f, ebits, sbits, mpzm.is_one(sgn), sig, mpzm.get_int64(exp_u)); - result = fu.mk_value(f); - } - break; - } - case OP_FLOAT_FP: { - bool is_internalized = ctx.e_internalized(m_a); - if (is_internalized) { - SASSERT(m_a->get_num_args() == 3); - app_ref a_sgn(m), a_sig(m), a_exp(m); - a_sgn = to_app(m_a->get_arg(0)); - a_exp = to_app(m_a->get_arg(1)); - a_sig = to_app(m_a->get_arg(2)); - - scoped_mpz bias(mpzm); - mpzm.power(mpz(2), ebits - 1, bias); - mpzm.dec(bias); - - rational sgn(0), sig(0), exp(bias); - th_bv->get_fixed_value(a_sgn, sgn); - th_bv->get_fixed_value(a_sig, sig); - th_bv->get_fixed_value(a_exp, exp); - - TRACE("t_fpa", tout << "sgn=" << sgn.to_string() << " ; " << - "sig=" << sig.to_string() << " ; " << - "exp=" << exp.to_string() << std::endl;); - - rational exp_u = exp - rational(bias); - SASSERT(exp_u.is_int64()); - - scoped_mpf f(mpfm); - scoped_mpq sig_q(mpqm); - sig_q = sig.to_mpq(); - mpfm.set(f, ebits, sbits, sgn.is_one(), sig_q.get().numerator(), exp_u.get_int64()); - result = fu.mk_value(f); - } - else { - result = fu.mk_nan(ebits, sbits); - } - break; - } - default: - NOT_IMPLEMENTED_YET(); - } - - TRACE("t_fpa", tout << "fpa_value_proc::mk_value result: " << mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + TRACE("t_fpa", tout << "fpa_value_proc::mk_value result: " << + mk_ismt2_pp(result, m_th.get_manager()) << "\n";); return result; } - app * theory_fpa::fpa_rm_value_proc::mk_value(model_generator & mg, ptr_vector & values) { - TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value for: " << mk_ismt2_pp(m_a, m_th.get_manager()) << "\n";); + app * theory_fpa::fpa_rm_value_proc::mk_value(model_generator & mg, ptr_vector & values) { + SASSERT(values.size() == 1); ast_manager & m = m_th.get_manager(); - context & ctx = m_th.get_context(); - theory_id bv_id = m.mk_family_id("bv"); - theory_bv * th_bv = dynamic_cast(ctx.get_theory(bv_id)); + + TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value for: [" << + mk_ismt2_pp(values[0], m) << "]" << std::endl;); app * result = 0; - mpf_rounding_mode rm; - if (m_th.m_converter.fu().is_rm_value(m_a, rm)) { - result = m_a.get(); - } - else { - sort * s = m.get_sort(m_a); - func_decl *w, *u; - m_th.get_wrap(s, w, u); + sort * s = m.get_sort(values[0]); + unsigned bv_sz; - app_ref bv_w(m); - bv_w = m.mk_app(w, m_a); - - rational val(0); - if (ctx.e_internalized(bv_w)) - if (!th_bv->get_fixed_value(bv_w, val)) - val = rational(0); + rational val(0); + bool r = m_bu.is_numeral(values[0], val, bv_sz); + SASSERT(r); + SASSERT(bv_sz == 3); - switch (val.get_uint64()) - { - case BV_RM_TIES_TO_AWAY: result = m_fu.mk_round_nearest_ties_to_away(); break; - case BV_RM_TIES_TO_EVEN: result = m_fu.mk_round_nearest_ties_to_even(); break; - case BV_RM_TO_NEGATIVE: result = m_fu.mk_round_toward_negative(); break; - case BV_RM_TO_POSITIVE: result = m_fu.mk_round_toward_positive(); break; - case BV_RM_TO_ZERO: - default: result = m_fu.mk_round_toward_zero(); - } + switch (val.get_uint64()) + { + case BV_RM_TIES_TO_AWAY: result = m_fu.mk_round_nearest_ties_to_away(); break; + case BV_RM_TIES_TO_EVEN: result = m_fu.mk_round_nearest_ties_to_even(); break; + case BV_RM_TO_NEGATIVE: result = m_fu.mk_round_toward_negative(); break; + case BV_RM_TO_POSITIVE: result = m_fu.mk_round_toward_positive(); break; + case BV_RM_TO_ZERO: + default: result = m_fu.mk_round_toward_zero(); } - TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value result: " << mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value result: " << + mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + return result; } - void theory_fpa::get_wrap(sort * s, func_decl *& wrap, func_decl *& unwrap) + void theory_fpa::get_wrap(sort * s, func_decl_ref & wrap, func_decl_ref & unwrap) { - if (!m_wraps.find(s, wrap) || !m_unwraps.find(s, unwrap)) { + func_decl *w, *u; + + if (!m_wraps.find(s, w) || !m_unwraps.find(s, u)) { SASSERT(!m_wraps.contains(s)); + SASSERT(!m_unwraps.contains(s)); ast_manager & m = get_manager(); + context & ctx = get_context(); sort * bv_srt = 0; if (m_converter.is_rm(s)) - bv_srt = m_converter.bu().mk_sort(3); + bv_srt = m_bv_util.mk_sort(3); else { - SASSERT(m_converter.is_float(s)); - unsigned ebits = m_converter.fu().get_ebits(s); - unsigned sbits = m_converter.fu().get_sbits(s); - bv_srt = m_converter.bu().mk_sort(ebits + sbits); + SASSERT(m_converter.is_float(s)); + unsigned ebits = m_float_util.get_ebits(s); + unsigned sbits = m_float_util.get_sbits(s); + bv_srt = m_bv_util.mk_sort(ebits + sbits); } - - wrap = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVWRAP, 0, 0, 1, &s, bv_srt); - unwrap = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); - m_wraps.insert(s, wrap); - m_unwraps.insert(s, unwrap); - get_context().push_trail(insert_obj_map(m_wraps, s)); - get_context().push_trail(insert_obj_map(m_unwraps, s)); + + w = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVWRAP, 0, 0, 1, &s, bv_srt); + u = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); + m_wraps.insert(s, w); + m_unwraps.insert(s, u); + m.inc_ref(w); + m.inc_ref(u); } + + wrap = w; + unwrap = u; } expr_ref theory_fpa::convert_atom(expr * e) { @@ -274,52 +251,91 @@ namespace smt { expr_ref res(m); proof_ref pr(m); m_rw(e, res); + m_th_rw(res, res); - TRACE("t_fpa", tout << "converted atom:" << std::endl; - tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << - mk_ismt2_pp(res, m) << std::endl;); + TRACE("t_fpa_detail", tout << "converted atom:" << std::endl; + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); + + SASSERT(is_app(res)); + SASSERT(m.is_bool(res)); return res; } expr_ref theory_fpa::convert_term(expr * e) { ast_manager & m = get_manager(); + context & ctx = get_context(); expr_ref res(m); proof_ref pr(m); m_rw(e, res); SASSERT(is_app(res)); - if (m_converter.fu().is_rm(e)) { - SASSERT(is_sort_of(m.get_sort(res), m_converter.bu().get_family_id(), BV_SORT)); - SASSERT(m_converter.bu().get_bv_size(res) == 3); + if (m_float_util.is_rm(e)) { + SASSERT(is_sort_of(m.get_sort(res), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(m_bv_util.get_bv_size(res) == 3); + ctx.internalize(res, false); } else { SASSERT(to_app(res)->get_family_id() == get_family_id()); decl_kind k = to_app(res)->get_decl_kind(); if (k == OP_FLOAT_TO_FP) { SASSERT(to_app(res)->get_num_args() == 3); - SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(0)), m_converter.bu().get_family_id(), BV_SORT)); - SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(1)), m_converter.bu().get_family_id(), BV_SORT)); - SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(2)), m_converter.bu().get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(0)), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(1)), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(2)), m_bv_util.get_family_id(), BV_SORT)); expr *sgn, *sig, *exp; expr_ref s_sgn(m), s_sig(m), s_exp(m); m_converter.split_triple(res, sgn, sig, exp); m_th_rw(sgn, s_sgn); m_th_rw(sig, s_sig); - m_th_rw(exp, s_exp); - + m_th_rw(exp, s_exp); + m_converter.mk_triple(s_sgn, s_sig, s_exp, res); } else { SASSERT(is_sort_of(m.get_sort(e), get_family_id(), ROUNDING_MODE_SORT)); - SASSERT(is_sort_of(m.get_sort(res), m_converter.bu().get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(res), m_bv_util.get_family_id(), BV_SORT)); } } - TRACE("t_fpa", tout << "converted term:" << std::endl; - tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << - mk_ismt2_pp(res, m) << std::endl;); + TRACE("t_fpa_detail", tout << "converted term:" << std::endl; + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); + return res; + } + + expr_ref theory_fpa::convert(expr * e) + { + ast_manager & m = get_manager(); + context & ctx = get_context(); + expr_ref res(m); + + if (m_conversions.contains(e)) { + res = m_conversions.find(e); + TRACE("t_fpa_detail", tout << "cached:" << std::endl; + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); + return res; + } + else { + if (m.is_bool(e)) + res = convert_atom(e); + else if (m_float_util.is_float(e) || m_float_util.is_rm(e)) + res = convert_term(e); + else + UNREACHABLE(); + + TRACE("t_fpa_detail", tout << "caching:" << std::endl; + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); + + m_conversions.insert(e, res); + m.inc_ref(res); + m_trail_stack.push(fpa_conv_trail(m, m_conversions, e)); + } + return res; } @@ -340,14 +356,14 @@ namespace smt { res = m.mk_and(res, t); } m_converter.m_extra_assertions.reset(); - - TRACE("t_fpa", if (!m.is_true(res)) tout << "side condition: " << mk_ismt2_pp(res, m) << "\n";); + + CTRACE("t_fpa", !m.is_true(res), tout << "side condition: " << mk_ismt2_pp(res, m) << "\n";); return res; } - void theory_fpa::assert_cnstr(expr * e) { + void theory_fpa::assert_cnstr(expr * e) { + TRACE("t_fpa_detail", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); if (get_manager().is_true(e)) return; - TRACE("t_fpa", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); context& ctx = get_context(); ctx.internalize(e, false); literal lit(ctx.get_literal(e)); @@ -359,7 +375,6 @@ namespace smt { context & ctx = get_context(); theory_var v = mk_var(n); ctx.attach_th_var(n, this, v); - m_tvars.push_back(v); TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), get_manager()) << " := " << v << "\n";); } @@ -381,7 +396,9 @@ namespace smt { ctx.set_var_theory(l.var(), get_id()); expr_ref bv_atom(m); - bv_atom = convert_atom(atom); + bv_atom = convert(atom); + TRACE("t_fpa_detail", tout << "converted: " << mk_ismt2_pp(bv_atom, get_manager()) << "\n";); + SASSERT(bv_atom.get()->get_kind() == AST_APP); bv_atom = m.mk_and(bv_atom, mk_side_conditions()); expr_ref atom_iff(m); @@ -390,13 +407,13 @@ namespace smt { } bool theory_fpa::internalize_term(app * term) { - TRACE("t_fpa_detail", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); - SASSERT(term->get_family_id() == get_family_id()); - SASSERT(!get_context().e_internalized(term)); - ast_manager & m = get_manager(); context & ctx = get_context(); + TRACE("t_fpa_detail", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); + SASSERT(term->get_family_id() == get_family_id()); + SASSERT(!ctx.e_internalized(term)); + unsigned num_args = term->get_num_args(); for (unsigned i = 0; i < num_args; i++) ctx.internalize(term->get_arg(i), false); @@ -407,8 +424,7 @@ namespace smt { if (is_attached_to_var(e)) return false; - attach_new_th_var(e); - TRACE("t_fpa", tout << "internalized? " << (ctx.e_internalized(term)?"yes":"no") << std::endl;); + attach_new_th_var(e); return true; } @@ -417,22 +433,25 @@ namespace smt { SASSERT(n->get_owner()->get_family_id() == get_family_id() || n->get_owner()->get_family_id() == null_theory_id); SASSERT(s->get_family_id() == get_family_id()); - ast_manager & m = get_manager(); + ast_manager & m = get_manager(); if (!is_attached_to_var(n)) attach_new_th_var(n); - app * owner = n->get_owner(); - sort * owner_sort = m.get_sort(owner); - if (m_converter.is_rm(owner_sort)) { - bv_util & bu = m_converter.bu(); - func_decl *wrap, *unwrap; + app_ref owner(m); + sort_ref owner_sort(m); + owner = n->get_owner(); + owner_sort = m.get_sort(owner); + + if (m_float_util.is_rm(owner_sort)) { + func_decl_ref wrap(m), unwrap(m); get_wrap(owner_sort, wrap, unwrap); if (owner->get_decl() != unwrap) - { - expr_ref converted(m), t(m); - m_rw(owner, converted); - t = bu.mk_ule(converted, bu.mk_numeral(4, 3)); + { + expr_ref converted(m), t(m), limit(m); + converted = convert(owner); + limit = m_bv_util.mk_numeral(4, 3); + t = m_bv_util.mk_ule(converted, limit); assert_cnstr(t); } } @@ -446,41 +465,45 @@ namespace smt { mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl; ); context & ctx = get_context(); - float_util & fu = m_converter.fu(); - bv_util & bu = m_converter.bu(); + float_util & fu = m_float_util; + bv_util & bu = m_bv_util; mpf_manager & mpfm = fu.fm(); app * xe = get_enode(x)->get_owner(); - app * ye = get_enode(y)->get_owner(); + app * ye = get_enode(y)->get_owner(); + + if (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye)) + { + SASSERT(xe->get_decl()->get_family_id() == get_family_id()); + return; + } + + expr_ref xc(m), yc(m); + xc = convert(xe); + yc = convert(ye); + + expr_ref c(m); if (fu.is_float(xe) && fu.is_float(ye)) { - expr_ref xc(m), yc(m); - xc = convert_term(xe); - yc = convert_term(ye); - expr *x_sgn, *x_sig, *x_exp; m_converter.split_triple(xc, x_sgn, x_sig, x_exp); expr *y_sgn, *y_sig, *y_exp; m_converter.split_triple(yc, y_sgn, y_sig, y_exp); - expr_ref c(m); c = m.mk_and(m.mk_eq(x_sgn, y_sgn), m.mk_eq(x_sig, y_sig), - m.mk_eq(x_exp, y_exp)); - assert_cnstr(c); - assert_cnstr(mk_side_conditions()); + m.mk_eq(x_exp, y_exp)); } - else if (fu.is_rm(xe) && fu.is_rm(ye)) { - expr_ref xc(m), yc(m); - xc = convert_term(xe); - yc = convert_term(ye); - expr_ref c(m); + else if (fu.is_rm(xe) && fu.is_rm(ye)) c = m.mk_eq(xc, yc); - assert_cnstr(c); - assert_cnstr(mk_side_conditions()); - } - + else + UNREACHABLE(); + + // assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); + assert_cnstr(c); + assert_cnstr(mk_side_conditions()); + return; } @@ -492,57 +515,55 @@ namespace smt { mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); context & ctx = get_context(); - float_util & fu = m_converter.fu(); - bv_util & bu = m_converter.bu(); - mpf_manager & mpfm = fu.fm(); + mpf_manager & mpfm = m_float_util.fm(); app * xe = get_enode(x)->get_owner(); app * ye = get_enode(y)->get_owner(); - if (fu.is_float(xe) && fu.is_float(ye)) + if (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye)) { - expr_ref xc(m), yc(m); - xc = convert_term(xe); - yc = convert_term(ye); + SASSERT(xe->get_decl()->get_family_id() == get_family_id()); + return; + } + expr_ref xc(m), yc(m); + xc = convert(xe); + yc = convert(ye); + + expr_ref c(m); + + if (m_float_util.is_float(xe) && m_float_util.is_float(ye)) + { expr *x_sgn, *x_sig, *x_exp; m_converter.split_triple(xc, x_sgn, x_sig, x_exp); expr *y_sgn, *y_sig, *y_exp; m_converter.split_triple(yc, y_sgn, y_sig, y_exp); - - expr_ref c(m); + c = m.mk_or(m.mk_not(m.mk_eq(x_sgn, y_sgn)), m.mk_not(m.mk_eq(x_sig, y_sig)), m.mk_not(m.mk_eq(x_exp, y_exp))); - assert_cnstr(c); - assert_cnstr(mk_side_conditions()); } - else if (fu.is_rm(xe) && fu.is_rm(ye)) { - expr_ref xc(m), yc(m); - xc = convert_term(xe); - yc = convert_term(ye); - expr_ref c(m); + else if (m_float_util.is_rm(xe) && m_float_util.is_rm(ye)) c = m.mk_not(m.mk_eq(xc, yc)); - assert_cnstr(c); - assert_cnstr(mk_side_conditions()); - } + else + UNREACHABLE(); + + // assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); + assert_cnstr(c); + assert_cnstr(mk_side_conditions()); return; } void theory_fpa::push_scope_eh() { theory::push_scope_eh(); - m_trail_stack.push_scope(); + m_trail_stack.push_scope(); } - void theory_fpa::pop_scope_eh(unsigned num_scopes) { - TRACE("t_fpa", tout << num_scopes << "\n";); + void theory_fpa::pop_scope_eh(unsigned num_scopes) { m_trail_stack.pop_scope(num_scopes); - unsigned num_old_vars = get_old_num_vars(num_scopes); - for (unsigned i = num_old_vars; i < get_num_vars(); i++) { - // m_trans_map.erase(get_enode(m_tvars[i])->get_owner()); - } - m_tvars.shrink(num_old_vars); + TRACE("t_fpa", tout << "pop " << num_scopes << "; now " << m_trail_stack.get_num_scopes() << "\n";); + // unsigned num_old_vars = get_old_num_vars(num_scopes); theory::pop_scope_eh(num_scopes); } @@ -554,57 +575,68 @@ namespace smt { TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << "):\n" << mk_ismt2_pp(e, m) << "\n";); expr_ref converted(m); - m_rw(e, converted); + converted = convert(e); converted = m.mk_and(converted, mk_side_conditions()); if (!is_true) converted = m.mk_not(converted); assert_cnstr(converted); } void theory_fpa::relevant_eh(app * n) { - TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, get_manager()) << "\n";); - - NOT_IMPLEMENTED_YET(); - ast_manager & m = get_manager(); + TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, m) << "\n";); - if (m.is_bool(n)) - return; + mpf_manager & mpfm = m_float_util.fm(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); - float_util & fu = m_converter.fu(); - bv_util & bu = m_converter.bu(); - mpf_manager & mpfm = fu.fm(); + if (m_float_util.is_float(n) || m_float_util.is_rm(n)) { + sort * s = m.get_sort(n); + func_decl_ref wrap(m), unwrap(m); + get_wrap(s, wrap, unwrap); - if (bu.is_bv(n)) - return; - - sort * s = m.get_sort(n); - func_decl *wrap, *unwrap; - get_wrap(s, wrap, unwrap); - - if (n->get_decl() != unwrap) { - expr * wrapped = m.mk_app(wrap, n); - mpf_rounding_mode rm; - scoped_mpf val(mpfm); - if (fu.is_rm_value(n, rm)) - assert_cnstr(m.mk_eq(wrapped, bu.mk_numeral(rm, 3))); - else if (fu.is_value(n, val)) { - unsigned sz = val.get().get_ebits() + val.get().get_sbits(); - scoped_mpq q(fu.fm().mpq_manager()); - mpfm.to_rational(val, q); - assert_cnstr(m.mk_eq(wrapped, bu.mk_numeral(rational(q), sz))); + if (n->get_decl() != unwrap) { + expr_ref wrapped(m), c(m); + wrapped = m.mk_app(wrap, n); + mpf_rounding_mode rm; + scoped_mpf val(mpfm); + if (m_float_util.is_rm_value(n, rm)) { + c = m.mk_eq(wrapped, m_bv_util.mk_numeral(rm, 3)); + c = m.mk_and(c, mk_side_conditions()); + assert_cnstr(c); + } + else if (m_float_util.is_value(n, val)) { + unsigned sz = val.get().get_ebits() + val.get().get_sbits(); + expr_ref bv_val_e(m); + bv_val_e = convert(n); + SASSERT(is_app(bv_val_e)); + SASSERT(to_app(bv_val_e)->get_num_args() == 3); + app_ref bv_val_a(to_app(bv_val_e.get()), m); + c = m.mk_eq(wrapped, m_bv_util.mk_concat( + m_bv_util.mk_concat(bv_val_a->get_arg(0), bv_val_a->get_arg(1)), + bv_val_a->get_arg(2))); + c = m.mk_and(c, mk_side_conditions()); + assert_cnstr(c); + } + else { + c = m.mk_eq(m.mk_app(unwrap, wrapped), n); + c = m.mk_and(c, mk_side_conditions()); + assert_cnstr(c); + } } - else - assert_cnstr(m.mk_eq(m.mk_app(unwrap, wrapped), n)); } } void theory_fpa::reset_eh() { - TRACE("t_fpa", tout << "reset_eh for: " << "\n";); + TRACE("t_fpa", tout << "reset_eh\n";); pop_scope_eh(m_trail_stack.get_num_scopes()); + m_converter.reset(); m_rw.reset(); - m_bool_var2atom.reset(); - m_temporaries.reset(); - m_tvars.reset(); + m_th_rw.reset(); + m_trail_stack.pop_scope(m_trail_stack.get_num_scopes()); + if (m_factory) dealloc(m_factory); m_factory = 0; + ast_manager & m = get_manager(); + dec_ref_map_values(m, m_conversions); + dec_ref_map_values(m, m_wraps); + dec_ref_map_values(m, m_unwraps); theory::reset_eh(); } @@ -615,28 +647,54 @@ namespace smt { TRACE("t_fpa", display(tout);); } + void theory_fpa::add_value_dep(fpa_value_proc * vp, expr * e) { + SASSERT(m_bv_util.is_bv(e)); + ast_manager & m = get_manager(); + context & ctx = get_context(); + if (ctx.e_internalized(e)) + vp->add_dependency(ctx.get_enode(e)); + else { + expr_ref n(m); + n = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(e)); + if (!ctx.e_internalized(n)) + ctx.internalize(n, false); + vp->add_dependency(ctx.get_enode(n)); + } + } + model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { - TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); + TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); ast_manager & m = get_manager(); - float_util & fu = m_converter.fu(); + context & ctx = get_context(); + app * owner = n->get_owner(); - expr * owner = n->get_owner(); - sort * o_srt = m.get_sort(owner); + app_ref c_a(m); + c_a = to_app(convert(owner)); + SASSERT(ctx.e_internalized(owner)); - mpf_rounding_mode rm; + TRACE("t_fpa", tout << "converted = " << mk_ismt2_pp(c_a, get_manager()) << "\n";); - if (fu.is_rm_value(n->get_owner(), rm)) - return alloc(expr_wrapper_proc, n->get_owner()); - else if (fu.is_value(n->get_owner())) - return alloc(expr_wrapper_proc, n->get_owner()); - else if (fu.is_rm(owner)) - return alloc(fpa_rm_value_proc, this, app_ref(to_app(owner), m)); - else if (fu.is_float(owner)) - return alloc(fpa_value_proc, this, app_ref(to_app(owner), m)); - - UNREACHABLE(); - return 0; + model_value_proc * res = 0; + + if (m_float_util.is_rm(owner)) { + fpa_rm_value_proc * vp = alloc(fpa_rm_value_proc, this); + add_value_dep(vp, c_a); + res = vp; + } + else if (m_float_util.is_float(owner)) { + fpa_value_proc * vp = alloc(fpa_value_proc, this); + expr_ref bv_sgn(m), bv_sig(m), bv_exp(m); + m_converter.split_triple(c_a, bv_sgn, bv_sig, bv_exp); + add_value_dep(vp, bv_sgn); + add_value_dep(vp, bv_sig); + add_value_dep(vp, bv_exp); + res = vp; + } + else + UNREACHABLE(); + + return res; } void theory_fpa::finalize_model(model_generator & mg) {} @@ -649,8 +707,10 @@ namespace smt { out << "theory variables:" << std::endl; ptr_vector::const_iterator it = ctx.begin_enodes(); ptr_vector::const_iterator end = ctx.end_enodes(); - for (; it != end; it++) - out << (*it)->get_th_var(get_family_id()) << " -> " << - mk_ismt2_pp((*it)->get_owner(), m) << std::endl; + for (; it != end; it++) { + theory_var v = (*it)->get_th_var(get_family_id()); + if (v != -1) out << v << " -> " << + mk_ismt2_pp((*it)->get_owner(), m) << std::endl; + } } }; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 0c472be33..bd2ea29f8 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -29,39 +29,10 @@ Revision History: namespace smt { - class fpa_factory : public value_factory { - float_util m_util; - - virtual app * mk_value_core(mpf const & val, sort * s) { - SASSERT(m_util.get_ebits(s) == val.get_ebits()); - SASSERT(m_util.get_sbits(s) == val.get_sbits()); - return m_util.mk_value(val); - } - - public: - fpa_factory(ast_manager & m, family_id fid) : - value_factory(m, fid), - m_util(m) { - } - - virtual ~fpa_factory() {} - - virtual expr * get_some_value(sort * s) { NOT_IMPLEMENTED_YET(); } - virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { NOT_IMPLEMENTED_YET(); } - virtual expr * get_fresh_value(sort * s) { NOT_IMPLEMENTED_YET(); } - virtual void register_value(expr * n) { /* Ignore */ } - - app * mk_value(mpf const & x) { - return m_util.mk_value(x); - } - }; + class fpa_factory; class theory_fpa : public theory { - class th_trail_stack : public trail_stack { - public: - th_trail_stack(theory_fpa & th) : trail_stack(th) {} - virtual ~th_trail_stack() {} - }; + typedef trail_stack th_trail_stack; class fpa2bv_converter_wrapped : public fpa2bv_converter { public: @@ -76,11 +47,13 @@ namespace smt { class fpa_value_proc : public model_value_proc { protected: - theory_fpa & m_th; - app_ref m_a; + theory_fpa & m_th; + float_util & m_fu; + bv_util & m_bu; svector m_dependencies; public: - fpa_value_proc(theory_fpa * th, app_ref & a) : m_th(*th), m_a(a) {} + fpa_value_proc(theory_fpa * th) : + m_th(*th),m_fu(th->m_float_util),m_bu(th->m_bv_util) {} void add_dependency(enode * n) { m_dependencies.push_back(model_value_dependency(n)); } virtual ~fpa_value_proc() {} virtual void get_dependencies(buffer & result) { @@ -89,50 +62,27 @@ namespace smt { virtual app * mk_value(model_generator & mg, ptr_vector & values); }; - class fpa_rm_value_proc : public fpa_value_proc { - float_util & m_fu; - bv_util & m_bu; + class fpa_rm_value_proc : public fpa_value_proc { public: - fpa_rm_value_proc(theory_fpa * th, app_ref & a) : - fpa_value_proc(th, a), - m_fu(th->m_converter.fu()), - m_bu(th->m_converter.bu()) {} + fpa_rm_value_proc(theory_fpa * th) : + fpa_value_proc(th) {} void add_dependency(enode * n) { fpa_value_proc::add_dependency(n); } virtual ~fpa_rm_value_proc() {} virtual app * mk_value(model_generator & mg, ptr_vector & values); }; - public: - class atom { - public: - virtual ~atom() {} - }; - - struct pred_atom : public atom { - literal m_var; - literal m_def; - pred_atom(literal v, literal d) : m_var(v), m_def(d) {} - virtual ~pred_atom() {} - }; - - typedef ptr_vector bool_var2atom; - void insert_bv2a(bool_var bv, pred_atom * a) { m_bool_var2atom.setx(bv, a, 0); } - void erase_bv2a(bool_var bv) { m_bool_var2atom[bv] = 0; } - pred_atom * get_bv2a(bool_var bv) const { return m_bool_var2atom.get(bv, 0); } - region & get_region() { return m_trail_stack.get_region(); } - protected: fpa2bv_converter_wrapped m_converter; fpa2bv_rewriter m_rw; th_rewriter m_th_rw; th_trail_stack m_trail_stack; - bool_var2atom m_bool_var2atom; - enode_vector m_temporaries; - vector m_tvars; fpa_factory * m_factory; + float_util & m_float_util; + bv_util & m_bv_util; + arith_util & m_arith_util; obj_map m_wraps; obj_map m_unwraps; - float_decl_plugin m_flt_plugin; + obj_map m_conversions; virtual final_check_status final_check_eh() { return FC_DONE; } virtual bool internalize_atom(app * atom, bool gate_ctx); @@ -161,14 +111,16 @@ namespace smt { protected: expr_ref mk_side_conditions(); + expr_ref convert(expr * e); expr_ref convert_atom(expr * e); expr_ref convert_term(expr * e); - void get_wrap(sort * s, func_decl *& wrap, func_decl *& unwrap); + void get_wrap(sort * s, func_decl_ref & wrap, func_decl_ref & unwrap); void add_trail(ast * a); void mk_bv_eq(expr * x, expr * y); void attach_new_th_var(enode * n); void assert_cnstr(expr * e); + void add_value_dep(fpa_value_proc * vp, expr * e); }; }; From 1aae53f48c9d82fa3173f9a33054e8d7b5896830 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 15:26:41 +0000 Subject: [PATCH 083/507] FPA: comment fixes Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 846d6ddb7..bfc038cf7 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -846,11 +846,11 @@ bool float_decl_plugin::is_unique_value(app* e) const { case OP_FLOAT_RM_TOWARD_ZERO: return true; case OP_FLOAT_PLUS_INF: /* No; +oo == fp(#b0 #b11 #b00) */ - case OP_FLOAT_MINUS_INF: /* Nol -oo == fp #b1 #b11 #b00) */ + case OP_FLOAT_MINUS_INF: /* No; -oo == fp #b1 #b11 #b00) */ case OP_FLOAT_PLUS_ZERO: /* No; +zero == fp #b0 #b00 #b000) */ case OP_FLOAT_MINUS_ZERO: /* No; -zero == fp #b1 #b00 #b000) */ case OP_FLOAT_NAN: /* No; NaN == (fp #b0 #b111111 #b0000001) */ - case OP_FLOAT_VALUE: /* above */ + case OP_FLOAT_VALUE: /* see NaN */ return false; case OP_FLOAT_FP: return m_manager->is_unique_value(e->get_arg(0)) && From 4d1f71775d1144fb7a2af4f548a8e1c9bc74cd03 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 15:26:52 +0000 Subject: [PATCH 084/507] FPA: added to_fp_unsigned Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 140 +++++++++++++++++++++++++++++-- src/ast/fpa/fpa2bv_rewriter.h | 3 +- 2 files changed, 134 insertions(+), 9 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 0de267d2f..4d2826681 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2171,11 +2171,6 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const unsigned bv_sz = m_bv_util.get_bv_size(x); SASSERT(m_bv_util.get_bv_size(rm) == 3); - //if (bv_sz < f_sz) { - // x = m_bv_util.mk_zero_extend(f_sz - bv_sz, x); - // bv_sz = f_sz; - //} - expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m); bv0_1 = m_bv_util.mk_numeral(0, 1); bv1_1 = m_bv_util.mk_numeral(1, 1); @@ -2245,12 +2240,14 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const unsigned exp_sz = ebits + 2; // (+2 for rounder) exp_2 = m_bv_util.mk_extract(exp_sz - 1, 0, s_exp); // the remaining bits are 0 if ebits is large enough. - exp_too_large = m.mk_false(); // This is always in range. + exp_too_large = m.mk_false(); // The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits. // exp < bv_sz (+sign bit which is [0]) unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); + TRACE("fpa2bv_to_fp_signed", tout << "exp worst case sz: " << exp_worst_case_sz << std::endl;); + if (exp_sz < exp_worst_case_sz) { // exp_sz < exp_worst_case_sz and exp >= 0. // Take the maximum legal exponent; this @@ -2266,7 +2263,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const sig_4 = m.mk_ite(exp_too_large, m_bv_util.mk_numeral(0, sig_sz), sig_4); exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2); } - dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large); + dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large); expr_ref sgn(m), sig(m), exp(m); sgn = is_neg_bit; @@ -2290,7 +2287,134 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con TRACE("fpa2bv_to_fp_unsigned", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); - NOT_IMPLEMENTED_YET(); + // This is a conversion from unsigned bitvector to float: + // ((_ to_fp_unsigned eb sb) RoundingMode(_ BitVec m) (_ FloatingPoint eb sb)) + // Semantics: + // Let b in[[(_ BitVec m)]] and let n be the unsigned integer represented by b. + // [[(_ to_fp_unsigned eb sb)]](r, x) = +infinity if n is too large to be + // represented as a finite number of[[(_ FloatingPoint eb sb)]]; + // [[(_ to_fp_unsigned eb sb)]](r, x) = y otherwise, where y is the finite number + // such that[[fp.to_real]](y) is closest to n according to rounding mode r. + + SASSERT(num == 2); + SASSERT(m_util.is_float(f->get_range())); + SASSERT(m_bv_util.is_bv(args[0])); + SASSERT(m_bv_util.is_bv(args[1])); + + expr_ref rm(m), x(m); + rm = args[0]; + x = args[1]; + + dbg_decouple("fpa2bv_to_fp_unsigned_x", x); + + unsigned ebits = m_util.get_ebits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); + unsigned f_sz = sbits + ebits; + unsigned bv_sz = m_bv_util.get_bv_size(x); + SASSERT(m_bv_util.get_bv_size(rm) == 3); + + expr_ref bv0_1(m), bv1_1(m), bv0_sz(m), bv1_sz(m); + bv0_1 = m_bv_util.mk_numeral(0, 1); + bv1_1 = m_bv_util.mk_numeral(1, 1); + bv0_sz = m_bv_util.mk_numeral(0, bv_sz); + bv1_sz = m_bv_util.mk_numeral(1, bv_sz); + + expr_ref is_zero(m), nzero(m), pzero(m), ninf(m), pinf(m); + is_zero = m.mk_eq(x, bv0_sz); + mk_nzero(f, nzero); + mk_pzero(f, pzero); + mk_ninf(f, ninf); + mk_pinf(f, pinf); + + // Special case: x == 0 -> p/n zero + expr_ref c1(m), v1(m), rm_is_to_neg(m); + c1 = is_zero; + mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_ite(rm_is_to_neg, nzero, pzero, v1); + + // Special case: x != 0 + expr_ref exp_too_large(m), sig_4(m), exp_2(m); + // x is [bv_sz-1] . [bv_sz-2 ... 0] * 2^(bv_sz-1) + // bv_sz-1 is the "1.0" bit for the rounder. + + expr_ref lz(m), e_bv_sz(m), e_rest_sz(m); + mk_leading_zeros(x, bv_sz, lz); + e_bv_sz = m_bv_util.mk_numeral(bv_sz, bv_sz); + e_rest_sz = m_bv_util.mk_bv_sub(e_bv_sz, lz); + SASSERT(m_bv_util.get_bv_size(lz) == m_bv_util.get_bv_size(e_bv_sz)); + dbg_decouple("fpa2bv_to_fp_unsigned_lz", lz); + expr_ref shifted_sig(m); + shifted_sig = m_bv_util.mk_bv_shl(x, lz); + + expr_ref sticky(m); + // shifted_sig is [bv_sz-1] . [bv_sz-2 ... 0] * 2^(bv_sz-1) * 2^(-lz) + unsigned sig_sz = sbits + 4; // we want extra rounding bits. + if (sig_sz <= bv_sz) { + expr_ref sig_rest(m); + sig_4 = m_bv_util.mk_extract(bv_sz - 1, bv_sz - sig_sz + 1, shifted_sig); // one short + sig_rest = m_bv_util.mk_extract(bv_sz - sig_sz, 0, shifted_sig); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest); + sig_4 = m_bv_util.mk_concat(sig_4, sticky); + } + else { + unsigned extra_bits = sig_sz - bv_sz; + expr_ref extra_zeros(m); + extra_zeros = m_bv_util.mk_numeral(0, extra_bits); + sig_4 = m_bv_util.mk_concat(shifted_sig, extra_zeros); + lz = m_bv_util.mk_bv_add(m_bv_util.mk_concat(extra_zeros, lz), + m_bv_util.mk_numeral(extra_bits, sig_sz)); + bv_sz = bv_sz + extra_bits; + SASSERT(is_well_sorted(m, lz)); + } + SASSERT(m_bv_util.get_bv_size(sig_4) == sig_sz); + + expr_ref s_exp(m), exp_rest(m); + s_exp = m_bv_util.mk_bv_sub(m_bv_util.mk_numeral(bv_sz - 2, bv_sz), lz); + // s_exp = (bv_sz-2) + (-lz) signed + SASSERT(m_bv_util.get_bv_size(s_exp) == bv_sz); + + unsigned exp_sz = ebits + 2; // (+2 for rounder) + exp_2 = m_bv_util.mk_extract(exp_sz - 1, 0, s_exp); + // the remaining bits are 0 if ebits is large enough. + exp_too_large = m.mk_false(); // This is always in range. + + // The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits. + // exp < bv_sz (+sign bit which is [0]) + unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); + + if (exp_sz < exp_worst_case_sz) { + // exp_sz < exp_worst_case_sz and exp >= 0. + // Take the maximum legal exponent; this + // allows us to keep the most precision. + expr_ref max_exp(m), max_exp_bvsz(m); + mk_max_exp(exp_sz, max_exp); + max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp); + + exp_too_large = m_bv_util.mk_ule(m_bv_util.mk_bv_add( + max_exp_bvsz, + m_bv_util.mk_numeral(1, bv_sz)), + s_exp); + sig_4 = m.mk_ite(exp_too_large, m_bv_util.mk_numeral(0, sig_sz), sig_4); + exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2); + } + dbg_decouple("fpa2bv_to_fp_unsigned_exp_too_large", exp_too_large); + + expr_ref sgn(m), sig(m), exp(m); + sgn = bv0_1; + sig = sig_4; + exp = exp_2; + + dbg_decouple("fpa2bv_to_fp_unsigned_sgn", sgn); + dbg_decouple("fpa2bv_to_fp_unsigned_sig", sig); + dbg_decouple("fpa2bv_to_fp_unsigned_exp", exp); + + SASSERT(m_bv_util.get_bv_size(sig) == sbits + 4); + SASSERT(m_bv_util.get_bv_size(exp) == ebits + 2); + + expr_ref v2(m); + round(f->get_range(), rm, sgn, sig, exp, v2); + + mk_ite(c1, v1, v2, result); } void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 17ee924ad..42fd7a7fe 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -144,7 +144,8 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_FP: m_conv.mk_to_fp(f, num, args, result); return BR_DONE; + case OP_FLOAT_TO_FP: m_conv.mk_to_fp(f, num, args, result); return BR_DONE; + case OP_FLOAT_TO_FP_UNSIGNED: m_conv.mk_to_fp_unsigned(f, num, args, result); return BR_DONE; case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; From 12aaa0610b5dc064e60f783a00a8af2525e91b1a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 15:27:40 +0000 Subject: [PATCH 085/507] FPA: added get_some_value/s for FP models Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index ec22e3ebb..f05bca4a1 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -41,8 +41,23 @@ namespace smt { virtual ~fpa_factory() {} - virtual expr * get_some_value(sort * s) { NOT_IMPLEMENTED_YET(); } - virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { NOT_IMPLEMENTED_YET(); } + virtual expr * get_some_value(sort * s) { + mpf_manager & mpfm = m_util.fm(); + scoped_mpf q(mpfm); + mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 0); + return m_util.mk_value(q); + } + + virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { + mpf_manager & mpfm = m_util.fm(); + scoped_mpf q(mpfm); + mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 0); + v1 = m_util.mk_value(q); + mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 1); + v2 = m_util.mk_value(q); + return true; + } + virtual expr * get_fresh_value(sort * s) { NOT_IMPLEMENTED_YET(); } virtual void register_value(expr * n) { /* Ignore */ } From 96c8bd7e91ac9952612e38e17b150f52ba174f76 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 17:57:21 +0000 Subject: [PATCH 086/507] MPF conversion bugfix Signed-off-by: Christoph M. Wintersteiger --- src/util/mpf.cpp | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index ac2eb3096..405f34c9d 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -218,39 +218,24 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode o.exponent--; } - m_mpz_manager.set(o.significand, 0); - // o.exponent += sbits ; - + m_mpz_manager.set(o.significand, 0); SASSERT(m_mpq_manager.lt(v, mpq(2))); SASSERT(m_mpq_manager.ge(v, mpq(1))); // 1.0 <= v < 2.0 (* 2^o.exponent) - // (and v != 0.0) + // (and v != 0.0) for (unsigned i = 0; i < sbits + 3 ; i++) { - m_mpz_manager.mul(o.significand, mpz(2), o.significand); - if (m_mpq_manager.ge(v, mpq(1))) - m_mpz_manager.add(o.significand, mpz(1), o.significand); - m_mpq_manager.sub(v, mpq(1), v); // v := v - 1.0 + m_mpz_manager.mul2k(o.significand, 1); + if (m_mpq_manager.ge(v, mpq(1))) { + m_mpz_manager.inc(o.significand); + m_mpq_manager.dec(v); // v := v - 1.0 + } m_mpq_manager.mul(mpq(2), v, v); // v := 2.0 * v - } - - // Sticky - // m_mpz_manager.mul(o.significand, mpz(2), o.significand); - /*if (!m_mpq_manager.is_zero(v)) - m_mpz_manager.add(o.significand, mpz(1), o.significand);*/ + } - // bias? - // o.exponent += m_mpz_manager.get_int64(m_powers2.m1(ebits - 1, false)); - - // mpq pow; - // m_mpq_manager.power(mpq(2), sbits + 3, pow); - // m_mpq_manager.div(o.significand, pow, o.significand); - // SASSERT(m_mpz_manager.ge(o.significand, mpq(1.0))); - // SASSERT(m_mpz_manager.lt(o.significand, mpq(2.0))); - - TRACE("mpf_dbg", tout << "sig=" << m_mpz_manager.to_string(o.significand) << " exp=" << o.exponent << - " sticky=" << (!m_mpq_manager.is_zero(v)) << std::endl;); + TRACE("mpf_dbg", tout << "rnd sig=" << m_mpz_manager.to_string(o.significand) << + " exp=" << o.exponent << std::endl;); round(rm, o); } From 621be0f47f37588c27d546916a9a3afb448171a4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 18:01:18 +0000 Subject: [PATCH 087/507] FPA: Added fp.to_ubv Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 8 +-- src/ast/fpa/fpa2bv_converter.cpp | 112 +++++++++++++++++++++++++++---- 2 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index bfc038cf7..a861865f5 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -562,9 +562,9 @@ func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, p m_manager->raise_exception("invalid number of arguments to fp.to_ubv"); if (num_parameters != 1) m_manager->raise_exception("invalid number of parameters to fp.to_ubv"); - if (parameters[0].is_int()) + if (!parameters[0].is_int()) m_manager->raise_exception("invalid parameter type; fp.to_ubv expects an int parameter"); - if (is_rm_sort(domain[0])) + if (!is_rm_sort(domain[0])) m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); @@ -573,7 +573,7 @@ func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, p symbol name("fp.to_ubv"); sort * bvs = m_bv_plugin->mk_sort(BV_SORT, 1, parameters); - return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k)); + return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k, num_parameters, parameters)); } func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -594,7 +594,7 @@ func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, p symbol name("fp.to_sbv"); sort * bvs = m_bv_plugin->mk_sort(BV_SORT, 1, parameters); - return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k)); + return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k, num_parameters, parameters)); } func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, parameter const * parameters, diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 4d2826681..88e738041 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1865,7 +1865,6 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args m_bv_util.get_bv_size(args[0]) == 3 && m_bv_util.is_bv(args[1])) { - mk_to_fp_signed(f, num, args, result); } else if (num == 3 && @@ -2457,27 +2456,114 @@ void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, e } void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 2); + TRACE("fpa2bv_to_ubv", for (unsigned i = 0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); + SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_int()); - - //unsigned ebits = m_util.get_ebits(f->get_range()); - //unsigned sbits = m_util.get_sbits(f->get_range()); - //int width = f->get_parameter(0).get_int(); + SASSERT(num == 2); + SASSERT(m_bv_util.get_bv_size(args[0]) == 3); + SASSERT(m_util.is_float(args[1])); - //expr * rm = args[0]; - //expr * x = args[1]; - - //expr * sgn, *s, *e; - //split_triple(x, sgn, s, e); + expr * rm = args[0]; + expr * x = args[1]; + sort * xs = m.get_sort(x); + sort * bv_srt = f->get_range(); - NOT_IMPLEMENTED_YET(); + dbg_decouple("fpa2bv_to_ubv_x", expr_ref(x, m)); + + unsigned ebits = m_util.get_ebits(xs); + unsigned sbits = m_util.get_sbits(xs); + unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); + + expr_ref bv0(m), bv1(m); + bv0 = m_bv_util.mk_numeral(0, 1); + bv1 = m_bv_util.mk_numeral(1, 1); + + expr_ref x_is_nan(m), x_is_inf(m), x_is_zero(m), x_is_neg(m), x_is_nzero(m); + mk_is_nan(x, x_is_nan); + mk_is_inf(x, x_is_inf); + mk_is_zero(x, x_is_zero); + mk_is_neg(x, x_is_neg); + mk_is_nzero(x, x_is_nzero); + + // NaN, Inf, or negative (except -0) -> undefined + expr_ref c1(m), v1(m); + c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); + v1 = mk_fresh_const(0, bv_sz); + dbg_decouple("fpa2bv_to_ubv_c1", c1); + + // +-Zero -> 0 + expr_ref c2(m), v2(m); + c2 = x_is_zero; + v2 = m_bv_util.mk_numeral(rational(0), bv_srt); + dbg_decouple("fpa2bv_to_ubv_c2", c2); + + // Otherwise... + expr_ref sgn(m), sig(m), exp(m), lz(m); + unpack(x, sgn, sig, exp, lz, true); + + // sig is of the form +- [1].[sig] * 2^(exp-lz) + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(sig) == sbits); + SASSERT(m_bv_util.get_bv_size(exp) == ebits); + SASSERT(m_bv_util.get_bv_size(lz) == ebits); + dbg_decouple("fpa2bv_to_ubv_sig", sig); + + // last number that's representable + expr_ref last_valid_bv(m); + last_valid_bv = m_bv_util.mk_numeral(-1, bv_sz); // == 1.0 * 2^bv_sz - 1.0 + + // first invalid bv + mpz const & first_invalid_bv = m_util.fm().m_powers2(bv_sz); + + unsigned sig_sz = m_bv_util.get_bv_size(sig); + SASSERT(sig_sz == sbits); + + expr_ref shift(m); + if (sig_sz < bv_sz) { + sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, bv_sz - sig_sz)); + shift = m_bv_util.mk_bv_sub(m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), + m_bv_util.mk_zero_extend(2, lz)), + m_bv_util.mk_numeral(bv_sz-1, ebits + 2)); + } + SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2); + SASSERT(m_bv_util.get_bv_size(sig) >= bv_sz); + dbg_decouple("fpa2bv_to_ubv_shift", shift); + + expr_ref c_in_limits(m); + c_in_limits = m_bv_util.mk_sle(shift, m_bv_util.mk_numeral(0, ebits + 2)); + dbg_decouple("fpa2bv_to_ubv_in_limits", c_in_limits); + + expr_ref shifted_sig(m), shift_abs(m); + shift_abs = m_bv_util.mk_bv_neg(shift); + SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits+2); + SASSERT(bv_sz > (ebits + 2)); + shift_abs = m_bv_util.mk_zero_extend(bv_sz - ebits - 2, shift_abs); + + shifted_sig = m_bv_util.mk_bv_lshr(sig, shift_abs); + dbg_decouple("fpa2bv_to_ubv_shift_abs", shift_abs); + dbg_decouple("fpa2bv_to_ubv_shifted_sig", shifted_sig); + + expr_ref rounded(m); + rounded = shifted_sig; // TODO. + + result = m.mk_ite(c_in_limits, rounded, mk_fresh_const(0, bv_sz)); + result = m.mk_ite(c2, v2, result); + result = m.mk_ite(c1, v1, result); + + SASSERT(is_well_sorted(m, result)); } void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 2); + TRACE("fpa2bv_to_sbv", for (unsigned i = 0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); + SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_int()); + SASSERT(num == 2); + SASSERT(m_bv_util.get_bv_size(args[0]) == 3); + SASSERT(m_util.is_float(args[1])); //unsigned ebits = m_util.get_ebits(f->get_range()); //unsigned sbits = m_util.get_sbits(f->get_range()); From 05121e25d45319c22d976bacdfb82502c9a89333 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 28 Dec 2014 19:28:48 +0000 Subject: [PATCH 088/507] FPA theory support for conversion functions Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 64 +++++++++++++++++++++++++++++++- src/ast/float_decl_plugin.h | 24 +++++++++--- src/ast/fpa/fpa2bv_converter.cpp | 12 ++++-- src/ast/fpa/fpa2bv_converter.h | 4 ++ src/smt/theory_fpa.cpp | 22 ++++++----- 5 files changed, 107 insertions(+), 19 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index a861865f5..b019c7359 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -655,6 +655,45 @@ func_decl * float_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_p return m_manager->mk_func_decl(symbol("bv_unwrap"), 1, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); } +func_decl * float_decl_plugin::mk_internal_to_ubv_unspecified( + decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 0) + m_manager->raise_exception("invalid number of arguments to fp.to_ubv_unspecified"); + if (num_parameters != 1) + m_manager->raise_exception("invalid number of parameters to fp.to_ubv_unspecified; expecting 1"); + if (!parameters[0].is_int()) + m_manager->raise_exception("invalid parameters type provided to fp.to_ubv_unspecified; expecting an integer"); + + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, parameters); + return m_manager->mk_func_decl(symbol("fp.to_ubv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + +func_decl * float_decl_plugin::mk_internal_to_sbv_unspecified( + decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 0) + m_manager->raise_exception("invalid number of arguments to internal_to_sbv_unspecified"); + if (!is_sort_of(domain[0], m_bv_fid, BV_SORT)) + m_manager->raise_exception("sort mismatch, expected argument of bitvector sort"); + if (!is_sort_of(range, m_bv_fid, BV_SORT)) + m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); + + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, parameters); + return m_manager->mk_func_decl(symbol("fp.to_sbv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + +func_decl * float_decl_plugin::mk_internal_to_real_unspecified( + decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (arity != 0) + m_manager->raise_exception("invalid number of arguments to internal_to_real_unspecified"); + if (!is_sort_of(range, m_arith_fid, REAL_SORT)) + m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); + + return m_manager->mk_func_decl(symbol("fp.to_real_unspecified"), 0, domain, m_real_sort, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { @@ -726,6 +765,12 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_INTERNAL_BVUNWRAP: return mk_internal_bv_unwrap(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED: + return mk_internal_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED: + return mk_internal_to_sbv_unspecified(k, num_parameters, parameters, arity, domain, range); + case OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED: + return mk_internal_to_real_unspecified(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; @@ -864,7 +909,8 @@ bool float_decl_plugin::is_unique_value(app* e) const { float_util::float_util(ast_manager & m): m_manager(m), m_fid(m.mk_family_id("float")), - m_a_util(m) { + m_a_util(m), + m_bv_util(m) { m_plugin = static_cast(m.get_plugin(m_fid)); } @@ -916,3 +962,19 @@ app * float_util::mk_nzero(unsigned ebits, unsigned sbits) { return mk_value(v); } +app * float_util::mk_internal_to_ubv_unspecified(unsigned width) { + parameter ps[] = { parameter(width) }; + sort * range = m_bv_util.mk_sort(width); + return m().mk_app(get_family_id(), OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED, 1, ps, 0, 0, range); +} + +app * float_util::mk_internal_to_sbv_unspecified(unsigned width) { + parameter ps[] = { parameter(width) }; + sort * range = m_bv_util.mk_sort(width); + return m().mk_app(get_family_id(), OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED, 1, ps, 0, 0, range); +} + +app * float_util::mk_internal_to_real_unspecified() { + sort * range = m_a_util.mk_real(); + return m().mk_app(get_family_id(), OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED, 0, 0, 0, 0, range); +} \ No newline at end of file diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 01daab8e3..3403665a9 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -47,7 +47,7 @@ enum float_op_kind { OP_FLOAT_NAN, OP_FLOAT_PLUS_ZERO, OP_FLOAT_MINUS_ZERO, - + OP_FLOAT_ADD, OP_FLOAT_SUB, OP_FLOAT_NEG, @@ -70,7 +70,7 @@ enum float_op_kind { OP_FLOAT_IS_INF, OP_FLOAT_IS_ZERO, OP_FLOAT_IS_NORMAL, - OP_FLOAT_IS_SUBNORMAL, + OP_FLOAT_IS_SUBNORMAL, OP_FLOAT_IS_PZERO, OP_FLOAT_IS_NZERO, OP_FLOAT_IS_NEGATIVE, @@ -85,10 +85,13 @@ enum float_op_kind { /* Extensions */ OP_FLOAT_TO_IEEE_BV, - + /* Internal use only */ OP_FLOAT_INTERNAL_BVWRAP, OP_FLOAT_INTERNAL_BVUNWRAP, + OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED, + OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED, + OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED, LAST_FLOAT_OP }; @@ -155,9 +158,15 @@ class float_decl_plugin : public decl_plugin { unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + unsigned arity, sort * const * domain, sort * range); func_decl * mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, - unsigned arity, sort * const * domain, sort * range); + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_internal_to_ubv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_internal_to_sbv_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); + func_decl * mk_internal_to_real_unspecified(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); virtual void set_manager(ast_manager * m, family_id id); unsigned mk_id(mpf const & v); @@ -203,6 +212,7 @@ class float_util { float_decl_plugin * m_plugin; family_id m_fid; arith_util m_a_util; + bv_util m_bv_util; public: float_util(ast_manager & m); ~float_util(); @@ -292,6 +302,10 @@ public: bool is_neg(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); } app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_TO_IEEE_BV, arg1); } + + app * mk_internal_to_ubv_unspecified(unsigned width); + app * mk_internal_to_sbv_unspecified(unsigned width); + app * mk_internal_to_real_unspecified(); }; #endif diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 88e738041..bd8240b31 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2487,10 +2487,13 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg mk_is_neg(x, x_is_neg); mk_is_nzero(x, x_is_nzero); + expr_ref undef(m); + undef = m_util.mk_internal_to_ubv_unspecified(bv_sz); + // NaN, Inf, or negative (except -0) -> undefined expr_ref c1(m), v1(m); c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); - v1 = mk_fresh_const(0, bv_sz); + v1 = undef; dbg_decouple("fpa2bv_to_ubv_c1", c1); // +-Zero -> 0 @@ -2546,9 +2549,10 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg dbg_decouple("fpa2bv_to_ubv_shifted_sig", shifted_sig); expr_ref rounded(m); - rounded = shifted_sig; // TODO. + // TODO: Rounding. + rounded = shifted_sig; - result = m.mk_ite(c_in_limits, rounded, mk_fresh_const(0, bv_sz)); + result = m.mk_ite(c_in_limits, rounded, undef); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); @@ -2658,7 +2662,7 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;); expr_ref undef(m); - undef = m.mk_fresh_const(0, rs); + undef = m_util.mk_internal_to_real_unspecified(); result = m.mk_ite(x_is_zero, zero, res); result = m.mk_ite(x_is_inf, undef, result); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index cd92a6ab2..ee7ffa192 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -149,6 +149,10 @@ public: void mk_internal_bvwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_internal_bvunwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + + void mk_internal_to_ubv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_internal_to_sbv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_internal_to_real_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); protected: void mk_is_nan(expr * e, expr_ref & result); diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index f05bca4a1..b63073893 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -291,7 +291,7 @@ namespace smt { SASSERT(m_bv_util.get_bv_size(res) == 3); ctx.internalize(res, false); } - else { + else if (m_float_util.is_float(e)) { SASSERT(to_app(res)->get_family_id() == get_family_id()); decl_kind k = to_app(res)->get_decl_kind(); if (k == OP_FLOAT_TO_FP) { @@ -314,6 +314,9 @@ namespace smt { SASSERT(is_sort_of(m.get_sort(res), m_bv_util.get_family_id(), BV_SORT)); } } + else { + /* ignore; these are the conversion functions fp.to_* */ + } TRACE("t_fpa_detail", tout << "converted term:" << std::endl; tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << @@ -339,6 +342,8 @@ namespace smt { res = convert_atom(e); else if (m_float_util.is_float(e) || m_float_util.is_rm(e)) res = convert_term(e); + else if (m_arith_util.is_real(e)) + res = convert_term(e); else UNREACHABLE(); @@ -508,12 +513,10 @@ namespace smt { c = m.mk_and(m.mk_eq(x_sgn, y_sgn), m.mk_eq(x_sig, y_sig), - m.mk_eq(x_exp, y_exp)); + m.mk_eq(x_exp, y_exp)); } - else if (fu.is_rm(xe) && fu.is_rm(ye)) - c = m.mk_eq(xc, yc); else - UNREACHABLE(); + c = m.mk_eq(xc, yc); // assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); assert_cnstr(c); @@ -556,12 +559,10 @@ namespace smt { c = m.mk_or(m.mk_not(m.mk_eq(x_sgn, y_sgn)), m.mk_not(m.mk_eq(x_sig, y_sig)), - m.mk_not(m.mk_eq(x_exp, y_exp))); + m.mk_not(m.mk_eq(x_exp, y_exp))); } - else if (m_float_util.is_rm(xe) && m_float_util.is_rm(ye)) - c = m.mk_not(m.mk_eq(xc, yc)); else - UNREACHABLE(); + c = m.mk_not(m.mk_eq(xc, yc)); // assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); assert_cnstr(c); @@ -638,6 +639,9 @@ namespace smt { } } } + else { + // These are the conversion functions fp.to_* */ + } } void theory_fpa::reset_eh() { From 0ab2782048b733f31ff0364069ac8bb2284ce191 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 29 Dec 2014 17:08:46 +0000 Subject: [PATCH 089/507] FPA: name consistency Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 3403665a9..1598db9c3 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -264,7 +264,7 @@ public: bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } - bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_FLOAT_TO_FP); } + bool is_to_fp(expr * n) { return is_app_of(n, m_fid, OP_FLOAT_TO_FP); } app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); } app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } From 33af7e8468ba0621149f65cfd856df72444c181a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 29 Dec 2014 17:09:18 +0000 Subject: [PATCH 090/507] FPA: bugfixes for fp.to_ubv Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 163 +++++++++++++++++++------------ src/ast/fpa/fpa2bv_converter.h | 1 + 2 files changed, 102 insertions(+), 62 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index bd8240b31..7edc4a7a0 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2475,6 +2475,7 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg unsigned ebits = m_util.get_ebits(xs); unsigned sbits = m_util.get_sbits(xs); unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); + unsigned rounding_sz = bv_sz + 3; expr_ref bv0(m), bv1(m); bv0 = m_bv_util.mk_numeral(0, 1); @@ -2489,6 +2490,7 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg expr_ref undef(m); undef = m_util.mk_internal_to_ubv_unspecified(bv_sz); + dbg_decouple("fpa2bv_to_ubv_undef", undef); // NaN, Inf, or negative (except -0) -> undefined expr_ref c1(m), v1(m); @@ -2499,7 +2501,7 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg // +-Zero -> 0 expr_ref c2(m), v2(m); c2 = x_is_zero; - v2 = m_bv_util.mk_numeral(rational(0), bv_srt); + v2 = m_bv_util.mk_numeral(rational(0), bv_srt); dbg_decouple("fpa2bv_to_ubv_c2", c2); // Otherwise... @@ -2512,47 +2514,73 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg SASSERT(m_bv_util.get_bv_size(exp) == ebits); SASSERT(m_bv_util.get_bv_size(lz) == ebits); dbg_decouple("fpa2bv_to_ubv_sig", sig); - - // last number that's representable - expr_ref last_valid_bv(m); - last_valid_bv = m_bv_util.mk_numeral(-1, bv_sz); // == 1.0 * 2^bv_sz - 1.0 - - // first invalid bv - mpz const & first_invalid_bv = m_util.fm().m_powers2(bv_sz); - unsigned sig_sz = m_bv_util.get_bv_size(sig); SASSERT(sig_sz == sbits); - - expr_ref shift(m); - if (sig_sz < bv_sz) { - sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, bv_sz - sig_sz)); - shift = m_bv_util.mk_bv_sub(m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), - m_bv_util.mk_zero_extend(2, lz)), - m_bv_util.mk_numeral(bv_sz-1, ebits + 2)); - } + if (sig_sz < (bv_sz + 3)) + sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, bv_sz - sig_sz + 3)); + sig_sz = m_bv_util.get_bv_size(sig); + SASSERT(sig_sz >= (bv_sz + 3)); + + expr_ref exp_m_lz(m), shift(m), shift_neg(m), bv0_e2(m), shift_abs(m); + exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), + m_bv_util.mk_zero_extend(2, lz)); + shift = m_bv_util.mk_bv_sub(exp_m_lz, + m_bv_util.mk_numeral(bv_sz - 1, ebits + 2)); + shift_neg = m_bv_util.mk_bv_neg(shift); + bv0_e2 = m_bv_util.mk_numeral(0, ebits + 2); + shift_abs = m.mk_ite(m_bv_util.mk_sle(shift, bv0_e2), shift_neg, shift); SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2); - SASSERT(m_bv_util.get_bv_size(sig) >= bv_sz); + SASSERT(m_bv_util.get_bv_size(shift_neg) == ebits + 2); + SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2); dbg_decouple("fpa2bv_to_ubv_shift", shift); + dbg_decouple("fpa2bv_to_ubv_shift_abs", shift_abs); + + // sig is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long + // [1][ ... sig ... ][r][g][ ... s ...] + // [ ... ubv ... ][r][g][ ... s ... ] + expr_ref max_shift(m); + max_shift = m_bv_util.mk_numeral(sig_sz, sig_sz); + shift_abs = m_bv_util.mk_zero_extend(sig_sz - ebits - 2, shift_abs); + SASSERT(m_bv_util.get_bv_size(shift_abs) == sig_sz); expr_ref c_in_limits(m); c_in_limits = m_bv_util.mk_sle(shift, m_bv_util.mk_numeral(0, ebits + 2)); dbg_decouple("fpa2bv_to_ubv_in_limits", c_in_limits); - expr_ref shifted_sig(m), shift_abs(m); - shift_abs = m_bv_util.mk_bv_neg(shift); - SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits+2); - SASSERT(bv_sz > (ebits + 2)); - shift_abs = m_bv_util.mk_zero_extend(bv_sz - ebits - 2, shift_abs); - + expr_ref shifted_sig(m); shifted_sig = m_bv_util.mk_bv_lshr(sig, shift_abs); - dbg_decouple("fpa2bv_to_ubv_shift_abs", shift_abs); dbg_decouple("fpa2bv_to_ubv_shifted_sig", shifted_sig); - expr_ref rounded(m); - // TODO: Rounding. - rounded = shifted_sig; + expr_ref last(m), round(m), sticky(m); + last = m_bv_util.mk_extract(sig_sz - bv_sz - 0, sig_sz - bv_sz - 0, shifted_sig); + round = m_bv_util.mk_extract(sig_sz - bv_sz - 1, sig_sz - bv_sz - 1, shifted_sig); + sticky = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(sig_sz - bv_sz - 2, 0, shifted_sig), + m_bv_util.mk_numeral(0, sig_sz - (bv_sz + 3) + 2)), + bv0, + bv1); + dbg_decouple("fpa2bv_to_ubv_last", last); + dbg_decouple("fpa2bv_to_ubv_round", round); + dbg_decouple("fpa2bv_to_ubv_sticky", sticky); + + expr_ref rounding_decision(m); + rounding_decision = mk_rounding_decision(rm, sgn, last, round, sticky); + SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1); + dbg_decouple("fpa2bv_to_ubv_rounding_decision", rounding_decision); - result = m.mk_ite(c_in_limits, rounded, undef); + expr_ref unrounded_sig(m), pre_rounded(m), inc(m); + unrounded_sig = m_bv_util.mk_zero_extend(1, + m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz, shifted_sig)); + inc = m_bv_util.mk_zero_extend(1, + m_bv_util.mk_zero_extend(bv_sz - 1, rounding_decision)); + pre_rounded = m_bv_util.mk_bv_add(unrounded_sig, inc); + + expr_ref rnd_overflow(m), rounded(m), rnd_has_overflown(m); + rnd_overflow = m_bv_util.mk_extract(bv_sz, bv_sz, pre_rounded); + rounded = m_bv_util.mk_extract(bv_sz - 1, 0, pre_rounded); + rnd_has_overflown = m.mk_eq(rnd_overflow, bv1); + + result = m.mk_ite(rnd_has_overflown, undef, rounded); + result = m.mk_ite(c_in_limits, result, undef); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); @@ -3016,6 +3044,41 @@ void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #endif } +expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky) { + expr_ref last_or_sticky(m), round_or_sticky(m), not_round(m), not_lors(m), not_rors(m), not_sgn(m); + expr * last_sticky[2] = { last, sticky }; + expr * round_sticky[2] = { round, sticky }; + last_or_sticky = m_bv_util.mk_bv_or(2, last_sticky); + round_or_sticky = m_bv_util.mk_bv_or(2, round_sticky); + not_round = m_bv_util.mk_bv_not(round); + not_lors = m_bv_util.mk_bv_not(last_or_sticky); + not_rors = m_bv_util.mk_bv_not(round_or_sticky); + not_sgn = m_bv_util.mk_bv_not(sgn); + expr * round_lors[2] = { not_round, not_lors }; + expr * pos_args[2] = { sgn, not_rors }; + expr * neg_args[2] = { not_sgn, not_rors }; + + expr_ref inc_teven(m), inc_taway(m), inc_pos(m), inc_neg(m); + inc_teven = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, round_lors)); + inc_taway = round; + inc_pos = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, pos_args)); + inc_neg = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, neg_args)); + + expr_ref res(m), inc_c2(m), inc_c3(m), inc_c4(m); + expr_ref rm_is_to_neg(m), rm_is_to_pos(m), rm_is_away(m), rm_is_even(m), nil_1(m); + nil_1 = m_bv_util.mk_numeral(0, 1); + mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_to_pos); + mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_is_away); + mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_is_even); + m_simp.mk_ite(rm_is_to_neg, inc_neg, nil_1, inc_c4); + m_simp.mk_ite(rm_is_to_pos, inc_pos, inc_c4, inc_c3); + m_simp.mk_ite(rm_is_away, inc_taway, inc_c3, inc_c2); + m_simp.mk_ite(rm_is_even, inc_teven, inc_c2, res); + + return res; +} + void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result) { unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); @@ -3110,7 +3173,6 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & SASSERT(is_well_sorted(m, beta)); dbg_decouple("fpa2bv_rnd_beta", beta); - dbg_decouple("fpa2bv_rnd_e_min", e_min); dbg_decouple("fpa2bv_rnd_e_max", e_max); @@ -3191,36 +3253,8 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig = m_bv_util.mk_extract(sbits+1, 2, sig); - expr_ref last_or_sticky(m), round_or_sticky(m), not_round(m), not_lors(m), not_rors(m), not_sgn(m); - expr * last_sticky[2] = { last, sticky }; - expr * round_sticky[2] = { round, sticky }; - last_or_sticky = m_bv_util.mk_bv_or(2, last_sticky); - round_or_sticky = m_bv_util.mk_bv_or(2, round_sticky); - not_round = m_bv_util.mk_bv_not(round); - not_lors = m_bv_util.mk_bv_not(last_or_sticky); - not_rors = m_bv_util.mk_bv_not(round_or_sticky); - not_sgn = m_bv_util.mk_bv_not(sgn); - expr * round_lors[2] = { not_round, not_lors}; - expr * pos_args[2] = { sgn, not_rors }; - expr * neg_args[2] = { not_sgn, not_rors }; - - expr_ref inc_teven(m), inc_taway(m), inc_pos(m), inc_neg(m); - inc_teven = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, round_lors)); - inc_taway = round; - inc_pos = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, pos_args)); - inc_neg = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, neg_args)); - - expr_ref inc(m), inc_c2(m), inc_c3(m), inc_c4(m); - expr_ref rm_is_to_neg(m), rm_is_to_pos(m), rm_is_away(m), rm_is_even(m), nil_1(m); - nil_1 = m_bv_util.mk_numeral(0, 1); - mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); - mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_to_pos); - mk_is_rm(rm, BV_RM_TIES_TO_AWAY, rm_is_away); - mk_is_rm(rm, BV_RM_TIES_TO_EVEN, rm_is_even); - m_simp.mk_ite(rm_is_to_neg, inc_neg, nil_1, inc_c4); - m_simp.mk_ite(rm_is_to_pos, inc_pos, inc_c4, inc_c3); - m_simp.mk_ite(rm_is_away, inc_taway, inc_c3, inc_c2); - m_simp.mk_ite(rm_is_even, inc_teven, inc_c2, inc); + expr_ref inc(m); + inc = mk_rounding_decision(rm, sgn, last, round, sticky); SASSERT(m_bv_util.get_bv_size(inc) == 1 && is_well_sorted(m, inc)); dbg_decouple("fpa2bv_rnd_inc", inc); @@ -3289,8 +3323,13 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & mk_top_exp(ebits, top_exp); mk_bot_exp(ebits, bot_exp); - expr_ref rm_is_to_zero(m), rm_zero_or_neg(m), rm_zero_or_pos(m); + expr_ref nil_1(m); + nil_1 = m_bv_util.mk_numeral(0, 1); + + expr_ref rm_is_to_zero(m), rm_is_to_neg(m), rm_is_to_pos(m), rm_zero_or_neg(m), rm_zero_or_pos(m); mk_is_rm(rm, BV_RM_TO_ZERO, rm_is_to_zero); + mk_is_rm(rm, BV_RM_TO_NEGATIVE, rm_is_to_neg); + mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_to_pos); m_simp.mk_or(rm_is_to_zero, rm_is_to_neg, rm_zero_or_neg); m_simp.mk_or(rm_is_to_zero, rm_is_to_pos, rm_zero_or_pos); @@ -3306,7 +3345,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & dbg_decouple("fpa2bv_rnd_max_exp", max_exp); - expr_ref ovfl_exp(m), max_inf_exp_neg(m), max_inf_exp_pos(m), n_d_check(m), n_d_exp(m); + expr_ref ovfl_exp(m), max_inf_exp_neg(m), max_inf_exp_pos(m), n_d_check(m), n_d_exp(m); m_simp.mk_ite(rm_zero_or_neg, max_exp, inf_exp, max_inf_exp_neg); m_simp.mk_ite(rm_zero_or_pos, max_exp, inf_exp, max_inf_exp_pos); m_simp.mk_ite(sgn_is_zero, max_inf_exp_neg, max_inf_exp_pos, ovfl_exp); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index ee7ffa192..6a854adb3 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -181,6 +181,7 @@ protected: void unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & lz, bool normalize); void round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & result); + expr_ref mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky); void add_core(unsigned sbits, unsigned ebits, expr_ref & rm, expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp, From defb6158fe61d0c93662b07bd547c6dcf2dd7beb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 29 Dec 2014 17:09:28 +0000 Subject: [PATCH 091/507] MPF: bugfix Signed-off-by: Christoph M. Wintersteiger --- src/util/mpf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 405f34c9d..e3f35538e 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -1174,7 +1174,7 @@ std::string mpf_manager::to_string(mpf const & x) { if (is_nan(x)) res = "NaN"; else { - res = sgn(x) ? "-" : "+"; + res = sgn(x) ? "-" : ""; if (is_inf(x)) res += "INF"; From 2258988b37e7d8869ab5c2cf003d7e12272f92b4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 14:48:06 +0000 Subject: [PATCH 092/507] MPF bugfix Signed-off-by: Christoph M. Wintersteiger --- src/util/mpf.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index e3f35538e..245120866 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -301,28 +301,36 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode m_mpq_manager.mul(sig, 2, sig); m_mpz_manager.dec(exp); } - + // 1.0 <= sig < 2.0 SASSERT((m_mpq_manager.le(1, sig) && m_mpq_manager.lt(sig, 2))); - TRACE("mpf_dbg", tout << "sig = " << m_mpq_manager.to_string(sig) << " exp = " << m_mpz_manager.to_string(exp) << std::endl;); - + TRACE("mpf_dbg", tout << "sig = " << m_mpq_manager.to_string(sig) << + " exp = " << m_mpz_manager.to_string(exp) << std::endl;); + m_mpz_manager.set(o.significand, 0); for (unsigned i = 0; i < (sbits+3); i++) { m_mpz_manager.mul2k(o.significand, 1); - if (!m_mpq_manager.lt(sig, 1)) { - m_mpz_manager.inc(o.significand); + if (m_mpq_manager.ge(sig, 1)) { + m_mpz_manager.inc(o.significand); m_mpq_manager.dec(sig); } - m_mpq_manager.mul(sig, 2, sig); + m_mpq_manager.mul(sig, mpq(2), sig); } + + // sticky + if (!m_mpq_manager.is_zero(sig) && m_mpz_manager.is_even(o.significand)) + m_mpz_manager.inc(o.significand); + + TRACE("mpf_dbg", tout << "sig = " << m_mpz_manager.to_string(o.significand) << + " exp = " << o.exponent << std::endl;); if (m_mpz_manager.is_small(exp)) { o.exponent = m_mpz_manager.get_int64(exp); round(rm, o); } else - mk_inf(ebits, sbits, o.sign, o); // CMW: output warning message? throw exception? + mk_inf(ebits, sbits, o.sign, o); } TRACE("mpf_dbg", tout << "set: res = " << to_string(o) << std::endl;); From 4d18e24fb4ee28431cdbe7461ae611473076895c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 14:48:45 +0000 Subject: [PATCH 093/507] FPA rewriter bugfix Signed-off-by: Christoph M. Wintersteiger --- src/ast/rewriter/float_rewriter.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index 522fad678..96561395e 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -587,9 +587,14 @@ br_status float_rewriter::mk_to_real(expr * arg1, expr_ref & result) { scoped_mpf fv(m_util.fm()); if (m_util.is_value(arg1, fv)) { - scoped_mpq r(m_fm.mpq_manager()); - m_fm.to_rational(fv, r); - result = m_util.au().mk_numeral(r.get(), false); + if (m_fm.is_nan(fv) || m_fm.is_inf(fv)) { + result = m_util.mk_internal_to_real_unspecified(); + } + else { + scoped_mpq r(m_fm.mpq_manager()); + m_fm.to_rational(fv, r); + result = m_util.au().mk_numeral(r.get(), false); + } return BR_DONE; } From 01d78b7274d578e174851263728341ccde58ee4c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 14:49:52 +0000 Subject: [PATCH 094/507] added internal functions to fpa2bv converter Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 36 ++++++-------------------------- src/ast/fpa/fpa2bv_converter.h | 7 ------- src/ast/fpa/fpa2bv_rewriter.h | 7 +++++-- 3 files changed, 11 insertions(+), 39 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 7edc4a7a0..e396bb6b5 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2422,29 +2422,6 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * split_triple(args[0], sgn, s, e); result = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s); } -void fpa2bv_converter::mk_internal_bvwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - TRACE("fpa2bv_internal", tout << "wrap "; - for (unsigned i = 0; i < num; i++) - tout << " " << mk_ismt2_pp(args[i], m); - tout << std::endl;); - SASSERT(num == 1); - result = m.mk_app(f, num, args); -} - -void fpa2bv_converter::mk_internal_bvunwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - TRACE("fpa2bv_internal", tout << "unwrap "; - for (unsigned i = 0; i < num; i++) - tout << " " << mk_ismt2_pp(args[i], m); - tout << std::endl;); - SASSERT(num == 1); - app * a0 = to_app(args[0]); - SASSERT(a0->get_kind() == AST_APP); - SASSERT(is_float_family(a0->get_decl())); - decl_kind k = a0->get_decl_kind(); - SASSERT(k == OP_FLOAT_INTERNAL_BVWRAP); - SASSERT(a0->get_num_args() == 1); - result = a0->get_arg(0); -} void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 3); @@ -2631,7 +2608,7 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar expr_ref sgn(m), sig(m), exp(m), lz(m); unpack(x, sgn, sig, exp, lz, true); // sig is of the form [1].[sigbits] - + SASSERT(m_bv_util.get_bv_size(sgn) == 1); SASSERT(m_bv_util.get_bv_size(sig) == sbits); SASSERT(m_bv_util.get_bv_size(exp) == ebits); @@ -2646,8 +2623,8 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar for (unsigned i = sbits-2; i != (unsigned)-1; i--) { bit = m_bv_util.mk_extract(i, i, sig); - rsig = m_arith_util.mk_mul(rsig, two); - rsig = m_arith_util.mk_add(rsig, m.mk_ite(m.mk_eq(bit, bv1), one, zero)); + rsig = m_arith_util.mk_add(m_arith_util.mk_mul(rsig, two), + m.mk_ite(m.mk_eq(bit, bv1), one, zero)); } const mpz & p2 = fu().fm().m_powers2(sbits-1); @@ -2661,19 +2638,18 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar exp_is_neg = m.mk_eq(m_bv_util.mk_extract(ebits - 1, ebits - 1, exp), bv1); dbg_decouple("fpa2bv_to_real_exp_is_neg", exp_is_neg); exp_p = m_bv_util.mk_sign_extend(1, exp); - exp_n = m_bv_util.mk_bv_not(m_bv_util.mk_sign_extend(1, exp)); + exp_n = m_bv_util.mk_bv_neg(exp_p); exp_abs = m.mk_ite(exp_is_neg, exp_n, exp_p); dbg_decouple("fpa2bv_to_real_exp_abs", exp); SASSERT(m_bv_util.get_bv_size(exp_abs) == ebits + 1); expr_ref exp2(m), prev_bit(m); exp2 = zero; - prev_bit = bv0; for (unsigned i = ebits; i != (unsigned)-1; i--) { bit = m_bv_util.mk_extract(i, i, exp_abs); - exp2 = m_arith_util.mk_mul(exp2, two); - exp2 = m_arith_util.mk_add(exp2, m.mk_ite(m.mk_eq(bit, prev_bit), zero, one)); + exp2 = m_arith_util.mk_add(m_arith_util.mk_mul(exp2, two), + m.mk_ite(m.mk_eq(bit, bv1), one, zero)); prev_bit = bit; } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 6a854adb3..440fc9d14 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -147,13 +147,6 @@ public: void dbg_decouple(const char * prefix, expr_ref & e); expr_ref_vector m_extra_assertions; - void mk_internal_bvwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_internal_bvunwrap(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - - void mk_internal_to_ubv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_internal_to_sbv_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_internal_to_real_unspecified(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - protected: void mk_is_nan(expr * e, expr_ref & result); void mk_is_inf(expr * e, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 42fd7a7fe..c9296dd5b 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -151,8 +151,11 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FLOAT_INTERNAL_BVWRAP: m_conv.mk_internal_bvwrap(f, num, args, result); return BR_DONE; - case OP_FLOAT_INTERNAL_BVUNWRAP: m_conv.mk_internal_bvunwrap(f, num, args, result); return BR_DONE; + case OP_FLOAT_INTERNAL_BVWRAP: + case OP_FLOAT_INTERNAL_BVUNWRAP: + case OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED: + case OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED: + case OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED: return BR_FAILED; default: TRACE("fpa2bv", tout << "unsupported operator: " << f->get_name() << "\n"; for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << std::endl;); From 208994e2dc63214ddcf3f4dd25e344a253db484c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 15:33:50 +0000 Subject: [PATCH 095/507] Renamed the default tactics form QF_FPA and QF_FPABV to QF_FP and QF_FPBV, in anticipation of the logic name QF_FPA to mean floats+arrays. Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/qffpa_tactic.cpp | 53 +++---------------- src/tactic/fpa/qffpa_tactic.h | 14 ++--- src/tactic/portfolio/default_tactic.cpp | 2 +- src/tactic/portfolio/smt_strategic_solver.cpp | 6 +-- 4 files changed, 18 insertions(+), 57 deletions(-) diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffpa_tactic.cpp index f9b7f88a1..6f1517c98 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffpa_tactic.cpp @@ -24,7 +24,7 @@ Notes: #include"qffpa_tactic.h" -tactic * mk_qffpa_tactic(ast_manager & m, params_ref const & p) { +tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { params_ref sat_simp_p = p; sat_simp_p .set_bool("elim_and", true); @@ -37,40 +37,14 @@ tactic * mk_qffpa_tactic(ast_manager & m, params_ref const & p) { mk_fail_if_undecided_tactic()); } -struct is_non_qffpa_predicate { - struct found {}; - ast_manager & m; - float_util u; - - is_non_qffpa_predicate(ast_manager & _m) : m(_m), u(m) {} - - void operator()(var *) { throw found(); } - - void operator()(quantifier *) { throw found(); } - - void operator()(app * n) { - sort * s = get_sort(n); - if (!m.is_bool(s) && !u.is_float(s) && !u.is_rm(s)) - throw found(); - family_id fid = n->get_family_id(); - if (fid == m.get_basic_family_id()) - return; - if (fid == u.get_family_id()) - return; - if (is_uninterp_const(n)) - return; - - throw found(); - } -}; - -struct is_non_qffpabv_predicate { +struct is_non_qffp_predicate { struct found {}; ast_manager & m; bv_util bu; float_util fu; + arith_util au; - is_non_qffpabv_predicate(ast_manager & _m) : m(_m), bu(m), fu(m) {} + is_non_qffp_predicate(ast_manager & _m) : m(_m), bu(m), fu(m), au(m) {} void operator()(var *) { throw found(); } @@ -78,7 +52,7 @@ struct is_non_qffpabv_predicate { void operator()(app * n) { sort * s = get_sort(n); - if (!m.is_bool(s) && !fu.is_float(s) && !fu.is_rm(s) && !bu.is_bv_sort(s)) + if (!m.is_bool(s) && !fu.is_float(s) && !fu.is_rm(s) && !bu.is_bv_sort(s) && !au.is_real(s)) throw found(); family_id fid = n->get_family_id(); if (fid == m.get_basic_family_id()) @@ -92,25 +66,14 @@ struct is_non_qffpabv_predicate { } }; -class is_qffpa_probe : public probe { +class is_qffp_probe : public probe { public: virtual result operator()(goal const & g) { - return !test(g); - } -}; - -class is_qffpabv_probe : public probe { -public: - virtual result operator()(goal const & g) { - return !test(g); + return !test(g); } }; probe * mk_is_qffpa_probe() { - return alloc(is_qffpa_probe); -} - -probe * mk_is_qffpabv_probe() { - return alloc(is_qffpabv_probe); + return alloc(is_qffp_probe); } \ No newline at end of file diff --git a/src/tactic/fpa/qffpa_tactic.h b/src/tactic/fpa/qffpa_tactic.h index cd16c5817..923c19970 100644 --- a/src/tactic/fpa/qffpa_tactic.h +++ b/src/tactic/fpa/qffpa_tactic.h @@ -24,17 +24,17 @@ Notes: class ast_manager; class tactic; -tactic * mk_qffpa_tactic(ast_manager & m, params_ref const & p = params_ref()); +tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p = params_ref()); /* - ADD_TACTIC("qffpa", "(try to) solve goal using the tactic for QF_FPA.", "mk_qffpa_tactic(m, p)") - ADD_TACTIC("qffpabv", "(try to) solve goal using the tactic for QF_FPABV (floats+bit-vectors).", "mk_qffpa_tactic(m, p)") + ADD_TACTIC("qffp", "(try to) solve goal using the tactic for QF_FPA.", "mk_qffp_tactic(m, p)") + ADD_TACTIC("qffpbv", "(try to) solve goal using the tactic for QF_FPABV (floats+bit-vectors).", "mk_qffp_tactic(m, p)") */ -probe * mk_is_qffpa_probe(); -probe * mk_is_qffpabv_probe(); +probe * mk_is_qffp_probe(); +probe * mk_is_qffpbv_probe(); /* - ADD_PROBE("is-qffpa", "true if the goal is in QF_FPA (FloatingPoints).", "mk_is_qffpa_probe()") - ADD_PROBE("is-qffpabv", "true if the goal is in QF_FPABV (FloatingPoints+Bitvectors).", "mk_is_qffpabv_probe()") + ADD_PROBE("is-qffp", "true if the goal is in QF_FPA (FloatingPoints).", "mk_is_qffp_probe()") + ADD_PROBE("is-qffpbv", "true if the goal is in QF_FPABV (FloatingPoints+Bitvectors).", "mk_is_qffp_probe()") */ #endif diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 9ecc16ecf..a01b547df 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -38,7 +38,7 @@ tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m), cond(mk_is_nra_probe(), mk_nra_tactic(m), cond(mk_is_lira_probe(), mk_lira_tactic(m, p), - cond(mk_is_qffpabv_probe(), mk_qffpa_tactic(m, p), + cond(mk_is_qffp_probe(), mk_qffp_tactic(m, p), mk_smt_tactic()))))))))), p); return st; diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index ae79446e3..9e0ce6e89 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -78,10 +78,8 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const return mk_ufbv_tactic(m, p); else if (logic=="BV") return mk_ufbv_tactic(m, p); - else if (logic=="QF_FPA") - return mk_qffpa_tactic(m, p); - else if (logic=="QF_FPABV") - return mk_qffpa_tactic(m, p); + else if (logic=="QF_FP" || logic=="QF_FPBV") + return mk_qffp_tactic(m, p); else if (logic=="HORN") return mk_horn_tactic(m, p); else From 21a847d299972b6498cdf335c7fa1d30f2748ac8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 15:36:11 +0000 Subject: [PATCH 096/507] More renamings for QF_FP/qffp/is-qffp Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/qffpa_tactic.cpp | 2 +- src/tactic/fpa/qffpa_tactic.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffpa_tactic.cpp index 6f1517c98..fc292bca6 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffpa_tactic.cpp @@ -73,7 +73,7 @@ public: } }; -probe * mk_is_qffpa_probe() { +probe * mk_is_qffp_probe() { return alloc(is_qffp_probe); } \ No newline at end of file diff --git a/src/tactic/fpa/qffpa_tactic.h b/src/tactic/fpa/qffpa_tactic.h index 923c19970..660622fb8 100644 --- a/src/tactic/fpa/qffpa_tactic.h +++ b/src/tactic/fpa/qffpa_tactic.h @@ -26,15 +26,15 @@ class tactic; tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p = params_ref()); /* - ADD_TACTIC("qffp", "(try to) solve goal using the tactic for QF_FPA.", "mk_qffp_tactic(m, p)") - ADD_TACTIC("qffpbv", "(try to) solve goal using the tactic for QF_FPABV (floats+bit-vectors).", "mk_qffp_tactic(m, p)") + ADD_TACTIC("qffp", "(try to) solve goal using the tactic for QF_FP.", "mk_qffp_tactic(m, p)") + ADD_TACTIC("qffpbv", "(try to) solve goal using the tactic for QF_FPBV (floats+bit-vectors).", "mk_qffp_tactic(m, p)") */ probe * mk_is_qffp_probe(); probe * mk_is_qffpbv_probe(); /* - ADD_PROBE("is-qffp", "true if the goal is in QF_FPA (FloatingPoints).", "mk_is_qffp_probe()") - ADD_PROBE("is-qffpbv", "true if the goal is in QF_FPABV (FloatingPoints+Bitvectors).", "mk_is_qffp_probe()") + ADD_PROBE("is-qffp", "true if the goal is in QF_FP (floats).", "mk_is_qffp_probe()") + ADD_PROBE("is-qffpbv", "true if the goal is in QF_FPBV (floats+bit-vectors).", "mk_is_qffp_probe()") */ #endif From afae49b9edd13cc45e8c5ae6a484b4a26abe1489 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 16:15:40 +0000 Subject: [PATCH 097/507] More renaming QF_FPA -> QF_FP Signed-off-by: Christoph M. Wintersteiger --- src/cmd_context/cmd_context.cpp | 10 +++++----- src/smt/smt_setup.cpp | 4 ++-- src/smt/smt_setup.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index ee5437bd6..4dd0cc614 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -512,8 +512,8 @@ bool cmd_context::logic_has_arith_core(symbol const & s) const { s == "UFNIA" || s == "LIA" || s == "LRA" || - s == "QF_FPA" || - s == "QF_FPABV" || + s == "QF_FP" || + s == "QF_FPBV" || s == "HORN"; } @@ -532,7 +532,7 @@ bool cmd_context::logic_has_bv_core(symbol const & s) const { s == "QF_ABV" || s == "QF_AUFBV" || s == "QF_BVRE" || - s == "QF_FPABV" || + s == "QF_FPBV" || s == "HORN"; } @@ -557,7 +557,7 @@ bool cmd_context::logic_has_seq() const { } bool cmd_context::logic_has_floats() const { - return !has_logic() || m_logic == "QF_FPA" || m_logic == "QF_FPABV"; + return !has_logic() || m_logic == "QF_FP" || m_logic == "QF_FPBV"; } bool cmd_context::logic_has_array_core(symbol const & s) const { @@ -668,7 +668,7 @@ bool cmd_context::supported_logic(symbol const & s) const { logic_has_arith_core(s) || logic_has_bv_core(s) || logic_has_array_core(s) || logic_has_seq_core(s) || logic_has_horn(s) || - s == "QF_FPA" || s == "QF_FPABV"; + s == "QF_FP" || s == "QF_FPBV"; } bool cmd_context::set_logic(symbol const & s) { diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 64477164a..68e960fb8 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -680,11 +680,11 @@ namespace smt { setup_mi_arith(); } - void setup::setup_QF_FPA() { + void setup::setup_QF_FP() { m_context.register_plugin(alloc(smt::theory_fpa, m_manager)); } - void setup::setup_QF_FPABV() { + void setup::setup_QF_FPBV() { setup_QF_BV(); m_context.register_plugin(alloc(smt::theory_fpa, m_manager)); } diff --git a/src/smt/smt_setup.h b/src/smt/smt_setup.h index 299ce7834..6cbcb9602 100644 --- a/src/smt/smt_setup.h +++ b/src/smt/smt_setup.h @@ -75,8 +75,8 @@ namespace smt { void setup_QF_AX(static_features const & st); void setup_QF_AUFLIA(); void setup_QF_AUFLIA(static_features const & st); - void setup_QF_FPA(); - void setup_QF_FPABV(); + void setup_QF_FP(); + void setup_QF_FPBV(); void setup_LRA(); void setup_AUFLIA(bool simple_array = true); void setup_AUFLIA(static_features const & st); From 80c025b2893cc6adc9d8747f0eb9145bfa04d2ec Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 16:15:55 +0000 Subject: [PATCH 098/507] Improved default tactic for QF_FP Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/qffpa_tactic.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffpa_tactic.cpp index fc292bca6..6cfc699c7 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffpa_tactic.cpp @@ -21,6 +21,7 @@ Notes: #include"bit_blaster_tactic.h" #include"sat_tactic.h" #include"fpa2bv_tactic.h" +#include"smt_tactic.h" #include"qffpa_tactic.h" @@ -28,13 +29,17 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { params_ref sat_simp_p = p; sat_simp_p .set_bool("elim_and", true); - return and_then(mk_simplify_tactic(m, p), + return cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), + and_then(mk_simplify_tactic(m), + mk_smt_tactic()), + and_then( + mk_simplify_tactic(m, p), mk_fpa2bv_tactic(m, p), using_params(mk_simplify_tactic(m, p), sat_simp_p), mk_bit_blaster_tactic(m, p), using_params(mk_simplify_tactic(m, p), sat_simp_p), mk_sat_tactic(m, p), - mk_fail_if_undecided_tactic()); + mk_fail_if_undecided_tactic())); } struct is_non_qffp_predicate { From 2b7f9b7e5c98f5433877a65605f4fed824904c6d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 16:40:54 +0000 Subject: [PATCH 099/507] build fix for floats Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_project.py b/scripts/mk_project.py index 2bdf7c4f8..1298093cf 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -53,8 +53,8 @@ def init_project_def(): add_lib('user_plugin', ['smt'], 'smt/user_plugin') add_lib('bv_tactics', ['tactic', 'bit_blaster'], 'tactic/bv') add_lib('fuzzing', ['ast'], 'test/fuzzing') - add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic'], 'tactic/fpa') add_lib('smt_tactic', ['smt'], 'smt/tactic') + add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic'], 'tactic/fpa') add_lib('sls_tactic', ['tactic', 'normal_forms', 'core_tactics', 'bv_tactics'], 'tactic/sls') add_lib('qe', ['smt','sat'], 'qe') add_lib('duality', ['smt', 'interp', 'qe']) From 7a5239ef707251a409894eef7eed773a96ede48e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 17:30:45 +0000 Subject: [PATCH 100/507] QF_FP default tactic bugfix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/fpa/qffpa_tactic.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffpa_tactic.cpp index 6cfc699c7..919cf0c1b 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffpa_tactic.cpp @@ -29,7 +29,8 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { params_ref sat_simp_p = p; sat_simp_p .set_bool("elim_and", true); - return cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), + tactic * st = + cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), and_then(mk_simplify_tactic(m), mk_smt_tactic()), and_then( @@ -40,6 +41,9 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m, p), sat_simp_p), mk_sat_tactic(m, p), mk_fail_if_undecided_tactic())); + + st->updt_params(p); + return st; } struct is_non_qffp_predicate { From 3fe11e4c38977e938c106166cc361a46469cebb1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 17:31:11 +0000 Subject: [PATCH 101/507] improved handling of unspecified values in FP Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 39 ++++++++++++++++++++++---------- src/ast/fpa/fpa2bv_converter.h | 6 +++++ src/ast/fpa/fpa2bv_rewriter.h | 14 +++++++++--- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index e396bb6b5..94538861d 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -32,6 +32,7 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_arith_util(m), m_mpf_manager(m_util.fm()), m_mpz_manager(m_mpf_manager.mpz_manager()), + m_hi_fp_unspecified(true), m_extra_assertions(m) { m_plugin = static_cast(m.get_plugin(m.mk_family_id("float"))); } @@ -2465,14 +2466,10 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg mk_is_neg(x, x_is_neg); mk_is_nzero(x, x_is_nzero); - expr_ref undef(m); - undef = m_util.mk_internal_to_ubv_unspecified(bv_sz); - dbg_decouple("fpa2bv_to_ubv_undef", undef); - // NaN, Inf, or negative (except -0) -> undefined expr_ref c1(m), v1(m); c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); - v1 = undef; + v1 = mk_to_ubv_unspecified(bv_sz); dbg_decouple("fpa2bv_to_ubv_c1", c1); // +-Zero -> 0 @@ -2556,8 +2553,8 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg rounded = m_bv_util.mk_extract(bv_sz - 1, 0, pre_rounded); rnd_has_overflown = m.mk_eq(rnd_overflow, bv1); - result = m.mk_ite(rnd_has_overflown, undef, rounded); - result = m.mk_ite(c_in_limits, result, undef); + result = m.mk_ite(rnd_has_overflown, mk_to_ubv_unspecified(bv_sz), rounded); + result = m.mk_ite(c_in_limits, result, mk_to_ubv_unspecified(bv_sz)); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); @@ -2664,17 +2661,35 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar TRACE("fpa2bv_to_real", tout << "rsig = " << mk_ismt2_pp(rsig, m) << std::endl; tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;); - - expr_ref undef(m); - undef = m_util.mk_internal_to_real_unspecified(); result = m.mk_ite(x_is_zero, zero, res); - result = m.mk_ite(x_is_inf, undef, result); - result = m.mk_ite(x_is_nan, undef, result); + result = m.mk_ite(x_is_inf, mk_to_real_unspecified(), result); + result = m.mk_ite(x_is_nan, mk_to_real_unspecified(), result); SASSERT(is_well_sorted(m, result)); } +expr_ref fpa2bv_converter::mk_to_ubv_unspecified(unsigned width) { + if (m_hi_fp_unspecified) + return expr_ref(m_bv_util.mk_numeral(0, width), m); + else + return expr_ref(m_util.mk_internal_to_ubv_unspecified(width), m); +} + +expr_ref fpa2bv_converter::mk_to_sbv_unspecified(unsigned width) { + if (m_hi_fp_unspecified) + return expr_ref(m_bv_util.mk_numeral(0, width), m); + else + return expr_ref(m_util.mk_internal_to_sbv_unspecified(width), m); +} + +expr_ref fpa2bv_converter::mk_to_real_unspecified() { + if (m_hi_fp_unspecified) + return expr_ref(m_arith_util.mk_numeral(rational(0), false), m); + else + return expr_ref(m_util.mk_internal_to_real_unspecified(), m); +} + void fpa2bv_converter::split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 440fc9d14..197c7ce9a 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -51,6 +51,7 @@ protected: mpf_manager & m_mpf_manager; unsynch_mpz_manager & m_mpz_manager; float_decl_plugin * m_plugin; + bool m_hi_fp_unspecified; obj_map m_const2bv; obj_map m_rm_const2bv; @@ -137,6 +138,11 @@ public: void mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void set_unspecified_fp_hi(bool v) { m_hi_fp_unspecified = v; } + expr_ref mk_to_ubv_unspecified(unsigned width); + expr_ref mk_to_sbv_unspecified(unsigned width); + expr_ref mk_to_real_unspecified(); + obj_map const & const2bv() const { return m_const2bv; } obj_map const & rm_const2bv() const { return m_rm_const2bv; } obj_map const & uf2bvuf() const { return m_uf2bvuf; } diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index c9296dd5b..797f681e7 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -24,6 +24,7 @@ Notes: #include"rewriter_def.h" #include"bv_decl_plugin.h" #include"fpa2bv_converter.h" +#include"fpa2bv_rewriter_params.hpp" struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { ast_manager & m_manager; @@ -36,7 +37,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { ast_manager & m() const { return m_manager; } - fpa2bv_rewriter_cfg(ast_manager & m, fpa2bv_converter & c, params_ref const & p): + fpa2bv_rewriter_cfg(ast_manager & m, fpa2bv_converter & c, params_ref const & p) : m_manager(m), m_out(m), m_conv(c), @@ -58,9 +59,16 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { void reset() { } + void updt_local_params(params_ref const & _p) { + fpa2bv_rewriter_params p(_p); + bool v = p.hi_fp_unspecified(); + m_conv.set_unspecified_fp_hi(v); + } + void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); - m_max_steps = p.get_uint("max_steps", UINT_MAX); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); + updt_local_params(p); } bool max_steps_exceeded(unsigned num_steps) const { From 7d61223a3a94b1ac1091ac0a4997cb009ac25b35 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 31 Dec 2014 18:34:42 +0000 Subject: [PATCH 102/507] Improved FP theory Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 360 +++++++++++++++++++++-------------------- src/smt/theory_fpa.h | 90 +++++++++-- 2 files changed, 260 insertions(+), 190 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index b63073893..f7fd1de30 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -24,55 +24,14 @@ Revision History: namespace smt { - class fpa_factory : public value_factory { - float_util m_util; - - virtual app * mk_value_core(mpf const & val, sort * s) { - SASSERT(m_util.get_ebits(s) == val.get_ebits()); - SASSERT(m_util.get_sbits(s) == val.get_sbits()); - return m_util.mk_value(val); - } - - public: - fpa_factory(ast_manager & m, family_id fid) : - value_factory(m, fid), - m_util(m) { - } - - virtual ~fpa_factory() {} - - virtual expr * get_some_value(sort * s) { - mpf_manager & mpfm = m_util.fm(); - scoped_mpf q(mpfm); - mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 0); - return m_util.mk_value(q); - } - - virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { - mpf_manager & mpfm = m_util.fm(); - scoped_mpf q(mpfm); - mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 0); - v1 = m_util.mk_value(q); - mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 1); - v2 = m_util.mk_value(q); - return true; - } - - virtual expr * get_fresh_value(sort * s) { NOT_IMPLEMENTED_YET(); } - virtual void register_value(expr * n) { /* Ignore */ } - - app * mk_value(mpf const & x) { - return m_util.mk_value(x); - } - }; - - class fpa_conv_trail : public trail { + class fpa2bv_conversion_trail_elem : public trail { ast_manager & m; obj_map & m_conversions; expr * m_e; public: - fpa_conv_trail(ast_manager & m, obj_map & c, expr * e) : m(m), m_conversions(c), m_e(e) {} - virtual ~fpa_conv_trail() {} + fpa2bv_conversion_trail_elem(ast_manager & m, obj_map & c, expr * e) : + m(m), m_conversions(c), m_e(e) {} + virtual ~fpa2bv_conversion_trail_elem() {} virtual void undo(theory_fpa & th) { expr * v = m_conversions.find(m_e); m_conversions.remove(m_e); @@ -150,50 +109,52 @@ namespace smt { } app * theory_fpa::fpa_value_proc::mk_value(model_generator & mg, ptr_vector & values) { - SASSERT(values.size() == 3); - ast_manager & m = m_th.get_manager(); - - TRACE("t_fpa", tout << "fpa_value_proc::mk_value for: [" << - mk_ismt2_pp(values[0], m) << " " << - mk_ismt2_pp(values[1], m) << " " << - mk_ismt2_pp(values[2], m) << "]" << std::endl;); + SASSERT(values.size() == 1); + ast_manager & m = m_th.get_manager(); mpf_manager & mpfm = m_fu.fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); - - unsigned ebits = m_bu.get_bv_size(values[2]); - unsigned sbits = m_bu.get_bv_size(values[1]) + 1; + + SASSERT(m_bu.get_bv_size(values[0]) == (m_ebits + m_sbits)); + app * result; - scoped_mpz sgn_z(mpzm), sig_z(mpzm), exp_z(mpzm); scoped_mpz bias(mpzm); - mpzm.power(mpz(2), ebits - 1, bias); + mpzm.power(mpz(2), m_ebits - 1, bias); mpzm.dec(bias); - rational sgn_q(0), sig_q(0), exp_q(bias); + rational all_rat(0); + scoped_mpz all_bits(mpzm); unsigned bv_sz; - bool r; - r = m_bu.is_numeral(values[0], sgn_q, bv_sz); SASSERT(r); SASSERT(bv_sz == 1); - r = m_bu.is_numeral(values[1], sig_q, bv_sz); SASSERT(r); SASSERT(bv_sz == sbits - 1); - r = m_bu.is_numeral(values[2], exp_q, bv_sz); SASSERT(r); SASSERT(bv_sz == ebits); + bool r = m_bu.is_numeral(values[0], all_rat, bv_sz); + SASSERT(r); + SASSERT(bv_sz == (m_ebits+m_sbits)); + SASSERT(all_rat.is_int()); + mpzm.set(all_bits, all_rat.to_mpq().numerator()); - TRACE("t_fpa", tout << "sgn=" << sgn_q.to_string() << " ; " << - "sig=" << sig_q.to_string() << " ; " << - "exp=" << exp_q.to_string() << std::endl;); + scoped_mpz sgn_z(mpzm), sig_z(mpzm), exp_z(mpzm); + mpzm.machine_div2k(all_bits, m_ebits + m_sbits - 1, sgn_z); + mpzm.mod(all_bits, mpfm.m_powers2(m_ebits + m_sbits - 1), all_bits); - rational exp_u = exp_q - rational(bias); - SASSERT(exp_u.is_int64()); + mpzm.machine_div2k(all_bits, m_sbits - 1, exp_z); + mpzm.mod(all_bits, mpfm.m_powers2(m_sbits - 1), all_bits); - scoped_mpf f(mpfm); - scoped_mpq sig_mpq(mpqm); - sig_mpq = sig_q.to_mpq(); - mpfm.set(f, ebits, sbits, sgn_q.is_one(), sig_mpq.get().numerator(), exp_u.get_int64()); + TRACE("t_fpa_detail", tout << "sgn=" << mpzm.to_string(sgn_z) << " ; " << + "sig=" << mpzm.to_string(sig_z) << " ; " << + "exp=" << mpzm.to_string(exp_z) << std::endl;); + + scoped_mpz exp_u = exp_z - bias; + SASSERT(mpzm.is_int64(exp_u)); + + scoped_mpf f(mpfm); + mpfm.set(f, m_ebits, m_sbits, mpzm.is_one(sgn_z), sig_z, mpzm.get_int64(exp_u)); result = m_fu.mk_value(f); - TRACE("t_fpa", tout << "fpa_value_proc::mk_value result: " << - mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + TRACE("t_fpa", tout << "fpa_value_proc::mk_value [" << + mk_ismt2_pp(values[0], m) << "] --> " << + mk_ismt2_pp(result, m_th.get_manager()) << "\n";); return result; } @@ -267,11 +228,6 @@ namespace smt { proof_ref pr(m); m_rw(e, res); m_th_rw(res, res); - - TRACE("t_fpa_detail", tout << "converted atom:" << std::endl; - tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << - mk_ismt2_pp(res, m) << std::endl;); - SASSERT(is_app(res)); SASSERT(m.is_bool(res)); return res; @@ -290,11 +246,13 @@ namespace smt { SASSERT(is_sort_of(m.get_sort(res), m_bv_util.get_family_id(), BV_SORT)); SASSERT(m_bv_util.get_bv_size(res) == 3); ctx.internalize(res, false); + m_th_rw(res, res); } else if (m_float_util.is_float(e)) { SASSERT(to_app(res)->get_family_id() == get_family_id()); - decl_kind k = to_app(res)->get_decl_kind(); - if (k == OP_FLOAT_TO_FP) { + float_op_kind k = (float_op_kind)(to_app(res)->get_decl_kind()); + switch (k) { + case OP_FLOAT_TO_FP: { SASSERT(to_app(res)->get_num_args() == 3); SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(0)), m_bv_util.get_family_id(), BV_SORT)); SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(1)), m_bv_util.get_family_id(), BV_SORT)); @@ -305,22 +263,32 @@ namespace smt { m_converter.split_triple(res, sgn, sig, exp); m_th_rw(sgn, s_sgn); m_th_rw(sig, s_sig); - m_th_rw(exp, s_exp); - - m_converter.mk_triple(s_sgn, s_sig, s_exp, res); - } - else { - SASSERT(is_sort_of(m.get_sort(e), get_family_id(), ROUNDING_MODE_SORT)); - SASSERT(is_sort_of(m.get_sort(res), m_bv_util.get_family_id(), BV_SORT)); - } - } - else { - /* ignore; these are the conversion functions fp.to_* */ - } + m_th_rw(exp, s_exp); - TRACE("t_fpa_detail", tout << "converted term:" << std::endl; - tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << - mk_ismt2_pp(res, m) << std::endl;); + m_converter.mk_triple(s_sgn, s_sig, s_exp, res); + break; + } + default: + /* nothing */; + } + } + else + UNREACHABLE(); + + return res; + } + + expr_ref theory_fpa::convert_conversion_term(expr * e) { + /* This is for the conversion functions fp.to_* */ + ast_manager & m = get_manager(); + context & ctx = get_context(); + expr_ref res(m); + proof_ref pr(m); + + SASSERT(m_arith_util.is_real(e) || m_bv_util.is_bv(e)); + + m_rw(e, res); + m_th_rw(res, res); return res; } @@ -342,18 +310,18 @@ namespace smt { res = convert_atom(e); else if (m_float_util.is_float(e) || m_float_util.is_rm(e)) res = convert_term(e); - else if (m_arith_util.is_real(e)) - res = convert_term(e); + else if (m_arith_util.is_real(e) || m_bv_util.is_bv(e)) + res = convert_conversion_term(e); else UNREACHABLE(); - TRACE("t_fpa_detail", tout << "caching:" << std::endl; + TRACE("t_fpa_detail", tout << "converted; caching:" << std::endl; tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << mk_ismt2_pp(res, m) << std::endl;); m_conversions.insert(e, res); m.inc_ref(res); - m_trail_stack.push(fpa_conv_trail(m, m_conversions, e)); + m_trail_stack.push(fpa2bv_conversion_trail_elem(m, m_conversions, e)); } return res; @@ -381,9 +349,9 @@ namespace smt { return res; } - void theory_fpa::assert_cnstr(expr * e) { - TRACE("t_fpa_detail", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); + void theory_fpa::assert_cnstr(expr * e) { if (get_manager().is_true(e)) return; + TRACE("t_fpa_detail", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); context& ctx = get_context(); ctx.internalize(e, false); literal lit(ctx.get_literal(e)); @@ -395,11 +363,11 @@ namespace smt { context & ctx = get_context(); theory_var v = mk_var(n); ctx.attach_th_var(n, this, v); - TRACE("t_fpa", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), get_manager()) << " := " << v << "\n";); + TRACE("t_fpa_detail", tout << "new theory var: " << mk_ismt2_pp(n->get_owner(), get_manager()) << " := " << v << "\n";); } bool theory_fpa::internalize_atom(app * atom, bool gate_ctx) { - TRACE("t_fpa_detail", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); + TRACE("t_fpa", tout << "internalizing atom: " << mk_ismt2_pp(atom, get_manager()) << "\n";); SASSERT(atom->get_family_id() == get_family_id()); ast_manager & m = get_manager(); @@ -416,9 +384,8 @@ namespace smt { ctx.set_var_theory(l.var(), get_id()); expr_ref bv_atom(m); - bv_atom = convert(atom); - TRACE("t_fpa_detail", tout << "converted: " << mk_ismt2_pp(bv_atom, get_manager()) << "\n";); - SASSERT(bv_atom.get()->get_kind() == AST_APP); + bv_atom = convert(atom); + SASSERT(is_app(bv_atom) && m.is_bool(bv_atom)); bv_atom = m.mk_and(bv_atom, mk_side_conditions()); expr_ref atom_iff(m); @@ -429,8 +396,7 @@ namespace smt { bool theory_fpa::internalize_term(app * term) { ast_manager & m = get_manager(); context & ctx = get_context(); - - TRACE("t_fpa_detail", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); + TRACE("t_fpa", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); SASSERT(term->get_family_id() == get_family_id()); SASSERT(!ctx.e_internalized(term)); @@ -438,51 +404,90 @@ namespace smt { for (unsigned i = 0; i < num_args; i++) ctx.internalize(term->get_arg(i), false); - enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : + enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : ctx.mk_enode(term, false, false, true); if (is_attached_to_var(e)) return false; - attach_new_th_var(e); + attach_new_th_var(e); + + // The conversion operators fp.to_* appear in non-FP constraints. + // The corresponding constraints will not be translated and added + // via convert(...) and assert_cnstr(...) in initialize_atom(...). + // Therefore, we translate and assert them here. + float_op_kind k = (float_op_kind)term->get_decl_kind(); + switch (k) { + case OP_FLOAT_TO_UBV: + case OP_FLOAT_TO_SBV: + case OP_FLOAT_TO_REAL: { + expr_ref conv(m); + conv = convert(term); + assert_cnstr(m.mk_eq(term, conv)); + assert_cnstr(mk_side_conditions()); + break; + } + default: /* ignore */; + } + return true; } - void theory_fpa::apply_sort_cnstr(enode * n, sort * s) { - TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); + void theory_fpa::apply_sort_cnstr(enode * n, sort * s) { + TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); SASSERT(n->get_owner()->get_family_id() == get_family_id() || n->get_owner()->get_family_id() == null_theory_id); - SASSERT(s->get_family_id() == get_family_id()); - ast_manager & m = get_manager(); + SASSERT(s->get_family_id() == get_family_id()); if (!is_attached_to_var(n)) attach_new_th_var(n); - + + ast_manager & m = get_manager(); + context & ctx = get_context(); + app_ref owner(m); sort_ref owner_sort(m); owner = n->get_owner(); owner_sort = m.get_sort(owner); if (m_float_util.is_rm(owner_sort)) { + // For every RM term, we need to make sure that it's + // associated bit-vector is within the valid range. + // This also ensures that wrap(owner) is internalized. func_decl_ref wrap(m), unwrap(m); get_wrap(owner_sort, wrap, unwrap); if (owner->get_decl() != unwrap) { - expr_ref converted(m), t(m), limit(m); - converted = convert(owner); + expr_ref wrapped(m), valid(m), limit(m); + wrapped = m.mk_app(wrap, owner.get()); limit = m_bv_util.mk_numeral(4, 3); - t = m_bv_util.mk_ule(converted, limit); - assert_cnstr(t); + valid = m_bv_util.mk_ule(wrapped, limit); + assert_cnstr(valid); } } + else if (m_float_util.is_float(owner_sort)) { + // For every FP term, we need to make sure that + // its wrapped version is also internalized so that + // we can build a model for it later. + func_decl_ref wrap(m), unwrap(m); + get_wrap(owner_sort, wrap, unwrap); + if (owner->get_decl() != unwrap) { + expr_ref wrapped(m); + wrapped = m.mk_app(wrap, owner.get()); + if (!ctx.e_internalized(wrapped)) + ctx.internalize(wrapped, false); + } + } + else + UNREACHABLE(); } void theory_fpa::new_eq_eh(theory_var x, theory_var y) { ast_manager & m = get_manager(); - TRACE("t_fpa", tout << "new eq: " << x << " = " << y << std::endl; - tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " = " << - mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl; ); + TRACE("t_fpa", tout << "new eq: " << x << " = " << y << std::endl;); + TRACE("t_fpa_detail", tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " = " << + mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); context & ctx = get_context(); float_util & fu = m_float_util; @@ -492,7 +497,8 @@ namespace smt { app * xe = get_enode(x)->get_owner(); app * ye = get_enode(y)->get_owner(); - if (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye)) + if ((m.is_bool(xe) && m.is_bool(ye)) || + (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye))) { SASSERT(xe->get_decl()->get_family_id() == get_family_id()); return; @@ -503,9 +509,14 @@ namespace smt { yc = convert(ye); expr_ref c(m); - + if (fu.is_float(xe) && fu.is_float(ye)) { + func_decl_ref wrap(m), unwrap(m); + get_wrap(m.get_sort(ye), wrap, unwrap); + if (ye->get_decl() == unwrap) + return; + expr *x_sgn, *x_sig, *x_exp; m_converter.split_triple(xc, x_sgn, x_sig, x_exp); expr *y_sgn, *y_sig, *y_exp; @@ -518,8 +529,7 @@ namespace smt { else c = m.mk_eq(xc, yc); - // assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); - assert_cnstr(c); + assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); assert_cnstr(mk_side_conditions()); return; @@ -528,9 +538,9 @@ namespace smt { void theory_fpa::new_diseq_eh(theory_var x, theory_var y) { ast_manager & m = get_manager(); - TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << std::endl; - tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " != " << - mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); + TRACE("t_fpa", tout << "new diseq: " << x << " != " << y << std::endl;); + TRACE("t_fpa_detail", tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " != " << + mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); context & ctx = get_context(); mpf_manager & mpfm = m_float_util.fm(); @@ -538,8 +548,8 @@ namespace smt { app * xe = get_enode(x)->get_owner(); app * ye = get_enode(y)->get_owner(); - if (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye)) - { + if ((m.is_bool(xe) && m.is_bool(ye)) || + (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye))) { SASSERT(xe->get_decl()->get_family_id() == get_family_id()); return; } @@ -559,13 +569,12 @@ namespace smt { c = m.mk_or(m.mk_not(m.mk_eq(x_sgn, y_sgn)), m.mk_not(m.mk_eq(x_sig, y_sig)), - m.mk_not(m.mk_eq(x_exp, y_exp))); + m.mk_not(m.mk_eq(x_exp, y_exp))); } else c = m.mk_not(m.mk_eq(xc, yc)); - // assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); - assert_cnstr(c); + assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); assert_cnstr(mk_side_conditions()); return; @@ -591,8 +600,7 @@ namespace smt { TRACE("t_fpa", tout << "assign_eh for: " << v << " (" << is_true << "):\n" << mk_ismt2_pp(e, m) << "\n";); expr_ref converted(m); - converted = convert(e); - converted = m.mk_and(converted, mk_side_conditions()); + converted = m.mk_and(convert(e), mk_side_conditions()); if (!is_true) converted = m.mk_not(converted); assert_cnstr(converted); } @@ -615,8 +623,7 @@ namespace smt { mpf_rounding_mode rm; scoped_mpf val(mpfm); if (m_float_util.is_rm_value(n, rm)) { - c = m.mk_eq(wrapped, m_bv_util.mk_numeral(rm, 3)); - c = m.mk_and(c, mk_side_conditions()); + c = m.mk_eq(wrapped, m_bv_util.mk_numeral(rm, 3)); assert_cnstr(c); } else if (m_float_util.is_value(n, val)) { @@ -626,22 +633,26 @@ namespace smt { SASSERT(is_app(bv_val_e)); SASSERT(to_app(bv_val_e)->get_num_args() == 3); app_ref bv_val_a(to_app(bv_val_e.get()), m); - c = m.mk_eq(wrapped, m_bv_util.mk_concat( - m_bv_util.mk_concat(bv_val_a->get_arg(0), bv_val_a->get_arg(1)), - bv_val_a->get_arg(2))); + c = m.mk_eq(wrapped, m_bv_util.mk_concat( m_bv_util.mk_concat( + bv_val_a->get_arg(0), + bv_val_a->get_arg(1)), + bv_val_a->get_arg(2))); c = m.mk_and(c, mk_side_conditions()); assert_cnstr(c); } else { c = m.mk_eq(m.mk_app(unwrap, wrapped), n); - c = m.mk_and(c, mk_side_conditions()); assert_cnstr(c); } } } - else { + else if (n->get_family_id() == get_family_id()) { + SASSERT(!m_float_util.is_float(n) && !m_float_util.is_rm(n)); // These are the conversion functions fp.to_* */ } + else + UNREACHABLE(); + } void theory_fpa::reset_eh() { @@ -659,26 +670,15 @@ namespace smt { theory::reset_eh(); } - void theory_fpa::init_model(model_generator & mg) { - TRACE("t_fpa", tout << "initializing model" << std::endl;); - m_factory = alloc(fpa_factory, get_manager(), get_family_id()); - mg.register_factory(m_factory); - TRACE("t_fpa", display(tout);); + final_check_status theory_fpa::final_check_eh() { + TRACE("t_fpa", tout << "final_check_eh\n";); + return FC_DONE; } - void theory_fpa::add_value_dep(fpa_value_proc * vp, expr * e) { - SASSERT(m_bv_util.is_bv(e)); - ast_manager & m = get_manager(); - context & ctx = get_context(); - if (ctx.e_internalized(e)) - vp->add_dependency(ctx.get_enode(e)); - else { - expr_ref n(m); - n = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(e)); - if (!ctx.e_internalized(n)) - ctx.internalize(n, false); - vp->add_dependency(ctx.get_enode(n)); - } + void theory_fpa::init_model(model_generator & mg) { + TRACE("t_fpa", tout << "initializing model" << std::endl; display(tout);); + m_factory = alloc(fpa_factory, get_manager(), get_family_id()); + mg.register_factory(m_factory); } model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { @@ -688,26 +688,36 @@ namespace smt { context & ctx = get_context(); app * owner = n->get_owner(); - app_ref c_a(m); - c_a = to_app(convert(owner)); + // If the owner is not internalized, it doesn't have an enode associated. SASSERT(ctx.e_internalized(owner)); - - TRACE("t_fpa", tout << "converted = " << mk_ismt2_pp(c_a, get_manager()) << "\n";); - + + if (m_float_util.is_rm_value(owner) || + m_float_util.is_value(owner)) + return alloc(expr_wrapper_proc, owner); + model_value_proc * res = 0; + func_decl_ref wrap(m), unwrap(m); + get_wrap(m.get_sort(owner), wrap, unwrap); + app_ref wrapped(m); + wrapped = m.mk_app(wrap, owner); + + CTRACE("t_fpa", !ctx.e_internalized(wrapped), + tout << "Model dependency not internalized: " << + mk_ismt2_pp(wrapped, m) << + " (owner " << (!ctx.e_internalized(owner) ? "not" : "is") << + " internalized)" << std::endl;); + if (m_float_util.is_rm(owner)) { - fpa_rm_value_proc * vp = alloc(fpa_rm_value_proc, this); - add_value_dep(vp, c_a); - res = vp; + fpa_rm_value_proc * vp = alloc(fpa_rm_value_proc, this); + vp->add_dependency(ctx.get_enode(wrapped)); + res = vp; } else if (m_float_util.is_float(owner)) { - fpa_value_proc * vp = alloc(fpa_value_proc, this); - expr_ref bv_sgn(m), bv_sig(m), bv_exp(m); - m_converter.split_triple(c_a, bv_sgn, bv_sig, bv_exp); - add_value_dep(vp, bv_sgn); - add_value_dep(vp, bv_sig); - add_value_dep(vp, bv_exp); + unsigned ebits = m_float_util.get_ebits(m.get_sort(owner)); + unsigned sbits = m_float_util.get_sbits(m.get_sort(owner)); + fpa_value_proc * vp = alloc(fpa_value_proc, this, ebits, sbits); + vp->add_dependency(ctx.get_enode(wrapped)); res = vp; } else diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index bd2ea29f8..c21096ec0 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -29,9 +29,49 @@ Revision History: namespace smt { - class fpa_factory; + class fpa_factory : public value_factory { + float_util m_util; + + virtual app * mk_value_core(mpf const & val, sort * s) { + SASSERT(m_util.get_ebits(s) == val.get_ebits()); + SASSERT(m_util.get_sbits(s) == val.get_sbits()); + return m_util.mk_value(val); + } + + public: + fpa_factory(ast_manager & m, family_id fid) : + value_factory(m, fid), + m_util(m) {} + + virtual ~fpa_factory() {} + + virtual expr * get_some_value(sort * s) { + mpf_manager & mpfm = m_util.fm(); + scoped_mpf q(mpfm); + mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 0); + return m_util.mk_value(q); + } + + virtual bool get_some_values(sort * s, expr_ref & v1, expr_ref & v2) { + mpf_manager & mpfm = m_util.fm(); + scoped_mpf q(mpfm); + mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 0); + v1 = m_util.mk_value(q); + mpfm.set(q, m_util.get_ebits(s), m_util.get_sbits(s), 1); + v2 = m_util.mk_value(q); + return true; + } + + virtual expr * get_fresh_value(sort * s) { NOT_IMPLEMENTED_YET(); } + virtual void register_value(expr * n) { /* Ignore */ } + + app * mk_value(mpf const & x) { + return m_util.mk_value(x); + } + }; class theory_fpa : public theory { + protected: typedef trail_stack th_trail_stack; class fpa2bv_converter_wrapped : public fpa2bv_converter { @@ -46,27 +86,48 @@ namespace smt { }; class fpa_value_proc : public model_value_proc { - protected: - theory_fpa & m_th; + protected: + theory_fpa & m_th; + ast_manager & m; float_util & m_fu; bv_util & m_bu; - svector m_dependencies; + buffer m_deps; + unsigned m_ebits; + unsigned m_sbits; + public: - fpa_value_proc(theory_fpa * th) : - m_th(*th),m_fu(th->m_float_util),m_bu(th->m_bv_util) {} - void add_dependency(enode * n) { m_dependencies.push_back(model_value_dependency(n)); } + fpa_value_proc(theory_fpa * th, unsigned ebits, unsigned sbits) : + m_th(*th), m_fu(th->m_float_util), m_bu(th->m_bv_util), m(th->get_manager()), + m_ebits(ebits), m_sbits(sbits) {} + virtual ~fpa_value_proc() {} + + void add_dependency(enode * e) { m_deps.push_back(model_value_dependency(e)); } + virtual void get_dependencies(buffer & result) { - result.append(m_dependencies.size(), m_dependencies.c_ptr()); + result.append(m_deps); } + virtual app * mk_value(model_generator & mg, ptr_vector & values); }; - class fpa_rm_value_proc : public fpa_value_proc { + class fpa_rm_value_proc : public model_value_proc { + theory_fpa & m_th; + ast_manager & m; + float_util & m_fu; + bv_util & m_bu; + buffer m_deps; + public: fpa_rm_value_proc(theory_fpa * th) : - fpa_value_proc(th) {} - void add_dependency(enode * n) { fpa_value_proc::add_dependency(n); } + m_th(*th), m_fu(th->m_float_util), m_bu(th->m_bv_util), m(th->get_manager()) {} + + void add_dependency(enode * e) { m_deps.push_back(model_value_dependency(e)); } + + virtual void get_dependencies(buffer & result) { + result.append(m_deps); + } + virtual ~fpa_rm_value_proc() {} virtual app * mk_value(model_generator & mg, ptr_vector & values); }; @@ -84,7 +145,7 @@ namespace smt { obj_map m_unwraps; obj_map m_conversions; - virtual final_check_status final_check_eh() { return FC_DONE; } + virtual final_check_status final_check_eh(); virtual bool internalize_atom(app * atom, bool gate_ctx); virtual bool internalize_term(app * term); virtual void apply_sort_cnstr(enode * n, sort * s); @@ -114,13 +175,12 @@ namespace smt { expr_ref convert(expr * e); expr_ref convert_atom(expr * e); expr_ref convert_term(expr * e); + expr_ref convert_conversion_term(expr * e); void get_wrap(sort * s, func_decl_ref & wrap, func_decl_ref & unwrap); void add_trail(ast * a); - void mk_bv_eq(expr * x, expr * y); void attach_new_th_var(enode * n); - void assert_cnstr(expr * e); - void add_value_dep(fpa_value_proc * vp, expr * e); + void assert_cnstr(expr * e); }; }; From 4f453703f7baf85a16a822a48edc7c6cb95d5a64 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 15:23:02 +0000 Subject: [PATCH 103/507] Added arguments of type float to the replayer. Signed-off-by: Christoph M. Wintersteiger --- src/api/z3_replayer.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- src/api/z3_replayer.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/api/z3_replayer.cpp b/src/api/z3_replayer.cpp index acdb10bf6..676ba0c69 100644 --- a/src/api/z3_replayer.cpp +++ b/src/api/z3_replayer.cpp @@ -40,11 +40,12 @@ struct z3_replayer::imp { __int64 m_int64; __uint64 m_uint64; double m_double; + float m_float; size_t m_ptr; size_t_map m_heap; svector m_cmds; - enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY }; + enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY, FLOAT }; struct value { value_kind m_kind; @@ -54,6 +55,7 @@ struct z3_replayer::imp { double m_double; char const * m_str; void * m_obj; + float m_float; }; value():m_kind(OBJECT), m_int(0) {} value(void * obj):m_kind(OBJECT), m_obj(obj) {} @@ -61,6 +63,7 @@ struct z3_replayer::imp { value(value_kind k, __uint64 u):m_kind(k), m_uint(u) {} value(value_kind k, __int64 i):m_kind(k), m_int(i) {} value(value_kind k, double d):m_kind(k), m_double(d) {} + value(value_kind k, float f):m_kind(k), m_float(f) {} }; svector m_args; @@ -85,9 +88,12 @@ struct z3_replayer::imp { case UINT64: out << v.m_uint; break; + case FLOAT: + out << v.m_float; + break; case DOUBLE: out << v.m_double; - break; + break; case STRING: out << v.m_str; break; @@ -219,6 +225,19 @@ struct z3_replayer::imp { return curr() == '-' || curr() == '.' || ('0' <= curr() && curr() <= '9') || curr() == 'e' || curr() == 'E'; } + void read_float() { + m_string.reset(); + while (is_double_char()) { + m_string.push_back(curr()); + next(); + } + if (m_string.empty()) + throw z3_replayer_exception("invalid float"); + m_string.push_back(0); + char * ptr; + m_float = strtof(m_string.begin(), &ptr); + } + void read_double() { m_string.reset(); while (is_double_char()) { @@ -407,12 +426,18 @@ struct z3_replayer::imp { TRACE("z3_replayer", tout << "[" << m_line << "] " << "U " << m_uint64 << "\n";); m_args.push_back(value(UINT64, m_uint64)); break; + case 'F': + // push float + next(); skip_blank(); read_float(); + TRACE("z3_replayer", tout << "[" << m_line << "] " << "F " << m_float << "\n";); + m_args.push_back(value(FLOAT, m_float)); + break; case 'D': // push double next(); skip_blank(); read_double(); TRACE("z3_replayer", tout << "[" << m_line << "] " << "D " << m_double << "\n";); m_args.push_back(value(DOUBLE, m_double)); - break; + break; case 'p': case 's': case 'u': @@ -516,6 +541,12 @@ struct z3_replayer::imp { return m_args[pos].m_uint; } + float get_float(unsigned pos) const { + if (pos >= m_args.size() || m_args[pos].m_kind != FLOAT) + throw_invalid_reference(); + return m_args[pos].m_float; + } + double get_double(unsigned pos) const { if (pos >= m_args.size() || m_args[pos].m_kind != DOUBLE) throw_invalid_reference(); @@ -653,6 +684,10 @@ __uint64 z3_replayer::get_uint64(unsigned pos) const { return m_imp->get_uint64(pos); } +float z3_replayer::get_float(unsigned pos) const { + return m_imp->get_float(pos); +} + double z3_replayer::get_double(unsigned pos) const { return m_imp->get_double(pos); } diff --git a/src/api/z3_replayer.h b/src/api/z3_replayer.h index 6de4bdb39..6320068ad 100644 --- a/src/api/z3_replayer.h +++ b/src/api/z3_replayer.h @@ -42,6 +42,7 @@ public: unsigned get_uint(unsigned pos) const; __int64 get_int64(unsigned pos) const; __uint64 get_uint64(unsigned pos) const; + float get_float(unsigned pos) const; double get_double(unsigned pos) const; bool get_bool(unsigned pos) const; Z3_string get_str(unsigned pos) const; From 97df505dbaed0e9c51cd756b5d84620e91ba2bb3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 15:23:27 +0000 Subject: [PATCH 104/507] MPF consistency fix Signed-off-by: Christoph M. Wintersteiger --- src/util/mpf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 245120866..cc4b3a35a 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -336,7 +336,7 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode TRACE("mpf_dbg", tout << "set: res = " << to_string(o) << std::endl;); } -void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, bool sign, uint64 significand, int exponent) { +void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, bool sign, uint64 significand, mpf_exp_t exponent) { // Assumption: this represents (sign * -1) * (significand/2^sbits) * 2^exponent. o.ebits = ebits; o.sbits = sbits; From a28454d95e314d17beb4ca21c2eb51b3ed726ecb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 15:24:36 +0000 Subject: [PATCH 105/507] FPA: sort names consistency fix Signed-off-by: Christoph M. Wintersteiger --- src/ast/ast_smt2_pp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index a9e223c55..982b80d37 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -396,7 +396,7 @@ format_ns::format * smt2_pp_environment::pp_sort(sort * s) { unsigned ebits = get_futil().get_ebits(s); unsigned sbits = get_futil().get_sbits(s); ptr_buffer fs; - fs.push_back(mk_string(m, "FP")); + fs.push_back(mk_string(m, "FloatingPoint")); fs.push_back(mk_unsigned(m, ebits)); fs.push_back(mk_unsigned(m, sbits)); return mk_seq1(m, fs.begin(), fs.end(), f2f(), "_"); From 09247d2e29563d2f2a5926c85816ac1c2fb69187 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 18:44:41 +0000 Subject: [PATCH 106/507] FPA theory and API overhaul Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 14 +- src/api/api_fpa.cpp | 354 +++++++++++++++++--- src/api/dotnet/Context.cs | 14 +- src/api/z3_api.h | 3 +- src/api/z3_fpa.h | 641 ++++++++++++++++++++++++++---------- src/ast/float_decl_plugin.h | 39 ++- src/smt/theory_fpa.cpp | 200 ++++++----- src/smt/theory_fpa.h | 8 +- src/util/mpf.h | 2 +- 9 files changed, 944 insertions(+), 331 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 2fbf42cca..a47835904 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -124,6 +124,7 @@ SYMBOL = 9 PRINT_MODE = 10 ERROR_CODE = 11 DOUBLE = 12 +FLOAT = 13 FIRST_OBJ_ID = 100 @@ -131,28 +132,28 @@ def is_obj(ty): return ty >= FIRST_OBJ_ID Type2Str = { VOID : 'void', VOID_PTR : 'void*', INT : 'int', UINT : 'unsigned', INT64 : '__int64', UINT64 : '__uint64', DOUBLE : 'double', - STRING : 'Z3_string', STRING_PTR : 'Z3_string_ptr', BOOL : 'Z3_bool', SYMBOL : 'Z3_symbol', + FLOAT : 'float', STRING : 'Z3_string', STRING_PTR : 'Z3_string_ptr', BOOL : 'Z3_bool', SYMBOL : 'Z3_symbol', PRINT_MODE : 'Z3_ast_print_mode', ERROR_CODE : 'Z3_error_code' } Type2PyStr = { VOID_PTR : 'ctypes.c_void_p', INT : 'ctypes.c_int', UINT : 'ctypes.c_uint', INT64 : 'ctypes.c_longlong', - UINT64 : 'ctypes.c_ulonglong', DOUBLE : 'ctypes.c_double', + UINT64 : 'ctypes.c_ulonglong', DOUBLE : 'ctypes.c_double', FLOAT : 'ctypes.c_float', STRING : 'ctypes.c_char_p', STRING_PTR : 'ctypes.POINTER(ctypes.c_char_p)', BOOL : 'ctypes.c_bool', SYMBOL : 'Symbol', PRINT_MODE : 'ctypes.c_uint', ERROR_CODE : 'ctypes.c_uint' } # Mapping to .NET types Type2Dotnet = { VOID : 'void', VOID_PTR : 'IntPtr', INT : 'int', UINT : 'uint', INT64 : 'Int64', UINT64 : 'UInt64', DOUBLE : 'double', - STRING : 'string', STRING_PTR : 'byte**', BOOL : 'int', SYMBOL : 'IntPtr', + FLOAT : 'float', STRING : 'string', STRING_PTR : 'byte**', BOOL : 'int', SYMBOL : 'IntPtr', PRINT_MODE : 'uint', ERROR_CODE : 'uint' } # Mapping to Java types Type2Java = { VOID : 'void', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', - STRING : 'String', STRING_PTR : 'StringPtr', + FLOAT : 'float', STRING : 'String', STRING_PTR : 'StringPtr', BOOL : 'boolean', SYMBOL : 'long', PRINT_MODE : 'int', ERROR_CODE : 'int'} Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', INT64 : 'jlong', UINT64 : 'jlong', DOUBLE : 'jdouble', - STRING : 'jstring', STRING_PTR : 'jobject', + FLOAT : 'jfloat', STRING : 'jstring', STRING_PTR : 'jobject', BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint'} @@ -927,6 +928,9 @@ def def_API(name, result, params): elif ty == DOUBLE: log_c.write(" D(a%s);\n" % i) exe_c.write("in.get_double(%s)" % i) + elif ty == FLOAT: + log_c.write(" D(a%s);\n" % i) + exe_c.write("in.get_float(%s)" % i) elif ty == BOOL: log_c.write(" I(a%s);\n" % i) exe_c.write("in.get_bool(%s)" % i) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index bbf27d25d..89b278c91 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -7,6 +7,7 @@ Module Name: Abstract: + Additional APIs for floating-point arithmetic (FP). Author: @@ -31,7 +32,7 @@ extern "C" { Z3_sort r = of_sort(ctx->float_util().mk_rm_sort()); RETURN_Z3(r); Z3_CATCH_RETURN(0); - } + } Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(Z3_context c) { @@ -44,10 +45,20 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_rne(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_fpa_rne(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_even()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(Z3_context c) { Z3_TRY; - LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + LOG_Z3_mk_fpa_round_nearest_ties_to_away(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_away()); @@ -55,10 +66,20 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_rna(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_fpa_rna(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_away()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(Z3_context c) { Z3_TRY; - LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + LOG_Z3_mk_fpa_round_toward_positive(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_round_toward_positive()); @@ -66,10 +87,20 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_rtp(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_fpa_rtp(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_round_toward_positive()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(Z3_context c) { Z3_TRY; - LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + LOG_Z3_mk_fpa_round_toward_negative(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_round_toward_negative()); @@ -77,10 +108,20 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_rtn(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_fpa_rtn(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_round_toward_negative()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(Z3_context c) { Z3_TRY; - LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); + LOG_Z3_mk_fpa_round_toward_zero(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_round_toward_zero()); @@ -88,6 +129,16 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_rtz(Z3_context c) { + Z3_TRY; + LOG_Z3_mk_fpa_rtz(c); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_round_toward_zero()); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_sort Z3_API Z3_mk_fpa_sort(Z3_context c, unsigned ebits, unsigned sbits) { Z3_TRY; @@ -102,35 +153,35 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_sort Z3_API Z3_mk_fpa_sort_half(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_half(Z3_context c) { return Z3_mk_fpa_sort(c, 5, 11); } - Z3_sort Z3_API Z3_mk_fpa_sort_16(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_16(Z3_context c) { return Z3_mk_fpa_sort(c, 5, 11); } - Z3_sort Z3_API Z3_mk_fpa_sort_single(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_single(Z3_context c) { return Z3_mk_fpa_sort(c, 8, 24); } - Z3_sort Z3_API Z3_mk_fpa_sort_32(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_32(Z3_context c) { return Z3_mk_fpa_sort(c, 8, 24); } - Z3_sort Z3_API Z3_mk_fpa_sort_double(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_double(Z3_context c) { return Z3_mk_fpa_sort(c, 11, 53); } - Z3_sort Z3_API Z3_mk_fpa_sort_64(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_64(Z3_context c) { return Z3_mk_fpa_sort(c, 11, 53); } - Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(Z3_context c) { return Z3_mk_fpa_sort(c, 15, 113); } - Z3_sort Z3_API Z3_mk_fpa_sort_128(__in Z3_context c) { + Z3_sort Z3_API Z3_mk_fpa_sort_128(Z3_context c) { return Z3_mk_fpa_sort(c, 15, 113); } @@ -164,6 +215,28 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_fp(Z3_context c, Z3_ast sgn, Z3_ast sig, Z3_ast exp) { + Z3_TRY; + LOG_Z3_mk_fpa_fp(c, sgn, sig, exp); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_numeral_float(Z3_context c, float v, Z3_sort ty) { + Z3_TRY; + LOG_Z3_mk_fpa_numeral_float(c, v, ty); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + scoped_mpf tmp(ctx->float_util().fm()); + ctx->float_util().fm().set(tmp, ctx->float_util().get_ebits(to_sort(ty)), ctx->float_util().get_sbits(to_sort(ty)), v); + Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_numeral_double(Z3_context c, double v, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_fpa_numeral_double(c, v, ty); @@ -175,6 +248,51 @@ extern "C" { RETURN_Z3(r); Z3_CATCH_RETURN(0); } + + Z3_ast Z3_API Z3_mk_fpa_numeral_int(Z3_context c, signed v, Z3_sort ty) { + Z3_TRY; + LOG_Z3_mk_fpa_numeral_int(c, v, ty); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + scoped_mpf tmp(ctx->float_util().fm()); + ctx->float_util().fm().set(tmp, + ctx->float_util().get_ebits(to_sort(ty)), + ctx->float_util().get_sbits(to_sort(ty)), + v); + Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(Z3_context c, bool sgn, unsigned sig, signed exp, Z3_sort ty) { + Z3_TRY; + LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + scoped_mpf tmp(ctx->float_util().fm()); + ctx->float_util().fm().set(tmp, + ctx->float_util().get_ebits(to_sort(ty)), + ctx->float_util().get_sbits(to_sort(ty)), + sgn, sig, exp); + Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(Z3_context c, bool sgn, __uint64 sig, __int64 exp, Z3_sort ty) { + Z3_TRY; + LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + scoped_mpf tmp(ctx->float_util().fm()); + ctx->float_util().fm().set(tmp, + ctx->float_util().get_ebits(to_sort(ty)), + ctx->float_util().get_sbits(to_sort(ty)), + sgn, sig, exp); + Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } Z3_ast Z3_API Z3_mk_fpa_abs(Z3_context c, Z3_ast t) { Z3_TRY; @@ -265,20 +383,40 @@ extern "C" { RETURN_Z3(r); Z3_CATCH_RETURN(0); } - - Z3_ast Z3_API Z3_mk_fpa_eq(Z3_context c, Z3_ast t1, Z3_ast t2) { + + Z3_ast Z3_API Z3_mk_fpa_round_to_integral(Z3_context c, Z3_ast rm, Z3_ast t) { Z3_TRY; - LOG_Z3_mk_fpa_eq(c, t1, t2); + LOG_Z3_mk_fpa_round_to_integral(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_float_eq(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_round_to_integral(to_expr(rm), to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_min(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_min(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_min(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_max(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_max(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_max(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_le(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_ast Z3_API Z3_mk_fpa_leq(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; - LOG_Z3_mk_fpa_le(c, t1, t2); + LOG_Z3_mk_fpa_leq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_le(to_expr(t1), to_expr(t2))); @@ -296,9 +434,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_ge(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_ast Z3_API Z3_mk_fpa_geq(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; - LOG_Z3_mk_fpa_ge(c, t1, t2); + LOG_Z3_mk_fpa_geq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_ge(to_expr(t1), to_expr(t2))); @@ -315,6 +453,16 @@ extern "C" { RETURN_Z3(r); Z3_CATCH_RETURN(0); } + + Z3_ast Z3_API Z3_mk_fpa_eq(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_TRY; + LOG_Z3_mk_fpa_eq(c, t1, t2); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_float_eq(to_expr(t1), to_expr(t2))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } Z3_ast Z3_API Z3_mk_fpa_is_normal(Z3_context c, Z3_ast t) { Z3_TRY; @@ -346,9 +494,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_is_inf(Z3_context c, Z3_ast t) { + Z3_ast Z3_API Z3_mk_fpa_is_infinite(Z3_context c, Z3_ast t) { Z3_TRY; - LOG_Z3_mk_fpa_is_inf(c, t); + LOG_Z3_mk_fpa_is_infinite(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); Z3_ast r = of_ast(ctx->float_util().mk_is_inf(to_expr(t))); @@ -366,40 +514,142 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_min(Z3_context c, Z3_ast t1, Z3_ast t2) { + Z3_ast Z3_API Z3_mk_fpa_is_negative(Z3_context c, Z3_ast t) { Z3_TRY; - LOG_Z3_mk_fpa_min(c, t1, t2); + LOG_Z3_mk_fpa_is_negative(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_min(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); - Z3_CATCH_RETURN(0); - } - - Z3_ast Z3_API Z3_mk_fpa_max(Z3_context c, Z3_ast t1, Z3_ast t2) { - Z3_TRY; - LOG_Z3_mk_fpa_max(c, t1, t2); - RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_max(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->float_util().mk_is_negative(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_convert(Z3_context c, Z3_sort s, Z3_ast rm, Z3_ast t) { + Z3_ast Z3_API Z3_mk_fpa_is_positive(Z3_context c, Z3_ast t) { Z3_TRY; - LOG_Z3_mk_fpa_convert(c, s, rm, t); + LOG_Z3_mk_fpa_is_positive(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - expr * args [2] = { to_expr(rm), to_expr(t) }; - Z3_ast r = of_ast(ctx->m().mk_app(ctx->float_util().get_family_id(), OP_FLOAT_TO_FP, - to_sort(s)->get_num_parameters(), to_sort(s)->get_parameters(), - 2, args)); + Z3_ast r = of_ast(ctx->float_util().mk_is_positive(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t) { + + Z3_ast Z3_API Z3_mk_fpa_to_fp_bv(Z3_context c, Z3_ast bv, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_to_fp_bv(c, bv, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util & fu = ctx->float_util(); + if (!ctx->bvutil().is_bv(to_expr(bv)) || + !fu.is_float(to_sort(s))) { + SET_ERROR_CODE(Z3_INVALID_ARG); + return 0; + } + Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(bv))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_fp_float(Z3_context c, Z3_ast rm, Z3_ast t, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_to_fp_float(c, rm, t, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util & fu = ctx->float_util(); + 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); + return 0; + } + Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_fp_real(Z3_context c, Z3_ast rm, Z3_ast t, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_to_fp_real(c, rm, t, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util & fu = ctx->float_util(); + 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); + return 0; + } + Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_fp_signed(Z3_context c, Z3_ast rm, Z3_ast t, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_to_fp_signed(c, rm, t, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util & fu = ctx->float_util(); + 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); + return 0; + } + Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_fp_unsigned(Z3_context c, Z3_ast rm, Z3_ast t, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_to_fp_unsigned(c, rm, t, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util & fu = ctx->float_util(); + 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); + return 0; + } + Z3_ast r = of_ast(fu.mk_to_fp_unsigned(to_sort(s), to_expr(rm), to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_ubv(Z3_context c, Z3_ast rm, Z3_ast t, unsigned sz) { + Z3_TRY; + LOG_Z3_mk_fpa_to_ubv(c, rm, t, sz); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_to_ubv(to_expr(rm), to_expr(t), sz)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_sbv(Z3_context c, Z3_ast rm, Z3_ast t, unsigned sz) { + Z3_TRY; + LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_to_sbv(to_expr(rm), to_expr(t), sz)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_real(Z3_context c, Z3_ast t) { + Z3_TRY; + LOG_Z3_mk_fpa_to_real(c, t); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + Z3_ast r = of_ast(ctx->float_util().mk_to_real(to_expr(t))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_to_ieee_bv(c, t); RESET_ERROR_CODE(); @@ -409,4 +659,22 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_ast Z3_API Z3_mk_fpa_to_fp_real_int(Z3_context c, Z3_ast rm, Z3_ast sig, Z3_ast exp, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_to_fp_real_int(c, rm, sig, exp, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + float_util & fu = ctx->float_util(); + if (!fu.is_rm(to_expr(rm)) || + !ctx->autil().is_real(to_expr(sig)) || + !ctx->autil().is_int(to_expr(exp)) || + !fu.is_float(to_sort(s))) { + SET_ERROR_CODE(Z3_INVALID_ARG); + return 0; + } + Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(sig), to_expr(exp))); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + }; diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 87090dcc9..69855fc4f 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3661,10 +3661,10 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - public BoolExpr MkFPLe(FPExpr t1, FPExpr t2) + public BoolExpr MkFPLEq(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); - return new BoolExpr(this, Native.Z3_mk_fpa_le(this.nCtx, t1.NativeObject, t2.NativeObject)); + return new BoolExpr(this, Native.Z3_mk_fpa_leq(this.nCtx, t1.NativeObject, t2.NativeObject)); } /// @@ -3683,10 +3683,10 @@ namespace Microsoft.Z3 /// /// floating point term /// floating point term - public BoolExpr MkFPGe(FPExpr t1, FPExpr t2) + public BoolExpr MkFPGEq(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); - return new BoolExpr(this, Native.Z3_mk_fpa_ge(this.nCtx, t1.NativeObject, t2.NativeObject)); + return new BoolExpr(this, Native.Z3_mk_fpa_geq(this.nCtx, t1.NativeObject, t2.NativeObject)); } /// @@ -3737,7 +3737,7 @@ namespace Microsoft.Z3 public BoolExpr MkFPIsInf(FPExpr t) { Contract.Ensures(Contract.Result() != null); - return new BoolExpr(this, Native.Z3_mk_fpa_is_inf(this.nCtx, t.NativeObject)); + return new BoolExpr(this, Native.Z3_mk_fpa_is_infinite(this.nCtx, t.NativeObject)); } /// @@ -3782,10 +3782,10 @@ namespace Microsoft.Z3 /// floating point sort /// floating point rounding mode term /// floating point term - public FPExpr MkFPConvert(FPSort s, FPRMExpr rm, FPExpr t) + public FPExpr MkFPToFP(FPSort s, FPRMExpr rm, FPExpr t) { Contract.Ensures(Contract.Result() != null); - return new FPExpr(this, Native.Z3_mk_fpa_convert(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); + return new FPExpr(this, Native.Z3_mk_fpa_to_fp_float(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); } #endregion diff --git a/src/api/z3_api.h b/src/api/z3_api.h index e4bb4bd1d..776e4e9fe 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -1700,8 +1700,7 @@ extern "C" { /** \brief Create the real type. - This type is not a floating point number. - Z3 does not have support for floating point numbers yet. + Note that this type is not a floating point number. def_API('Z3_mk_real_sort', SORT, (_in(CONTEXT), )) */ diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 50ad49590..48d3e790d 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -7,7 +7,7 @@ Module Name: Abstract: - Additional APIs for floating-point arithmetic (FPA). + Additional APIs for floating-point arithmetic (FP). Author: @@ -36,7 +36,7 @@ extern "C" { /*@{*/ /** - \brief Create a rounding mode sort. + \brief Create the RoundingMode sort. \param c logical context. @@ -45,7 +45,7 @@ extern "C" { Z3_sort Z3_API Z3_mk_fpa_rounding_mode_sort(__in Z3_context c); /** - \brief Create a numeral of rounding mode sort which represents the NearestTiesToEven rounding mode. + \brief Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. \param c logical context. @@ -54,7 +54,16 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(__in Z3_context c); /** - \brief Create a numeral of rounding mode sort which represents the NearestTiesToAway rounding mode. + \brief Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. + + \param c logical context. + + def_API('Z3_mk_fpa_rne', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_rne(__in Z3_context c); + + /** + \brief Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. \param c logical context. @@ -63,25 +72,52 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(__in Z3_context c); /** - \brief Create a numeral of rounding mode sort which represents the TowardPositive rounding mode. + \brief Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. + + \param c logical context. + + def_API('Z3_mk_fpa_rna', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_rna(__in Z3_context c); + + /** + \brief Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. \param c logical context. def_API('Z3_mk_fpa_round_toward_positive', AST, (_in(CONTEXT),)) */ - Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(__in Z3_context c); + Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(__in Z3_context c); /** - \brief Create a numeral of rounding mode sort which represents the TowardNegative rounding mode. + \brief Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. + + \param c logical context. + + def_API('Z3_mk_fpa_rtp', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_rtp(__in Z3_context c); + + /** + \brief Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. \param c logical context. def_API('Z3_mk_fpa_round_toward_negative', AST, (_in(CONTEXT),)) */ - Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(__in Z3_context c); + Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(__in Z3_context c); /** - \brief Create a numeral of rounding mode sort which represents the TowardZero rounding mode. + \brief Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. + + \param c logical context. + + def_API('Z3_mk_fpa_rtn', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_rtn(__in Z3_context c); + + /** + \brief Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. \param c logical context. @@ -89,14 +125,21 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(__in Z3_context c); - - /** - \brief Create a floating point sort. + \brief Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits + + def_API('Z3_mk_fpa_rtz', AST, (_in(CONTEXT),)) + */ + Z3_ast Z3_API Z3_mk_fpa_rtz(__in Z3_context c); + + /** + \brief Create a FloatingPoint sort. + + \param c logical context. + \param ebits number of exponent bits. + \param sbits number of significand bits. \remark ebits must be larger than 1 and sbits must be larger than 2. @@ -105,85 +148,61 @@ extern "C" { Z3_sort Z3_API Z3_mk_fpa_sort(__in Z3_context c, __in unsigned ebits, __in unsigned sbits); /** - \brief Create the half-precision (16-bit) floating point sort. + \brief Create the half-precision (16-bit) FloatingPoint sort. \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits - - \remark ebits must be larger than 1 and sbits must be larger than 2. def_API('Z3_mk_fpa_sort_half', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_half(__in Z3_context c); /** - \brief Create the half-precision (16-bit) floating point sort. + \brief Create the half-precision (16-bit) FloatingPoint sort. - \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits + \param c logical context. - \remark ebits must be larger than 1 and sbits must be larger than 2. - - def_API('Z3_mk_fpa_sort_16', SORT, (_in(CONTEXT),)) + def_API('Z3_mk_fpa_sort_16', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_16(__in Z3_context c); /** - \brief Create the single-precision (32-bit) floating point sort. + \brief Create the single-precision (32-bit) FloatingPoint sort. - \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits - - \remark ebits must be larger than 1 and sbits must be larger than 2. + \param c logical context. def_API('Z3_mk_fpa_sort_single', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_single(__in Z3_context c); /** - \brief Create the single-precision (32-bit) floating point sort. + \brief Create the single-precision (32-bit) FloatingPoint sort. - \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits + \param c logical context. - \remark ebits must be larger than 1 and sbits must be larger than 2. - - def_API('Z3_mk_fpa_sort_32', SORT, (_in(CONTEXT),)) + def_API('Z3_mk_fpa_sort_32', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_32(__in Z3_context c); /** - \brief Create the double-precision (64-bit) floating point sort. + \brief Create the double-precision (64-bit) FloatingPoint sort. \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits - - \remark ebits must be larger than 1 and sbits must be larger than 2. def_API('Z3_mk_fpa_sort_double', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_double(__in Z3_context c); /** - \brief Create the double-precision (64-bit) floating point sort. + \brief Create the double-precision (64-bit) FloatingPoint sort. - \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits + \param c logical context. - \remark ebits must be larger than 1 and sbits must be larger than 2. - - def_API('Z3_mk_fpa_sort_64', SORT, (_in(CONTEXT),)) + def_API('Z3_mk_fpa_sort_64', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_64(__in Z3_context c); /** - \brief Create the quadruple-precision (128-bit) floating point sort. + \brief Create the quadruple-precision (128-bit) FloatingPoint sort. \param c logical context. \param ebits number of exponent bits @@ -196,15 +215,15 @@ extern "C" { Z3_sort Z3_API Z3_mk_fpa_sort_quadruple(__in Z3_context c); /** - \brief Create the quadruple-precision (128-bit) floating point sort. + \brief Create the quadruple-precision (128-bit) FloatingPoint sort. - \param c logical context. - \param ebits number of exponent bits - \param sbits number of significand bits + \param c logical context. + \param ebits number of exponent bits + \param sbits number of significand bits - \remark ebits must be larger than 1 and sbits must be larger than 2. + \remark ebits must be larger than 1 and sbits must be larger than 2. - def_API('Z3_mk_fpa_sort_128', SORT, (_in(CONTEXT),)) + def_API('Z3_mk_fpa_sort_128', SORT, (_in(CONTEXT),)) */ Z3_sort Z3_API Z3_mk_fpa_sort_128(__in Z3_context c); @@ -219,7 +238,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_nan(__in Z3_context c, __in Z3_sort s); /** - \brief Create a floating point infinity of sort s. + \brief Create a floating-point infinity of sort s. \param c logical context. \param s target sort @@ -232,29 +251,64 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_inf(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); /** - \brief Create a floating point zero of sort s. + \brief Create a floating-point zero of sort s. - \param c logical context. - \param s target sort - \param negative indicates whether the result should be negative + \param c logical context. + \param s target sort + \param negative indicates whether the result should be negative - When \c negative is true, -zero will be generated instead of +zero. + When \c negative is true, -zero will be generated instead of +zero. - def_API('Z3_mk_fpa_zero', AST, (_in(CONTEXT),_in(SORT),_in(BOOL))) + def_API('Z3_mk_fpa_zero', AST, (_in(CONTEXT),_in(SORT),_in(BOOL))) */ Z3_ast Z3_API Z3_mk_fpa_zero(__in Z3_context c, __in Z3_sort s, __in Z3_bool negative); /** - \brief Create a numeral of floating point sort from a double. + \brief Create an expression of FloatingPoint sort from three bit-vector expressions. + + Note that \c sign is required to be a bit-vector of size 1. Significand and exponent + are required to be greater than 1 and 2 respectively. The FloatingPoint sort + of the resulting expression is automatically determined from the bit-vector sizes + of the arguments. + + \params c logical context. + \params sgn sign + \params sig significand + \params exp exponent + + def_API('Z3_mk_fpa_fp', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_fp(__in Z3_context c, __in Z3_ast sgn, __in Z3_ast sig, __in Z3_ast exp); + + /** + \brief Create a numeral of FloatingPoint sort from a float. + + This function is used to create numerals that fit in a float value. + It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. + + \params c logical context. + \params v value. + \params ty sort. + + ty must be a FloatingPoint sort + + \sa Z3_mk_numeral + + def_API('Z3_mk_fpa_numeral_float', AST, (_in(CONTEXT), _in(FLOAT), _in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_numeral_float(__in Z3_context c, __in float v, __in Z3_sort ty); + + /** + \brief Create a numeral of FloatingPoint sort from a double. - This function can be use to create numerals that fit in a double value. + This function is used to create numerals that fit in a double value. It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. \params c logical context. \params v value. \params ty sort. - ty must be a floating point sort + ty must be a FloatingPoint sort \sa Z3_mk_numeral @@ -262,13 +316,57 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_numeral_double(__in Z3_context c, __in double v, __in Z3_sort ty); + /** + \brief Create a numeral of FloatingPoint sort from a signed integer. + + \params c logical context. + \params v value. + + ty must be a FloatingPoint sort + + \sa Z3_mk_numeral + + def_API('Z3_mk_fpa_numeral_int', AST, (_in(CONTEXT), _in(INT), _in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_numeral_int(__in Z3_context c, __in signed v, Z3_sort ty); + + /** + \brief Create a numeral of FloatingPoint sort from a sign bit and two integers. + + \params c logical context. + \params sgn sign bit (true == negative). + \params sig significand. + \params exp exponent. + + ty must be a FloatingPoint sort + + \sa Z3_mk_numeral + + def_API('Z3_mk_fpa_numeral_uint_int', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(INT), _in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(__in Z3_context c, __in bool sgn, __in unsigned sig, __in signed exp, Z3_sort ty); + + /** + \brief Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. + + \params c logical context. + \params sgn sign bit (true == negative). + \params sig significand. + \params exp exponent. + + ty must be a FloatingPoint sort + + \sa Z3_mk_numeral + + def_API('Z3_mk_fpa_numeral_uint64_int64', AST, (_in(CONTEXT), _in(BOOL), _in(UINT64), _in(INT64), _in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(__in Z3_context c, __in bool sgn, __in __uint64 sig, __in __int64 exp, Z3_sort ty); + /** \brief Floating-point absolute value \param c logical context. - \param t floating-point term. - - t must have floating point sort. + \param t term of FloatingPoint sort. def_API('Z3_mk_fpa_abs', AST, (_in(CONTEXT),_in(AST))) */ @@ -278,9 +376,7 @@ extern "C" { \brief Floating-point negation \param c logical context. - \param t floating-point term. - - t must have floating point sort. + \param t term of FloatingPoint sort. def_API('Z3_mk_fpa_neg', AST, (_in(CONTEXT),_in(AST))) */ @@ -290,11 +386,11 @@ extern "C" { \brief Floating-point addition \param c logical context. - \param rm rounding mode - \param t1 floating-point term. - \param t2 floating-point term. + \param rm term of RoundingMode sort. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - rm must be of FPA rounding mode sort, t1 and t2 must have the same floating point sort. + rm must be of RoundingMode sort, t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_add', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -304,11 +400,11 @@ extern "C" { \brief Floating-point subtraction \param c logical context. - \param rm rounding mode - \param t1 floating-point term. - \param t2 floating-point term. + \param rm term of RoundingMode sort. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - rm must be of FPA rounding mode sort, t1 and t2 must have the same floating point sort. + rm must be of RoundingMode sort, t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_sub', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -318,11 +414,11 @@ extern "C" { \brief Floating-point multiplication \param c logical context. - \param rm rounding mode - \param t1 floating-point term. - \param t2 floating-point term. + \param rm term of RoundingMode sort. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - rm must be of FPA rounding mode sort, t1 and t2 must have the same floating point sort. + rm must be of RoundingMode sort, t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_mul', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -332,11 +428,11 @@ extern "C" { \brief Floating-point division \param c logical context. - \param rm rounding mode - \param t1 floating-point term. - \param t2 floating-point term. + \param rm term of RoundingMode sort. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - The nodes rm must be of FPA rounding mode sort t1 and t2 must have the same floating point sort. + The nodes rm must be of RoundingMode sort t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_div', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST))) */ @@ -346,13 +442,13 @@ extern "C" { \brief Floating-point fused multiply-add. \param c logical context. - \param rm rounding mode - \param t1 floating-point term. - \param t2 floating-point term. + \param rm term of RoundingMode sort. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. The result is round((t1 * t2) + t3) - rm must be of FPA rounding mode sort, t1, t2, and t3 must have the same floating point sort. + rm must be of RoundingMode sort, t1, t2, and t3 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_fma', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST),_in(AST))) */ @@ -362,10 +458,10 @@ extern "C" { \brief Floating-point square root \param c logical context. - \param rm rounding mode - \param t floating-point term. + \param rm term of RoundingMode sort. + \param t term of FloatingPoint sort. - rm must be of FPA rounding mode sort, t must have floating point sort. + rm must be of RoundingMode sort, t must have FloatingPoint sort. def_API('Z3_mk_fpa_sqrt', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ @@ -375,198 +471,387 @@ extern "C" { \brief Floating-point remainder \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - t1 and t2 must have the same floating point sort. + t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_rem', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_rem(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); - + Z3_ast Z3_API Z3_mk_fpa_rem(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + /** - \brief Floating-point equality + \brief Floating-point roundToIntegral. Rounds a floating-point number to + the closest integer, again represented as a floating-point number. \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param rm term of RoundingMode sort. + \param t term of FloatingPoint sort. - Note that this is IEEE 754 equality (as opposed to SMT-LIB =). + t must be of FloatingPoint sort. - t1 and t2 must have the same floating point sort. - - def_API('Z3_mk_fpa_eq', AST, (_in(CONTEXT),_in(AST),_in(AST))) - */ - Z3_ast Z3_API Z3_mk_fpa_eq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + def_API('Z3_mk_fpa_round_to_integral', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_round_to_integral(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t); + + /** + \brief Minimum of floating-point numbers + + \param c logical context. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. + + t1, t2 must have the same FloatingPoint sort. + + def_API('Z3_mk_fpa_min', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_min(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Maximum of floating-point numbers + + \param c logical context. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. + + t1, t2 must have the same FloatingPoint sort. + + def_API('Z3_mk_fpa_max', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_max(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** \brief Floating-point less than or equal \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - t1 and t2 must have the same floating point sort. + t1 and t2 must have the same FloatingPoint sort. - def_API('Z3_mk_fpa_le', AST, (_in(CONTEXT),_in(AST),_in(AST))) + def_API('Z3_mk_fpa_leq', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_le(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + Z3_ast Z3_API Z3_mk_fpa_leq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** \brief Floating-point less-than \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - t1 and t2 must have the same floating point sort. + t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_lt', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_lt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); - - + /** \brief Floating-point greater than or equal \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - t1 and t2 must have the same floating point sort. + t1 and t2 must have the same FloatingPoint sort. - def_API('Z3_mk_fpa_ge', AST, (_in(CONTEXT),_in(AST),_in(AST))) + def_API('Z3_mk_fpa_geq', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_ge(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + Z3_ast Z3_API Z3_mk_fpa_geq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** \brief Floating-point greater-than \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - t1 and t2 must have the same floating point sort. + t1 and t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_gt', AST, (_in(CONTEXT),_in(AST),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_gt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); - + /** - \brief Predicate indicating whether t is a normal floating point number + \brief Floating-point equality \param c logical context. - \param t floating-point term. + \param t1 term of FloatingPoint sort. + \param t2 term of FloatingPoint sort. - t must have floating point sort. + Note that this is IEEE 754 equality (as opposed to SMT-LIB =). + + t1 and t2 must have the same FloatingPoint sort. + + def_API('Z3_mk_fpa_eq', AST, (_in(CONTEXT),_in(AST),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_eq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + + /** + \brief Predicate indicating whether t is a normal floating-point number. + + \param c logical context. + \param t term of FloatingPoint sort. + + t must have FloatingPoint sort. def_API('Z3_mk_fpa_is_normal', AST, (_in(CONTEXT),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_is_normal(__in Z3_context c, __in Z3_ast t); /** - \brief Predicate indicating whether t is a subnormal floating point number + \brief Predicate indicating whether t is a subnormal floating-point number. \param c logical context. - \param t floating-point term. + \param t term of FloatingPoint sort. - t must have floating point sort. + t must have FloatingPoint sort. def_API('Z3_mk_fpa_is_subnormal', AST, (_in(CONTEXT),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_is_subnormal(__in Z3_context c, __in Z3_ast t); /** - \brief Predicate indicating whether t is a floating point number with zero value, i.e., +0 or -0. + \brief Predicate indicating whether t is a floating-point number with zero value, i.e., +zero or -zero. \param c logical context. - \param t floating-point term. + \param t term of FloatingPoint sort. - t must have floating point sort. + t must have FloatingPoint sort. def_API('Z3_mk_fpa_is_zero', AST, (_in(CONTEXT),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_is_zero(__in Z3_context c, __in Z3_ast t); /** - \brief Predicate indicating whether t is a floating point number representing +Inf or -Inf + \brief Predicate indicating whether t is a floating-point number representing +oo or -oo. \param c logical context. - \param t floating-point term. + \param t term of FloatingPoint sort. - t must have floating point sort. + t must have FloatingPoint sort. - def_API('Z3_mk_fpa_is_inf', AST, (_in(CONTEXT),_in(AST))) + def_API('Z3_mk_fpa_is_infinite', AST, (_in(CONTEXT),_in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_is_inf(__in Z3_context c, __in Z3_ast t); + Z3_ast Z3_API Z3_mk_fpa_is_infinite(__in Z3_context c, __in Z3_ast t); /** \brief Predicate indicating whether t is a NaN \param c logical context. - \param t floating-point term. + \param t term of FloatingPoint sort. - t must have floating point sort. + t must have FloatingPoint sort. def_API('Z3_mk_fpa_is_nan', AST, (_in(CONTEXT),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_is_nan(__in Z3_context c, __in Z3_ast t); /** - \brief Minimum of floating point numbers + \brief Predicate indicating whether t is a negative floating-point number. \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. + \param t term of FloatingPoint sort. - t1, t2 must have the same floating point sort. - - def_API('Z3_mk_fpa_min', AST, (_in(CONTEXT),_in(AST),_in(AST))) - */ - Z3_ast Z3_API Z3_mk_fpa_min(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); - - /** - \brief Maximum of floating point numbers + t must have FloatingPoint sort. - \param c logical context. - \param t1 floating-point term. - \param t2 floating-point term. - - t1, t2 must have the same floating point sort. - - def_API('Z3_mk_fpa_max', AST, (_in(CONTEXT),_in(AST),_in(AST))) - */ - Z3_ast Z3_API Z3_mk_fpa_max(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + def_API('Z3_mk_fpa_is_negative', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_negative(__in Z3_context c, __in Z3_ast t); /** - \brief Conversion of a floating point number to another floating-point sort s. - - Produces a term that represents the conversion of a floating-point term t to a different - floating point sort s. If necessary, rounding according to rm is applied. + \brief Predicate indicating whether t is a positive floating-point number. \param c logical context. + \param t term of FloatingPoint sort. + + t must have FloatingPoint sort. + + def_API('Z3_mk_fpa_is_positive', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_is_positive(__in Z3_context c, __in Z3_ast t); + + /** + \brief Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. + + Produces a term that represents the conversion of a bit-vector term bv to a + floating-point term of sort s. + + \param c logical context. + \param bv a bit-vector term. \param s floating-point sort. - \param rm rounding mode. - \param t floating-point term. - s must be a floating point sort, rm must have rounding mode sort, and t must have floating point sort. + s must be a FloatingPoint sort, t must be of bit-vector sort, and the bit-vector + size of bv, m, must be equal to ebits+sbits of s. The format of the bit-vector is + as defined by the IEEE 754-2008 interchange format and the resulting floating-point + sort (ebits, sbits) is automatically determined. - def_API('Z3_mk_fpa_convert', AST, (_in(CONTEXT),_in(SORT),_in(AST),_in(AST))) + def_API('Z3_mk_fpa_to_fp_bv', AST, (_in(CONTEXT),_in(AST),_in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_convert(__in Z3_context c, __in Z3_sort s, __in Z3_ast rm, __in Z3_ast t); + Z3_ast Z3_API Z3_mk_fpa_to_fp_bv(__in Z3_context c, __in Z3_ast bv, __in Z3_sort s); /** - \brief Conversion of a floating point term to a bit-vector term in IEEE754 format. + \brief Conversion of a floating-point term into another floating-point term of different floating-point sort. + + Produces a term that represents the conversion of a floating-point term t to a + floating-point term of sort s. If necessary, the result will be rounded according + to rounding mode rm. + + \param c logical context. + \param rm term of RoundingMode sort. + \param t term of FloatingPoint sort. + \param s floating-point sort. + + s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of floating-point sort. + + def_API('Z3_mk_fpa_to_fp_float', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_fp_float(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in Z3_sort s); + + /** + \brief Conversion of a term of real sort into a term of FloatingPoint sort. + + Produces a term that represents the conversion of term t of real sort into a + floating-point term of sort s. If necessary, the result will be rounded according + to rounding mode rm. + + \param c logical context. + \param rm term of RoundingMode sort. + \param t term of Real sort. + \param s floating-point sort. + + s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of real sort. + + def_API('Z3_mk_fpa_to_fp_real', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_fp_real(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in Z3_sort s); + + /** + \brief Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. + + Produces a term that represents the conversion of the bit-vector term t into a + floating-point term of sort s. The bit-vector t is taken to be in signed + 2's complement format. If necessary, the result will be rounded according + to rounding mode rm. + + \param c logical context. + \param rm term of RoundingMode sort. + \param t term of bit-vector sort. + \param s floating-point sort. + + s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of bit-vector sort. + + def_API('Z3_mk_fpa_to_fp_signed', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_fp_signed(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in Z3_sort s); + + /** + \brief Conversion of a 2's complement unsigned bit-vector term into a term of FloatingPoint sort. + + Produces a term that represents the conversion of the bit-vector term t into a + floating-point term of sort s. The bit-vector t is taken to be in unsigned + 2's complement format. If necessary, the result will be rounded according + to rounding mode rm. + + \param c logical context. + \param rm term of RoundingMode sort. + \param t term of bit-vector sort. + \param s floating-point sort. + + s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of bit-vector sort. + + def_API('Z3_mk_fpa_to_fp_unsigned', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_fp_unsigned(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in Z3_sort s); + + /** + \brief Conversion of a floating-point term into an unsigned bit-vector. + + Produces a term that represents the conversion of the floating-poiunt term t into a + bit-vector term in unsigned 2's complement format. If necessary, the result will be + rounded according to rounding mode rm. \param c logical context. - \param t floating-point term. + \param rm term of RoundingMode sort. + \param t term of FloatingPoint sort. + \param sz size of the resulting bit-vector. - t must have floating point sort. The size of the resulting bit-vector is automatically determined. + def_API('Z3_mk_fpa_to_ubv', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(UINT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_ubv(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in unsigned sz); + + /** + \brief Conversion of a floating-point term into a signed bit-vector. + + Produces a term that represents the conversion of the floating-poiunt term t into a + bit-vector term in signed 2's complement format. If necessary, the result will be + rounded according to rounding mode rm. + + \param c logical context. + \param rm term of RoundingMode sort. + \param t term of FloatingPoint sort. + \param sz size of the resulting bit-vector. + + def_API('Z3_mk_fpa_to_sbv', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(UINT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_sbv(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in unsigned sz); + + /** + \brief Conversion of a floating-point term into a real number. + + Produces a term that represents the conversion of the floating-poiunt term t into a + real number. Note that this type of conversion will often result in non-linear + constraints over real terms. + + \param c logical context. + \param t term of FloatingPoint sort. + + def_API('Z3_mk_fpa_to_real', AST, (_in(CONTEXT),_in(AST))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_real(__in Z3_context c, __in Z3_ast t); + + /** + @name Z3-specific extensions + */ + /*@{*/ + + /** + \brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. + + \param c logical context. + \param t term of FloatingPoint sort. + + t must have FloatingPoint sort. The size of the resulting bit-vector is automatically + determined. + + Note that IEEE 754-2008 allows multiple different representations of NaN. This conversion + knows only one NaN and it will always produce the same bit-vector represenatation of + that NaN. def_API('Z3_mk_fpa_to_ieee_bv', AST, (_in(CONTEXT),_in(AST))) */ Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(__in Z3_context c, __in Z3_ast t); + /** + \brief Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. + + Produces a term that represents the conversion of sig * 2^exp into a + floating-point term of sort s. If necessary, the result will be rounded + according to rounding mode rm. + + \param c logical context. + \param rm term of RoundingMode sort. + \param sig significand term of Real sort. + \param exp exponent term of Real sort. + \param s floating-point sort. + + s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of real sort. + + def_API('Z3_mk_fpa_to_fp_real_int', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST),_in(SORT))) + */ + Z3_ast Z3_API Z3_mk_fpa_to_fp_real_int(__in Z3_context c, __in Z3_ast rm, __in Z3_ast sig, __in Z3_ast exp, __in Z3_sort s); + + /*@}*/ /*@}*/ /*@}*/ diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 1598db9c3..cbcd706cd 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -263,9 +263,41 @@ public: bool is_zero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_zero(v); } bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } + + app * mk_fp(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_FP, arg1, arg2, arg3); } + app * mk_to_fp(sort * s, expr * bv_t) { + SASSERT(is_float(s) && s->get_num_parameters() == 2); + return m().mk_app(m_fid, OP_FLOAT_TO_FP, 2, s->get_parameters(), 1, &bv_t); + } + app * mk_to_fp(sort * s, expr * rm, expr * t) { + SASSERT(is_float(s) && s->get_num_parameters() == 2); + expr * args[] = { rm, t }; + return m().mk_app(m_fid, OP_FLOAT_TO_FP, 2, s->get_parameters(), 2, args); + } + app * mk_to_fp(sort * s, expr * rm, expr * sig, expr * exp) { + SASSERT(is_float(s) && s->get_num_parameters() == 2); + expr * args[] = { rm, sig, exp }; + return m().mk_app(m_fid, OP_FLOAT_TO_FP, 2, s->get_parameters(), 3, args); + } + app * mk_to_fp_unsigned(sort * s, expr * rm, expr * t) { + SASSERT(is_float(s) && s->get_num_parameters() == 2); + expr * args[] = { rm, t }; + return m().mk_app(m_fid, OP_FLOAT_TO_FP_UNSIGNED, 2, s->get_parameters(), 2, args); + } bool is_to_fp(expr * n) { return is_app_of(n, m_fid, OP_FLOAT_TO_FP); } - + + app * mk_to_ubv(expr * rm, expr * t, unsigned sz) { + parameter ps[] = { parameter(sz) }; + expr * args[] = { rm, t }; + return m().mk_app(m_fid, OP_FLOAT_TO_UBV, 1, ps, 2, args); } + app * mk_to_sbv(expr * rm, expr * t, unsigned sz) { + parameter ps[] = { parameter(sz) }; + expr * args[] = { rm, t }; + return m().mk_app(m_fid, OP_FLOAT_TO_SBV, 1, ps, 2, args); + } + app * mk_to_real(expr * t) { return m().mk_app(m_fid, OP_FLOAT_TO_REAL, t); } + app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); } app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); } @@ -276,7 +308,7 @@ public: app * mk_min(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MIN, arg1, arg2); } app * mk_abs(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_ABS, arg1); } app * mk_sqrt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_SQRT, arg1, arg2); } - app * mk_round(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ROUND_TO_INTEGRAL, arg1, arg2); } + app * mk_round_to_integral(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ROUND_TO_INTEGRAL, arg1, arg2); } app * mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4) { expr * args[4] = { arg1, arg2, arg3, arg4 }; return m().mk_app(m_fid, OP_FLOAT_FMA, 4, args); @@ -306,6 +338,9 @@ public: app * mk_internal_to_ubv_unspecified(unsigned width); app * mk_internal_to_sbv_unspecified(unsigned width); app * mk_internal_to_real_unspecified(); + + bool is_wrap(expr * e) const { return is_app_of(e, get_family_id(), OP_FLOAT_INTERNAL_BVWRAP); } + bool is_unwrap(expr * e) const { return is_app_of(e, get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP); } }; #endif diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index f7fd1de30..03a2e73bf 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -48,13 +48,11 @@ namespace smt { } else { sort * s = f->get_range(); - func_decl_ref w(m), u(m); - m_th.get_wrap(s, w, u); expr_ref bv(m); - bv = m.mk_app(w, m.mk_const(f)); + bv = m_th.wrap(m.mk_const(f)); unsigned bv_sz = m_th.m_bv_util.get_bv_size(bv); - unsigned ebits = m_th.m_float_util.get_ebits(f->get_range()); - unsigned sbits = m_th.m_float_util.get_sbits(f->get_range()); + unsigned ebits = m_th.m_float_util.get_ebits(s); + unsigned sbits = m_th.m_float_util.get_sbits(s); SASSERT(bv_sz == ebits + sbits); m_th.m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), m_bv_util.mk_extract(sbits - 2, 0, bv), @@ -76,12 +74,7 @@ namespace smt { } else { SASSERT(is_rm(f->get_range())); - - sort * s = f->get_range(); - func_decl_ref w(m), u(m); - m_th.get_wrap(s, w, u); - result = m.mk_app(w, m.mk_const(f)); - + result = m_th.wrap(m.mk_const(f)); m_rm_const2bv.insert(f, result); m.inc_ref(f); m.inc_ref(result); @@ -133,13 +126,15 @@ namespace smt { SASSERT(bv_sz == (m_ebits+m_sbits)); SASSERT(all_rat.is_int()); mpzm.set(all_bits, all_rat.to_mpq().numerator()); - + scoped_mpz sgn_z(mpzm), sig_z(mpzm), exp_z(mpzm); mpzm.machine_div2k(all_bits, m_ebits + m_sbits - 1, sgn_z); mpzm.mod(all_bits, mpfm.m_powers2(m_ebits + m_sbits - 1), all_bits); mpzm.machine_div2k(all_bits, m_sbits - 1, exp_z); mpzm.mod(all_bits, mpfm.m_powers2(m_sbits - 1), all_bits); + + mpzm.set(sig_z, all_bits); TRACE("t_fpa_detail", tout << "sgn=" << mpzm.to_string(sgn_z) << " ; " << "sig=" << mpzm.to_string(sig_z) << " ; " << @@ -190,36 +185,53 @@ namespace smt { return result; } - void theory_fpa::get_wrap(sort * s, func_decl_ref & wrap, func_decl_ref & unwrap) - { - func_decl *w, *u; + app_ref theory_fpa::wrap(expr * e) { + SASSERT(!m_float_util.is_wrap(e)); + ast_manager & m = get_manager(); + context & ctx = get_context(); + sort * e_srt = m.get_sort(e); - if (!m_wraps.find(s, w) || !m_unwraps.find(s, u)) { - SASSERT(!m_wraps.contains(s)); - SASSERT(!m_unwraps.contains(s)); - ast_manager & m = get_manager(); - context & ctx = get_context(); + func_decl *w; + + if (!m_wraps.find(e_srt, w)) { + SASSERT(!m_wraps.contains(e_srt)); + sort * bv_srt = 0; - if (m_converter.is_rm(s)) + if (m_converter.is_rm(e_srt)) bv_srt = m_bv_util.mk_sort(3); else { - SASSERT(m_converter.is_float(s)); - unsigned ebits = m_float_util.get_ebits(s); - unsigned sbits = m_float_util.get_sbits(s); + SASSERT(m_converter.is_float(e_srt)); + unsigned ebits = m_float_util.get_ebits(e_srt); + unsigned sbits = m_float_util.get_sbits(e_srt); bv_srt = m_bv_util.mk_sort(ebits + sbits); } - w = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVWRAP, 0, 0, 1, &s, bv_srt); + w = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVWRAP, 0, 0, 1, &e_srt, bv_srt); + m_wraps.insert(e_srt, w); + m.inc_ref(w); + } + + return app_ref(m.mk_app(w, e), m); + } + + app_ref theory_fpa::unwrap(expr * e, sort * s) { + SASSERT(!m_float_util.is_unwrap(e)); + ast_manager & m = get_manager(); + context & ctx = get_context(); + sort * e_srt = m.get_sort(e); + + func_decl *u; + + if (!m_unwraps.find(e_srt, u)) { + SASSERT(!m_unwraps.contains(e_srt)); + sort * bv_srt = m.get_sort(e); u = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); - m_wraps.insert(s, w); m_unwraps.insert(s, u); - m.inc_ref(w); m.inc_ref(u); } - wrap = w; - unwrap = u; + return app_ref(m.mk_app(u, e), m); } expr_ref theory_fpa::convert_atom(expr * e) { @@ -235,32 +247,39 @@ namespace smt { expr_ref theory_fpa::convert_term(expr * e) { ast_manager & m = get_manager(); + TRACE("t_fpa_detail", tout << "converting: " << mk_ismt2_pp(e, m) << " sort is: " << mk_ismt2_pp(m.get_sort(e), m) << std::endl;); + context & ctx = get_context(); - expr_ref res(m); + expr_ref ec(m), res(m); proof_ref pr(m); - m_rw(e, res); - - SASSERT(is_app(res)); - - if (m_float_util.is_rm(e)) { - SASSERT(is_sort_of(m.get_sort(res), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(m_bv_util.get_bv_size(res) == 3); - ctx.internalize(res, false); - m_th_rw(res, res); + m_rw(e, ec); + + SASSERT(is_app(ec)); + app_ref eca(to_app(ec), m); + TRACE("t_fpa_detail", tout << "eca = " << mk_ismt2_pp(eca, m) << " sort is: " << mk_ismt2_pp(m.get_sort(eca), m) << std::endl;); + + if (m_float_util.is_rm(e)) { + expr_ref bv_rm(m); + bv_rm = eca; + TRACE("t_fpa_detail", tout << "bvrm = " << mk_ismt2_pp(bv_rm, m) << " sort is: " << mk_ismt2_pp(m.get_sort(bv_rm), m) << std::endl;); + SASSERT(is_sort_of(m.get_sort(bv_rm), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); + m_th_rw(bv_rm, res); } else if (m_float_util.is_float(e)) { - SASSERT(to_app(res)->get_family_id() == get_family_id()); - float_op_kind k = (float_op_kind)(to_app(res)->get_decl_kind()); + SASSERT(eca->get_family_id() == get_family_id()); + float_op_kind k = (float_op_kind)(eca->get_decl_kind()); + SASSERT(k == OP_FLOAT_TO_FP || k == OP_FLOAT_INTERNAL_BVUNWRAP); switch (k) { case OP_FLOAT_TO_FP: { - SASSERT(to_app(res)->get_num_args() == 3); - SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(0)), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(1)), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(is_sort_of(m.get_sort(to_app(res)->get_arg(2)), m_bv_util.get_family_id(), BV_SORT)); - + SASSERT(eca->get_num_args() == 3); + SASSERT(is_sort_of(m.get_sort(eca->get_arg(0)), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(eca->get_arg(1)), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(is_sort_of(m.get_sort(eca->get_arg(2)), m_bv_util.get_family_id(), BV_SORT)); + expr *sgn, *sig, *exp; expr_ref s_sgn(m), s_sig(m), s_exp(m); - m_converter.split_triple(res, sgn, sig, exp); + m_converter.split_triple(eca, sgn, sig, exp); m_th_rw(sgn, s_sgn); m_th_rw(sig, s_sig); m_th_rw(exp, s_exp); @@ -269,12 +288,13 @@ namespace smt { break; } default: - /* nothing */; + res = eca; } } else UNREACHABLE(); + SASSERT(res.get() != 0); return res; } @@ -292,6 +312,28 @@ namespace smt { return res; } + expr_ref theory_fpa::convert_unwrap(expr * e) { + SASSERT(m_float_util.is_unwrap(e)); + ast_manager & m = get_manager(); + sort * srt = m.get_sort(e); + expr_ref res(m); + if (m_float_util.is_rm(srt)) { + res = to_app(e)->get_arg(0); + } + else { + SASSERT(m_float_util.is_float(srt)); + unsigned ebits = m_float_util.get_ebits(srt); + unsigned sbits = m_float_util.get_sbits(srt); + expr * bv = to_app(e)->get_arg(0); + unsigned bv_sz = m_bv_util.get_bv_size(bv); + m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), + m_bv_util.mk_extract(sbits - 2, 0, bv), + m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), + res); + } + return res; + } + expr_ref theory_fpa::convert(expr * e) { ast_manager & m = get_manager(); @@ -306,7 +348,9 @@ namespace smt { return res; } else { - if (m.is_bool(e)) + if (m_float_util.is_unwrap(e)) + res = convert_unwrap(e); + else if (m.is_bool(e)) res = convert_atom(e); else if (m_float_util.is_float(e) || m_float_util.is_rm(e)) res = convert_term(e); @@ -452,34 +496,18 @@ namespace smt { if (m_float_util.is_rm(owner_sort)) { // For every RM term, we need to make sure that it's - // associated bit-vector is within the valid range. - // This also ensures that wrap(owner) is internalized. - func_decl_ref wrap(m), unwrap(m); - get_wrap(owner_sort, wrap, unwrap); - if (owner->get_decl() != unwrap) + // associated bit-vector is within the valid range. + if (!m_float_util.is_unwrap(owner)) { - expr_ref wrapped(m), valid(m), limit(m); - wrapped = m.mk_app(wrap, owner.get()); + expr_ref valid(m), limit(m); limit = m_bv_util.mk_numeral(4, 3); - valid = m_bv_util.mk_ule(wrapped, limit); + valid = m_bv_util.mk_ule(wrap(owner), limit); assert_cnstr(valid); } } - else if (m_float_util.is_float(owner_sort)) { - // For every FP term, we need to make sure that - // its wrapped version is also internalized so that - // we can build a model for it later. - func_decl_ref wrap(m), unwrap(m); - get_wrap(owner_sort, wrap, unwrap); - if (owner->get_decl() != unwrap) { - expr_ref wrapped(m); - wrapped = m.mk_app(wrap, owner.get()); - if (!ctx.e_internalized(wrapped)) - ctx.internalize(wrapped, false); - } - } - else - UNREACHABLE(); + + if (!ctx.relevancy() && !m_float_util.is_unwrap(owner)) + assert_cnstr(m.mk_eq(unwrap(wrap(owner), owner_sort), owner)); } void theory_fpa::new_eq_eh(theory_var x, theory_var y) { @@ -498,8 +526,7 @@ namespace smt { app * ye = get_enode(y)->get_owner(); if ((m.is_bool(xe) && m.is_bool(ye)) || - (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye))) - { + (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye))) { SASSERT(xe->get_decl()->get_family_id() == get_family_id()); return; } @@ -509,16 +536,13 @@ namespace smt { yc = convert(ye); expr_ref c(m); - + if (fu.is_float(xe) && fu.is_float(ye)) { - func_decl_ref wrap(m), unwrap(m); - get_wrap(m.get_sort(ye), wrap, unwrap); - if (ye->get_decl() == unwrap) - return; expr *x_sgn, *x_sig, *x_exp; m_converter.split_triple(xc, x_sgn, x_sig, x_exp); + expr *y_sgn, *y_sig, *y_exp; m_converter.split_triple(yc, y_sgn, y_sig, y_exp); @@ -614,12 +638,10 @@ namespace smt { if (m_float_util.is_float(n) || m_float_util.is_rm(n)) { sort * s = m.get_sort(n); - func_decl_ref wrap(m), unwrap(m); - get_wrap(s, wrap, unwrap); - if (n->get_decl() != unwrap) { + if (!m_float_util.is_unwrap(n)) { expr_ref wrapped(m), c(m); - wrapped = m.mk_app(wrap, n); + wrapped = wrap(n); mpf_rounding_mode rm; scoped_mpf val(mpfm); if (m_float_util.is_rm_value(n, rm)) { @@ -633,15 +655,13 @@ namespace smt { SASSERT(is_app(bv_val_e)); SASSERT(to_app(bv_val_e)->get_num_args() == 3); app_ref bv_val_a(to_app(bv_val_e.get()), m); - c = m.mk_eq(wrapped, m_bv_util.mk_concat( m_bv_util.mk_concat( - bv_val_a->get_arg(0), - bv_val_a->get_arg(1)), - bv_val_a->get_arg(2))); + expr * args[] = { bv_val_a->get_arg(0), bv_val_a->get_arg(1), bv_val_a->get_arg(2) }; + c = m.mk_eq(wrapped, m_bv_util.mk_concat(3, args)); c = m.mk_and(c, mk_side_conditions()); assert_cnstr(c); } else { - c = m.mk_eq(m.mk_app(unwrap, wrapped), n); + c = m.mk_eq(unwrap(wrapped, m.get_sort(n)), n); assert_cnstr(c); } } @@ -696,11 +716,9 @@ namespace smt { return alloc(expr_wrapper_proc, owner); model_value_proc * res = 0; - func_decl_ref wrap(m), unwrap(m); - get_wrap(m.get_sort(owner), wrap, unwrap); app_ref wrapped(m); - wrapped = m.mk_app(wrap, owner); + wrapped = wrap(owner); CTRACE("t_fpa", !ctx.e_internalized(wrapped), tout << "Model dependency not internalized: " << diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index c21096ec0..c51b02c28 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -176,11 +176,15 @@ namespace smt { expr_ref convert_atom(expr * e); expr_ref convert_term(expr * e); expr_ref convert_conversion_term(expr * e); - void get_wrap(sort * s, func_decl_ref & wrap, func_decl_ref & unwrap); + expr_ref convert_unwrap(expr * e); + void add_trail(ast * a); void attach_new_th_var(enode * n); - void assert_cnstr(expr * e); + void assert_cnstr(expr * e); + + app_ref wrap(expr * e); + app_ref unwrap(expr * e, sort * s); }; }; diff --git a/src/util/mpf.h b/src/util/mpf.h index 83646f9f3..b919e0371 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -75,7 +75,7 @@ public: void set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode rm, mpq const & value); void set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode rm, char const * value); void set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode rm, mpq const & significand, mpz const & exponent); - void set(mpf & o, unsigned ebits, unsigned sbits, bool sign, uint64 significand, int exponent); + void set(mpf & o, unsigned ebits, unsigned sbits, bool sign, uint64 significand, mpf_exp_t exponent); void set(mpf & o, unsigned ebits, unsigned sbits, bool sign, mpz const & significand, mpf_exp_t exponent); void set(mpf & o, mpf const & x); void set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode rm, mpf const & x); From 076c709453146ca526fa454340370bbf2ad2376b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 19:00:06 +0000 Subject: [PATCH 107/507] cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/smt/theory_fpa.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 03a2e73bf..bec9cf235 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -344,7 +344,7 @@ namespace smt { res = m_conversions.find(e); TRACE("t_fpa_detail", tout << "cached:" << std::endl; tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << - mk_ismt2_pp(res, m) << std::endl;); + mk_ismt2_pp(res, m) << std::endl;); return res; } else { @@ -360,8 +360,8 @@ namespace smt { UNREACHABLE(); TRACE("t_fpa_detail", tout << "converted; caching:" << std::endl; - tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << - mk_ismt2_pp(res, m) << std::endl;); + tout << mk_ismt2_pp(e, m) << std::endl << " -> " << std::endl << + mk_ismt2_pp(res, m) << std::endl;); m_conversions.insert(e, res); m.inc_ref(res); @@ -539,10 +539,8 @@ namespace smt { if (fu.is_float(xe) && fu.is_float(ye)) { - expr *x_sgn, *x_sig, *x_exp; m_converter.split_triple(xc, x_sgn, x_sig, x_exp); - expr *y_sgn, *y_sig, *y_exp; m_converter.split_triple(yc, y_sgn, y_sig, y_exp); From 6e849d7f73905d415a9fd4e07970a52baa1972bf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 19:16:02 +0000 Subject: [PATCH 108/507] FPA API cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 8 ++++---- src/api/z3_fpa.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 89b278c91..97225f0f3 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -264,7 +264,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(Z3_context c, bool sgn, unsigned sig, signed exp, Z3_sort ty) { + Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(Z3_context c, Z3_bool sgn, unsigned sig, signed exp, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); RESET_ERROR_CODE(); @@ -273,13 +273,13 @@ extern "C" { ctx->float_util().fm().set(tmp, ctx->float_util().get_ebits(to_sort(ty)), ctx->float_util().get_sbits(to_sort(ty)), - sgn, sig, exp); + sgn != 0, sig, exp); Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(Z3_context c, bool sgn, __uint64 sig, __int64 exp, Z3_sort ty) { + Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(Z3_context c, Z3_bool sgn, __uint64 sig, __int64 exp, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); RESET_ERROR_CODE(); @@ -288,7 +288,7 @@ extern "C" { ctx->float_util().fm().set(tmp, ctx->float_util().get_ebits(to_sort(ty)), ctx->float_util().get_sbits(to_sort(ty)), - sgn, sig, exp); + sgn != 0, sig, exp); Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 48d3e790d..61ee0bd7f 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -344,7 +344,7 @@ extern "C" { def_API('Z3_mk_fpa_numeral_uint_int', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(INT), _in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(__in Z3_context c, __in bool sgn, __in unsigned sig, __in signed exp, Z3_sort ty); + Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(__in Z3_context c, __in Z3_bool sgn, __in unsigned sig, __in signed exp, Z3_sort ty); /** \brief Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. @@ -360,7 +360,7 @@ extern "C" { def_API('Z3_mk_fpa_numeral_uint64_int64', AST, (_in(CONTEXT), _in(BOOL), _in(UINT64), _in(INT64), _in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(__in Z3_context c, __in bool sgn, __in __uint64 sig, __in __int64 exp, Z3_sort ty); + Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(__in Z3_context c, __in Z3_bool sgn, __in __uint64 sig, __in __int64 exp, Z3_sort ty); /** \brief Floating-point absolute value From b46d76cddbc889822ff5a1bdab7ab104113c9628 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 1 Jan 2015 19:16:44 +0000 Subject: [PATCH 109/507] New FPA C-API example Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 149 ++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 76 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 1aef9eb1b..920fdeb8c 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2595,16 +2595,20 @@ void substitute_vars_example() { Z3_del_context(ctx); } +/** + \brief Demonstrates some basic features of the FloatingPoint theory. +*/ + void fpa_example() { Z3_config cfg; Z3_context ctx; Z3_sort double_sort, rm_sort; - Z3_symbol symbol_rm, symbol_x, symbol_y, symbol_q; - Z3_ast rm, x, y, n, q, c1, c2, c3, c4, c5, c6; + Z3_symbol s_rm, s_x, s_y, s_x_plus_y; + Z3_ast rm, x, y, n, x_plus_y, c1, c2, c3, c4, c5, c6; + + printf("\nFPA-example\n"); + LOG_MSG("FPA-example"); - printf("\nfpa_example\n"); - LOG_MSG("fpa_example"); - cfg = Z3_mk_config(); ctx = Z3_mk_context(cfg); Z3_del_config(cfg); @@ -2612,83 +2616,76 @@ void fpa_example() { double_sort = Z3_mk_fpa_sort(ctx, 11, 53); rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); - symbol_rm = Z3_mk_string_symbol(ctx, "rm"); - rm = Z3_mk_const(ctx, symbol_rm, rm_sort); - symbol_x = Z3_mk_string_symbol(ctx, "x"); - symbol_y = Z3_mk_string_symbol(ctx, "y"); - x = Z3_mk_const(ctx, symbol_x, double_sort); - y = Z3_mk_const(ctx, symbol_y, double_sort); - n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); + { + // Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). + s_rm = Z3_mk_string_symbol(ctx, "rm"); + rm = Z3_mk_const(ctx, s_rm, rm_sort); + s_x = Z3_mk_string_symbol(ctx, "x"); + s_y = Z3_mk_string_symbol(ctx, "y"); + x = Z3_mk_const(ctx, s_x, double_sort); + y = Z3_mk_const(ctx, s_y, double_sort); + n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); - symbol_q = Z3_mk_string_symbol(ctx, "q"); - q = Z3_mk_const(ctx, symbol_q, double_sort); - c1 = Z3_mk_eq(ctx, q, Z3_mk_fpa_add(ctx, rm, x, y)); + s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y"); + x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort); + c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y)); - Z3_ast args[2] = { c1, Z3_mk_eq(ctx, q, n) }; - c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); + Z3_ast args[2] = { c1, Z3_mk_eq(ctx, x_plus_y, n) }; + c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); - Z3_ast args2[2] = { c2, Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_round_nearest_ties_to_away(ctx))) }; - c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); + Z3_ast args2[2] = { c2, Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx))) }; + c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); - Z3_ast and_args[3] = { - Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)), - Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)), - Z3_mk_not(ctx, Z3_mk_fpa_is_inf(ctx, y)) }; - Z3_ast args3[2] = { c3, Z3_mk_and(ctx, 3, and_args) }; - c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); - - - Z3_assert_cnstr(ctx, c4); - Z3_push(ctx); - - // c5 := (IEEEBV(x) == 7.0). - c5 = Z3_mk_eq(ctx, Z3_mk_fpa_to_ieee_bv(ctx, x), - Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64))); - - Z3_assert_cnstr(ctx, c5); - - Z3_model m = 0; - Z3_lbool result = Z3_check_and_get_model(ctx, &m); - switch (result) { - case Z3_L_FALSE: - printf("unsat\n"); - break; - case Z3_L_UNDEF: - printf("unknown\n"); - printf("potential model:\n%s\n", Z3_model_to_string(ctx, m)); - break; - case Z3_L_TRUE: - printf("sat\n%s\n", Z3_model_to_string(ctx, m)); - Z3_del_model(ctx, m); - break; - } - - Z3_pop(ctx, 1); - - // c6 := (IEEEBV(x) == 28.0). - c6 = Z3_mk_eq(ctx, Z3_mk_fpa_to_ieee_bv(ctx, x), - Z3_mk_numeral(ctx, "4628574517030027264", Z3_mk_bv_sort(ctx, 64))); - - Z3_assert_cnstr(ctx, c6); - Z3_push(ctx); - - m = 0; - result = Z3_check_and_get_model(ctx, &m); - switch (result) { - case Z3_L_FALSE: - printf("unsat\n"); - break; - case Z3_L_UNDEF: - printf("unknown\n"); - printf("potential model:\n%s\n", Z3_model_to_string(ctx, m)); - break; - case Z3_L_TRUE: - printf("sat\n%s\n", Z3_model_to_string(ctx, m)); - Z3_del_model(ctx, m); - break; + Z3_ast and_args[3] = { + Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)), + Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)), + Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y)) }; + Z3_ast args3[2] = { c3, Z3_mk_and(ctx, 3, and_args) }; + c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); + + printf("c4: %s\n", Z3_ast_to_string(ctx, c4)); + Z3_push(ctx); + Z3_assert_cnstr(ctx, c4); + check(ctx, Z3_L_TRUE); + Z3_pop(ctx, 1); } - Z3_pop(ctx, 1); + + { + // Show that the following are equal: + // (fp #b0 #b10000000001 #xc000000000000) + // ((_ to_fp 11 53) #x401c000000000000)) + // ((_ to_fp 11 53) RTZ 1.75 2))) + // ((_ to_fp 11 53) RTZ 7.0))) + Z3_ast args3[3]; + + Z3_push(ctx); + c1 = Z3_mk_fpa_fp(ctx, + Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), + Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)), + Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52))); + c2 = Z3_mk_fpa_to_fp_bv(ctx, + Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), + Z3_mk_fpa_sort(ctx, 11, 53)); + c3 = Z3_mk_fpa_to_fp_real_int(ctx, + Z3_mk_fpa_rtz(ctx), + Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), + Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), + Z3_mk_fpa_sort(ctx, 11, 53)); + c4 = Z3_mk_fpa_to_fp_real(ctx, + Z3_mk_fpa_rtz(ctx), + Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), + Z3_mk_fpa_sort(ctx, 11, 53)); + args3[0] = Z3_mk_eq(ctx, c1, c2); + args3[1] = Z3_mk_eq(ctx, c1, c3); + args3[2] = Z3_mk_eq(ctx, c1, c4); + c5 = Z3_mk_and(ctx, 3, args3); + + printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); + Z3_assert_cnstr(ctx, c5); + check(ctx, Z3_L_TRUE); + Z3_pop(ctx, 1); + } Z3_del_context(ctx); } From 8e7278f02c15cc6f2cef6f3585c5fd206b62f62f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 2 Jan 2015 18:10:47 +0000 Subject: [PATCH 110/507] Java API: Removed unnecessary imports Signed-off-by: Christoph M. Wintersteiger --- src/api/java/InterpolationContext.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/api/java/InterpolationContext.java b/src/api/java/InterpolationContext.java index 3e9996b3e..05d99b305 100644 --- a/src/api/java/InterpolationContext.java +++ b/src/api/java/InterpolationContext.java @@ -20,8 +20,6 @@ package com.microsoft.z3; import java.util.Map; import java.lang.String; -import com.microsoft.z3.Native.IntPtr; -import com.microsoft.z3.Native.UIntArrayPtr; import com.microsoft.z3.enumerations.Z3_lbool; /** From 09814128a62446d40f9aad264bce092321188c59 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 2 Jan 2015 18:57:38 +0000 Subject: [PATCH 111/507] Update MPF toString Signed-off-by: Christoph M. Wintersteiger --- src/util/mpf.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index cc4b3a35a..f5dcfc612 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -1181,14 +1181,13 @@ std::string mpf_manager::to_string(mpf const & x) { if (is_nan(x)) res = "NaN"; - else { - res = sgn(x) ? "-" : ""; - + else { if (is_inf(x)) - res += "INF"; + res = sgn(x) ? "-oo" : "+oo"; else if (is_zero(x)) - res += "0"; + res = sgn(x) ? "-zero" : "+zero"; else { + res = sgn(x) ? "-" : ""; scoped_mpz num(m_mpq_manager), denom(m_mpq_manager); num = 0; denom = 1; @@ -1218,7 +1217,7 @@ std::string mpf_manager::to_string(mpf const & x) { m_mpq_manager.display_decimal(ss, r, x.sbits); if (m_mpq_manager.is_int(r)) ss << ".0"; - ss << " " << exponent; + ss << "p" << exponent; res += ss.str(); } } From f684675a6e7bf18722ccb9d21b15768853a14cb9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 2 Jan 2015 18:58:43 +0000 Subject: [PATCH 112/507] FPA API: Added get_ebits/get_sbits + doc fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 20 +++++++++++++++ src/api/z3_fpa.h | 59 ++++++++++++++++++++++++++++++--------------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 97225f0f3..d2d4e7155 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -649,6 +649,26 @@ extern "C" { Z3_CATCH_RETURN(0); } + unsigned int Z3_API Z3_mk_fpa_get_ebits(Z3_context c, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_get_ebits(c, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + unsigned r = ctx->float_util().get_ebits(to_sort(s)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + + unsigned Z3_API Z3_mk_fpa_get_sbits(Z3_context c, Z3_sort s) { + Z3_TRY; + LOG_Z3_mk_fpa_get_sbits(c, s); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + unsigned r = ctx->float_util().get_sbits(to_sort(s)); + RETURN_Z3(r); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_to_ieee_bv(c, t); diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 61ee0bd7f..8208fbb2c 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -228,7 +228,7 @@ extern "C" { Z3_sort Z3_API Z3_mk_fpa_sort_128(__in Z3_context c); /** - \brief Create a NaN of sort s. + \brief Create a floating-point NaN of sort s. \param c logical context. \param s target sort @@ -266,6 +266,7 @@ extern "C" { /** \brief Create an expression of FloatingPoint sort from three bit-vector expressions. + This is the operator named `fp' in the SMT FP theory definition. Note that \c sign is required to be a bit-vector of size 1. Significand and exponent are required to be greater than 1 and 2 respectively. The FloatingPoint sort of the resulting expression is automatically determined from the bit-vector sizes @@ -495,7 +496,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_round_to_integral(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t); /** - \brief Minimum of floating-point numbers + \brief Minimum of floating-point numbers. \param c logical context. \param t1 term of FloatingPoint sort. @@ -508,7 +509,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_min(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Maximum of floating-point numbers + \brief Maximum of floating-point numbers. \param c logical context. \param t1 term of FloatingPoint sort. @@ -521,7 +522,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_max(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Floating-point less than or equal + \brief Floating-point less than or equal. \param c logical context. \param t1 term of FloatingPoint sort. @@ -534,7 +535,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_leq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Floating-point less-than + \brief Floating-point less than. \param c logical context. \param t1 term of FloatingPoint sort. @@ -547,7 +548,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_lt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Floating-point greater than or equal + \brief Floating-point greater than or equal. \param c logical context. \param t1 term of FloatingPoint sort. @@ -560,7 +561,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_geq(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Floating-point greater-than + \brief Floating-point greater than. \param c logical context. \param t1 term of FloatingPoint sort. @@ -573,7 +574,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_gt(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); /** - \brief Floating-point equality + \brief Floating-point equality. \param c logical context. \param t1 term of FloatingPoint sort. @@ -636,7 +637,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_is_infinite(__in Z3_context c, __in Z3_ast t); /** - \brief Predicate indicating whether t is a NaN + \brief Predicate indicating whether t is a NaN. \param c logical context. \param t term of FloatingPoint sort. @@ -682,16 +683,15 @@ extern "C" { \param s floating-point sort. s must be a FloatingPoint sort, t must be of bit-vector sort, and the bit-vector - size of bv, m, must be equal to ebits+sbits of s. The format of the bit-vector is - as defined by the IEEE 754-2008 interchange format and the resulting floating-point - sort (ebits, sbits) is automatically determined. + size of bv must be equal to ebits+sbits of s. The format of the bit-vector is + as defined by the IEEE 754-2008 interchange format. def_API('Z3_mk_fpa_to_fp_bv', AST, (_in(CONTEXT),_in(AST),_in(SORT))) */ Z3_ast Z3_API Z3_mk_fpa_to_fp_bv(__in Z3_context c, __in Z3_ast bv, __in Z3_sort s); /** - \brief Conversion of a floating-point term into another floating-point term of different floating-point sort. + \brief Conversion of a FloatingPoint term into another term of different FloatingPoint sort. Produces a term that represents the conversion of a floating-point term t to a floating-point term of sort s. If necessary, the result will be rounded according @@ -768,8 +768,8 @@ extern "C" { \brief Conversion of a floating-point term into an unsigned bit-vector. Produces a term that represents the conversion of the floating-poiunt term t into a - bit-vector term in unsigned 2's complement format. If necessary, the result will be - rounded according to rounding mode rm. + bit-vector term of size sz in unsigned 2's complement format. If necessary, the result + will be rounded according to rounding mode rm. \param c logical context. \param rm term of RoundingMode sort. @@ -784,8 +784,8 @@ extern "C" { \brief Conversion of a floating-point term into a signed bit-vector. Produces a term that represents the conversion of the floating-poiunt term t into a - bit-vector term in signed 2's complement format. If necessary, the result will be - rounded according to rounding mode rm. + bit-vector term of size sz in signed 2's complement format. If necessary, the result + will be rounded according to rounding mode rm. \param c logical context. \param rm term of RoundingMode sort. @@ -797,7 +797,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_to_sbv(__in Z3_context c, __in Z3_ast rm, __in Z3_ast t, __in unsigned sz); /** - \brief Conversion of a floating-point term into a real number. + \brief Conversion of a floating-point term into a real-numbered term. Produces a term that represents the conversion of the floating-poiunt term t into a real number. Note that this type of conversion will often result in non-linear @@ -810,11 +810,30 @@ extern "C" { */ Z3_ast Z3_API Z3_mk_fpa_to_real(__in Z3_context c, __in Z3_ast t); + /** @name Z3-specific extensions */ /*@{*/ + /** + \brief Retrieves the number of bits reserved for the exponent in a FloatingPoint sort. + + \param s FloatingPoint sort. + + def_API('Z3_mk_fpa_get_ebits', UINT, (_in(CONTEXT),_in(SORT))) + */ + unsigned Z3_API Z3_mk_fpa_get_ebits(__in Z3_context c, __in Z3_sort s); + + /** + \brief Retrieves the number of bits reserved for the significand in a FloatingPoint sort. + + \param s FloatingPoint sort. + + def_API('Z3_mk_fpa_get_sbits', UINT, (_in(CONTEXT),_in(SORT))) + */ + unsigned Z3_API Z3_mk_fpa_get_sbits(__in Z3_context c, __in Z3_sort s); + /** \brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. @@ -842,8 +861,8 @@ extern "C" { \param c logical context. \param rm term of RoundingMode sort. \param sig significand term of Real sort. - \param exp exponent term of Real sort. - \param s floating-point sort. + \param exp exponent term of Int sort. + \param s FloatingPoint sort. s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of real sort. From 3266e96e8008e1544e0ecb86717ab7314ac5c125 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 2 Jan 2015 18:59:27 +0000 Subject: [PATCH 113/507] fpa2bv slight refactoring Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 349 ++++++++++++++++--------------- src/ast/fpa/fpa2bv_converter.h | 6 +- 2 files changed, 181 insertions(+), 174 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 94538861d..d51e34058 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1873,7 +1873,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args m_arith_util.is_numeral(args[1]) && m_arith_util.is_numeral(args[2])) { - // Three arguments, some of them are not numerals. + // rm + real + int -> float SASSERT(m_util.is_float(f->get_range())); unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); @@ -1926,191 +1926,197 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args else if (num == 1 && m_bv_util.is_bv(args[0])) { sort * s = f->get_range(); unsigned to_sbits = m_util.get_sbits(s); - unsigned to_ebits = m_util.get_ebits(s); + unsigned to_ebits = m_util.get_ebits(s); expr * bv = args[0]; int sz = m_bv_util.get_bv_size(bv); SASSERT((unsigned)sz == to_sbits + to_ebits); - + mk_triple(m_bv_util.mk_extract(sz - 1, sz - 1, bv), m_bv_util.mk_extract(sz - to_ebits - 2, 0, bv), m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), result); } - else if (num == 2 && + else if (num == 2 && + m_util.is_rm(args[0]) && is_app(args[1]) && - m_util.is_float(m.get_sort(args[1]))) { - // We also support float to float conversion - sort * s = f->get_range(); - expr_ref rm(m), x(m); - rm = args[0]; - x = args[1]; - - unsigned from_sbits = m_util.get_sbits(m.get_sort(x)); - unsigned from_ebits = m_util.get_ebits(m.get_sort(x)); - unsigned to_sbits = m_util.get_sbits(s); - unsigned to_ebits = m_util.get_ebits(s); - - if (from_sbits == to_sbits && from_ebits == to_ebits) - result = x; - else { - expr_ref c1(m), c2(m), c3(m), c4(m), c5(m); - expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m); - expr_ref one1(m); - - one1 = m_bv_util.mk_numeral(1, 1); - expr_ref ninf(m), pinf(m); - mk_pinf(f, pinf); - mk_ninf(f, ninf); - - // NaN -> NaN - mk_is_nan(x, c1); - mk_nan(f, v1); - - // +0 -> +0 - mk_is_pzero(x, c2); - mk_pzero(f, v2); - - // -0 -> -0 - mk_is_nzero(x, c3); - mk_nzero(f, v3); - - // +oo -> +oo - mk_is_pinf(x, c4); - v4 = pinf; - - // -oo -> -oo - mk_is_ninf(x, c5); - v5 = ninf; - - // otherwise: the actual conversion with rounding. - expr_ref sgn(m), sig(m), exp(m), lz(m); - unpack(x, sgn, sig, exp, lz, true); - - dbg_decouple("fpa2bv_to_float_x_sig", sig); - dbg_decouple("fpa2bv_to_float_x_exp", exp); - dbg_decouple("fpa2bv_to_float_lz", lz); - - expr_ref res_sgn(m), res_sig(m), res_exp(m); - - res_sgn = sgn; - - SASSERT(m_bv_util.get_bv_size(sgn) == 1); - SASSERT(m_bv_util.get_bv_size(sig) == from_sbits); - SASSERT(m_bv_util.get_bv_size(exp) == from_ebits); - SASSERT(m_bv_util.get_bv_size(lz) == from_ebits); - - if (from_sbits < (to_sbits + 3)) - { - // make sure that sig has at least to_sbits + 3 - res_sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, to_sbits+3-from_sbits)); - } - else if (from_sbits > (to_sbits + 3)) - { - // collapse the extra bits into a sticky bit. - expr_ref sticky(m), low(m), high(m); - low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig); - high = m_bv_util.mk_extract(from_sbits - 1, from_sbits - to_sbits - 2, sig); - sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, low.get()); - res_sig = m_bv_util.mk_concat(high, sticky); - } - else - res_sig = sig; - - res_sig = m_bv_util.mk_zero_extend(1, res_sig); // extra zero in the front for the rounder. - unsigned sig_sz = m_bv_util.get_bv_size(res_sig); - SASSERT(sig_sz == to_sbits+4); - - expr_ref exponent_overflow(m); - exponent_overflow = m.mk_false(); - - if (from_ebits < (to_ebits + 2)) - { - res_exp = m_bv_util.mk_sign_extend(to_ebits-from_ebits+2, exp); - - // subtract lz for subnormal numbers. - expr_ref lz_ext(m); - lz_ext = m_bv_util.mk_zero_extend(to_ebits-from_ebits+2, lz); - res_exp = m_bv_util.mk_bv_sub(res_exp, lz_ext); - } - else if (from_ebits > (to_ebits + 2)) - { - expr_ref high(m), low(m), lows(m), high_red_or(m), high_red_and(m), h_or_eq(m), h_and_eq(m); - expr_ref no_ovf(m), zero1(m), s_is_one(m), s_is_zero(m); - high = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, exp); - low = m_bv_util.mk_extract(to_ebits+1, 0, exp); - lows = m_bv_util.mk_extract(to_ebits+1, to_ebits+1, low); - - high_red_or = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, high.get()); - high_red_and = m.mk_app(m_bv_util.get_fid(), OP_BREDAND, high.get()); - - zero1 = m_bv_util.mk_numeral(0, 1); - m_simp.mk_eq(high_red_and, one1, h_and_eq); - m_simp.mk_eq(high_red_or, zero1, h_or_eq); - m_simp.mk_eq(lows, zero1, s_is_zero); - m_simp.mk_eq(lows, one1, s_is_one); - - expr_ref c2(m); - m_simp.mk_ite(h_or_eq, s_is_one, m.mk_false(), c2); - m_simp.mk_ite(h_and_eq, s_is_zero, c2, exponent_overflow); - - // Note: Upon overflow, we _could_ try to shift the significand around... - - // subtract lz for subnormal numbers. - expr_ref lz_ext(m), lz_rest(m), lz_redor(m), lz_redor_bool(m); - lz_ext = m_bv_util.mk_extract(to_ebits+1, 0, lz); - lz_rest = m_bv_util.mk_extract(from_ebits-1, to_ebits+2, lz); - lz_redor = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, lz_rest.get()); - m_simp.mk_eq(lz_redor, one1, lz_redor_bool); - m_simp.mk_or(exponent_overflow, lz_redor_bool, exponent_overflow); - - res_exp = m_bv_util.mk_bv_sub(low, lz_ext); - } - else // from_ebits == (to_ebits + 2) - res_exp = m_bv_util.mk_bv_sub(exp, lz); - - SASSERT(m_bv_util.get_bv_size(res_exp) == to_ebits+2); - SASSERT(is_well_sorted(m, res_exp)); - - dbg_decouple("fpa2bv_to_float_res_sig", res_sig); - dbg_decouple("fpa2bv_to_float_res_exp", res_exp); - - expr_ref rounded(m); - round(s, rm, res_sgn, res_sig, res_exp, rounded); - - expr_ref is_neg(m), sig_inf(m); - m_simp.mk_eq(sgn, one1, is_neg); - mk_ite(is_neg, ninf, pinf, sig_inf); - - dbg_decouple("fpa2bv_to_float_exp_ovf", exponent_overflow); - mk_ite(exponent_overflow, sig_inf, rounded, v6); - - // And finally, we tie them together. - mk_ite(c5, v5, v6, result); - mk_ite(c4, v4, result, result); - mk_ite(c3, v3, result, result); - mk_ite(c2, v2, result, result); - mk_ite(c1, v1, result, result); - } + m_util.is_float(m.get_sort(args[1]))) { + // float -> float conversion + mk_to_fp_float(f, f->get_range(), args[0], args[1], result); } - else if (num == 2 && + else if (num == 2 && m_util.is_rm(args[0]), m_arith_util.is_real(args[1])) { - // .. other than that, we only support rationals for to_fp - SASSERT(m_util.is_float(f->get_range())); - unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); + // rm + real -> float + mk_to_fp_real(f, f->get_range(), args[0], args[1], result); + } + else + UNREACHABLE(); - SASSERT(m_bv_util.is_numeral(args[0])); + SASSERT(is_well_sorted(m, result)); +} + +void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result) { + unsigned from_sbits = m_util.get_sbits(m.get_sort(x)); + unsigned from_ebits = m_util.get_ebits(m.get_sort(x)); + unsigned to_sbits = m_util.get_sbits(s); + unsigned to_ebits = m_util.get_ebits(s); + + if (from_sbits == to_sbits && from_ebits == to_ebits) + result = x; + else { + expr_ref c1(m), c2(m), c3(m), c4(m), c5(m); + expr_ref v1(m), v2(m), v3(m), v4(m), v5(m), v6(m); + expr_ref one1(m); + + one1 = m_bv_util.mk_numeral(1, 1); + expr_ref ninf(m), pinf(m); + mk_pinf(f, pinf); + mk_ninf(f, ninf); + + // NaN -> NaN + mk_is_nan(x, c1); + mk_nan(f, v1); + + // +0 -> +0 + mk_is_pzero(x, c2); + mk_pzero(f, v2); + + // -0 -> -0 + mk_is_nzero(x, c3); + mk_nzero(f, v3); + + // +oo -> +oo + mk_is_pinf(x, c4); + v4 = pinf; + + // -oo -> -oo + mk_is_ninf(x, c5); + v5 = ninf; + + // otherwise: the actual conversion with rounding. + expr_ref sgn(m), sig(m), exp(m), lz(m); + unpack(x, sgn, sig, exp, lz, true); + + dbg_decouple("fpa2bv_to_float_x_sig", sig); + dbg_decouple("fpa2bv_to_float_x_exp", exp); + dbg_decouple("fpa2bv_to_float_lz", lz); + + expr_ref res_sgn(m), res_sig(m), res_exp(m); + + res_sgn = sgn; + + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(sig) == from_sbits); + SASSERT(m_bv_util.get_bv_size(exp) == from_ebits); + SASSERT(m_bv_util.get_bv_size(lz) == from_ebits); + + if (from_sbits < (to_sbits + 3)) { + // make sure that sig has at least to_sbits + 3 + res_sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, to_sbits + 3 - from_sbits)); + } + else if (from_sbits >(to_sbits + 3)) { + // collapse the extra bits into a sticky bit. + expr_ref sticky(m), low(m), high(m); + low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig); + high = m_bv_util.mk_extract(from_sbits - 1, from_sbits - to_sbits - 2, sig); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, low.get()); + res_sig = m_bv_util.mk_concat(high, sticky); + } + else + res_sig = sig; + + res_sig = m_bv_util.mk_zero_extend(1, res_sig); // extra zero in the front for the rounder. + unsigned sig_sz = m_bv_util.get_bv_size(res_sig); + SASSERT(sig_sz == to_sbits + 4); + + expr_ref exponent_overflow(m); + exponent_overflow = m.mk_false(); + + if (from_ebits < (to_ebits + 2)) { + res_exp = m_bv_util.mk_sign_extend(to_ebits - from_ebits + 2, exp); + + // subtract lz for subnormal numbers. + expr_ref lz_ext(m); + lz_ext = m_bv_util.mk_zero_extend(to_ebits - from_ebits + 2, lz); + res_exp = m_bv_util.mk_bv_sub(res_exp, lz_ext); + } + else if (from_ebits >(to_ebits + 2)) { + expr_ref high(m), low(m), lows(m), high_red_or(m), high_red_and(m), h_or_eq(m), h_and_eq(m); + expr_ref no_ovf(m), zero1(m), s_is_one(m), s_is_zero(m); + high = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, exp); + low = m_bv_util.mk_extract(to_ebits + 1, 0, exp); + lows = m_bv_util.mk_extract(to_ebits + 1, to_ebits + 1, low); + + high_red_or = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, high.get()); + high_red_and = m.mk_app(m_bv_util.get_fid(), OP_BREDAND, high.get()); + + zero1 = m_bv_util.mk_numeral(0, 1); + m_simp.mk_eq(high_red_and, one1, h_and_eq); + m_simp.mk_eq(high_red_or, zero1, h_or_eq); + m_simp.mk_eq(lows, zero1, s_is_zero); + m_simp.mk_eq(lows, one1, s_is_one); + + expr_ref c2(m); + m_simp.mk_ite(h_or_eq, s_is_one, m.mk_false(), c2); + m_simp.mk_ite(h_and_eq, s_is_zero, c2, exponent_overflow); + + // Note: Upon overflow, we _could_ try to shift the significand around... + + // subtract lz for subnormal numbers. + expr_ref lz_ext(m), lz_rest(m), lz_redor(m), lz_redor_bool(m); + lz_ext = m_bv_util.mk_extract(to_ebits + 1, 0, lz); + lz_rest = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, lz); + lz_redor = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, lz_rest.get()); + m_simp.mk_eq(lz_redor, one1, lz_redor_bool); + m_simp.mk_or(exponent_overflow, lz_redor_bool, exponent_overflow); + + res_exp = m_bv_util.mk_bv_sub(low, lz_ext); + } + else // from_ebits == (to_ebits + 2) + res_exp = m_bv_util.mk_bv_sub(exp, lz); + + SASSERT(m_bv_util.get_bv_size(res_exp) == to_ebits + 2); + SASSERT(is_well_sorted(m, res_exp)); + + dbg_decouple("fpa2bv_to_float_res_sig", res_sig); + dbg_decouple("fpa2bv_to_float_res_exp", res_exp); + + expr_ref rounded(m); + round(s, expr_ref (rm, m), res_sgn, res_sig, res_exp, rounded); + + expr_ref is_neg(m), sig_inf(m); + m_simp.mk_eq(sgn, one1, is_neg); + mk_ite(is_neg, ninf, pinf, sig_inf); + + dbg_decouple("fpa2bv_to_float_exp_ovf", exponent_overflow); + mk_ite(exponent_overflow, sig_inf, rounded, v6); + + // And finally, we tie them together. + mk_ite(c5, v5, v6, result); + mk_ite(c4, v4, result, result); + mk_ite(c3, v3, result, result); + mk_ite(c2, v2, result, result); + mk_ite(c1, v1, result, result); + } + + SASSERT(is_well_sorted(m, result)); +} + +void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result) { + SASSERT(m_util.is_float(s)); + unsigned ebits = m_util.get_ebits(s); + unsigned sbits = m_util.get_sbits(s); + + if (m_bv_util.is_numeral(rm) && m_util.au().is_numeral(x)) { rational tmp_rat; unsigned sz; - m_bv_util.is_numeral(to_expr(args[0]), tmp_rat, sz); + m_bv_util.is_numeral(to_expr(rm), tmp_rat, sz); SASSERT(tmp_rat.is_int32()); SASSERT(sz == 3); BV_RM_VAL bv_rm = (BV_RM_VAL)tmp_rat.get_unsigned(); mpf_rounding_mode rm; - switch (bv_rm) - { + switch (bv_rm) { case BV_RM_TIES_TO_AWAY: rm = MPF_ROUND_NEAREST_TAWAY; break; case BV_RM_TIES_TO_EVEN: rm = MPF_ROUND_NEAREST_TEVEN; break; case BV_RM_TO_NEGATIVE: rm = MPF_ROUND_TOWARD_NEGATIVE; break; @@ -2119,10 +2125,8 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args default: UNREACHABLE(); } - SASSERT(m_util.au().is_numeral(args[1])); - rational q; - m_util.au().is_numeral(args[1], q); + m_util.au().is_numeral(x, q); scoped_mpf v(m_mpf_manager); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq()); @@ -2135,10 +2139,11 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args mk_triple(sgn, s, e, result); } - else - UNREACHABLE(); + else { + NOT_IMPLEMENTED_YET(); + } - SASSERT(is_well_sorted(m, result)); + SASSERT(is_well_sorted(m, result)); } void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 197c7ce9a..6a7b6e92f 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -129,7 +129,9 @@ public: void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); + void mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); void mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); @@ -186,7 +188,7 @@ protected: expr_ref & c_sgn, expr_ref & c_sig, expr_ref & c_exp, expr_ref & d_sgn, expr_ref & d_sig, expr_ref & d_exp, expr_ref & res_sgn, expr_ref & res_sig, expr_ref & res_exp); - app * mk_fresh_const(char const * prefix, unsigned sz); + app * mk_fresh_const(char const * prefix, unsigned sz); }; #endif From 3c75b700e88d04cac373e05ecef1cbd9270e4090 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 2 Jan 2015 19:03:20 +0000 Subject: [PATCH 114/507] Updates to the .NET API for FP Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 665 +++++++++++++++++++++++++++++++------ src/api/dotnet/FPExpr.cs | 2 +- src/api/dotnet/FPNum.cs | 2 +- src/api/dotnet/FPRMExpr.cs | 2 +- src/api/dotnet/FPRMNum.cs | 2 +- src/api/dotnet/FPRMSort.cs | 4 +- src/api/dotnet/FPSort.cs | 15 +- 7 files changed, 575 insertions(+), 117 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 69855fc4f..986efc94d 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3439,65 +3439,118 @@ namespace Microsoft.Z3 #endregion #region Floating-Point Arithmetic + + #region Rounding Modes + #region RoundingMode Sort /// - /// Create a floating point rounding mode sort. + /// Create the floating-point RoundingMode sort. /// - public FPRMSort MkFPRMSort() + public FPRMSort MkFPRoundingModeSort() { Contract.Ensures(Contract.Result() != null); return new FPRMSort(this); } - + #endregion + + #region Numerals /// - /// Create a NearestTiesToEven rounding mode numeral. + /// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. /// - public FPRMNum MkFPRMNearestTiesToEven() + public FPRMNum MkFPRoundNearestTiesToEven() { Contract.Ensures(Contract.Result() != null); return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_even(nCtx)); } /// - /// Create a NearestTiesToAway rounding mode numeral. + /// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. /// - public FPRMNum MkFPRMNearestTiesToAway() + public FPRMNum MkFPRNE() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_rne(nCtx)); + } + + /// + /// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. + /// + public FPRMNum MkFPRoundNearestTiesToAway() { Contract.Ensures(Contract.Result() != null); return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx)); } /// - /// Create a TowardPositive rounding mode numeral. + /// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. /// - public FPRMNum MkFPRMTowardPositive() + public FPRMNum MkFPRNA() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_rna(nCtx)); + } + + /// + /// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. + /// + public FPRMNum MkFPRoundTowardPositive() { Contract.Ensures(Contract.Result() != null); return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_positive(nCtx)); } /// - /// Create a TowardNegative rounding mode numeral. + /// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. /// - public FPRMNum MkFPRMTowardNegative() + public FPRMNum MkFPRTP() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_rtp(nCtx)); + } + + /// + /// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. + /// + public FPRMNum MkFPRoundTowardNegative() { Contract.Ensures(Contract.Result() != null); return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_negative(nCtx)); } /// - /// Create a TowardZero rounding mode numeral. + /// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. /// - public FPRMNum MkFPRMTowardZero() + public FPRMNum MkFPRTN() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_rtn(nCtx)); + } + + /// + /// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. + /// + public FPRMNum MkFPRoundTowardZero() { Contract.Ensures(Contract.Result() != null); return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_zero(nCtx)); } /// - /// Create a floating point sort. + /// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. /// - /// exponent bits in the floating point sort. - /// significand bits in the floating point sort. + public FPRMNum MkFPRTZ() + { + Contract.Ensures(Contract.Result() != null); + return new FPRMNum(this, Native.Z3_mk_fpa_rtz(nCtx)); + } + #endregion + #endregion + + #region FloatingPoint Sorts + /// + /// Create a FloatingPoint sort. + /// + /// exponent bits in the FloatingPoint sort. + /// significand bits in the FloatingPoint sort. public FPSort MkFPSort(uint ebits, uint sbits) { Contract.Ensures(Contract.Result() != null); @@ -3505,9 +3558,83 @@ namespace Microsoft.Z3 } /// - /// Create a floating point NaN numeral. + /// Create the half-precision (16-bit) FloatingPoint sort. + /// + public FPSort MkFPSortHalf() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_half(nCtx)); + } + + /// + /// Create the half-precision (16-bit) FloatingPoint sort. + /// + public FPSort MkFPSort16() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_16(nCtx)); + } + + /// + /// Create the single-precision (32-bit) FloatingPoint sort. + /// + public FPSort MkFPSortSingle() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_single(nCtx)); + } + + /// + /// Create the single-precision (32-bit) FloatingPoint sort. + /// + public FPSort MkFPSort32() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_16(nCtx)); + } + + /// + /// Create the double-precision (64-bit) FloatingPoint sort. + /// + public FPSort MkFPSortDouble() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_double(nCtx)); + } + + /// + /// Create the double-precision (64-bit) FloatingPoint sort. + /// + public FPSort MkFPSort64() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_64(nCtx)); + } + + /// + /// Create the quadruple-precision (128-bit) FloatingPoint sort. + /// + public FPSort MkFPSortQuadruple() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_double(nCtx)); + } + + /// + /// Create the quadruple-precision (128-bit) FloatingPoint sort. + /// + public FPSort MkFPSort128() + { + Contract.Ensures(Contract.Result() != null); + return new FPSort(this, Native.Z3_mk_fpa_sort_128(nCtx)); + } + #endregion + + #region Numerals + /// + /// Create a NaN of sort s. /// - /// floating point sort. + /// FloatingPoint sort. public FPNum MkFPNaN(FPSort s) { Contract.Ensures(Contract.Result() != null); @@ -3515,9 +3642,9 @@ namespace Microsoft.Z3 } /// - /// Create a floating point Inf numeral. + /// Create a floating-point infinity of sort s. /// - /// floating point sort. + /// FloatingPoint sort. /// indicates whether the result should be negative. public FPNum MkFPInf(FPSort s, bool negative) { @@ -3526,20 +3653,141 @@ namespace Microsoft.Z3 } /// - /// Create a floating point numeral. - /// - /// A string representing the value in decimal notation. - /// floating point sort + /// Create a floating-point zero of sort s. + /// + /// FloatingPoint sort. + /// indicates whether the result should be negative. + public FPNum MkFPZero(FPSort s, bool negative) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_zero(nCtx, s.NativeObject, negative ? 1 : 0)); + } + + /// + /// Create a numeral of FloatingPoint sort from a float. + /// + /// numeral value. + /// FloatingPoint sort. + public FPNum MkFPNumeral(float v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_numeral_float(nCtx, v, s.NativeObject)); + } + + /// + /// Create a numeral of FloatingPoint sort from a float. + /// + /// numeral value. + /// FloatingPoint sort. + public FPNum MkFPNumeral(double v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_numeral_double(nCtx, v, s.NativeObject)); + } + + /// + /// Create a numeral of FloatingPoint sort from an int. + /// + /// numeral value. + /// FloatingPoint sort. + public FPNum MkFPNumeral(int v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_numeral_int(nCtx, v, s.NativeObject)); + } + + /// + /// Create a numeral of FloatingPoint sort from a sign bit and two integers. + /// + /// the sign. + /// the significand. + /// the exponent. + /// FloatingPoint sort. + public FPNum MkFPNumeral(bool sgn, uint sig, int exp, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_numeral_uint_int(nCtx, sgn ? 1 : 0, sig, exp, s.NativeObject)); + } + + /// + /// Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. + /// + /// the sign. + /// the significand. + /// the exponent. + /// FloatingPoint sort. + public FPNum MkFPNumeral(bool sgn, UInt64 sig, Int64 exp, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPNum(this, Native.Z3_mk_fpa_numeral_uint64_int64(nCtx, sgn ? 1 : 0, sig, exp, s.NativeObject)); + } + + /// + /// Create a numeral of FloatingPoint sort from a float. + /// + /// numeral value. + /// FloatingPoint sort. + public FPNum MkFP(float v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return MkFPNumeral(v, s); + } + + /// + /// Create a numeral of FloatingPoint sort from a float. + /// + /// numeral value. + /// FloatingPoint sort. public FPNum MkFP(double v, FPSort s) { - Contract.Ensures(Contract.Result() != null); - return new FPNum(this, Native.Z3_mk_fpa_numeral_double(this.nCtx, v, s.NativeObject)); - } + Contract.Ensures(Contract.Result() != null); + return MkFPNumeral(v, s); + } + /// + /// Create a numeral of FloatingPoint sort from an int. + /// + /// numeral value. + /// FloatingPoint sort. + public FPNum MkFP(int v, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return MkFPNumeral(v, s); + } + + /// + /// Create a numeral of FloatingPoint sort from a sign bit and two integers. + /// + /// the sign. + /// the significand. + /// the exponent. + /// FloatingPoint sort. + public FPNum MkFP(bool sgn, uint sig, int exp, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return MkFPNumeral(sgn, sig, exp, s); + } + + /// + /// Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. + /// + /// the sign. + /// the significand. + /// the exponent. + /// FloatingPoint sort. + public FPNum MkFP(bool sgn, UInt64 sig, Int64 exp, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return MkFPNumeral(sgn, sig, exp, s); + } + + #endregion + + #region Operators /// /// Floating-point absolute value /// - /// floating point term + /// floating-point term public FPExpr MkFPAbs(FPExpr t) { Contract.Ensures(Contract.Result() != null); @@ -3549,7 +3797,7 @@ namespace Microsoft.Z3 /// /// Floating-point negation /// - /// floating point term + /// floating-point term public FPExpr MkFPNeg(FPExpr t) { Contract.Ensures(Contract.Result() != null); @@ -3560,8 +3808,8 @@ namespace Microsoft.Z3 /// Floating-point addition /// /// rounding mode term - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public FPExpr MkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3572,8 +3820,8 @@ namespace Microsoft.Z3 /// Floating-point subtraction /// /// rounding mode term - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public FPExpr MkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3584,8 +3832,8 @@ namespace Microsoft.Z3 /// Floating-point multiplication /// /// rounding mode term - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public FPExpr MkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3596,8 +3844,8 @@ namespace Microsoft.Z3 /// Floating-point division /// /// rounding mode term - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public FPExpr MkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3611,9 +3859,9 @@ namespace Microsoft.Z3 /// The result is round((t1 * t2) + t3) /// /// rounding mode term - /// floating point term - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term + /// floating-point term public FPExpr MkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3) { Contract.Ensures(Contract.Result() != null); @@ -3624,7 +3872,7 @@ namespace Microsoft.Z3 /// Floating-point square root /// /// rounding mode term - /// floating point term + /// floating-point term public FPExpr MkFPSqrt(FPRMExpr rm, FPExpr t) { Contract.Ensures(Contract.Result() != null); @@ -3634,33 +3882,53 @@ namespace Microsoft.Z3 /// /// Floating-point remainder /// - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public FPExpr MkFPRem(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_rem(this.nCtx, t1.NativeObject, t2.NativeObject)); } - + /// - /// Floating-point equality - /// - /// - /// Note that this is IEEE 754 equality (as opposed to standard =). - /// - /// floating point term - /// floating point term - public BoolExpr MkFPEq(FPExpr t1, FPExpr t2) - { - Contract.Ensures(Contract.Result() != null); - return new BoolExpr(this, Native.Z3_mk_fpa_eq(this.nCtx, t1.NativeObject, t2.NativeObject)); - } - - /// - /// Floating-point less than or equal + /// Floating-point roundToIntegral. Rounds a floating-point number to + /// the closest integer, again represented as a floating-point number. /// - /// floating point term - /// floating point term + /// term of RoundingMode sort + /// floating-point term + public FPExpr MkFPRoundToIntegral(FPRMExpr rm, FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_round_to_integral(this.nCtx, rm.NativeObject, t.NativeObject)); + } + + /// + /// Minimum of floating-point numbers. + /// + /// floating-point term + /// floating-point term + public FPExpr MkFPMin(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_min(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Maximum of floating-point numbers. + /// + /// floating-point term + /// floating-point term + public FPExpr MkFPMax(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_max(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Floating-point less than or equal. + /// + /// floating-point term + /// floating-point term public BoolExpr MkFPLEq(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3668,10 +3936,10 @@ namespace Microsoft.Z3 } /// - /// Floating-point less than + /// Floating-point less than. /// - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public BoolExpr MkFPLt(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3679,10 +3947,10 @@ namespace Microsoft.Z3 } /// - /// Floating-point greater than or equal + /// Floating-point greater than or equal. /// - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public BoolExpr MkFPGEq(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3690,10 +3958,10 @@ namespace Microsoft.Z3 } /// - /// Floating-point greater than + /// Floating-point greater than. /// - /// floating point term - /// floating point term + /// floating-point term + /// floating-point term public BoolExpr MkFPGt(FPExpr t1, FPExpr t2) { Contract.Ensures(Contract.Result() != null); @@ -3701,9 +3969,23 @@ namespace Microsoft.Z3 } /// - /// Predicate indicating whether t is a normal floating point number + /// Floating-point equality. + /// + /// + /// Note that this is IEEE 754 equality (as opposed to standard =). + /// + /// floating-point term + /// floating-point term + public BoolExpr MkFPEq(FPExpr t1, FPExpr t2) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_eq(this.nCtx, t1.NativeObject, t2.NativeObject)); + } + + /// + /// Predicate indicating whether t is a normal floating-point number. /// - /// floating point term + /// floating-point term public BoolExpr MkFPIsNormal(FPExpr t) { Contract.Ensures(Contract.Result() != null); @@ -3711,9 +3993,9 @@ namespace Microsoft.Z3 } /// - /// Predicate indicating whether t is a subnormal floating point number + /// Predicate indicating whether t is a subnormal floating-point number. /// - /// floating point term + /// floating-point term public BoolExpr MkFPIsSubnormal(FPExpr t) { Contract.Ensures(Contract.Result() != null); @@ -3721,29 +4003,29 @@ namespace Microsoft.Z3 } /// - /// Predicate indicating whether t is a floating point number with zero value, i.e., +0 or -0. + /// Predicate indicating whether t is a floating-point number with zero value, i.e., +0 or -0. /// - /// floating point term - public BoolExpr MkFPIsZero(FPExpr t) - { + /// floating-point term + public BoolExpr MkFPIsZero(FPExpr t) + { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_zero(this.nCtx, t.NativeObject)); } /// - /// Predicate indicating whether t is a floating point number representing +Inf or -Inf + /// Predicate indicating whether t is a floating-point number representing +oo or -oo. /// - /// floating point term - public BoolExpr MkFPIsInf(FPExpr t) - { + /// floating-point term + public BoolExpr MkFPIsInfinite(FPExpr t) + { Contract.Ensures(Contract.Result() != null); return new BoolExpr(this, Native.Z3_mk_fpa_is_infinite(this.nCtx, t.NativeObject)); } /// - /// Predicate indicating whether t is a NaN + /// Predicate indicating whether t is a NaN. /// - /// floating point term + /// floating-point term public BoolExpr MkFPIsNaN(FPExpr t) { Contract.Ensures(Contract.Result() != null); @@ -3751,45 +4033,212 @@ namespace Microsoft.Z3 } /// - /// Floating-point minimum + /// Predicate indicating whether t is a negative floating-point number. /// - /// floating point term - /// floating point term - public FPExpr MkFPMin(FPExpr t1, FPExpr t2) + /// floating-point term + public BoolExpr MkFPIsNegative(FPExpr t) { - Contract.Ensures(Contract.Result() != null); - return new FPExpr(this, Native.Z3_mk_fpa_min(this.nCtx, t1.NativeObject, t2.NativeObject)); + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_negative(this.nCtx, t.NativeObject)); } - - /// - /// Floating-point maximium - /// - /// floating point term - /// floating point term - public FPExpr MkFPMax(FPExpr t1, FPExpr t2) - { - Contract.Ensures(Contract.Result() != null); - return new FPExpr(this, Native.Z3_mk_fpa_max(this.nCtx, t1.NativeObject, t2.NativeObject)); - } /// - /// Conversion of a floating point number to another floating-point sort s. + /// Predicate indicating whether t is a positive floating-point number. + /// + /// floating-point term + public BoolExpr MkFPIsPositive(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BoolExpr(this, Native.Z3_mk_fpa_is_positive(this.nCtx, t.NativeObject)); + } + #endregion + + #region Conversions to FloatingPoint terms + /// + /// Create an expression of FloatingPoint sort from three bit-vector expressions. + /// + /// + /// This is the operator named `fp' in the SMT FP theory definition. + /// Note that sgn is required to be a bit-vector of size 1. Significand and exponent + /// are required to be greater than 1 and 2 respectively. The FloatingPoint sort + /// of the resulting expression is automatically determined from the bit-vector sizes + /// of the arguments. + /// + /// bit-vector term (of size 1) representing the sign. + /// bit-vector term representing the significand. + /// bit-vector term representing the exponent. + public FPExpr MkFP(BitVecExpr sgn, BitVecExpr sig, BitVecExpr exp) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_fp(this.nCtx, sgn.NativeObject, sig.NativeObject, exp.NativeObject)); + } + + /// + /// Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. + /// + /// + /// Produces a term that represents the conversion of a bit-vector term bv to a + /// floating-point term of sort s. The bit-vector size of bv (m) must be equal + /// to ebits+sbits of s. The format of the bit-vector is as defined by the + /// IEEE 754-2008 interchange format. + /// + /// bit-vector value (of size m). + /// FloatingPoint sort (ebits+sbits == m) + public FPExpr MkFPToFP(BitVecExpr bv, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_to_fp_bv(this.nCtx, bv.NativeObject, s.NativeObject)); + } + + /// + /// Conversion of a FloatingPoint term into another term of different FloatingPoint sort. + /// + /// + /// Produces a term that represents the conversion of a floating-point term t to a + /// floating-point term of sort s. If necessary, the result will be rounded according + /// to rounding mode rm. + /// + /// RoundingMode term. + /// FloatingPoint term. + /// FloatingPoint sort. + public FPExpr MkFPToFP(FPRMExpr rm, FPExpr t, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_to_fp_float(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject)); + } + + /// + /// Conversion of a term of real sort into a term of FloatingPoint sort. + /// + /// + /// Produces a term that represents the conversion of term t of real sort into a + /// floating-point term of sort s. If necessary, the result will be rounded according + /// to rounding mode rm. + /// + /// RoundingMode term. + /// term of Real sort. + /// FloatingPoint sort. + public FPExpr MkFPToFP(FPRMExpr rm, RealExpr t, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new FPExpr(this, Native.Z3_mk_fpa_to_fp_real(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject)); + } + + /// + /// Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. + /// + /// + /// Produces a term that represents the conversion of the bit-vector term t into a + /// floating-point term of sort s. The bit-vector t is taken to be in signed + /// 2's complement format (when signed==true, otherwise unsigned). If necessary, the + /// result will be rounded according to rounding mode rm. + /// + /// RoundingMode term. + /// term of bit-vector sort. + /// FloatingPoint sort. + /// flag indicating whether t is interpreted as signed or unsigned bit-vector. + public FPExpr MkFPToFP(FPRMExpr rm, BitVecExpr t, FPSort s, bool signed) + { + Contract.Ensures(Contract.Result() != null); + if (signed) + return new FPExpr(this, Native.Z3_mk_fpa_to_fp_signed(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject)); + else + return new FPExpr(this, Native.Z3_mk_fpa_to_fp_unsigned(this.nCtx, rm.NativeObject, t.NativeObject, s.NativeObject)); + } + + /// + /// Conversion of a floating-point number to another FloatingPoint sort s. /// /// /// Produces a term that represents the conversion of a floating-point term t to a different - /// floating point sort s. If necessary, rounding according to rm is applied. + /// FloatingPoint sort s. If necessary, rounding according to rm is applied. /// - /// floating point sort - /// floating point rounding mode term - /// floating point term - public FPExpr MkFPToFP(FPSort s, FPRMExpr rm, FPExpr t) + /// FloatingPoint sort + /// floating-point rounding mode term + /// floating-point term + public FPExpr MkFPToFP(FPSort s, FPRMExpr rm, FPExpr t) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_to_fp_float(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); } #endregion + #region Conversions from FloatingPoint terms + /// + /// Conversion of a floating-point term into a bit-vector. + /// + /// + /// Produces a term that represents the conversion of the floating-poiunt term t into a + /// bit-vector term of size sz in 2's complement format (signed when signed==true). If necessary, + /// the result will be rounded according to rounding mode rm. + /// + /// RoundingMode term. + /// FloatingPoint term + /// Size of the resulting bit-vector. + /// Indicates whether the result is a signed or unsigned bit-vector. + public BitVecExpr MkFPToBV(FPRMExpr rm, FPExpr t, uint sz, bool signed) + { + Contract.Ensures(Contract.Result() != null); + if (signed) + return new BitVecExpr(this, Native.Z3_mk_fpa_to_sbv(this.nCtx, rm.NativeObject, t.NativeObject, sz)); + else + return new BitVecExpr(this, Native.Z3_mk_fpa_to_ubv(this.nCtx, rm.NativeObject, t.NativeObject, sz)); + } + + /// + /// Conversion of a floating-point term into a real-numbered term. + /// + /// + /// Produces a term that represents the conversion of the floating-poiunt term t into a + /// real number. Note that this type of conversion will often result in non-linear + /// constraints over real terms. + /// + /// FloatingPoint term + public RealExpr MkFPToReal(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new RealExpr(this, Native.Z3_mk_fpa_to_real(this.nCtx, t.NativeObject)); + } + #endregion + + #region Z3-specific extensions + /// + /// Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. + /// + /// + /// The size of the resulting bit-vector is automatically determined. Note that + /// IEEE 754-2008 allows multiple different representations of NaN. This conversion + /// knows only one NaN and it will always produce the same bit-vector represenatation of + /// that NaN. + /// + /// FloatingPoint term. + public BitVecExpr MkFPToIEEEBV(FPExpr t) + { + Contract.Ensures(Contract.Result() != null); + return new BitVecExpr(this, Native.Z3_mk_fpa_to_ieee_bv(this.nCtx, t.NativeObject)); + } + + /// + /// Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. + /// + /// + /// Produces a term that represents the conversion of sig * 2^exp into a + /// floating-point term of sort s. If necessary, the result will be rounded + /// according to rounding mode rm. + /// + /// RoundingMode term. + /// Significand term of Real sort. + /// Exponent term of Int sort. + /// FloatingPoint sort. + public BitVecExpr MkFPToFP(FPRMExpr rm, RealExpr sig, IntExpr exp, FPSort s) + { + Contract.Ensures(Contract.Result() != null); + return new BitVecExpr(this, Native.Z3_mk_fpa_to_fp_real_int(this.nCtx, rm.NativeObject, sig.NativeObject, exp.NativeObject, s.NativeObject)); + } + #endregion + #endregion // Floating-point Arithmetic + #region Miscellaneous /// /// Wraps an AST. diff --git a/src/api/dotnet/FPExpr.cs b/src/api/dotnet/FPExpr.cs index 0bb1e4c09..cbba272d1 100644 --- a/src/api/dotnet/FPExpr.cs +++ b/src/api/dotnet/FPExpr.cs @@ -26,7 +26,7 @@ using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// Floating Point Expressions + /// FloatingPoint Expressions /// public class FPExpr : Expr { diff --git a/src/api/dotnet/FPNum.cs b/src/api/dotnet/FPNum.cs index 044598e58..ab57d57c3 100644 --- a/src/api/dotnet/FPNum.cs +++ b/src/api/dotnet/FPNum.cs @@ -22,7 +22,7 @@ using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// Floatiung Point Numerals + /// FloatiungPoint Numerals /// [ContractVerification(true)] public class FPNum : FPExpr diff --git a/src/api/dotnet/FPRMExpr.cs b/src/api/dotnet/FPRMExpr.cs index b95816023..92fea1ad4 100644 --- a/src/api/dotnet/FPRMExpr.cs +++ b/src/api/dotnet/FPRMExpr.cs @@ -26,7 +26,7 @@ using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// Floating Point Expressions + /// FloatingPoint RoundingMode Expressions /// public class FPRMExpr : Expr { diff --git a/src/api/dotnet/FPRMNum.cs b/src/api/dotnet/FPRMNum.cs index eaf105718..7caa56f9f 100644 --- a/src/api/dotnet/FPRMNum.cs +++ b/src/api/dotnet/FPRMNum.cs @@ -22,7 +22,7 @@ using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// Floatiung Point Rounding Mode Numerals + /// FloatingPoint RoundingMode Numerals /// [ContractVerification(true)] public class FPRMNum : FPRMExpr diff --git a/src/api/dotnet/FPRMSort.cs b/src/api/dotnet/FPRMSort.cs index 23d454a65..1d8334eb5 100644 --- a/src/api/dotnet/FPRMSort.cs +++ b/src/api/dotnet/FPRMSort.cs @@ -7,7 +7,7 @@ Module Name: Abstract: - Z3 Managed API: Floating Point Rounding Mode Sorts + Z3 Managed API: Rounding Mode Sort Author: @@ -23,7 +23,7 @@ using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// A floating point rounding mode sort + /// The FloatingPoint RoundingMode sort /// public class FPRMSort : Sort { diff --git a/src/api/dotnet/FPSort.cs b/src/api/dotnet/FPSort.cs index a79557ae6..8d8560e53 100644 --- a/src/api/dotnet/FPSort.cs +++ b/src/api/dotnet/FPSort.cs @@ -16,17 +16,26 @@ Author: Notes: --*/ - using System; using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// A floating point sort + /// FloatingPoint sort /// public class FPSort : Sort { + /// + /// The number of exponent bits. + /// + public uint EBits { get { return Native.Z3_mk_fpa_get_ebits(Context.nCtx, NativeObject); } } + + /// + /// The number of significand bits. + /// + public uint SBits { get { return Native.Z3_mk_fpa_get_ebits(Context.nCtx, NativeObject); } } + #region Internal internal FPSort(Context ctx, IntPtr obj) : base(ctx, obj) @@ -39,5 +48,5 @@ namespace Microsoft.Z3 Contract.Requires(ctx != null); } #endregion - } + } } From 263456116dde88c961900c88dc4da96b72deeb06 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 2 Jan 2015 19:05:40 +0000 Subject: [PATCH 115/507] Added fpa2bv_rewriter_params Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_rewriter_params.pyg | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/ast/fpa/fpa2bv_rewriter_params.pyg diff --git a/src/ast/fpa/fpa2bv_rewriter_params.pyg b/src/ast/fpa/fpa2bv_rewriter_params.pyg new file mode 100644 index 000000000..42df0fa0e --- /dev/null +++ b/src/ast/fpa/fpa2bv_rewriter_params.pyg @@ -0,0 +1,5 @@ +def_module_params(module_name='rewriter', + class_name='fpa2bv_rewriter_params', + export=True, + params=(("hi_fp_unspecified", BOOL, True, "use the 'hardware interpretation' for unspecified values in fp.to_ubv, fp.to_sbv, and fp.to_real)"), + )) From 376614a7822d8de38b764c5f6ba392930d8ea7d8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 3 Jan 2015 15:09:52 +0000 Subject: [PATCH 116/507] Java API: slight overhaul in preparation for the FP additions Signed-off-by: Christoph M. Wintersteiger --- src/api/java/AST.java | 30 +- src/api/java/ASTMap.java | 23 +- src/api/java/ASTVector.java | 20 +- src/api/java/AlgebraicNum.java | 22 +- src/api/java/ApplyResult.java | 6 +- src/api/java/ArithExpr.java | 2 +- src/api/java/ArrayExpr.java | 2 +- src/api/java/ArraySort.java | 4 + src/api/java/BitVecExpr.java | 4 +- src/api/java/BitVecSort.java | 2 + src/api/java/BoolExpr.java | 5 +- src/api/java/Constructor.java | 6 + src/api/java/ConstructorList.java | 1 + src/api/java/Context.java | 1009 +++++++++++------------- src/api/java/DatatypeExpr.java | 2 +- src/api/java/DatatypeSort.java | 5 + src/api/java/EnumSort.java | 4 + src/api/java/Expr.java | 692 ++++++++++++---- src/api/java/FiniteDomainSort.java | 1 + src/api/java/Fixedpoint.java | 11 +- src/api/java/FuncDecl.java | 26 +- src/api/java/FuncInterp.java | 16 +- src/api/java/Global.java | 20 +- src/api/java/Goal.java | 25 +- src/api/java/IntExpr.java | 3 +- src/api/java/IntSymbol.java | 5 +- src/api/java/InterpolationContext.java | 54 +- src/api/java/Log.java | 11 +- src/api/java/Model.java | 46 +- src/api/java/Probe.java | 4 +- src/api/java/RatNum.java | 5 +- src/api/java/RealExpr.java | 2 +- src/api/java/Solver.java | 83 +- src/api/java/Sort.java | 4 +- src/api/java/Statistics.java | 7 +- src/api/java/StringSymbol.java | 5 +- src/api/java/Tactic.java | 8 +- src/api/java/Version.java | 3 +- 38 files changed, 1289 insertions(+), 889 deletions(-) diff --git a/src/api/java/AST.java b/src/api/java/AST.java index a201d5697..30d303d6c 100644 --- a/src/api/java/AST.java +++ b/src/api/java/AST.java @@ -28,7 +28,8 @@ public class AST extends Z3Object /** * Object comparison. - * another AST + * + * @param o another AST **/ public boolean equals(Object o) { @@ -46,10 +47,12 @@ public class AST extends Z3Object } /** - * Object Comparison. Another AST + * Object Comparison. + * @param other Another AST * - * @return Negative if the object should be sorted before , positive if after else zero. + * @return Negative if the object should be sorted before {@code other}, + * positive if after else zero. + * @throws Z3Exception on error **/ public int compareTo(Object other) throws Z3Exception { @@ -90,6 +93,7 @@ public class AST extends Z3Object /** * A unique identifier for the AST (unique among all ASTs). + * @throws Z3Exception on error **/ public int getId() throws Z3Exception { @@ -97,10 +101,11 @@ public class AST extends Z3Object } /** - * Translates (copies) the AST to the Context . A context + * Translates (copies) the AST to the Context {@code ctx}. + * @param ctx A context * - * @return A copy of the AST which is associated with + * @return A copy of the AST which is associated with {@code ctx} + * @throws Z3Exception on error **/ public AST translate(Context ctx) throws Z3Exception { @@ -114,6 +119,7 @@ public class AST extends Z3Object /** * The kind of the AST. + * @throws Z3Exception on error **/ public Z3_ast_kind getASTKind() throws Z3Exception { @@ -123,6 +129,8 @@ public class AST extends Z3Object /** * Indicates whether the AST is an Expr + * @throws Z3Exception on error + * @throws Z3Exception on error **/ public boolean isExpr() throws Z3Exception { @@ -140,6 +148,8 @@ public class AST extends Z3Object /** * Indicates whether the AST is an application + * @return a boolean + * @throws Z3Exception on error **/ public boolean isApp() throws Z3Exception { @@ -147,7 +157,9 @@ public class AST extends Z3Object } /** - * Indicates whether the AST is a BoundVariable + * Indicates whether the AST is a BoundVariable. + * @return a boolean + * @throws Z3Exception on error **/ public boolean isVar() throws Z3Exception { @@ -156,6 +168,8 @@ public class AST extends Z3Object /** * Indicates whether the AST is a Quantifier + * @return a boolean + * @throws Z3Exception on error **/ public boolean isQuantifier() throws Z3Exception { diff --git a/src/api/java/ASTMap.java b/src/api/java/ASTMap.java index 6a4e6d56f..3d63939ca 100644 --- a/src/api/java/ASTMap.java +++ b/src/api/java/ASTMap.java @@ -23,10 +23,10 @@ package com.microsoft.z3; class ASTMap extends Z3Object { /** - * Checks whether the map contains the key . An AST + * Checks whether the map contains the key {@code k}. + * @param k An AST * - * @return True if is a key in the map, false + * @return True if {@code k} is a key in the map, false * otherwise. **/ public boolean contains(AST k) throws Z3Exception @@ -37,9 +37,10 @@ class ASTMap extends Z3Object } /** - * Finds the value associated with the key . - * This function signs an error when is not a key in - * the map. An AST + * Finds the value associated with the key {@code k}. + * Remarks: This function signs an error when {@code k} is not a key in + * the map. + * @param k An AST * * @throws Z3Exception **/ @@ -50,8 +51,9 @@ class ASTMap extends Z3Object } /** - * Stores or replaces a new key/value pair in the map. The - * key AST The value AST + * Stores or replaces a new key/value pair in the map. + * @param k The key AST + * @param v The value AST **/ public void insert(AST k, AST v) throws Z3Exception { @@ -61,12 +63,11 @@ class ASTMap extends Z3Object } /** - * Erases the key from the map. An - * AST + * Erases the key {@code k} from the map. + * @param k An AST **/ public void erase(AST k) throws Z3Exception { - Native.astMapErase(getContext().nCtx(), getNativeObject(), k.getNativeObject()); } diff --git a/src/api/java/ASTVector.java b/src/api/java/ASTVector.java index 07b7dbf56..d4df02244 100644 --- a/src/api/java/ASTVector.java +++ b/src/api/java/ASTVector.java @@ -31,9 +31,10 @@ class ASTVector extends Z3Object } /** - * Retrieves the i-th object in the vector. May throw an - * IndexOutOfBoundsException when is out of - * range. Index + * Retrieves the i-th object in the vector. + * Remarks: May throw an {@code IndexOutOfBoundsException} when + * {@code i} is out of range. + * @param i Index * * @return An AST * @throws Z3Exception @@ -52,8 +53,8 @@ class ASTVector extends Z3Object } /** - * Resize the vector to . The new size of the vector. + * Resize the vector to {@code newSize}. + * @param newSize The new size of the vector. **/ public void resize(int newSize) throws Z3Exception { @@ -61,8 +62,9 @@ class ASTVector extends Z3Object } /** - * Add the AST to the back of the vector. The size is - * increased by 1. An AST + * Add the AST {@code a} to the back of the vector. The size is + * increased by 1. + * @param a An AST **/ public void push(AST a) throws Z3Exception { @@ -70,8 +72,8 @@ class ASTVector extends Z3Object } /** - * Translates all ASTs in the vector to . A context + * Translates all ASTs in the vector to {@code ctx}. + * @param ctx A context * * @return A new ASTVector * @throws Z3Exception diff --git a/src/api/java/AlgebraicNum.java b/src/api/java/AlgebraicNum.java index 340f37f80..322b24d39 100644 --- a/src/api/java/AlgebraicNum.java +++ b/src/api/java/AlgebraicNum.java @@ -24,11 +24,13 @@ public class AlgebraicNum extends ArithExpr { /** * Return a upper bound for a given real algebraic number. The interval - * isolating the number is smaller than 1/10^. - * the - * precision of the result + * isolating the number is smaller than 1/10^{@code precision}. + * + * @see Expr#isAlgebraicNumber + * @param precision the precision of the result * * @return A numeral Expr of sort Real + * @throws Z3Exception on error **/ public RatNum toUpper(int precision) throws Z3Exception { @@ -39,10 +41,13 @@ public class AlgebraicNum extends ArithExpr /** * Return a lower bound for the given real algebraic number. The interval - * isolating the number is smaller than 1/10^. - * + * isolating the number is smaller than 1/10^{@code precision}. + * + * @see Expr#isAlgebraicNumber + * @param precision precision * * @return A numeral Expr of sort Real + * @throws Z3Exception on error **/ public RatNum toLower(int precision) throws Z3Exception { @@ -52,8 +57,11 @@ public class AlgebraicNum extends ArithExpr } /** - * Returns a string representation in decimal notation. The result - * has at most decimal places. + * Returns a string representation in decimal notation. + * Remarks: The result has at most {@code precision} decimal places. + * @param precision precision + * @return String + * @throws Z3Exception on error **/ public String toDecimal(int precision) throws Z3Exception { diff --git a/src/api/java/ApplyResult.java b/src/api/java/ApplyResult.java index c550c05ae..d21a78a9c 100644 --- a/src/api/java/ApplyResult.java +++ b/src/api/java/ApplyResult.java @@ -48,10 +48,10 @@ public class ApplyResult extends Z3Object } /** - * Convert a model for the subgoal into a model for the - * original goal g, that the ApplyResult was obtained from. + * Convert a model for the subgoal {@code i} into a model for the + * original goal {@code g}, that the ApplyResult was obtained from. * - * @return A model for g + * @return A model for {@code g} * @throws Z3Exception **/ public Model convertModel(int i, Model m) throws Z3Exception diff --git a/src/api/java/ArithExpr.java b/src/api/java/ArithExpr.java index 83ec35d01..a788fda35 100644 --- a/src/api/java/ArithExpr.java +++ b/src/api/java/ArithExpr.java @@ -23,7 +23,7 @@ package com.microsoft.z3; public class ArithExpr extends Expr { /** - * Constructor for ArithExpr + * Constructor for ArithExpr **/ protected ArithExpr(Context ctx) { diff --git a/src/api/java/ArrayExpr.java b/src/api/java/ArrayExpr.java index 2d5a5a273..34d04693f 100644 --- a/src/api/java/ArrayExpr.java +++ b/src/api/java/ArrayExpr.java @@ -24,7 +24,7 @@ package com.microsoft.z3; public class ArrayExpr extends Expr { /** - * Constructor for ArrayExpr + * Constructor for ArrayExpr **/ protected ArrayExpr(Context ctx) { diff --git a/src/api/java/ArraySort.java b/src/api/java/ArraySort.java index a371fa3cb..ab545b7c1 100644 --- a/src/api/java/ArraySort.java +++ b/src/api/java/ArraySort.java @@ -25,6 +25,8 @@ public class ArraySort extends Sort /** * The domain of the array sort. * @throws Z3Exception + * @throws Z3Exception on error + * @return a sort **/ public Sort getDomain() throws Z3Exception { @@ -35,6 +37,8 @@ public class ArraySort extends Sort /** * The range of the array sort. * @throws Z3Exception + * @throws Z3Exception on error + * @return a sort **/ public Sort getRange() throws Z3Exception { diff --git a/src/api/java/BitVecExpr.java b/src/api/java/BitVecExpr.java index 24b1cfdf3..c410e33a6 100644 --- a/src/api/java/BitVecExpr.java +++ b/src/api/java/BitVecExpr.java @@ -26,6 +26,8 @@ public class BitVecExpr extends Expr /** * The size of the sort of a bit-vector term. * @throws Z3Exception + * @throws Z3Exception on error + * @return an int **/ public int getSortSize() throws Z3Exception { @@ -33,7 +35,7 @@ public class BitVecExpr extends Expr } /** - * Constructor for BitVecExpr + * Constructor for BitVecExpr **/ BitVecExpr(Context ctx) { diff --git a/src/api/java/BitVecSort.java b/src/api/java/BitVecSort.java index be406c806..69d74151c 100644 --- a/src/api/java/BitVecSort.java +++ b/src/api/java/BitVecSort.java @@ -24,6 +24,8 @@ public class BitVecSort extends Sort { /** * The size of the bit-vector sort. + * @throws Z3Exception on error + * @return an int **/ public int getSize() throws Z3Exception { diff --git a/src/api/java/BoolExpr.java b/src/api/java/BoolExpr.java index 99453496a..ea3cdbfb4 100644 --- a/src/api/java/BoolExpr.java +++ b/src/api/java/BoolExpr.java @@ -23,7 +23,7 @@ package com.microsoft.z3; public class BoolExpr extends Expr { /** - * Constructor for BoolExpr + * Constructor for BoolExpr **/ protected BoolExpr(Context ctx) { @@ -31,8 +31,9 @@ public class BoolExpr extends Expr } /** - * Constructor for BoolExpr + * Constructor for BoolExpr * @throws Z3Exception + * @throws Z3Exception on error **/ BoolExpr(Context ctx, long obj) throws Z3Exception { diff --git a/src/api/java/Constructor.java b/src/api/java/Constructor.java index 4813c2b0a..a5440092c 100644 --- a/src/api/java/Constructor.java +++ b/src/api/java/Constructor.java @@ -25,6 +25,8 @@ public class Constructor extends Z3Object /** * The number of fields of the constructor. * @throws Z3Exception + * @throws Z3Exception on error + * @return an int **/ public int getNumFields() throws Z3Exception { @@ -34,6 +36,7 @@ public class Constructor extends Z3Object /** * The function declaration of the constructor. * @throws Z3Exception + * @throws Z3Exception on error **/ public FuncDecl ConstructorDecl() throws Z3Exception { @@ -47,6 +50,7 @@ public class Constructor extends Z3Object /** * The function declaration of the tester. * @throws Z3Exception + * @throws Z3Exception on error **/ public FuncDecl getTesterDecl() throws Z3Exception { @@ -60,6 +64,7 @@ public class Constructor extends Z3Object /** * The function declarations of the accessors * @throws Z3Exception + * @throws Z3Exception on error **/ public FuncDecl[] getAccessorDecls() throws Z3Exception { @@ -75,6 +80,7 @@ public class Constructor extends Z3Object /** * Destructor. + * @throws Z3Exception on error **/ protected void finalize() throws Z3Exception { diff --git a/src/api/java/ConstructorList.java b/src/api/java/ConstructorList.java index 315a2e535..b38678b8a 100644 --- a/src/api/java/ConstructorList.java +++ b/src/api/java/ConstructorList.java @@ -24,6 +24,7 @@ public class ConstructorList extends Z3Object { /** * Destructor. + * @throws Z3Exception on error **/ protected void finalize() throws Z3Exception { diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 4fbd79be2..f7fa471fb 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -38,7 +38,7 @@ public class Context extends IDisposable /** * Constructor. - * + * Remarks: * The following parameters can be set: * - proof (Boolean) Enable proof generation * - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting @@ -51,8 +51,7 @@ public class Context extends IDisposable * - model_validate validate models produced by solvers * - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver * Note that in previous versions of Z3, this constructor was also used to set global and - * module parameters. For this purpose we should now use - * + * module parameters. For this purpose we should now use {@code Global.setParameter} **/ public Context(Map settings) throws Z3Exception { @@ -66,9 +65,9 @@ public class Context extends IDisposable } /** - * Creates a new symbol using an integer. Not all integers can be - * passed to this function. The legal range of unsigned integers is 0 to - * 2^30-1. + * Creates a new symbol using an integer. + * Remarks: Not all integers can be passed to this function. + * The legal range of unsigned integers is 0 to 2^30-1. **/ public IntSymbol mkSymbol(int i) throws Z3Exception { @@ -135,7 +134,6 @@ public class Context extends IDisposable **/ public BoolSort mkBoolSort() throws Z3Exception { - return new BoolSort(this); } @@ -144,7 +142,6 @@ public class Context extends IDisposable **/ public UninterpretedSort mkUninterpretedSort(Symbol s) throws Z3Exception { - checkContextMatch(s); return new UninterpretedSort(this, s); } @@ -154,7 +151,6 @@ public class Context extends IDisposable **/ public UninterpretedSort mkUninterpretedSort(String str) throws Z3Exception { - return mkUninterpretedSort(mkSymbol(str)); } @@ -163,7 +159,6 @@ public class Context extends IDisposable **/ public IntSort mkIntSort() throws Z3Exception { - return new IntSort(this); } @@ -172,7 +167,6 @@ public class Context extends IDisposable **/ public RealSort mkRealSort() throws Z3Exception { - return new RealSort(this); } @@ -181,7 +175,6 @@ public class Context extends IDisposable **/ public BitVecSort mkBitVecSort(int size) throws Z3Exception { - return new BitVecSort(this, Native.mkBvSort(nCtx(), size)); } @@ -190,7 +183,6 @@ public class Context extends IDisposable **/ public ArraySort mkArraySort(Sort domain, Sort range) throws Z3Exception { - checkContextMatch(domain); checkContextMatch(range); return new ArraySort(this, domain, range); @@ -202,7 +194,6 @@ public class Context extends IDisposable public TupleSort mkTupleSort(Symbol name, Symbol[] fieldNames, Sort[] fieldSorts) throws Z3Exception { - checkContextMatch(name); checkContextMatch(fieldNames); checkContextMatch(fieldSorts); @@ -216,7 +207,6 @@ public class Context extends IDisposable public EnumSort mkEnumSort(Symbol name, Symbol... enumNames) throws Z3Exception { - checkContextMatch(name); checkContextMatch(enumNames); return new EnumSort(this, name, enumNames); @@ -236,7 +226,6 @@ public class Context extends IDisposable **/ public ListSort mkListSort(Symbol name, Sort elemSort) throws Z3Exception { - checkContextMatch(name); checkContextMatch(elemSort); return new ListSort(this, name, elemSort); @@ -247,7 +236,6 @@ public class Context extends IDisposable **/ public ListSort mkListSort(String name, Sort elemSort) throws Z3Exception { - checkContextMatch(elemSort); return new ListSort(this, mkSymbol(name), elemSort); } @@ -258,7 +246,6 @@ public class Context extends IDisposable public FiniteDomainSort mkFiniteDomainSort(Symbol name, long size) throws Z3Exception { - checkContextMatch(name); return new FiniteDomainSort(this, name, size); } @@ -269,20 +256,19 @@ public class Context extends IDisposable public FiniteDomainSort mkFiniteDomainSort(String name, long size) throws Z3Exception { - return new FiniteDomainSort(this, mkSymbol(name), size); } /** - * Create a datatype constructor. constructor - * name name of recognizer - * function. names of the constructor - * fields. field sorts, 0 if the field sort - * refers to a recursive sort. reference to - * datatype sort that is an argument to the constructor; if the - * corresponding sort reference is 0, then the value in sort_refs should be + * Create a datatype constructor. + * @param name constructor name + * @param recognizer name of recognizer function. + * @param fieldNames names of the constructor fields. + * @param sorts field sorts, 0 if the field sort refers to a recursive sort. + * @param sortRefs reference to datatype sort that is an argument to the + * constructor; if the corresponding sort reference is 0, then the value in sort_refs should be * an index referring to one of the recursive datatypes that is - * declared. + * declared. **/ public Constructor mkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames, Sort[] sorts, int[] sortRefs) @@ -294,9 +280,12 @@ public class Context extends IDisposable } /** - * Create a datatype constructor. + * Create a datatype constructor. + * @param name + * @param recognizer + * @param fieldNames + * @param sorts + * @param sortRefs * * @return **/ @@ -315,7 +304,6 @@ public class Context extends IDisposable public DatatypeSort mkDatatypeSort(Symbol name, Constructor[] constructors) throws Z3Exception { - checkContextMatch(name); checkContextMatch(constructors); return new DatatypeSort(this, name, constructors); @@ -327,20 +315,18 @@ public class Context extends IDisposable public DatatypeSort mkDatatypeSort(String name, Constructor[] constructors) throws Z3Exception { - checkContextMatch(constructors); return new DatatypeSort(this, mkSymbol(name), constructors); } /** - * Create mutually recursive datatypes. names of - * datatype sorts list of constructors, one list per - * sort. + * Create mutually recursive datatypes. + * @param names names of datatype sorts + * @param c list of constructors, one list per sort. **/ public DatatypeSort[] mkDatatypeSorts(Symbol[] names, Constructor[][] c) throws Z3Exception { - checkContextMatch(names); int n = (int) names.length; ConstructorList[] cla = new ConstructorList[n]; @@ -363,15 +349,15 @@ public class Context extends IDisposable } /** - * Create mutually recursive data-types. + * Create mutually recursive data-types. + * @param names + * @param c * * @return **/ public DatatypeSort[] mkDatatypeSorts(String[] names, Constructor[][] c) throws Z3Exception { - return mkDatatypeSorts(MkSymbols(names), c); } @@ -381,7 +367,6 @@ public class Context extends IDisposable public FuncDecl mkFuncDecl(Symbol name, Sort[] domain, Sort range) throws Z3Exception { - checkContextMatch(name); checkContextMatch(domain); checkContextMatch(range); @@ -394,7 +379,6 @@ public class Context extends IDisposable public FuncDecl mkFuncDecl(Symbol name, Sort domain, Sort range) throws Z3Exception { - checkContextMatch(name); checkContextMatch(domain); checkContextMatch(range); @@ -408,7 +392,6 @@ public class Context extends IDisposable public FuncDecl mkFuncDecl(String name, Sort[] domain, Sort range) throws Z3Exception { - checkContextMatch(domain); checkContextMatch(range); return new FuncDecl(this, mkSymbol(name), domain, range); @@ -420,7 +403,6 @@ public class Context extends IDisposable public FuncDecl mkFuncDecl(String name, Sort domain, Sort range) throws Z3Exception { - checkContextMatch(domain); checkContextMatch(range); Sort[] q = new Sort[] { domain }; @@ -428,14 +410,14 @@ public class Context extends IDisposable } /** - * Creates a fresh function declaration with a name prefixed with . + * Creates a fresh function declaration with a name prefixed with + * {@code prefix}. + * @see mkFuncDecl(String,Sort,Sort) + * @see mkFuncDecl(String,Sort[],Sort) **/ public FuncDecl mkFreshFuncDecl(String prefix, Sort[] domain, Sort range) throws Z3Exception { - checkContextMatch(domain); checkContextMatch(range); return new FuncDecl(this, prefix, domain, range); @@ -446,7 +428,6 @@ public class Context extends IDisposable **/ public FuncDecl mkConstDecl(Symbol name, Sort range) throws Z3Exception { - checkContextMatch(name); checkContextMatch(range); return new FuncDecl(this, name, null, range); @@ -457,27 +438,27 @@ public class Context extends IDisposable **/ public FuncDecl mkConstDecl(String name, Sort range) throws Z3Exception { - checkContextMatch(range); return new FuncDecl(this, mkSymbol(name), null, range); } /** * Creates a fresh constant function declaration with a name prefixed with - * . - * + * {@code prefix"}. + * @see mkFuncDecl(String,Sort,Sort) + * @see mkFuncDecl(String,Sort[],Sort) **/ public FuncDecl mkFreshConstDecl(String prefix, Sort range) throws Z3Exception { - checkContextMatch(range); return new FuncDecl(this, prefix, null, range); } /** - * Creates a new bound variable. The de-Bruijn index of - * the variable The sort of the variable + * Creates a new bound variable. + * @param index The de-Bruijn index of the variable + * @param ty The sort of the variable **/ public Expr mkBound(int index, Sort ty) throws Z3Exception { @@ -499,12 +480,11 @@ public class Context extends IDisposable } /** - * Creates a new Constant of sort and named - * . + * Creates a new Constant of sort {@code range} and named + * {@code name}. **/ public Expr mkConst(Symbol name, Sort range) throws Z3Exception { - checkContextMatch(name); checkContextMatch(range); @@ -515,34 +495,31 @@ public class Context extends IDisposable } /** - * Creates a new Constant of sort and named - * . + * Creates a new Constant of sort {@code range} and named + * {@code name}. **/ public Expr mkConst(String name, Sort range) throws Z3Exception { - return mkConst(mkSymbol(name), range); } /** - * Creates a fresh Constant of sort and a name - * prefixed with . + * Creates a fresh Constant of sort {@code range} and a name + * prefixed with {@code prefix}. **/ public Expr mkFreshConst(String prefix, Sort range) throws Z3Exception { - checkContextMatch(range); return Expr.create(this, Native.mkFreshConst(nCtx(), prefix, range.getNativeObject())); } /** - * Creates a fresh constant from the FuncDecl . A decl of a 0-arity function + * Creates a fresh constant from the FuncDecl {@code f}. + * @param f A decl of a 0-arity function **/ public Expr mkConst(FuncDecl f) throws Z3Exception { - return mkApp(f, (Expr[]) null); } @@ -551,7 +528,6 @@ public class Context extends IDisposable **/ public BoolExpr mkBoolConst(Symbol name) throws Z3Exception { - return (BoolExpr) mkConst(name, getBoolSort()); } @@ -560,7 +536,6 @@ public class Context extends IDisposable **/ public BoolExpr mkBoolConst(String name) throws Z3Exception { - return (BoolExpr) mkConst(mkSymbol(name), getBoolSort()); } @@ -569,7 +544,6 @@ public class Context extends IDisposable **/ public IntExpr mkIntConst(Symbol name) throws Z3Exception { - return (IntExpr) mkConst(name, getIntSort()); } @@ -578,7 +552,6 @@ public class Context extends IDisposable **/ public IntExpr mkIntConst(String name) throws Z3Exception { - return (IntExpr) mkConst(name, getIntSort()); } @@ -587,7 +560,6 @@ public class Context extends IDisposable **/ public RealExpr mkRealConst(Symbol name) throws Z3Exception { - return (RealExpr) mkConst(name, getRealSort()); } @@ -596,7 +568,6 @@ public class Context extends IDisposable **/ public RealExpr mkRealConst(String name) throws Z3Exception { - return (RealExpr) mkConst(name, getRealSort()); } @@ -605,7 +576,6 @@ public class Context extends IDisposable **/ public BitVecExpr mkBVConst(Symbol name, int size) throws Z3Exception { - return (BitVecExpr) mkConst(name, mkBitVecSort(size)); } @@ -614,7 +584,6 @@ public class Context extends IDisposable **/ public BitVecExpr mkBVConst(String name, int size) throws Z3Exception { - return (BitVecExpr) mkConst(name, mkBitVecSort(size)); } @@ -653,7 +622,7 @@ public class Context extends IDisposable } /** - * Creates the equality = . + * Creates the equality {@code x"/> = An expression with Boolean - * sort An expression An - * expression with the same sort as + * {@code ite(t1, t2, t3)}. + * @param t1 An expression with Boolean sort + * @param t2 An expression + * @param t3 An expression with the same sort as {@code t2} **/ public Expr mkITE(BoolExpr t1, Expr t2, Expr t3) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); checkContextMatch(t3); @@ -700,11 +668,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 iff t2. + * Create an expression representing {@code t1 iff t2}. **/ public BoolExpr mkIff(BoolExpr t1, BoolExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkIff(nCtx(), t1.getNativeObject(), @@ -712,11 +679,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 -> t2. + * Create an expression representing {@code t1 -> t2}. **/ public BoolExpr mkImplies(BoolExpr t1, BoolExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkImplies(nCtx(), @@ -724,11 +690,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 xor t2. + * Create an expression representing {@code t1 xor t2}. **/ public BoolExpr mkXor(BoolExpr t1, BoolExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkXor(nCtx(), t1.getNativeObject(), @@ -736,77 +701,70 @@ public class Context extends IDisposable } /** - * Create an expression representing t[0] and t[1] and .... + * Create an expression representing {@code t[0] and t[1] and ...}. **/ public BoolExpr mkAnd(BoolExpr... t) throws Z3Exception { - checkContextMatch(t); return new BoolExpr(this, Native.mkAnd(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** - * Create an expression representing t[0] or t[1] or .... + * Create an expression representing {@code t[0] or t[1] or ...}. **/ public BoolExpr mkOr(BoolExpr... t) throws Z3Exception { - checkContextMatch(t); return new BoolExpr(this, Native.mkOr(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** - * Create an expression representing t[0] + t[1] + .... + * Create an expression representing {@code t[0] + t[1] + ...}. **/ public ArithExpr mkAdd(ArithExpr... t) throws Z3Exception { - checkContextMatch(t); return (ArithExpr) Expr.create(this, Native.mkAdd(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** - * Create an expression representing t[0] * t[1] * .... + * Create an expression representing {@code t[0] * t[1] * ...}. **/ public ArithExpr mkMul(ArithExpr... t) throws Z3Exception { - checkContextMatch(t); return (ArithExpr) Expr.create(this, Native.mkMul(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** - * Create an expression representing t[0] - t[1] - .... + * Create an expression representing {@code t[0] - t[1] - ...}. **/ public ArithExpr mkSub(ArithExpr... t) throws Z3Exception { - checkContextMatch(t); return (ArithExpr) Expr.create(this, Native.mkSub(nCtx(), (int) t.length, AST.arrayToNative(t))); } /** - * Create an expression representing -t. + * Create an expression representing {@code -t}. **/ public ArithExpr mkUnaryMinus(ArithExpr t) throws Z3Exception { - checkContextMatch(t); return (ArithExpr) Expr.create(this, Native.mkUnaryMinus(nCtx(), t.getNativeObject())); } /** - * Create an expression representing t1 / t2. + * Create an expression representing {@code t1 / t2}. **/ public ArithExpr mkDiv(ArithExpr t1, ArithExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return (ArithExpr) Expr.create(this, Native.mkDiv(nCtx(), @@ -814,12 +772,12 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 mod t2. The - * arguments must have int type. + * Create an expression representing {@code t1 mod t2}. + * Remarks: The + * arguments must have int type. **/ public IntExpr mkMod(IntExpr t1, IntExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new IntExpr(this, Native.mkMod(nCtx(), t1.getNativeObject(), @@ -827,12 +785,12 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 rem t2. The - * arguments must have int type. + * Create an expression representing {@code t1 rem t2}. + * Remarks: The + * arguments must have int type. **/ public IntExpr mkRem(IntExpr t1, IntExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new IntExpr(this, Native.mkRem(nCtx(), t1.getNativeObject(), @@ -840,11 +798,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 ^ t2. + * Create an expression representing {@code t1 ^ t2}. **/ public ArithExpr mkPower(ArithExpr t1, ArithExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return (ArithExpr) Expr.create( @@ -854,11 +811,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 < t2 + * Create an expression representing {@code t1 < t2} **/ public BoolExpr mkLt(ArithExpr t1, ArithExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkLt(nCtx(), t1.getNativeObject(), @@ -866,11 +822,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 <= t2 + * Create an expression representing {@code t1 <= t2} **/ public BoolExpr mkLe(ArithExpr t1, ArithExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkLe(nCtx(), t1.getNativeObject(), @@ -878,11 +833,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 > t2 + * Create an expression representing {@code t1 > t2} **/ public BoolExpr mkGt(ArithExpr t1, ArithExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkGt(nCtx(), t1.getNativeObject(), @@ -890,11 +844,10 @@ public class Context extends IDisposable } /** - * Create an expression representing t1 >= t2 + * Create an expression representing {@code t1 >= t2} **/ public BoolExpr mkGe(ArithExpr t1, ArithExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkGe(nCtx(), t1.getNativeObject(), @@ -902,30 +855,30 @@ public class Context extends IDisposable } /** - * Coerce an integer to a real. There is also a converse operation + * Coerce an integer to a real. + * Remarks: There is also a converse operation * exposed. It follows the semantics prescribed by the SMT-LIB standard. * * You can take the floor of a real by creating an auxiliary integer Term - * k and and asserting - * MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. The argument - * must be of integer sort. + * {@code k} and and asserting + * {@code MakeInt2Real(k) <= t1 < MkInt2Real(k)+1}. The argument + * must be of integer sort. **/ public RealExpr mkInt2Real(IntExpr t) throws Z3Exception { - checkContextMatch(t); return new RealExpr(this, Native.mkInt2real(nCtx(), t.getNativeObject())); } /** - * Coerce a real to an integer. The semantics of this function + * Coerce a real to an integer. + * Remarks: The semantics of this function * follows the SMT-LIB standard for the function to_int. The argument must - * be of real sort. + * be of real sort. **/ public IntExpr mkReal2Int(RealExpr t) throws Z3Exception { - checkContextMatch(t); return new IntExpr(this, Native.mkReal2int(nCtx(), t.getNativeObject())); } @@ -935,29 +888,28 @@ public class Context extends IDisposable **/ public BoolExpr mkIsInteger(RealExpr t) throws Z3Exception { - checkContextMatch(t); return new BoolExpr(this, Native.mkIsInt(nCtx(), t.getNativeObject())); } /** - * Bitwise negation. The argument must have a bit-vector - * sort. + * Bitwise negation. + * Remarks: The argument must have a bit-vector + * sort. **/ public BitVecExpr mkBVNot(BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkBvnot(nCtx(), t.getNativeObject())); } /** * Take conjunction of bits in a vector, return vector of length 1. - * The argument must have a bit-vector sort. + * + * Remarks: The argument must have a bit-vector sort. **/ public BitVecExpr mkBVRedAND(BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkBvredand(nCtx(), t.getNativeObject())); @@ -965,23 +917,23 @@ public class Context extends IDisposable /** * Take disjunction of bits in a vector, return vector of length 1. - * The argument must have a bit-vector sort. + * + * Remarks: The argument must have a bit-vector sort. **/ public BitVecExpr mkBVRedOR(BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkBvredor(nCtx(), t.getNativeObject())); } /** - * Bitwise conjunction. The arguments must have a bit-vector - * sort. + * Bitwise conjunction. + * Remarks: The arguments must have a bit-vector + * sort. **/ public BitVecExpr mkBVAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvand(nCtx(), @@ -989,12 +941,12 @@ public class Context extends IDisposable } /** - * Bitwise disjunction. The arguments must have a bit-vector - * sort. + * Bitwise disjunction. + * Remarks: The arguments must have a bit-vector + * sort. **/ public BitVecExpr mkBVOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvor(nCtx(), t1.getNativeObject(), @@ -1002,12 +954,12 @@ public class Context extends IDisposable } /** - * Bitwise XOR. The arguments must have a bit-vector - * sort. + * Bitwise XOR. + * Remarks: The arguments must have a bit-vector + * sort. **/ public BitVecExpr mkBVXOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvxor(nCtx(), @@ -1015,12 +967,12 @@ public class Context extends IDisposable } /** - * Bitwise NAND. The arguments must have a bit-vector - * sort. + * Bitwise NAND. + * Remarks: The arguments must have a bit-vector + * sort. **/ public BitVecExpr mkBVNAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvnand(nCtx(), @@ -1028,12 +980,12 @@ public class Context extends IDisposable } /** - * Bitwise NOR. The arguments must have a bit-vector - * sort. + * Bitwise NOR. + * Remarks: The arguments must have a bit-vector + * sort. **/ public BitVecExpr mkBVNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvnor(nCtx(), @@ -1041,12 +993,12 @@ public class Context extends IDisposable } /** - * Bitwise XNOR. The arguments must have a bit-vector - * sort. + * Bitwise XNOR. + * Remarks: The arguments must have a bit-vector + * sort. **/ public BitVecExpr mkBVXNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvxnor(nCtx(), @@ -1054,23 +1006,23 @@ public class Context extends IDisposable } /** - * Standard two's complement unary minus. The arguments must have a - * bit-vector sort. + * Standard two's complement unary minus. + * Remarks: The arguments must have a + * bit-vector sort. **/ public BitVecExpr mkBVNeg(BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkBvneg(nCtx(), t.getNativeObject())); } /** - * Two's complement addition. The arguments must have the same - * bit-vector sort. + * Two's complement addition. + * Remarks: The arguments must have the same + * bit-vector sort. **/ public BitVecExpr mkBVAdd(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvadd(nCtx(), @@ -1078,12 +1030,12 @@ public class Context extends IDisposable } /** - * Two's complement subtraction. The arguments must have the same - * bit-vector sort. + * Two's complement subtraction. + * Remarks: The arguments must have the same + * bit-vector sort. **/ public BitVecExpr mkBVSub(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvsub(nCtx(), @@ -1091,12 +1043,12 @@ public class Context extends IDisposable } /** - * Two's complement multiplication. The arguments must have the - * same bit-vector sort. + * Two's complement multiplication. + * Remarks: The arguments must have the + * same bit-vector sort. **/ public BitVecExpr mkBVMul(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvmul(nCtx(), @@ -1104,14 +1056,14 @@ public class Context extends IDisposable } /** - * Unsigned division. It is defined as the floor of - * t1/t2 if \c t2 is different from zero. If t2 is + * Unsigned division. + * Remarks: It is defined as the floor of + * {@code t1/t2} if \c t2 is different from zero. If {@code t2} is * zero, then the result is undefined. The arguments must have the same - * bit-vector sort. + * bit-vector sort. **/ public BitVecExpr mkBVUDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvudiv(nCtx(), @@ -1119,20 +1071,20 @@ public class Context extends IDisposable } /** - * Signed division. It is defined in the following way: + * Signed division. + * Remarks: It is defined in the following way: * - * - The \c floor of t1/t2 if \c t2 is different from zero, and - * t1*t2 >= 0. + * - The \c floor of {@code t1/t2} if \c t2 is different from zero, and + * {@code t1*t2 >= 0}. * - * - The \c ceiling of t1/t2 if \c t2 is different from zero, - * and t1*t2 < 0. + * - The \c ceiling of {@code t1/t2} if \c t2 is different from zero, + * and {@code t1*t2 < 0}. * - * If t2 is zero, then the result is undefined. The arguments - * must have the same bit-vector sort. + * If {@code t2} is zero, then the result is undefined. The arguments + * must have the same bit-vector sort. **/ public BitVecExpr mkBVSDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvsdiv(nCtx(), @@ -1140,14 +1092,14 @@ public class Context extends IDisposable } /** - * Unsigned remainder. It is defined as - * t1 - (t1 /u t2) * t2, where /u represents - * unsigned division. If t2 is zero, then the result is - * undefined. The arguments must have the same bit-vector sort. + * Unsigned remainder. + * Remarks: It is defined as + * {@code t1 - (t1 /u t2) * t2}, where {@code /u} represents + * unsigned division. If {@code t2} is zero, then the result is + * undefined. The arguments must have the same bit-vector sort. **/ public BitVecExpr mkBVURem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvurem(nCtx(), @@ -1155,17 +1107,17 @@ public class Context extends IDisposable } /** - * Signed remainder. It is defined as - * t1 - (t1 /s t2) * t2, where /s represents + * Signed remainder. + * Remarks: It is defined as + * {@code t1 - (t1 /s t2) * t2}, where {@code /s} represents * signed division. The most significant bit (sign) of the result is equal * to the most significant bit of \c t1. * - * If t2 is zero, then the result is undefined. The arguments - * must have the same bit-vector sort. + * If {@code t2} is zero, then the result is undefined. The arguments + * must have the same bit-vector sort. **/ public BitVecExpr mkBVSRem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvsrem(nCtx(), @@ -1173,13 +1125,13 @@ public class Context extends IDisposable } /** - * Two's complement signed remainder (sign follows divisor). If - * t2 is zero, then the result is undefined. The arguments must - * have the same bit-vector sort. + * Two's complement signed remainder (sign follows divisor). + * Remarks: If + * {@code t2} is zero, then the result is undefined. The arguments must + * have the same bit-vector sort. **/ public BitVecExpr mkBVSMod(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvsmod(nCtx(), @@ -1187,12 +1139,12 @@ public class Context extends IDisposable } /** - * Unsigned less-than The arguments must have the same bit-vector - * sort. + * Unsigned less-than + * Remarks: The arguments must have the same bit-vector + * sort. **/ public BoolExpr mkBVULT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvult(nCtx(), t1.getNativeObject(), @@ -1200,12 +1152,12 @@ public class Context extends IDisposable } /** - * Two's complement signed less-than The arguments must have the - * same bit-vector sort. + * Two's complement signed less-than + * Remarks: The arguments must have the + * same bit-vector sort. **/ public BoolExpr mkBVSLT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvslt(nCtx(), t1.getNativeObject(), @@ -1213,12 +1165,12 @@ public class Context extends IDisposable } /** - * Unsigned less-than or equal to. The arguments must have the - * same bit-vector sort. + * Unsigned less-than or equal to. + * Remarks: The arguments must have the + * same bit-vector sort. **/ public BoolExpr mkBVULE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvule(nCtx(), t1.getNativeObject(), @@ -1226,12 +1178,12 @@ public class Context extends IDisposable } /** - * Two's complement signed less-than or equal to. The arguments - * must have the same bit-vector sort. + * Two's complement signed less-than or equal to. + * Remarks: The arguments + * must have the same bit-vector sort. **/ public BoolExpr mkBVSLE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsle(nCtx(), t1.getNativeObject(), @@ -1239,12 +1191,12 @@ public class Context extends IDisposable } /** - * Unsigned greater than or equal to. The arguments must have the - * same bit-vector sort. + * Unsigned greater than or equal to. + * Remarks: The arguments must have the + * same bit-vector sort. **/ public BoolExpr mkBVUGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvuge(nCtx(), t1.getNativeObject(), @@ -1252,12 +1204,12 @@ public class Context extends IDisposable } /** - * Two's complement signed greater than or equal to. The arguments - * must have the same bit-vector sort. + * Two's complement signed greater than or equal to. + * Remarks: The arguments + * must have the same bit-vector sort. **/ public BoolExpr mkBVSGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsge(nCtx(), t1.getNativeObject(), @@ -1265,12 +1217,12 @@ public class Context extends IDisposable } /** - * Unsigned greater-than. The arguments must have the same - * bit-vector sort. + * Unsigned greater-than. + * Remarks: The arguments must have the same + * bit-vector sort. **/ public BoolExpr mkBVUGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvugt(nCtx(), t1.getNativeObject(), @@ -1278,12 +1230,12 @@ public class Context extends IDisposable } /** - * Two's complement signed greater-than. The arguments must have - * the same bit-vector sort. + * Two's complement signed greater-than. + * Remarks: The arguments must have + * the same bit-vector sort. **/ public BoolExpr mkBVSGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsgt(nCtx(), t1.getNativeObject(), @@ -1291,17 +1243,17 @@ public class Context extends IDisposable } /** - * Bit-vector concatenation. The arguments must have a bit-vector - * sort. + * Bit-vector concatenation. + * Remarks: The arguments must have a bit-vector + * sort. * - * @return The result is a bit-vector of size n1+n2, where - * n1 (n2) is the size of t1 - * (t2). + * @return The result is a bit-vector of size {@code n1+n2}, where + * {@code n1} ({@code n2}) is the size of {@code t1} + * ({@code t2}). * **/ public BitVecExpr mkConcat(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkConcat(nCtx(), @@ -1309,74 +1261,74 @@ public class Context extends IDisposable } /** - * Bit-vector extraction. Extract the bits - * down to from a bitvector of size m to - * yield a new bitvector of size n, where - * n = high - low + 1. The argument must - * have a bit-vector sort. + * Bit-vector extraction. + * Remarks: Extract the bits {@code high} + * down to {@code low} from a bitvector of size {@code m} to + * yield a new bitvector of size {@code n}, where + * {@code n = high - low + 1}. The argument {@code t} must + * have a bit-vector sort. **/ public BitVecExpr mkExtract(int high, int low, BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkExtract(nCtx(), high, low, t.getNativeObject())); } /** - * Bit-vector sign extension. Sign-extends the given bit-vector to - * the (signed) equivalent bitvector of size m+i, where \c m is - * the size of the given bit-vector. The argument must - * have a bit-vector sort. + * Bit-vector sign extension. + * Remarks: Sign-extends the given bit-vector to + * the (signed) equivalent bitvector of size {@code m+i}, where \c m is + * the size of the given bit-vector. The argument {@code t} must + * have a bit-vector sort. **/ public BitVecExpr mkSignExt(int i, BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkSignExt(nCtx(), i, t.getNativeObject())); } /** - * Bit-vector zero extension. Extend the given bit-vector with - * zeros to the (unsigned) equivalent bitvector of size m+i, - * where \c m is the size of the given bit-vector. The argument must have a bit-vector sort. + * Bit-vector zero extension. + * Remarks: Extend the given bit-vector with + * zeros to the (unsigned) equivalent bitvector of size {@code m+i}, + * where \c m is the size of the given bit-vector. The argument {@code t} + * must have a bit-vector sort. **/ public BitVecExpr mkZeroExt(int i, BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkZeroExt(nCtx(), i, t.getNativeObject())); } /** - * Bit-vector repetition. The argument must - * have a bit-vector sort. + * Bit-vector repetition. + * Remarks: The argument {@code t} must + * have a bit-vector sort. **/ public BitVecExpr mkRepeat(int i, BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkRepeat(nCtx(), i, t.getNativeObject())); } /** - * Shift left. It is equivalent to multiplication by - * 2^x where \c x is the value of . + * Shift left. + * Remarks: It is equivalent to multiplication by + * {@code 2^x} where \c x is the value of {@code t2}. * * NB. The semantics of shift operations varies between environments. This * definition does not necessarily capture directly the semantics of the * programming language or assembly architecture you are modeling. * - * The arguments must have a bit-vector sort. + * The arguments must have a bit-vector sort. **/ public BitVecExpr mkBVSHL(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvshl(nCtx(), @@ -1384,18 +1336,18 @@ public class Context extends IDisposable } /** - * Logical shift right It is equivalent to unsigned division by - * 2^x where \c x is the value of . + * Logical shift right + * Remarks: It is equivalent to unsigned division by + * {@code 2^x} where \c x is the value of {@code t2}. * * NB. The semantics of shift operations varies between environments. This * definition does not necessarily capture directly the semantics of the * programming language or assembly architecture you are modeling. * - * The arguments must have a bit-vector sort. + * The arguments must have a bit-vector sort. **/ public BitVecExpr mkBVLSHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvlshr(nCtx(), @@ -1403,7 +1355,8 @@ public class Context extends IDisposable } /** - * Arithmetic shift right It is like logical shift right except + * Arithmetic shift right + * Remarks: It is like logical shift right except * that the most significant bits of the result always copy the most * significant bit of the second argument. * @@ -1411,11 +1364,10 @@ public class Context extends IDisposable * definition does not necessarily capture directly the semantics of the * programming language or assembly architecture you are modeling. * - * The arguments must have a bit-vector sort. + * The arguments must have a bit-vector sort. **/ public BitVecExpr mkBVASHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkBvashr(nCtx(), @@ -1423,38 +1375,38 @@ public class Context extends IDisposable } /** - * Rotate Left. Rotate bits of \c t to the left \c i times. The - * argument must have a bit-vector sort. + * Rotate Left. + * Remarks: Rotate bits of \c t to the left \c i times. The + * argument {@code t} must have a bit-vector sort. **/ public BitVecExpr mkBVRotateLeft(int i, BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkRotateLeft(nCtx(), i, t.getNativeObject())); } /** - * Rotate Right. Rotate bits of \c t to the right \c i times. The - * argument must have a bit-vector sort. + * Rotate Right. + * Remarks: Rotate bits of \c t to the right \c i times. The + * argument {@code t} must have a bit-vector sort. **/ public BitVecExpr mkBVRotateRight(int i, BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkRotateRight(nCtx(), i, t.getNativeObject())); } /** - * Rotate Left. Rotate bits of to the left - * times. The arguments must have the same bit-vector - * sort. + * Rotate Left. + * Remarks: Rotate bits of {@code t1} to the left + * {@code t2} times. The arguments must have the same bit-vector + * sort. **/ public BitVecExpr mkBVRotateLeft(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkExtRotateLeft(nCtx(), @@ -1462,14 +1414,14 @@ public class Context extends IDisposable } /** - * Rotate Right. Rotate bits of to the - * right times. The arguments must have the same - * bit-vector sort. + * Rotate Right. + * Remarks: Rotate bits of {@code t1} to the + * right{@code t2} times. The arguments must have the same + * bit-vector sort. **/ public BitVecExpr mkBVRotateRight(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BitVecExpr(this, Native.mkExtRotateRight(nCtx(), @@ -1477,38 +1429,37 @@ public class Context extends IDisposable } /** - * Create an bit bit-vector from the integer argument - * . NB. This function is essentially treated + * Create an {@code n} bit bit-vector from the integer argument + * {@code t}. + * Remarks: NB. This function is essentially treated * as uninterpreted. So you cannot expect Z3 to precisely reflect the * semantics of this function when solving constraints with this function. * - * The argument must be of integer sort. + * The argument must be of integer sort. **/ public BitVecExpr mkInt2BV(int n, IntExpr t) throws Z3Exception { - checkContextMatch(t); return new BitVecExpr(this, Native.mkInt2bv(nCtx(), n, t.getNativeObject())); } /** - * Create an integer from the bit-vector argument . - * If \c is_signed is false, then the bit-vector \c t1 is treated + * Create an integer from the bit-vector argument {@code t}. + * Remarks: If \c is_signed is false, then the bit-vector \c t1 is treated * as unsigned. So the result is non-negative and in the range - * [0..2^N-1], where N are the number of bits in . If \c is_signed is true, \c t1 is treated as a signed + * {@code [0..2^N-1]}, where N are the number of bits in {@code t}. + * If \c is_signed is true, \c t1 is treated as a signed * bit-vector. * * NB. This function is essentially treated as uninterpreted. So you cannot * expect Z3 to precisely reflect the semantics of this function when * solving constraints with this function. * - * The argument must be of bit-vector sort. + * The argument must be of bit-vector sort. **/ public IntExpr mkBV2Int(BitVecExpr t, boolean signed) throws Z3Exception { - checkContextMatch(t); return new IntExpr(this, Native.mkBv2int(nCtx(), t.getNativeObject(), (signed) ? true : false)); @@ -1516,12 +1467,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise addition does not - * overflow. The arguments must be of bit-vector sort. + * overflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvaddNoOverflow(nCtx(), t1 @@ -1531,12 +1482,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise addition does not - * underflow. The arguments must be of bit-vector sort. + * underflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvaddNoUnderflow(nCtx(), @@ -1545,12 +1496,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise subtraction does not - * overflow. The arguments must be of bit-vector sort. + * overflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsubNoOverflow(nCtx(), @@ -1559,12 +1510,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise subtraction does not - * underflow. The arguments must be of bit-vector sort. + * underflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsubNoUnderflow(nCtx(), t1 @@ -1574,12 +1525,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise signed division does not - * overflow. The arguments must be of bit-vector sort. + * overflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvsdivNoOverflow(nCtx(), @@ -1588,11 +1539,11 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise negation does not - * overflow. The arguments must be of bit-vector sort. + * overflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVNegNoOverflow(BitVecExpr t) throws Z3Exception { - checkContextMatch(t); return new BoolExpr(this, Native.mkBvnegNoOverflow(nCtx(), t.getNativeObject())); @@ -1600,12 +1551,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise multiplication does not - * overflow. The arguments must be of bit-vector sort. + * overflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvmulNoOverflow(nCtx(), t1 @@ -1615,12 +1566,12 @@ public class Context extends IDisposable /** * Create a predicate that checks that the bit-wise multiplication does not - * underflow. The arguments must be of bit-vector sort. + * underflow. + * Remarks: The arguments must be of bit-vector sort. **/ public BoolExpr mkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new BoolExpr(this, Native.mkBvmulNoUnderflow(nCtx(), @@ -1633,7 +1584,6 @@ public class Context extends IDisposable public ArrayExpr mkArrayConst(Symbol name, Sort domain, Sort range) throws Z3Exception { - return (ArrayExpr) mkConst(name, mkArraySort(domain, range)); } @@ -1643,22 +1593,24 @@ public class Context extends IDisposable public ArrayExpr mkArrayConst(String name, Sort domain, Sort range) throws Z3Exception { - return (ArrayExpr) mkConst(mkSymbol(name), mkArraySort(domain, range)); } /** - * Array read. The argument a is the array and - * i is the index of the array that gets read. + * Array read. + * Remarks: The argument {@code a} is the array and + * {@code i} is the index of the array that gets read. * - * The node a must have an array sort - * [domain -> range], and i must have the sort - * domain. The sort of the result is range. - * + * The node {@code a} must have an array sort + * {@code [domain -> range]}, and {@code i} must have the sort + * {@code domain}. The sort of the result is {@code range}. + * + * @see mkArraySort + * @see mkStore + **/ public Expr mkSelect(ArrayExpr a, Expr i) throws Z3Exception { - checkContextMatch(a); checkContextMatch(i); return Expr.create( @@ -1668,21 +1620,23 @@ public class Context extends IDisposable } /** - * Array update. The node a must have an array sort - * [domain -> range], i must have sort - * domain, v must have sort range. The sort of the - * result is [domain -> range]. The semantics of this function + * Array update. + * Remarks: The node {@code a} must have an array sort + * {@code [domain -> range]}, {@code i} must have sort + * {@code domain}, {@code v} must have sort range. The sort of the + * result is {@code [domain -> range]}. The semantics of this function * is given by the theory of arrays described in the SMT-LIB standard. See * http://smtlib.org for more details. The result of this function is an - * array that is equal to a (with respect to - * select) on all indices except for i, where it - * maps to v (and the select of a - * with respect to i may be a different value). + * array that is equal to {@code a} (with respect to + * {@code select}) on all indices except for {@code i}, where it + * maps to {@code v} (and the {@code select} of {@code a} + * with respect to {@code i} may be a different value). + * @see mkArraySort + * @see mkSelect + **/ public ArrayExpr mkStore(ArrayExpr a, Expr i, Expr v) throws Z3Exception { - checkContextMatch(a); checkContextMatch(i); checkContextMatch(v); @@ -1691,14 +1645,16 @@ public class Context extends IDisposable } /** - * Create a constant array. The resulting term is an array, such - * that a selecton an arbitrary index produces the value - * v. - * + * Create a constant array. + * Remarks: The resulting term is an array, such + * that a {@code select} on an arbitrary index produces the value + * {@code v}. + * @see mkArraySort + * @see mkSelect + * **/ public ArrayExpr mkConstArray(Sort domain, Expr v) throws Z3Exception { - checkContextMatch(domain); checkContextMatch(v); return new ArrayExpr(this, Native.mkConstArray(nCtx(), @@ -1706,17 +1662,20 @@ public class Context extends IDisposable } /** - * Maps f on the argument arrays. Eeach element of - * args must be of an array sort - * [domain_i -> range_i]. The function declaration - * f must have type range_1 .. range_n -> range. - * v must have sort range. The sort of the result is - * [domain_i -> range]. + * Maps f on the argument arrays. + * Remarks: Eeach element of + * {@code args} must be of an array sort + * {@code [domain_i -> range_i]}. The function declaration + * {@code f} must have type {@code range_1 .. range_n -> range}. + * {@code v} must have sort range. The sort of the result is + * {@code [domain_i -> range]}. + * @see mkArraySort + * @see mkSelect + * @see mkStore + **/ public ArrayExpr mkMap(FuncDecl f, ArrayExpr... args) throws Z3Exception { - checkContextMatch(f); checkContextMatch(args); return (ArrayExpr) Expr.create(this, Native.mkMap(nCtx(), @@ -1725,13 +1684,13 @@ public class Context extends IDisposable } /** - * Access the array default value. Produces the default range + * Access the array default value. + * Remarks: Produces the default range * value, for arrays that can be represented as finite maps with a default - * range value. + * range value. **/ public Expr mkTermArray(ArrayExpr array) throws Z3Exception { - checkContextMatch(array); return Expr.create(this, Native.mkArrayDefault(nCtx(), array.getNativeObject())); @@ -1742,7 +1701,6 @@ public class Context extends IDisposable **/ public SetSort mkSetSort(Sort ty) throws Z3Exception { - checkContextMatch(ty); return new SetSort(this, ty); } @@ -1752,7 +1710,6 @@ public class Context extends IDisposable **/ public Expr mkEmptySet(Sort domain) throws Z3Exception { - checkContextMatch(domain); return Expr.create(this, Native.mkEmptySet(nCtx(), domain.getNativeObject())); @@ -1763,7 +1720,6 @@ public class Context extends IDisposable **/ public Expr mkFullSet(Sort domain) throws Z3Exception { - checkContextMatch(domain); return Expr.create(this, Native.mkFullSet(nCtx(), domain.getNativeObject())); @@ -1774,7 +1730,6 @@ public class Context extends IDisposable **/ public Expr mkSetAdd(Expr set, Expr element) throws Z3Exception { - checkContextMatch(set); checkContextMatch(element); return Expr.create( @@ -1788,7 +1743,6 @@ public class Context extends IDisposable **/ public Expr mkSetDel(Expr set, Expr element) throws Z3Exception { - checkContextMatch(set); checkContextMatch(element); return Expr.create( @@ -1802,7 +1756,6 @@ public class Context extends IDisposable **/ public Expr mkSetUnion(Expr... args) throws Z3Exception { - checkContextMatch(args); return Expr.create( this, @@ -1815,7 +1768,6 @@ public class Context extends IDisposable **/ public Expr mkSetIntersection(Expr... args) throws Z3Exception { - checkContextMatch(args); return Expr.create( this, @@ -1828,7 +1780,6 @@ public class Context extends IDisposable **/ public Expr mkSetDifference(Expr arg1, Expr arg2) throws Z3Exception { - checkContextMatch(arg1); checkContextMatch(arg2); return Expr.create( @@ -1842,7 +1793,6 @@ public class Context extends IDisposable **/ public Expr mkSetComplement(Expr arg) throws Z3Exception { - checkContextMatch(arg); return Expr.create(this, Native.mkSetComplement(nCtx(), arg.getNativeObject())); @@ -1853,7 +1803,6 @@ public class Context extends IDisposable **/ public Expr mkSetMembership(Expr elem, Expr set) throws Z3Exception { - checkContextMatch(elem); checkContextMatch(set); return Expr.create( @@ -1867,7 +1816,6 @@ public class Context extends IDisposable **/ public Expr mkSetSubset(Expr arg1, Expr arg2) throws Z3Exception { - checkContextMatch(arg1); checkContextMatch(arg2); return Expr.create( @@ -1877,19 +1825,18 @@ public class Context extends IDisposable } /** - * Create a Term of a given sort. A string representing the - * Term value in decimal notation. If the given sort is a real, then the + * Create a Term of a given sort. + * @param v A string representing the term value in decimal notation. If the given sort is a real, then the * Term can be a rational, that is, a string of the form - * [num]* / [num]*. The sort of the + * {@code [num]* / [num]*}. + * @param ty The sort of the * numeral. In the current implementation, the given sort can be an int, - * real, or bit-vectors of arbitrary size. + * real, or bit-vectors of arbitrary size. * - * @return A Term with value and sort + * @return A Term with value {@code v} and sort {@code ty} **/ public Expr mkNumeral(String v, Sort ty) throws Z3Exception { - checkContextMatch(ty); return Expr.create(this, Native.mkNumeral(nCtx(), v, ty.getNativeObject())); @@ -1898,16 +1845,15 @@ public class Context extends IDisposable /** * Create a Term of a given sort. This function can be use to create * numerals that fit in a machine integer. It is slightly faster than - * MakeNumeral since it is not necessary to parse a string. - * Value of the numeral Sort of the - * numeral + * {@code MakeNumeral} since it is not necessary to parse a string. * - * @return A Term with value and type + * @param v Value of the numeral + * @param ty Sort of the numeral + * + * @return A Term with value {@code v} and type {@code ty} **/ public Expr mkNumeral(int v, Sort ty) throws Z3Exception { - checkContextMatch(ty); return Expr.create(this, Native.mkInt(nCtx(), v, ty.getNativeObject())); } @@ -1915,27 +1861,28 @@ public class Context extends IDisposable /** * Create a Term of a given sort. This function can be use to create * numerals that fit in a machine integer. It is slightly faster than - * MakeNumeral since it is not necessary to parse a string. - * Value of the numeral Sort of the - * numeral + * {@code MakeNumeral} since it is not necessary to parse a string. * - * @return A Term with value and type + * @param v Value of the numeral + * @param ty Sort of the numeral + * + * @return A Term with value {@code v} and type {@code ty} **/ public Expr mkNumeral(long v, Sort ty) throws Z3Exception { - checkContextMatch(ty); return Expr.create(this, Native.mkInt64(nCtx(), v, ty.getNativeObject())); } /** - * Create a real from a fraction. numerator of - * rational. denominator of rational. + * Create a real from a fraction. + * @param num numerator of rational. + * @param den denominator of rational. * - * @return A Term with value / - * and sort Real + * @return A Term with value {@code num}/{@code den} + * and sort Real + * @see mkNumeral(String,Sort) **/ public RatNum mkReal(int num, int den) throws Z3Exception { @@ -1946,10 +1893,10 @@ public class Context extends IDisposable } /** - * Create a real numeral. A string representing the Term - * value in decimal notation. + * Create a real numeral. + * @param v A string representing the Term value in decimal notation. * - * @return A Term with value and sort Real + * @return A Term with value {@code v} and sort Real **/ public RatNum mkReal(String v) throws Z3Exception { @@ -1959,9 +1906,10 @@ public class Context extends IDisposable } /** - * Create a real numeral. value of the numeral. + * Create a real numeral. + * @param v value of the numeral. * - * @return A Term with value and sort Real + * @return A Term with value {@code v} and sort Real **/ public RatNum mkReal(int v) throws Z3Exception { @@ -1971,9 +1919,10 @@ public class Context extends IDisposable } /** - * Create a real numeral. value of the numeral. + * Create a real numeral. + * @param v value of the numeral. * - * @return A Term with value and sort Real + * @return A Term with value {@code v} and sort Real **/ public RatNum mkReal(long v) throws Z3Exception { @@ -1983,8 +1932,8 @@ public class Context extends IDisposable } /** - * Create an integer numeral. A string representing the Term - * value in decimal notation. + * Create an integer numeral. + * @param v A string representing the Term value in decimal notation. **/ public IntNum mkInt(String v) throws Z3Exception { @@ -1994,9 +1943,10 @@ public class Context extends IDisposable } /** - * Create an integer numeral. value of the numeral. + * Create an integer numeral. + * @param v value of the numeral. * - * @return A Term with value and sort Integer + * @return A Term with value {@code v} and sort Integer **/ public IntNum mkInt(int v) throws Z3Exception { @@ -2006,9 +1956,10 @@ public class Context extends IDisposable } /** - * Create an integer numeral. value of the numeral. + * Create an integer numeral. + * @param v value of the numeral. * - * @return A Term with value and sort Integer + * @return A Term with value {@code v} and sort Integer **/ public IntNum mkInt(long v) throws Z3Exception { @@ -2018,54 +1969,56 @@ public class Context extends IDisposable } /** - * Create a bit-vector numeral. A string representing the - * value in decimal notation. the size of the - * bit-vector + * Create a bit-vector numeral. + * @param v A string representing the value in decimal notation. + * @param size the size of the bit-vector **/ public BitVecNum mkBV(String v, int size) throws Z3Exception { - return (BitVecNum) mkNumeral(v, mkBitVecSort(size)); } /** - * Create a bit-vector numeral. value of the - * numeral. the size of the bit-vector + * Create a bit-vector numeral. + * @param v value of the numeral. + * @param size the size of the bit-vector **/ public BitVecNum mkBV(int v, int size) throws Z3Exception { - return (BitVecNum) mkNumeral(v, mkBitVecSort(size)); } /** - * Create a bit-vector numeral. value of the - * numeral. * the size of the bit-vector + * Create a bit-vector numeral. + * @param v value of the numeral. * + * @param size the size of the bit-vector **/ public BitVecNum mkBV(long v, int size) throws Z3Exception { - return (BitVecNum) mkNumeral(v, mkBitVecSort(size)); } /** - * Create a universal Quantifier. Creates a forall formula, where - * is the weight, is - * an array of patterns, is an array with the sorts - * of the bound variables, is an array with the - * 'names' of the bound variables, and is the body + * Create a universal Quantifier. + * Remarks: Creates a forall formula, where + * {@code weight"/> is the weight, the sorts of the bound variables. names of the bound variables the - * body of the quantifier. quantifiers are + * importance of using the quantifier during instantiation. + * + * @param sorts the sorts of the bound variables. + * @param names names of the bound variables + * @param body the body of the quantifier. + * @param weight quantifiers are * associated with weights indicating the importance of using the quantifier - * during instantiation. By default, pass the weight 0. array containing the patterns created using - * MkPattern. array containing - * the anti-patterns created using MkPattern. optional symbol to track quantifier. optional symbol to track skolem constants. + * during instantiation. By default, pass the weight 0. + * @param patterns array containing the patterns created using + * {@code MkPattern}. + * @param noPatterns array containing the anti-patterns created using {@code MkPattern}. + * @param quantifierID optional symbol to track quantifier. + * @param skolemID optional symbol to track skolem constants. **/ public Quantifier mkForall(Sort[] sorts, Symbol[] names, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, @@ -2089,8 +2042,8 @@ public class Context extends IDisposable } /** - * Create an existential Quantifier. + * Create an existential Quantifier. + * @see mkForall(Sort[],Symbol[],Expr,int,Pattern[],Expr[],Symbol,Symbol) **/ public Quantifier mkExists(Sort[] sorts, Symbol[] names, Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, @@ -2147,15 +2100,18 @@ public class Context extends IDisposable } /** - * Selects the format used for pretty-printing expressions. The + * Selects the format used for pretty-printing expressions. + * Remarks: The * default mode for pretty printing expressions is to produce SMT-LIB style * output where common subexpressions are printed at each occurrence. The * mode is called Z3_PRINT_SMTLIB_FULL. To print shared common * subexpressions only once, use the Z3_PRINT_LOW_LEVEL mode. To print in * way that conforms to SMT-LIB standards and uses let expressions to share - * common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + * common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + * @see AST#toString + * @see Pattern#toString + * @see FuncDecl#toString + * @see Sort#toString **/ public void setPrintMode(Z3_ast_print_mode value) throws Z3Exception { @@ -2163,14 +2119,15 @@ public class Context extends IDisposable } /** - * Convert a benchmark into an SMT-LIB formatted string. Name of the benchmark. The argument is optional. - * The benchmark logic. The status string (sat, unsat, or unknown) Other attributes, such as source, difficulty or - * category. Auxiliary - * assumptions. Formula to be checked for - * consistency in conjunction with assumptions. + * Convert a benchmark into an SMT-LIB formatted string. + * @param name Name of the benchmark. The argument is optional. + * + * @param logic The benchmark logic. + * @param status The status string (sat, unsat, or unknown) + * @param attributes Other attributes, such as source, difficulty or + * category. + * @param assumptions Auxiliary assumptions. + * @param formula Formula to be checked for consistency in conjunction with assumptions. * * @return A string representation of the benchmark. **/ @@ -2185,13 +2142,13 @@ public class Context extends IDisposable } /** - * Parse the given string using the SMT-LIB parser. The symbol + * Parse the given string using the SMT-LIB parser. + * Remarks: The symbol * table of the parser can be initialized using the given sorts and - * declarations. The symbols in the arrays and - * don't need to match the names of the sorts - * and declarations in the arrays and . This is a useful feature since we can use arbitrary names - * to reference sorts and declarations. + * declarations. The symbols in the arrays {@code sortNames} and + * {@code declNames} don't need to match the names of the sorts + * and declarations in the arrays {@code sorts} and {@code decls}. This is a useful feature since we can use arbitrary names + * to reference sorts and declarations. **/ public void parseSMTLIBString(String str, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) throws Z3Exception @@ -2209,8 +2166,8 @@ public class Context extends IDisposable } /** - * Parse the given file using the SMT-LIB parser. + * Parse the given file using the SMT-LIB parser. + * @see parseSMTLIBString **/ public void parseSMTLIBFile(String fileName, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) @@ -2230,7 +2187,7 @@ public class Context extends IDisposable /** * The number of SMTLIB formulas parsed by the last call to - * ParseSMTLIBString or ParseSMTLIBFile. + * {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}. **/ public int getNumSMTLIBFormulas() throws Z3Exception { @@ -2238,8 +2195,8 @@ public class Context extends IDisposable } /** - * The formulas parsed by the last call to ParseSMTLIBString or - * ParseSMTLIBFile. + * The formulas parsed by the last call to {@code ParseSMTLIBString} or + * {@code ParseSMTLIBFile}. **/ public BoolExpr[] getSMTLIBFormulas() throws Z3Exception { @@ -2254,7 +2211,7 @@ public class Context extends IDisposable /** * The number of SMTLIB assumptions parsed by the last call to - * ParseSMTLIBString or ParseSMTLIBFile. + * {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}. **/ public int getNumSMTLIBAssumptions() throws Z3Exception { @@ -2262,8 +2219,8 @@ public class Context extends IDisposable } /** - * The assumptions parsed by the last call to ParseSMTLIBString - * or ParseSMTLIBFile. + * The assumptions parsed by the last call to {@code ParseSMTLIBString} + * or {@code ParseSMTLIBFile}. **/ public BoolExpr[] getSMTLIBAssumptions() throws Z3Exception { @@ -2278,7 +2235,7 @@ public class Context extends IDisposable /** * The number of SMTLIB declarations parsed by the last call to - * ParseSMTLIBString or ParseSMTLIBFile. + * {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}. **/ public int getNumSMTLIBDecls() throws Z3Exception { @@ -2287,7 +2244,7 @@ public class Context extends IDisposable /** * The declarations parsed by the last call to - * ParseSMTLIBString or ParseSMTLIBFile. + * {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}. **/ public FuncDecl[] getSMTLIBDecls() throws Z3Exception { @@ -2301,7 +2258,7 @@ public class Context extends IDisposable /** * The number of SMTLIB sorts parsed by the last call to - * ParseSMTLIBString or ParseSMTLIBFile. + * {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}. **/ public int getNumSMTLIBSorts() throws Z3Exception { @@ -2310,7 +2267,7 @@ public class Context extends IDisposable /** * The declarations parsed by the last call to - * ParseSMTLIBString or ParseSMTLIBFile. + * {@code ParseSMTLIBString} or {@code ParseSMTLIBFile}. **/ public Sort[] getSMTLIBSorts() throws Z3Exception { @@ -2323,8 +2280,8 @@ public class Context extends IDisposable } /** - * Parse the given string using the SMT-LIB2 parser. + * Parse the given string using the SMT-LIB2 parser. + * @see parseSMTLIBString * * @return A conjunction of assertions in the scope (up to push/pop) at the * end of the string. @@ -2347,8 +2304,8 @@ public class Context extends IDisposable } /** - * Parse the given file using the SMT-LIB2 parser. + * Parse the given file using the SMT-LIB2 parser. + * @see parseSMTLIB2String **/ public BoolExpr parseSMTLIB2File(String fileName, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) @@ -2369,18 +2326,18 @@ public class Context extends IDisposable } /** - * Creates a new Goal. Note that the Context must have been - * created with proof generation support if is set - * to true here. Indicates whether model - * generation should be enabled. Indicates - * whether unsat core generation should be enabled. Indicates whether proof generation should be - * enabled. + * Creates a new Goal. + * Remarks: Note that the Context must have been + * created with proof generation support if {@code proofs} is set + * to true here. + * @param models Indicates whether model generation should be enabled. + * @param unsatCores Indicates whether unsat core generation should be enabled. + * @param proofs Indicates whether proof generation should be + * enabled. **/ public Goal mkGoal(boolean models, boolean unsatCores, boolean proofs) throws Z3Exception { - return new Goal(this, models, unsatCores, proofs); } @@ -2389,7 +2346,6 @@ public class Context extends IDisposable **/ public Params mkParams() throws Z3Exception { - return new Params(this); } @@ -2420,7 +2376,6 @@ public class Context extends IDisposable **/ public String getTacticDescription(String name) throws Z3Exception { - return Native.tacticGetDescr(nCtx(), name); } @@ -2429,13 +2384,12 @@ public class Context extends IDisposable **/ public Tactic mkTactic(String name) throws Z3Exception { - return new Tactic(this, name); } /** - * Create a tactic that applies to a Goal and then - * to every subgoal produced by . + * Create a tactic that applies {@code t1} to a Goal and then + * {@code t2"/> to every subgoal produced by to a Goal and then - * to every subgoal produced by . - * Shorthand for AndThen. + * Create a tactic that applies {@code t1} to a Goal and then + * {@code t2"/> to every subgoal produced by to a Goal and if - * it fails then returns the result of applied to the + * Create a tactic that first applies {@code t1} to a Goal and if + * it fails then returns the result of {@code t2} applied to the * Goal. **/ public Tactic orElse(Tactic t1, Tactic t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new Tactic(this, Native.tacticOrElse(nCtx(), @@ -2487,28 +2441,26 @@ public class Context extends IDisposable } /** - * Create a tactic that applies to a goal for milliseconds. If does not - * terminate within milliseconds, then it fails. - * + * Create a tactic that applies {@code t} to a goal for {@code ms} milliseconds. + * Remarks: If {@code t} does not + * terminate within {@code ms} milliseconds, then it fails. + * **/ public Tactic tryFor(Tactic t, int ms) throws Z3Exception { - checkContextMatch(t); return new Tactic(this, Native.tacticTryFor(nCtx(), t.getNativeObject(), ms)); } /** - * Create a tactic that applies to a given goal if the - * probe evaluates to true. If evaluates to false, then the new tactic behaves like the - * skip tactic. + * Create a tactic that applies {@code t} to a given goal if the + * probe {@code p} evaluates to true. + * Remarks: If {@code p} evaluates to false, then the new tactic behaves like the + * {@code skip} tactic. **/ public Tactic when(Probe p, Tactic t) throws Z3Exception { - checkContextMatch(t); checkContextMatch(p); return new Tactic(this, Native.tacticWhen(nCtx(), p.getNativeObject(), @@ -2516,13 +2468,12 @@ public class Context extends IDisposable } /** - * Create a tactic that applies to a given goal if the - * probe evaluates to true and + * Create a tactic that applies {@code t1} to a given goal if the + * probe {@code p"/> evaluates to true and until the goal - * is not modified anymore or the maximum number of iterations is reached. + * Create a tactic that keeps applying {@code t} until the goal + * is not modified anymore or the maximum number of iterations {@code max} is reached. **/ public Tactic repeat(Tactic t, int max) throws Z3Exception { - checkContextMatch(t); return new Tactic(this, Native.tacticRepeat(nCtx(), t.getNativeObject(), max)); @@ -2548,7 +2497,6 @@ public class Context extends IDisposable **/ public Tactic skip() throws Z3Exception { - return new Tactic(this, Native.tacticSkip(nCtx())); } @@ -2557,17 +2505,15 @@ public class Context extends IDisposable **/ public Tactic fail() throws Z3Exception { - return new Tactic(this, Native.tacticFail(nCtx())); } /** - * Create a tactic that fails if the probe evaluates to + * Create a tactic that fails if the probe {@code p} evaluates to * false. **/ public Tactic failIf(Probe p) throws Z3Exception { - checkContextMatch(p); return new Tactic(this, Native.tacticFailIf(nCtx(), p.getNativeObject())); @@ -2583,8 +2529,8 @@ public class Context extends IDisposable } /** - * Create a tactic that applies using the given set of - * parameters . + * Create a tactic that applies {@code t} using the given set of + * parameters {@code p}. **/ public Tactic usingParams(Tactic t, Params p) throws Z3Exception { @@ -2595,9 +2541,10 @@ public class Context extends IDisposable } /** - * Create a tactic that applies using the given set of - * parameters . Alias for - * UsingParams + * Create a tactic that applies {@code t} using the given set of + * parameters {@code p}. + * Remarks: Alias for + * {@code UsingParams} **/ public Tactic with(Tactic t, Params p) throws Z3Exception { @@ -2615,13 +2562,11 @@ public class Context extends IDisposable } /** - * Create a tactic that applies to a given goal and - * then to every subgoal produced by . The subgoals are processed in parallel. + * Create a tactic that applies {@code t1} to a given goal and + * then {@code t2} to every subgoal produced by {@code t1}. The subgoals are processed in parallel. **/ public Tactic parAndThen(Tactic t1, Tactic t2) throws Z3Exception { - checkContextMatch(t1); checkContextMatch(t2); return new Tactic(this, Native.tacticParAndThen(nCtx(), @@ -2629,8 +2574,9 @@ public class Context extends IDisposable } /** - * Interrupt the execution of a Z3 procedure. This procedure can be - * used to interrupt: solvers, simplifiers and tactics. + * Interrupt the execution of a Z3 procedure. + * Remarks: This procedure can be + * used to interrupt: solvers, simplifiers and tactics. **/ public void interrupt() throws Z3Exception { @@ -2676,7 +2622,7 @@ public class Context extends IDisposable } /** - * Create a probe that always evaluates to . + * Create a probe that always evaluates to {@code val}. **/ public Probe constProbe(double val) throws Z3Exception { @@ -2685,12 +2631,10 @@ public class Context extends IDisposable /** * Create a probe that evaluates to "true" when the value returned by - * is less than the value returned by + * {@code p1} is less than the value returned by {@code p2} **/ public Probe lt(Probe p1, Probe p2) throws Z3Exception { - checkContextMatch(p1); checkContextMatch(p2); return new Probe(this, Native.probeLt(nCtx(), p1.getNativeObject(), @@ -2699,12 +2643,10 @@ public class Context extends IDisposable /** * Create a probe that evaluates to "true" when the value returned by - * is greater than the value returned by + * {@code p1} is greater than the value returned by {@code p2} **/ public Probe gt(Probe p1, Probe p2) throws Z3Exception { - checkContextMatch(p1); checkContextMatch(p2); return new Probe(this, Native.probeGt(nCtx(), p1.getNativeObject(), @@ -2713,12 +2655,11 @@ public class Context extends IDisposable /** * Create a probe that evaluates to "true" when the value returned by - * is less than or equal the value returned by - * + * {@code p1} is less than or equal the value returned by + * {@code p2} **/ public Probe le(Probe p1, Probe p2) throws Z3Exception { - checkContextMatch(p1); checkContextMatch(p2); return new Probe(this, Native.probeLe(nCtx(), p1.getNativeObject(), @@ -2727,8 +2668,8 @@ public class Context extends IDisposable /** * Create a probe that evaluates to "true" when the value returned by - * is greater than or equal the value returned by - * + * {@code p1} is greater than or equal the value returned by + * {@code p2} **/ public Probe ge(Probe p1, Probe p2) throws Z3Exception { @@ -2740,8 +2681,7 @@ public class Context extends IDisposable /** * Create a probe that evaluates to "true" when the value returned by - * is equal to the value returned by + * {@code p1} is equal to the value returned by {@code p2} **/ public Probe eq(Probe p1, Probe p2) throws Z3Exception { @@ -2752,8 +2692,7 @@ public class Context extends IDisposable } /** - * Create a probe that evaluates to "true" when the value and evaluate to "true". + * Create a probe that evaluates to "true" when the value {@code p1} and {@code p2} evaluate to "true". **/ public Probe and(Probe p1, Probe p2) throws Z3Exception { @@ -2764,8 +2703,7 @@ public class Context extends IDisposable } /** - * Create a probe that evaluates to "true" when the value or evaluate to "true". + * Create a probe that evaluates to "true" when the value {@code p1} or {@code p2} evaluate to "true". **/ public Probe or(Probe p1, Probe p2) throws Z3Exception { @@ -2776,21 +2714,20 @@ public class Context extends IDisposable } /** - * Create a probe that evaluates to "true" when the value does not evaluate to "true". + * Create a probe that evaluates to "true" when the value {@code p} does not evaluate to "true". **/ public Probe not(Probe p) throws Z3Exception { - checkContextMatch(p); return new Probe(this, Native.probeNot(nCtx(), p.getNativeObject())); } /** - * Creates a new (incremental) solver. This solver also uses a set + * Creates a new (incremental) solver. + * Remarks: This solver also uses a set * of builtin tactics for handling the first check-sat command, and * check-sat commands that take more than a given number of milliseconds to - * be solved. + * be solved. **/ public Solver mkSolver() throws Z3Exception { @@ -2798,10 +2735,11 @@ public class Context extends IDisposable } /** - * Creates a new (incremental) solver. This solver also uses a set + * Creates a new (incremental) solver. + * Remarks: This solver also uses a set * of builtin tactics for handling the first check-sat command, and * check-sat commands that take more than a given number of milliseconds to - * be solved. + * be solved. **/ public Solver mkSolver(Symbol logic) throws Z3Exception { @@ -2814,11 +2752,11 @@ public class Context extends IDisposable } /** - * Creates a new (incremental) solver. + * Creates a new (incremental) solver. + * @see mkSolver(Symbol) **/ public Solver mkSolver(String logic) throws Z3Exception { - return mkSolver(mkSymbol(logic)); } @@ -2827,14 +2765,14 @@ public class Context extends IDisposable **/ public Solver mkSimpleSolver() throws Z3Exception { - return new Solver(this, Native.mkSimpleSolver(nCtx())); } /** - * Creates a solver that is implemented using the given tactic. - * The solver supports the commands Push and Pop, - * but it will always solve each check from scratch. + * Creates a solver that is implemented using the given tactic. + * Remarks: + * The solver supports the commands {@code Push} and {@code Pop}, + * but it will always solve each check from scratch. **/ public Solver mkSolver(Tactic t) throws Z3Exception { @@ -2848,33 +2786,35 @@ public class Context extends IDisposable **/ public Fixedpoint mkFixedpoint() throws Z3Exception { - return new Fixedpoint(this); } /** - * Wraps an AST. This function is used for transitions between - * native and managed objects. Note that - * must be a native object obtained from Z3 (e.g., through ) and that it must have a correct reference count (see - * e.g., . The native pointer to - * wrap. + * Wraps an AST. + * Remarks: This function is used for transitions between + * native and managed objects. Note that {@code nativeObject} + * must be a native object obtained from Z3 (e.g., through + * {@code UnwrapAST}) and that it must have a correct reference count. + * @see Native#incRef + * @see unwrapAST + * @param nativeObject The native pointer to wrap. **/ public AST wrapAST(long nativeObject) throws Z3Exception { - return AST.create(this, nativeObject); } /** - * Unwraps an AST. This function is used for transitions between + * Unwraps an AST. + * Remarks: This function is used for transitions between * native and managed objects. It returns the native pointer to the AST. * Note that AST objects are reference counted and unwrapping an AST * disables automatic reference counting, i.e., all references to the IntPtr * that is returned must be handled externally and through native calls (see - * e.g., ). The AST to unwrap. + * e.g., + * @see Native#incRef + * @see wrapAST + * @param a The AST to unwrap. **/ public long unwrapAST(AST a) { @@ -2883,11 +2823,10 @@ public class Context extends IDisposable /** * Return a string describing all available parameters to - * Expr.Simplify. + * {@code Expr.Simplify}. **/ public String SimplifyHelp() throws Z3Exception { - return Native.simplifyGetHelp(nCtx()); } @@ -2900,9 +2839,10 @@ public class Context extends IDisposable } /** - * Enable/disable printing of warning messages to the console. Note + * Enable/disable printing of warning messages to the console. + * Remarks: Note * that this function is static and effects the behaviour of all contexts - * globally. + * globally. **/ public static void ToggleWarningMessages(boolean enabled) throws Z3Exception @@ -2911,11 +2851,12 @@ public class Context extends IDisposable } /** - * Update a mutable configuration parameter. The list of all + * Update a mutable configuration parameter. + * Remarks: The list of all * configuration parameters can be obtained using the Z3 executable: - * z3.exe -ini? Only a few configuration parameters are mutable + * {@code z3.exe -ini?} Only a few configuration parameters are mutable * once the context is created. An exception is thrown when trying to modify - * an immutable parameter. + * an immutable parameter. **/ public void updateParamValue(String id, String value) throws Z3Exception { diff --git a/src/api/java/DatatypeExpr.java b/src/api/java/DatatypeExpr.java index 806ceacab..805784642 100644 --- a/src/api/java/DatatypeExpr.java +++ b/src/api/java/DatatypeExpr.java @@ -23,7 +23,7 @@ package com.microsoft.z3; public class DatatypeExpr extends Expr { /** - * Constructor for DatatypeExpr + * Constructor for DatatypeExpr **/ protected DatatypeExpr(Context ctx) { diff --git a/src/api/java/DatatypeSort.java b/src/api/java/DatatypeSort.java index 9c339d932..4a31b6c38 100644 --- a/src/api/java/DatatypeSort.java +++ b/src/api/java/DatatypeSort.java @@ -24,6 +24,8 @@ public class DatatypeSort extends Sort { /** * The number of constructors of the datatype sort. + * @throws Z3Exception on error + * @return an int **/ public int getNumConstructors() throws Z3Exception { @@ -35,6 +37,7 @@ public class DatatypeSort extends Sort * The constructors. * * @throws Z3Exception + * @throws Z3Exception on error **/ public FuncDecl[] getConstructors() throws Z3Exception { @@ -50,6 +53,7 @@ public class DatatypeSort extends Sort * The recognizers. * * @throws Z3Exception + * @throws Z3Exception on error **/ public FuncDecl[] getRecognizers() throws Z3Exception { @@ -65,6 +69,7 @@ public class DatatypeSort extends Sort * The constructor accessors. * * @throws Z3Exception + * @throws Z3Exception on error **/ public FuncDecl[][] getAccessors() throws Z3Exception { diff --git a/src/api/java/EnumSort.java b/src/api/java/EnumSort.java index 9715b9a97..6176f020a 100644 --- a/src/api/java/EnumSort.java +++ b/src/api/java/EnumSort.java @@ -24,6 +24,7 @@ public class EnumSort extends Sort { /** * The function declarations of the constants in the enumeration. + * @throws Z3Exception on error **/ public FuncDecl[] getConstDecls() throws Z3Exception { @@ -36,6 +37,8 @@ public class EnumSort extends Sort /** * The constants in the enumeration. + * @throws Z3Exception on error + * @return an Expr **/ public Expr[] getConsts() throws Z3Exception { @@ -48,6 +51,7 @@ public class EnumSort extends Sort /** * The test predicates for the constants in the enumeration. + * @throws Z3Exception on error **/ public FuncDecl[] getTesterDecls() throws Z3Exception { diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index a4c669dad..f94eb12cb 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -31,6 +31,9 @@ public class Expr extends AST { /** * Returns a simplified version of the expression + * @return Expr + * @throws Z3Exception on error + * @return an Expr **/ public Expr simplify() throws Z3Exception { @@ -40,8 +43,12 @@ public class Expr extends AST /** * Returns a simplified version of the expression * A set of - * parameters a Params object to configure the simplifier - * + * parameters + * @param p a Params object to configure the simplifier + * @see Context#SimplifyHelp + * @return an Expr + * @throws Z3Exception on error + * @return an Expr **/ public Expr simplify(Params p) throws Z3Exception { @@ -59,6 +66,8 @@ public class Expr extends AST /** * The function declaration of the function that is applied in this * expression. + * @return a FuncDecl + * @throws Z3Exception on error **/ public FuncDecl getFuncDecl() throws Z3Exception { @@ -69,6 +78,8 @@ public class Expr extends AST /** * Indicates whether the expression is the true or false expression or * something else (Z3_L_UNDEF). + * @throws Z3Exception on error + * @return a Z3_lbool **/ public Z3_lbool getBoolValue() throws Z3Exception { @@ -78,6 +89,8 @@ public class Expr extends AST /** * The number of arguments of the expression. + * @throws Z3Exception on error + * @return an int **/ public int getNumArgs() throws Z3Exception { @@ -86,6 +99,8 @@ public class Expr extends AST /** * The arguments of the expression. + * @throws Z3Exception on error + * @return an Expr[] **/ public Expr[] getArgs() throws Z3Exception { @@ -98,9 +113,11 @@ public class Expr extends AST } /** - * Update the arguments of the expression using the arguments The number of new arguments should coincide with the + * Update the arguments of the expression using the arguments {@code args} + * The number of new arguments should coincide with the * current number of arguments. + * @param args arguments + * @throws Z3Exception on error **/ public void update(Expr[] args) throws Z3Exception { @@ -112,13 +129,16 @@ public class Expr extends AST } /** - * Substitute every occurrence of from[i] in the expression - * with to[i], for i smaller than - * num_exprs. The result is the new expression. The - * arrays from and to must have size - * num_exprs. For every i smaller than - * num_exprs, we must have that sort of from[i] - * must be equal to sort of to[i]. + * Substitute every occurrence of {@code from[i]} in the expression + * with {@code to[i]}, for {@code i} smaller than + * {@code num_exprs}. + * Remarks: The result is the new expression. The + * arrays {@code from} and {@code to} must have size + * {@code num_exprs}. For every {@code i} smaller than + * {@code num_exprs}, we must have that sort of {@code from[i]} + * must be equal to sort of {@code to[i]}. + * @throws Z3Exception on error + * @return an Expr **/ public Expr substitute(Expr[] from, Expr[] to) throws Z3Exception { @@ -132,8 +152,11 @@ public class Expr extends AST } /** - * Substitute every occurrence of from in the expression with - * to. + * Substitute every occurrence of {@code from} in the expression with + * {@code to}. + * @see Expr#substitute(Expr[],Expr[]) + * @throws Z3Exception on error + * @return an Expr **/ public Expr substitute(Expr from, Expr to) throws Z3Exception { @@ -143,9 +166,13 @@ public class Expr extends AST /** * Substitute the free variables in the expression with the expressions in - * For every i smaller than - * num_exprs, the variable with de-Bruijn index i - * is replaced with term to[i]. + * {@code to} + * Remarks: For every {@code i} smaller than * {@code num_exprs}, the + * variable with de-Bruijn index {@code i} * is replaced with term + * {@code to[i]}. + * @throws Z3Exception on error + * @throws Z3Exception on error + * @return an Expr **/ public Expr substituteVars(Expr[] to) throws Z3Exception { @@ -156,11 +183,13 @@ public class Expr extends AST } /** - * Translates (copies) the term to the Context . - * A context + * Translates (copies) the term to the Context {@code ctx}. * - * @return A copy of the term which is associated with + * @param ctx A context + * + * @return A copy of the term which is associated with {@code ctx} + * @throws Z3Exception on error + * @return an Expr **/ public Expr translate(Context ctx) throws Z3Exception { @@ -184,6 +213,8 @@ public class Expr extends AST /** * Indicates whether the term is a numeral + * @throws Z3Exception on error + * @return a boolean **/ public boolean isNumeral() throws Z3Exception { @@ -194,6 +225,8 @@ public class Expr extends AST * Indicates whether the term is well-sorted. * * @return True if the term is well-sorted, false otherwise. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isWellSorted() throws Z3Exception { @@ -202,6 +235,8 @@ public class Expr extends AST /** * The Sort of the term. + * @throws Z3Exception on error + * @return a sort **/ public Sort getSort() throws Z3Exception { @@ -211,6 +246,8 @@ public class Expr extends AST /** * Indicates whether the term represents a constant. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isConst() throws Z3Exception { @@ -219,6 +256,8 @@ public class Expr extends AST /** * Indicates whether the term is an integer numeral. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isIntNum() throws Z3Exception { @@ -227,6 +266,8 @@ public class Expr extends AST /** * Indicates whether the term is a real numeral. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRatNum() throws Z3Exception { @@ -235,6 +276,8 @@ public class Expr extends AST /** * Indicates whether the term is an algebraic number + * @throws Z3Exception on error + * @return a boolean **/ public boolean isAlgebraicNumber() throws Z3Exception { @@ -243,6 +286,8 @@ public class Expr extends AST /** * Indicates whether the term has Boolean sort. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBool() throws Z3Exception { @@ -253,6 +298,8 @@ public class Expr extends AST /** * Indicates whether the term is the constant true. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isTrue() throws Z3Exception { @@ -261,6 +308,8 @@ public class Expr extends AST /** * Indicates whether the term is the constant false. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isFalse() throws Z3Exception { @@ -269,6 +318,8 @@ public class Expr extends AST /** * Indicates whether the term is an equality predicate. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isEq() throws Z3Exception { @@ -278,6 +329,8 @@ public class Expr extends AST /** * Indicates whether the term is an n-ary distinct predicate (every argument * is mutually distinct). + * @throws Z3Exception on error + * @return a boolean **/ public boolean isDistinct() throws Z3Exception { @@ -286,6 +339,8 @@ public class Expr extends AST /** * Indicates whether the term is a ternary if-then-else term + * @throws Z3Exception on error + * @return a boolean **/ public boolean isITE() throws Z3Exception { @@ -294,6 +349,8 @@ public class Expr extends AST /** * Indicates whether the term is an n-ary conjunction + * @throws Z3Exception on error + * @return a boolean **/ public boolean isAnd() throws Z3Exception { @@ -302,6 +359,8 @@ public class Expr extends AST /** * Indicates whether the term is an n-ary disjunction + * @throws Z3Exception on error + * @return a boolean **/ public boolean isOr() throws Z3Exception { @@ -311,6 +370,8 @@ public class Expr extends AST /** * Indicates whether the term is an if-and-only-if (Boolean equivalence, * binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isIff() throws Z3Exception { @@ -319,6 +380,8 @@ public class Expr extends AST /** * Indicates whether the term is an exclusive or + * @throws Z3Exception on error + * @return a boolean **/ public boolean isXor() throws Z3Exception { @@ -327,6 +390,8 @@ public class Expr extends AST /** * Indicates whether the term is a negation + * @throws Z3Exception on error + * @return a boolean **/ public boolean isNot() throws Z3Exception { @@ -335,6 +400,8 @@ public class Expr extends AST /** * Indicates whether the term is an implication + * @throws Z3Exception on error + * @return a boolean **/ public boolean isImplies() throws Z3Exception { @@ -343,6 +410,8 @@ public class Expr extends AST /** * Indicates whether the term is of integer sort. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isInt() throws Z3Exception { @@ -354,6 +423,8 @@ public class Expr extends AST /** * Indicates whether the term is of sort real. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isReal() throws Z3Exception { @@ -364,6 +435,8 @@ public class Expr extends AST /** * Indicates whether the term is an arithmetic numeral. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isArithmeticNumeral() throws Z3Exception { @@ -372,6 +445,8 @@ public class Expr extends AST /** * Indicates whether the term is a less-than-or-equal + * @throws Z3Exception on error + * @return a boolean **/ public boolean isLE() throws Z3Exception { @@ -380,6 +455,8 @@ public class Expr extends AST /** * Indicates whether the term is a greater-than-or-equal + * @throws Z3Exception on error + * @return a boolean **/ public boolean isGE() throws Z3Exception { @@ -388,6 +465,8 @@ public class Expr extends AST /** * Indicates whether the term is a less-than + * @throws Z3Exception on error + * @return a boolean **/ public boolean isLT() throws Z3Exception { @@ -396,6 +475,8 @@ public class Expr extends AST /** * Indicates whether the term is a greater-than + * @throws Z3Exception on error + * @return a boolean **/ public boolean isGT() throws Z3Exception { @@ -404,6 +485,8 @@ public class Expr extends AST /** * Indicates whether the term is addition (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isAdd() throws Z3Exception { @@ -412,6 +495,8 @@ public class Expr extends AST /** * Indicates whether the term is subtraction (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSub() throws Z3Exception { @@ -420,6 +505,8 @@ public class Expr extends AST /** * Indicates whether the term is a unary minus + * @throws Z3Exception on error + * @return a boolean **/ public boolean isUMinus() throws Z3Exception { @@ -428,6 +515,8 @@ public class Expr extends AST /** * Indicates whether the term is multiplication (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isMul() throws Z3Exception { @@ -436,6 +525,8 @@ public class Expr extends AST /** * Indicates whether the term is division (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isDiv() throws Z3Exception { @@ -444,6 +535,8 @@ public class Expr extends AST /** * Indicates whether the term is integer division (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isIDiv() throws Z3Exception { @@ -452,6 +545,8 @@ public class Expr extends AST /** * Indicates whether the term is remainder (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRemainder() throws Z3Exception { @@ -460,6 +555,8 @@ public class Expr extends AST /** * Indicates whether the term is modulus (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isModulus() throws Z3Exception { @@ -468,6 +565,8 @@ public class Expr extends AST /** * Indicates whether the term is a coercion of integer to real (unary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isIntToReal() throws Z3Exception { @@ -476,6 +575,8 @@ public class Expr extends AST /** * Indicates whether the term is a coercion of real to integer (unary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRealToInt() throws Z3Exception { @@ -485,6 +586,8 @@ public class Expr extends AST /** * Indicates whether the term is a check that tests whether a real is * integral (unary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRealIsInt() throws Z3Exception { @@ -493,6 +596,8 @@ public class Expr extends AST /** * Indicates whether the term is of an array sort. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isArray() throws Z3Exception { @@ -502,9 +607,10 @@ public class Expr extends AST } /** - * Indicates whether the term is an array store. It satisfies - * select(store(a,i,v),j) = if i = j then v else select(a,j). Array store - * takes at least 3 arguments. + * Indicates whether the term is an array store. + * Remarks: It satisfies * select(store(a,i,v),j) = if i = j then v else select(a,j). Array store * takes at least 3 arguments. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isStore() throws Z3Exception { @@ -513,6 +619,8 @@ public class Expr extends AST /** * Indicates whether the term is an array select. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSelect() throws Z3Exception { @@ -520,9 +628,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a constant array. For example, - * select(const(v),i) = v holds for every v and i. The function is - * unary. + * Indicates whether the term is a constant array. + * Remarks: For example, * select(const(v),i) = v holds for every v and i. The function is * unary. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isConstantArray() throws Z3Exception { @@ -530,8 +639,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a default array. For example - * default(const(v)) = v. The function is unary. + * Indicates whether the term is a default array. + * Remarks: For example default(const(v)) = v. The function is unary. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isDefaultArray() throws Z3Exception { @@ -539,8 +650,11 @@ public class Expr extends AST } /** - * Indicates whether the term is an array map. It satisfies - * map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + * Indicates whether the term is an array map. + * Remarks: It satisfies + * map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isArrayMap() throws Z3Exception { @@ -548,9 +662,10 @@ public class Expr extends AST } /** - * Indicates whether the term is an as-array term. An as-array term - * is n array value that behaves as the function graph of the function - * passed as parameter. + * Indicates whether the term is an as-array term. + * Remarks: An as-array term * is n array value that behaves as the function graph of the function * passed as parameter. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isAsArray() throws Z3Exception { @@ -559,6 +674,8 @@ public class Expr extends AST /** * Indicates whether the term is set union + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSetUnion() throws Z3Exception { @@ -567,6 +684,8 @@ public class Expr extends AST /** * Indicates whether the term is set intersection + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSetIntersect() throws Z3Exception { @@ -575,6 +694,8 @@ public class Expr extends AST /** * Indicates whether the term is set difference + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSetDifference() throws Z3Exception { @@ -583,6 +704,8 @@ public class Expr extends AST /** * Indicates whether the term is set complement + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSetComplement() throws Z3Exception { @@ -591,6 +714,8 @@ public class Expr extends AST /** * Indicates whether the term is set subset + * @throws Z3Exception on error + * @return a boolean **/ public boolean isSetSubset() throws Z3Exception { @@ -599,6 +724,8 @@ public class Expr extends AST /** * Indicates whether the terms is of bit-vector sort. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBV() throws Z3Exception { @@ -609,6 +736,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector numeral + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVNumeral() throws Z3Exception { @@ -617,6 +746,8 @@ public class Expr extends AST /** * Indicates whether the term is a one-bit bit-vector with value one + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVBitOne() throws Z3Exception { @@ -625,6 +756,8 @@ public class Expr extends AST /** * Indicates whether the term is a one-bit bit-vector with value zero + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVBitZero() throws Z3Exception { @@ -633,6 +766,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector unary minus + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVUMinus() throws Z3Exception { @@ -641,6 +776,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector addition (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVAdd() throws Z3Exception { @@ -649,6 +786,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector subtraction (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSub() throws Z3Exception { @@ -657,6 +796,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector multiplication (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVMul() throws Z3Exception { @@ -665,6 +806,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector signed division (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSDiv() throws Z3Exception { @@ -673,6 +816,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector unsigned division (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVUDiv() throws Z3Exception { @@ -681,6 +826,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector signed remainder (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSRem() throws Z3Exception { @@ -689,6 +836,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector unsigned remainder (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVURem() throws Z3Exception { @@ -697,6 +846,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector signed modulus + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSMod() throws Z3Exception { @@ -705,46 +856,58 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector signed division by zero + * @return a boolean + * @throws Z3Exception on error **/ - boolean IsBVSDiv0() throws Z3Exception + boolean isBVSDiv0() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSDIV0; } /** * Indicates whether the term is a bit-vector unsigned division by zero + * @return a boolean + * @throws Z3Exception on error **/ - boolean IsBVUDiv0() throws Z3Exception + boolean isBVUDiv0() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BUDIV0; } /** * Indicates whether the term is a bit-vector signed remainder by zero + * @return a boolean + * @throws Z3Exception on error **/ - boolean IsBVSRem0() throws Z3Exception + boolean isBVSRem0() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSREM0; } /** * Indicates whether the term is a bit-vector unsigned remainder by zero + * @return a boolean + * @throws Z3Exception on error **/ - boolean IsBVURem0() throws Z3Exception + boolean isBVURem0() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BUREM0; } /** * Indicates whether the term is a bit-vector signed modulus by zero + * @return a boolean + * @throws Z3Exception on error **/ - boolean IsBVSMod0() throws Z3Exception + boolean isBVSMod0() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_BSMOD0; } /** * Indicates whether the term is an unsigned bit-vector less-than-or-equal + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVULE() throws Z3Exception { @@ -753,6 +916,8 @@ public class Expr extends AST /** * Indicates whether the term is a signed bit-vector less-than-or-equal + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSLE() throws Z3Exception { @@ -762,6 +927,8 @@ public class Expr extends AST /** * Indicates whether the term is an unsigned bit-vector * greater-than-or-equal + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVUGE() throws Z3Exception { @@ -770,6 +937,8 @@ public class Expr extends AST /** * Indicates whether the term is a signed bit-vector greater-than-or-equal + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSGE() throws Z3Exception { @@ -778,6 +947,8 @@ public class Expr extends AST /** * Indicates whether the term is an unsigned bit-vector less-than + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVULT() throws Z3Exception { @@ -786,6 +957,8 @@ public class Expr extends AST /** * Indicates whether the term is a signed bit-vector less-than + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSLT() throws Z3Exception { @@ -794,6 +967,8 @@ public class Expr extends AST /** * Indicates whether the term is an unsigned bit-vector greater-than + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVUGT() throws Z3Exception { @@ -802,6 +977,8 @@ public class Expr extends AST /** * Indicates whether the term is a signed bit-vector greater-than + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSGT() throws Z3Exception { @@ -810,6 +987,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise AND + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVAND() throws Z3Exception { @@ -818,6 +997,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise OR + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVOR() throws Z3Exception { @@ -826,6 +1007,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise NOT + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVNOT() throws Z3Exception { @@ -834,6 +1017,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise XOR + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVXOR() throws Z3Exception { @@ -842,6 +1027,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise NAND + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVNAND() throws Z3Exception { @@ -850,6 +1037,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise NOR + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVNOR() throws Z3Exception { @@ -858,6 +1047,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-wise XNOR + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVXNOR() throws Z3Exception { @@ -866,6 +1057,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector concatenation (binary) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVConcat() throws Z3Exception { @@ -874,6 +1067,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector sign extension + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVSignExtension() throws Z3Exception { @@ -882,6 +1077,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector zero extension + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVZeroExtension() throws Z3Exception { @@ -890,6 +1087,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector extraction + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVExtract() throws Z3Exception { @@ -898,6 +1097,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector repetition + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVRepeat() throws Z3Exception { @@ -906,6 +1107,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector reduce OR + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVReduceOR() throws Z3Exception { @@ -914,6 +1117,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector reduce AND + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVReduceAND() throws Z3Exception { @@ -922,6 +1127,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector comparison + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVComp() throws Z3Exception { @@ -930,6 +1137,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector shift left + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVShiftLeft() throws Z3Exception { @@ -938,6 +1147,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector logical shift right + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVShiftRightLogical() throws Z3Exception { @@ -946,6 +1157,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector arithmetic shift left + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVShiftRightArithmetic() throws Z3Exception { @@ -954,6 +1167,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector rotate left + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVRotateLeft() throws Z3Exception { @@ -962,6 +1177,8 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector rotate right + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVRotateRight() throws Z3Exception { @@ -970,8 +1187,10 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector rotate left (extended) - * Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator - * instead of a parametric one. + * Remarks: Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator + * instead of a parametric one. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVRotateLeftExtended() throws Z3Exception { @@ -980,8 +1199,10 @@ public class Expr extends AST /** * Indicates whether the term is a bit-vector rotate right (extended) - * Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator - * instead of a parametric one. + * Remarks: Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator + * instead of a parametric one. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVRotateRightExtended() throws Z3Exception { @@ -990,9 +1211,10 @@ public class Expr extends AST /** * Indicates whether the term is a coercion from integer to bit-vector - * This function is not supported by the decision procedures. Only - * the most rudimentary simplification rules are applied to this - * function. + * + * Remarks: This function is not supported by the decision procedures. Only * the most rudimentary simplification rules are applied to this * function. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isIntToBV() throws Z3Exception { @@ -1001,9 +1223,10 @@ public class Expr extends AST /** * Indicates whether the term is a coercion from bit-vector to integer - * This function is not supported by the decision procedures. Only - * the most rudimentary simplification rules are applied to this - * function. + * + * Remarks: This function is not supported by the decision procedures. Only * the most rudimentary simplification rules are applied to this * function. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVToInt() throws Z3Exception { @@ -1011,9 +1234,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a bit-vector carry Compute the - * carry bit in a full-adder. The meaning is given by the equivalence (carry - * l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + * Indicates whether the term is a bit-vector carry + * Remarks: Compute the * carry bit in a full-adder. The meaning is given by the equivalence (carry * l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVCarry() throws Z3Exception { @@ -1021,9 +1245,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a bit-vector ternary XOR The - * meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor - * l1 l2) l3) + * Indicates whether the term is a bit-vector ternary XOR + * Remarks: The * meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor * l1 l2) l3) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isBVXOR3() throws Z3Exception { @@ -1032,8 +1257,11 @@ public class Expr extends AST /** * Indicates whether the term is a label (used by the Boogie Verification - * condition generator). The label has two parameters, a string and - * a Boolean polarity. It takes one argument, a formula. + * condition generator). + * Remarks: The label has two parameters, a string and + * a Boolean polarity. It takes one argument, a formula. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isLabel() throws Z3Exception { @@ -1042,8 +1270,11 @@ public class Expr extends AST /** * Indicates whether the term is a label literal (used by the Boogie - * Verification condition generator). A label literal has a set of - * string parameters. It takes no arguments. + * Verification condition generator). + * Remarks: A label literal has a set of + * string parameters. It takes no arguments. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isLabelLit() throws Z3Exception { @@ -1052,8 +1283,10 @@ public class Expr extends AST /** * Indicates whether the term is a binary equivalence modulo namings. - * This binary predicate is used in proof terms. It captures - * equisatisfiability and equivalence modulo renamings. + * Remarks: This binary predicate is used in proof terms. It captures + * equisatisfiability and equivalence modulo renamings. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isOEQ() throws Z3Exception { @@ -1062,6 +1295,8 @@ public class Expr extends AST /** * Indicates whether the term is a Proof for the expression 'true'. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofTrue() throws Z3Exception { @@ -1070,6 +1305,8 @@ public class Expr extends AST /** * Indicates whether the term is a proof for a fact asserted by the user. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofAsserted() throws Z3Exception { @@ -1079,6 +1316,8 @@ public class Expr extends AST /** * Indicates whether the term is a proof for a fact (tagged as goal) * asserted by the user. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofGoal() throws Z3Exception { @@ -1086,10 +1325,13 @@ public class Expr extends AST } /** - * Indicates whether the term is proof via modus ponens Given a + * Indicates whether the term is proof via modus ponens + * Remarks: Given a * proof for p and a proof for (implies p q), produces a proof for q. T1: p * T2: (implies p q) [mp T1 T2]: q The second antecedents may also be a - * proof for (iff p q). + * proof for (iff p q). + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofModusPonens() throws Z3Exception { @@ -1098,10 +1340,13 @@ public class Expr extends AST /** * Indicates whether the term is a proof for (R t t), where R is a reflexive - * relation. This proof object has no antecedents. The only + * relation. + * Remarks: This proof object has no antecedents. The only * reflexive relations that are used are equivalence modulo namings, * equality and equivalence. That is, R is either '~', '=' or - * 'iff'. + * 'iff'. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofReflexivity() throws Z3Exception { @@ -1110,9 +1355,10 @@ public class Expr extends AST /** * Indicates whether the term is proof by symmetricity of a relation - * Given an symmetric relation R and a proof for (R t s), produces - * a proof for (R s t). T1: (R t s) [symmetry T1]: (R s t) T1 is the - * antecedent of this proof object. + * + * Remarks: Given an symmetric relation R and a proof for (R t s), produces * a proof for (R s t). T1: (R t s) [symmetry T1]: (R s t) T1 is the * antecedent of this proof object. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofSymmetry() throws Z3Exception { @@ -1121,9 +1367,10 @@ public class Expr extends AST /** * Indicates whether the term is a proof by transitivity of a relation - * Given a transitive relation R, and proofs for (R t s) and (R s - * u), produces a proof for (R t u). T1: (R t s) T2: (R s u) [trans T1 T2]: - * (R t u) + * + * Remarks: Given a transitive relation R, and proofs for (R t s) and (R s * u), produces a proof for (R t u). T1: (R t s) T2: (R s u) [trans T1 T2]: * (R t u) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofTransitivity() throws Z3Exception { @@ -1132,7 +1379,8 @@ public class Expr extends AST /** * Indicates whether the term is a proof by condensed transitivity of a - * relation Condensed transitivity proof. This proof object is + * relation + * Remarks: Condensed transitivity proof. This proof object is * only used if the parameter PROOF_MODE is 1. It combines several symmetry * and transitivity proofs. Example: T1: (R a b) T2: (R c b) T3: (R c d) * [trans* T1 T2 T3]: (R a d) R must be a symmetric and transitive relation. @@ -1141,7 +1389,9 @@ public class Expr extends AST * checker must check if it is possible to prove (R s t) using the * antecedents, symmetry and transitivity. That is, if there is a path from * s to t, if we view every antecedent (R a b) as an edge between a and b. - * + * + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofTransitivityStar() throws Z3Exception { @@ -1149,11 +1399,14 @@ public class Expr extends AST } /** - * Indicates whether the term is a monotonicity proof object. T1: + * Indicates whether the term is a monotonicity proof object. + * Remarks: T1: * (R t_1 s_1) ... Tn: (R t_n s_n) [monotonicity T1 ... Tn]: (R (f t_1 ... * t_n) (f s_1 ... s_n)) Remark: if t_i == s_i, then the antecedent Ti is * suppressed. That is, reflexivity proofs are supressed to save space. - * + * + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofMonotonicity() throws Z3Exception { @@ -1161,9 +1414,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a quant-intro proof Given a proof - * for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). T1: - * (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) + * Indicates whether the term is a quant-intro proof + * Remarks: Given a proof * for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). T1: * (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofQuantIntro() throws Z3Exception { @@ -1171,7 +1425,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a distributivity proof object. + * Indicates whether the term is a distributivity proof object. + * Remarks: * Given that f (= or) distributes over g (= and), produces a proof for (= * (f a (g c d)) (g (f a c) (f a d))) If f and g are associative, this proof * also justifies the following equality: (= (f (g a b) (g c d)) (g (f a c) @@ -1179,7 +1434,9 @@ public class Expr extends AST * arguments. * * This proof object has no antecedents. Remark. This rule is used by the - * CNF conversion pass and instantiated by f = or, and g = and. + * CNF conversion pass and instantiated by f = or, and g = and. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofDistributivity() throws Z3Exception { @@ -1187,9 +1444,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by elimination of AND - * Given a proof for (and l_1 ... l_n), produces a proof for l_i T1: (and - * l_1 ... l_n) [and-elim T1]: l_i + * Indicates whether the term is a proof by elimination of AND + * Remarks: * Given a proof for (and l_1 ... l_n), produces a proof for l_i T1: (and * l_1 ... l_n) [and-elim T1]: l_i + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofAndElimination() throws Z3Exception { @@ -1197,9 +1455,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by eliminiation of not-or - * Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - * T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) + * Indicates whether the term is a proof by eliminiation of not-or + * Remarks: * Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). * T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofOrElimination() throws Z3Exception { @@ -1207,7 +1466,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by rewriting A proof for + * Indicates whether the term is a proof by rewriting + * Remarks: A proof for * a local rewriting step (= t s). The head function symbol of t is * interpreted. * @@ -1216,7 +1476,9 @@ public class Expr extends AST * equi-satisfiability (~ t s). Remark: if f is bool, then = is iff. * * Examples: (= (+ x 0) x) (= (+ x 1 2) (+ 3 x)) (iff (or x false) x) - * + * + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofRewrite() throws Z3Exception { @@ -1224,7 +1486,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by rewriting A proof for + * Indicates whether the term is a proof by rewriting + * Remarks: A proof for * rewriting an expression t into an expression s. This proof object is used * if the parameter PROOF_MODE is 1. This proof object can have n * antecedents. The antecedents are proofs for equalities used as @@ -1232,7 +1495,9 @@ public class Expr extends AST * parameter PROOF_MODE is 2. The cases are: - When applying contextual * simplification (CONTEXT_SIMPLIFIER=true) - When converting bit-vectors to * Booleans (BIT2BOOL=true) - When pulling ite expression up - * (PULL_CHEAP_ITE_TREES=true) + * (PULL_CHEAP_ITE_TREES=true) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofRewriteStar() throws Z3Exception { @@ -1241,8 +1506,10 @@ public class Expr extends AST /** * Indicates whether the term is a proof for pulling quantifiers out. - * A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) - * r))). This proof object has no antecedents. + * Remarks: A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) + * r))). This proof object has no antecedents. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofPullQuant() throws Z3Exception { @@ -1251,9 +1518,10 @@ public class Expr extends AST /** * Indicates whether the term is a proof for pulling quantifiers out. - * A proof for (iff P Q) where Q is in prenex normal form. This - * proof object is only used if the parameter PROOF_MODE is 1. This proof - * object has no antecedents + * + * Remarks: A proof for (iff P Q) where Q is in prenex normal form. This * proof object is only used if the parameter PROOF_MODE is 1. This proof * object has no antecedents + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofPullQuantStar() throws Z3Exception { @@ -1262,10 +1530,12 @@ public class Expr extends AST /** * Indicates whether the term is a proof for pushing quantifiers in. - * A proof for: (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] + * Remarks: A proof for: (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] * ... p_n[x_1 ... x_m])) (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) ... * (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) This proof object has no - * antecedents + * antecedents + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofPushQuant() throws Z3Exception { @@ -1274,11 +1544,14 @@ public class Expr extends AST /** * Indicates whether the term is a proof for elimination of unused - * variables. A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) + * variables. + * Remarks: A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) * p[x_1 ... x_n]) (forall (x_1 ... x_n) p[x_1 ... x_n])) * * It is used to justify the elimination of unused variables. This proof - * object has no antecedents. + * object has no antecedents. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofElimUnusedVars() throws Z3Exception { @@ -1287,12 +1560,14 @@ public class Expr extends AST /** * Indicates whether the term is a proof for destructive equality resolution - * A proof for destructive equality resolution: (iff (forall (x) + * Remarks: A proof for destructive equality resolution: (iff (forall (x) * (or (not (= x t)) P[x])) P[t]) if x does not occur in t. * * This proof object has no antecedents. * - * Several variables can be eliminated simultaneously. + * Several variables can be eliminated simultaneously. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofDER() throws Z3Exception { @@ -1301,7 +1576,10 @@ public class Expr extends AST /** * Indicates whether the term is a proof for quantifier instantiation - * A proof of (or (not (forall (x) (P x))) (P a)) + * + * Remarks: A proof of (or (not (forall (x) (P x))) (P a)) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofQuantInst() throws Z3Exception { @@ -1309,8 +1587,11 @@ public class Expr extends AST } /** - * Indicates whether the term is a hypthesis marker. Mark a - * hypothesis in a natural deduction style proof. + * Indicates whether the term is a hypthesis marker. + * Remarks: Mark a + * hypothesis in a natural deduction style proof. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofHypothesis() throws Z3Exception { @@ -1318,12 +1599,15 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by lemma T1: false [lemma + * Indicates whether the term is a proof by lemma + * Remarks: T1: false [lemma * T1]: (or (not l_1) ... (not l_n)) * * This proof object has one antecedent: a hypothetical proof for false. It * converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 - * contains the hypotheses: l_1, ..., l_n. + * contains the hypotheses: l_1, ..., l_n. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofLemma() throws Z3Exception { @@ -1331,9 +1615,10 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by unit resolution T1: - * (or l_1 ... l_n l_1' ... l_m') T2: (not l_1) ... T(n+1): (not l_n) - * [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') + * Indicates whether the term is a proof by unit resolution + * Remarks: T1: * (or l_1 ... l_n l_1' ... l_m') T2: (not l_1) ... T(n+1): (not l_n) * [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofUnitResolution() throws Z3Exception { @@ -1341,8 +1626,11 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by iff-true T1: p - * [iff-true T1]: (iff p true) + * Indicates whether the term is a proof by iff-true + * Remarks: T1: p + * [iff-true T1]: (iff p true) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofIFFTrue() throws Z3Exception { @@ -1350,8 +1638,11 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by iff-false T1: (not p) - * [iff-false T1]: (iff p false) + * Indicates whether the term is a proof by iff-false + * Remarks: T1: (not p) + * [iff-false T1]: (iff p false) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofIFFFalse() throws Z3Exception { @@ -1359,13 +1650,16 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof by commutativity [comm]: + * Indicates whether the term is a proof by commutativity + * Remarks: [comm]: * (= (f a b) (f b a)) * * f is a commutative operator. * * This proof object has no antecedents. Remark: if f is bool, then = is - * iff. + * iff. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofCommutativity() throws Z3Exception { @@ -1373,7 +1667,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof for Tseitin-like axioms + * Indicates whether the term is a proof for Tseitin-like axioms + * Remarks: * Proof object used to justify Tseitin's like axioms: * * (or (not (and p q)) p) (or (not (and p q)) q) (or (not (and p q r)) p) @@ -1388,7 +1683,9 @@ public class Expr extends AST * tautologies. Note also that 'and' and 'or' can take multiple arguments. * You can recover the propositional tautologies by unfolding the Boolean * connectives in the axioms a small bounded number of steps (=3). - * + * + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofDefAxiom() throws Z3Exception { @@ -1397,7 +1694,7 @@ public class Expr extends AST /** * Indicates whether the term is a proof for introduction of a name - * Introduces a name for a formula/term. Suppose e is an + * Remarks: Introduces a name for a formula/term. Suppose e is an * expression with free variables x, and def-intro introduces the name n(x). * The possible cases are: * @@ -1409,7 +1706,9 @@ public class Expr extends AST * When e is of the form (ite cond th el): [def-intro]: (and (or (not cond) * (= n th)) (or cond (= n el))) * - * Otherwise: [def-intro]: (= n e) + * Otherwise: [def-intro]: (= n e) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofDefIntro() throws Z3Exception { @@ -1418,8 +1717,10 @@ public class Expr extends AST /** * Indicates whether the term is a proof for application of a definition - * [apply-def T1]: F ~ n F is 'equivalent' to n, given that T1 is - * a proof that n is a name for F. + * Remarks: [apply-def T1]: F ~ n F is 'equivalent' to n, given that T1 is + * a proof that n is a name for F. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofApplyDef() throws Z3Exception { @@ -1427,8 +1728,11 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof iff-oeq T1: (iff p q) - * [iff~ T1]: (~ p q) + * Indicates whether the term is a proof iff-oeq + * Remarks: T1: (iff p q) + * [iff~ T1]: (~ p q) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofIFFOEQ() throws Z3Exception { @@ -1436,7 +1740,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof for a positive NNF step + * Indicates whether the term is a proof for a positive NNF step + * Remarks: * Proof for a (positive) NNF step. Example: * * T1: (not s_1) ~ r_1 T2: (not s_2) ~ r_2 T3: s_1 ~ r_1' T4: s_2 ~ r_2' @@ -1453,7 +1758,9 @@ public class Expr extends AST * top-level connective is changed during NNF conversion. The relevant * Boolean connectives for NNF_POS are 'implies', 'iff', 'xor', 'ite'. * NNF_NEG furthermore handles the case where negation is pushed over - * Boolean connectives 'and' and 'or'. + * Boolean connectives 'and' and 'or'. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofNNFPos() throws Z3Exception { @@ -1461,7 +1768,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof for a negative NNF step + * Indicates whether the term is a proof for a negative NNF step + * Remarks: * Proof for a (negative) NNF step. Examples: * * T1: (not s_1) ~ r_1 ... Tn: (not s_n) ~ r_n [nnf-neg T1 ... Tn]: (not @@ -1469,7 +1777,9 @@ public class Expr extends AST * (not s_n) ~ r_n [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 * ... r_n) and T1: (not s_1) ~ r_1 T2: (not s_2) ~ r_2 T3: s_1 ~ r_1' T4: * s_2 ~ r_2' [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 - * r_2) (or r_1' r_2'))) + * r_2) (or r_1' r_2'))) + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofNNFNeg() throws Z3Exception { @@ -1478,13 +1788,16 @@ public class Expr extends AST /** * Indicates whether the term is a proof for (~ P Q) here Q is in negation - * normal form. A proof for (~ P Q) where Q is in negation normal + * normal form. + * Remarks: A proof for (~ P Q) where Q is in negation normal * form. * * This proof object is only used if the parameter PROOF_MODE is 1. * * This proof object may have n antecedents. Each antecedent is a - * PR_DEF_INTRO. + * PR_DEF_INTRO. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofNNFStar() throws Z3Exception { @@ -1493,10 +1806,13 @@ public class Expr extends AST /** * Indicates whether the term is a proof for (~ P Q) where Q is in - * conjunctive normal form. A proof for (~ P Q) where Q is in + * conjunctive normal form. + * Remarks: A proof for (~ P Q) where Q is in * conjunctive normal form. This proof object is only used if the parameter * PROOF_MODE is 1. This proof object may have n antecedents. Each - * antecedent is a PR_DEF_INTRO. + * antecedent is a PR_DEF_INTRO. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofCNFStar() throws Z3Exception { @@ -1504,13 +1820,16 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof for a Skolemization step + * Indicates whether the term is a proof for a Skolemization step + * Remarks: * Proof for: * * [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y))) [sk]: (~ (exists x * (p x y)) (p (sk y) y)) * - * This proof object has no antecedents. + * This proof object has no antecedents. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofSkolemize() throws Z3Exception { @@ -1519,8 +1838,11 @@ public class Expr extends AST /** * Indicates whether the term is a proof by modus ponens for - * equi-satisfiability. Modus ponens style rule for - * equi-satisfiability. T1: p T2: (~ p q) [mp~ T1 T2]: q + * equi-satisfiability. + * Remarks: Modus ponens style rule for + * equi-satisfiability. T1: p T2: (~ p q) [mp~ T1 T2]: q + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofModusPonensOEQ() throws Z3Exception { @@ -1528,7 +1850,8 @@ public class Expr extends AST } /** - * Indicates whether the term is a proof for theory lemma Generic + * Indicates whether the term is a proof for theory lemma + * Remarks: Generic * proof for theory lemmas. * * The theory lemma function comes with one or more parameters. The first @@ -1539,7 +1862,9 @@ public class Expr extends AST * (negated) inequalities and obtain a contradiction. - triangle-eq - * Indicates a lemma related to the equivalence: (iff (= t1 t2) (and (<= * t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear - * arithmetic lemma that uses a gcd test. + * arithmetic lemma that uses a gcd test. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isProofTheoryLemma() throws Z3Exception { @@ -1548,6 +1873,8 @@ public class Expr extends AST /** * Indicates whether the term is of an array sort. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelation() throws Z3Exception { @@ -1558,10 +1885,13 @@ public class Expr extends AST } /** - * Indicates whether the term is an relation store Insert a record - * into a relation. The function takes n+1 arguments, where the - * first argument is the relation and the remaining n elements - * correspond to the n columns of the relation. + * Indicates whether the term is an relation store + * Remarks: Insert a record + * into a relation. The function takes {@code n+1} arguments, where the + * first argument is the relation and the remaining {@code n} elements + * correspond to the {@code n} columns of the relation. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationStore() throws Z3Exception { @@ -1570,6 +1900,8 @@ public class Expr extends AST /** * Indicates whether the term is an empty relation + * @throws Z3Exception on error + * @return a boolean **/ public boolean isEmptyRelation() throws Z3Exception { @@ -1578,6 +1910,8 @@ public class Expr extends AST /** * Indicates whether the term is a test for the emptiness of a relation + * @throws Z3Exception on error + * @return a boolean **/ public boolean isIsEmptyRelation() throws Z3Exception { @@ -1586,6 +1920,8 @@ public class Expr extends AST /** * Indicates whether the term is a relational join + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationalJoin() throws Z3Exception { @@ -1594,7 +1930,10 @@ public class Expr extends AST /** * Indicates whether the term is the union or convex hull of two relations. - * The function takes two arguments. + * + * Remarks: The function takes two arguments. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationUnion() throws Z3Exception { @@ -1602,8 +1941,11 @@ public class Expr extends AST } /** - * Indicates whether the term is the widening of two relations The - * function takes two arguments. + * Indicates whether the term is the widening of two relations + * Remarks: The + * function takes two arguments. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationWiden() throws Z3Exception { @@ -1612,8 +1954,11 @@ public class Expr extends AST /** * Indicates whether the term is a projection of columns (provided as - * numbers in the parameters). The function takes one - * argument. + * numbers in the parameters). + * Remarks: The function takes one + * argument. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationProject() throws Z3Exception { @@ -1621,11 +1966,14 @@ public class Expr extends AST } /** - * Indicates whether the term is a relation filter Filter + * Indicates whether the term is a relation filter + * Remarks: Filter * (restrict) a relation with respect to a predicate. The first argument is * a relation. The second argument is a predicate with free de-Brujin * indices corresponding to the columns of the relation. So the first column - * in the relation has index 0. + * in the relation has index 0. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationFilter() throws Z3Exception { @@ -1634,7 +1982,8 @@ public class Expr extends AST /** * Indicates whether the term is an intersection of a relation with the - * negation of another. Intersect the first relation with respect + * negation of another. + * Remarks: Intersect the first relation with respect * to negation of the second relation (the function takes two arguments). * Logically, the specification can be described by a function * @@ -1642,7 +1991,9 @@ public class Expr extends AST * * where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, * such that target are elements in x in pos, such that there is no y in neg - * that agrees with x on the columns c1, d1, .., cN, dN. + * that agrees with x on the columns c1, d1, .., cN, dN. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationNegationFilter() throws Z3Exception { @@ -1651,8 +2002,10 @@ public class Expr extends AST /** * Indicates whether the term is the renaming of a column in a relation - * The function takes one argument. The parameters contain the - * renaming as a cycle. + * Remarks: The function takes one argument. The parameters contain the + * renaming as a cycle. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationRename() throws Z3Exception { @@ -1661,6 +2014,8 @@ public class Expr extends AST /** * Indicates whether the term is the complement of a relation + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationComplement() throws Z3Exception { @@ -1668,10 +2023,13 @@ public class Expr extends AST } /** - * Indicates whether the term is a relational select Check if a - * record is an element of the relation. The function takes n+1 + * Indicates whether the term is a relational select + * Remarks: Check if a + * record is an element of the relation. The function takes {@code n+1} * arguments, where the first argument is a relation, and the remaining - * n arguments correspond to a record. + * {@code n} arguments correspond to a record. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationSelect() throws Z3Exception { @@ -1679,11 +2037,15 @@ public class Expr extends AST } /** - * Indicates whether the term is a relational clone (copy) Create + * Indicates whether the term is a relational clone (copy) + * Remarks: Create * a fresh copy (clone) of a relation. The function is logically the * identity, but in the context of a register machine allows for terms of - * kind to perform destructive updates to - * the first argument. + * kind {@code isRelationUnion} to perform destructive updates to + * the first argument. + * @see isRelationUnion + * @throws Z3Exception on error + * @return a boolean **/ public boolean isRelationClone() throws Z3Exception { @@ -1692,6 +2054,8 @@ public class Expr extends AST /** * Indicates whether the term is of an array sort. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isFiniteDomain() throws Z3Exception { @@ -1703,6 +2067,8 @@ public class Expr extends AST /** * Indicates whether the term is a less than predicate over a finite domain. + * @throws Z3Exception on error + * @return a boolean **/ public boolean isFiniteDomainLT() throws Z3Exception { @@ -1710,19 +2076,22 @@ public class Expr extends AST } /** - * The de-Burijn index of a bound variable. Bound variables are + * The de-Burijn index of a bound variable. + * Remarks: Bound variables are * indexed by de-Bruijn indices. It is perhaps easiest to explain the * meaning of de-Bruijn indices by indicating the compilation process from - * non-de-Bruijn formulas to de-Bruijn format. + * non-de-Bruijn formulas to de-Bruijn format. {@code * abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) * abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) * abs1(x, x, n) = b_n * abs1(y, x, n) = y * abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) * abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - * The last line is significant: the index of a bound variable is + * } The last line is significant: the index of a bound variable is * different depending on the scope in which it appears. The deeper x - * appears, the higher is its index. + * appears, the higher is its index. + * @throws Z3Exception on error + * @return an int **/ public int getIndex() throws Z3Exception { @@ -1744,6 +2113,7 @@ public class Expr extends AST /** * Constructor for Expr + * @throws Z3Exception on error **/ protected Expr(Context ctx, long obj) throws Z3Exception { diff --git a/src/api/java/FiniteDomainSort.java b/src/api/java/FiniteDomainSort.java index 4cb2ab917..cece06f1a 100644 --- a/src/api/java/FiniteDomainSort.java +++ b/src/api/java/FiniteDomainSort.java @@ -24,6 +24,7 @@ public class FiniteDomainSort extends Sort { /** * The size of the finite domain sort. + * @throws Z3Exception on error **/ public long getSize() throws Z3Exception { diff --git a/src/api/java/Fixedpoint.java b/src/api/java/Fixedpoint.java index 57e1e105a..587f47cbb 100644 --- a/src/api/java/Fixedpoint.java +++ b/src/api/java/Fixedpoint.java @@ -163,7 +163,8 @@ public class Fixedpoint extends Z3Object } /** - * Creates a backtracking point. + * Creates a backtracking point. + * @see pop **/ public void push() throws Z3Exception { @@ -171,9 +172,11 @@ public class Fixedpoint extends Z3Object } /** - * Backtrack one backtracking point. Note that an exception is - * thrown if Pop is called without a corresponding Push - * + * Backtrack one backtracking point. + * Remarks: Note that an exception is thrown if {#code pop} + * is called without a corresponding {@code push} + * + * @see push **/ public void pop() throws Z3Exception { diff --git a/src/api/java/FuncDecl.java b/src/api/java/FuncDecl.java index 573ebd102..5307951e5 100644 --- a/src/api/java/FuncDecl.java +++ b/src/api/java/FuncDecl.java @@ -29,7 +29,7 @@ public class FuncDecl extends AST /** * Comparison operator. * - * @return True if and share the + * @return True if {@code a"/> and and do not + * @return True if {@code a"/> and + * The size of the domain of the function declaration + * @see getArity **/ public int getDomainSize() throws Z3Exception { @@ -221,7 +221,7 @@ public class FuncDecl extends AST private String r; /** - * The int value of the parameter. + * The int value of the parameter. **/ public int getInt() throws Z3Exception { @@ -231,7 +231,7 @@ public class FuncDecl extends AST } /** - * The double value of the parameter. + * The double value of the parameter. **/ public double getDouble() throws Z3Exception { @@ -241,7 +241,7 @@ public class FuncDecl extends AST } /** - * The Symbol value of the parameter. + * The Symbol value of the parameter. **/ public Symbol getSymbol() throws Z3Exception { @@ -251,7 +251,7 @@ public class FuncDecl extends AST } /** - * The Sort value of the parameter. + * The Sort value of the parameter. **/ public Sort getSort() throws Z3Exception { @@ -261,7 +261,7 @@ public class FuncDecl extends AST } /** - * The AST value of the parameter. + * The AST value of the parameter. **/ public AST getAST() throws Z3Exception { @@ -271,7 +271,7 @@ public class FuncDecl extends AST } /** - * The FunctionDeclaration value of the parameter. + * The FunctionDeclaration value of the parameter. **/ public FuncDecl getFuncDecl() throws Z3Exception { @@ -281,7 +281,7 @@ public class FuncDecl extends AST } /** - * The rational string value of the parameter. + * The rational string value of the parameter. **/ public String getRational() throws Z3Exception { @@ -375,8 +375,8 @@ public class FuncDecl extends AST } /** - * Create expression that applies function to arguments. + * Create expression that applies function to arguments. + * @param args * * @return **/ diff --git a/src/api/java/FuncInterp.java b/src/api/java/FuncInterp.java index 243ade71f..fd0c10d2e 100644 --- a/src/api/java/FuncInterp.java +++ b/src/api/java/FuncInterp.java @@ -34,7 +34,8 @@ public class FuncInterp extends Z3Object * Return the (symbolic) value of this entry. * * @throws Z3Exception - **/ + * @throws Z3Exception on error + **/ public Expr getValue() throws Z3Exception { return Expr.create(getContext(), @@ -43,7 +44,8 @@ public class FuncInterp extends Z3Object /** * The number of arguments of the entry. - **/ + * @throws Z3Exception on error + **/ public int getNumArgs() throws Z3Exception { return Native.funcEntryGetNumArgs(getContext().nCtx(), getNativeObject()); @@ -53,7 +55,8 @@ public class FuncInterp extends Z3Object * The arguments of the function entry. * * @throws Z3Exception - **/ + * @throws Z3Exception on error + **/ public Expr[] getArgs() throws Z3Exception { int n = getNumArgs(); @@ -103,6 +106,8 @@ public class FuncInterp extends Z3Object /** * The number of entries in the function interpretation. + * @throws Z3Exception on error + * @return an int **/ public int getNumEntries() throws Z3Exception { @@ -113,6 +118,7 @@ public class FuncInterp extends Z3Object * The entries in the function interpretation * * @throws Z3Exception + * @throws Z3Exception on error **/ public Entry[] getEntries() throws Z3Exception { @@ -128,6 +134,8 @@ public class FuncInterp extends Z3Object * The (symbolic) `else' value of the function interpretation. * * @throws Z3Exception + * @throws Z3Exception on error + * @return an Expr **/ public Expr getElse() throws Z3Exception { @@ -137,6 +145,8 @@ public class FuncInterp extends Z3Object /** * The arity of the function interpretation + * @throws Z3Exception on error + * @return an int **/ public int getArity() throws Z3Exception { diff --git a/src/api/java/Global.java b/src/api/java/Global.java index c93f46c88..b31c4a7ae 100644 --- a/src/api/java/Global.java +++ b/src/api/java/Global.java @@ -19,16 +19,16 @@ package com.microsoft.z3; /** * Global functions for Z3. - * + * Remarks: * This (static) class contains functions that effect the behaviour of Z3 * globally across contexts, etc. - * + * **/ public final class Global { /** * Set a global (or module) parameter, which is shared by all Z3 contexts. - * + * Remarks: * When a Z3 module is initialized it will use the value of these parameters * when Z3_params objects are not provided. * The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. @@ -36,11 +36,11 @@ public final class Global * The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. * Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". * This function can be used to set parameters for a specific Z3 module. - * This can be done by using .. + * This can be done by using <module-name>.<parameter-name>. * For example: * Z3_global_param_set('pp.decimal', 'true') * will set the parameter "decimal" in the module "pp" to true. - * + * **/ public static void setParameter(String id, String value) { @@ -49,11 +49,10 @@ public final class Global /** * Get a global (or module) parameter. - * - * Returns null if the parameter parameter id does not exist. + * Remarks: * This function cannot be invoked simultaneously from different threads without synchronization. * The result string stored in param_value is stored in a shared location. - * + * @return null if the parameter {@code id} does not exist. **/ public static String getParameter(String id) { @@ -66,10 +65,9 @@ public final class Global /** * Restore the value of all global (and module) parameters. - * + * Remarks: * This command will not affect already created objects (such as tactics and solvers) - * - * + * @see setParameter **/ public static void resetParameters() { diff --git a/src/api/java/Goal.java b/src/api/java/Goal.java index aba8b0149..5a9221b63 100644 --- a/src/api/java/Goal.java +++ b/src/api/java/Goal.java @@ -26,11 +26,12 @@ import com.microsoft.z3.enumerations.Z3_goal_prec; public class Goal extends Z3Object { /** - * The precision of the goal. Goals can be transformed using over + * The precision of the goal. + * Remarks: Goals can be transformed using over * and under approximations. An under approximation is applied when the * objective is to find a model for a given goal. An over approximation is * applied when the objective is to find a proof for a given goal. - * + * **/ public Z3_goal_prec getPrecision() throws Z3Exception { @@ -72,7 +73,7 @@ public class Goal extends Z3Object } /** - * Adds the to the given goal. + * Adds the {@code constraints} to the given goal. * * @throws Z3Exception **/ @@ -95,8 +96,9 @@ public class Goal extends Z3Object } /** - * The depth of the goal. This tracks how many transformations - * were applied to it. + * The depth of the goal. + * Remarks: This tracks how many transformations + * were applied to it. **/ public int getDepth() throws Z3Exception { @@ -162,8 +164,7 @@ public class Goal extends Z3Object } /** - * Translates (copies) the Goal to the target Context . + * Translates (copies) the Goal to the target Context {@code ctx}. * * @throws Z3Exception **/ @@ -174,8 +175,9 @@ public class Goal extends Z3Object } /** - * Simplifies the goal. Essentially invokes the `simplify' tactic - * on the goal. + * Simplifies the goal. + * Remarks: Essentially invokes the `simplify' tactic + * on the goal. **/ public Goal simplify() throws Z3Exception { @@ -189,8 +191,9 @@ public class Goal extends Z3Object } /** - * Simplifies the goal. Essentially invokes the `simplify' tactic - * on the goal. + * Simplifies the goal. + * Remarks: Essentially invokes the `simplify' tactic + * on the goal. **/ public Goal simplify(Params p) throws Z3Exception { diff --git a/src/api/java/IntExpr.java b/src/api/java/IntExpr.java index 2e90c3cbf..712b950aa 100644 --- a/src/api/java/IntExpr.java +++ b/src/api/java/IntExpr.java @@ -23,7 +23,8 @@ package com.microsoft.z3; public class IntExpr extends ArithExpr { /** - * Constructor for IntExpr + * Constructor for IntExpr + * @throws Z3Exception on error **/ protected IntExpr(Context ctx) throws Z3Exception { diff --git a/src/api/java/IntSymbol.java b/src/api/java/IntSymbol.java index b0f1af685..a677c9102 100644 --- a/src/api/java/IntSymbol.java +++ b/src/api/java/IntSymbol.java @@ -25,8 +25,9 @@ import com.microsoft.z3.enumerations.Z3_symbol_kind; public class IntSymbol extends Symbol { /** - * The int value of the symbol. Throws an exception if the symbol - * is not of int kind. + * The int value of the symbol. + * Remarks: Throws an exception if the symbol + * is not of int kind. **/ public int getInt() throws Z3Exception { diff --git a/src/api/java/InterpolationContext.java b/src/api/java/InterpolationContext.java index 05d99b305..c1590e07f 100644 --- a/src/api/java/InterpolationContext.java +++ b/src/api/java/InterpolationContext.java @@ -22,11 +22,11 @@ import java.lang.String; import com.microsoft.z3.enumerations.Z3_lbool; -/** +/** * The InterpolationContext is suitable for generation of interpolants. - * - * For more information on interpolation please refer - * too the C/C++ API, which is well documented. + * + * Remarks: For more information on interpolation please refer + * too the C/C++ API, which is well documented. **/ public class InterpolationContext extends Context { @@ -42,7 +42,9 @@ public class InterpolationContext extends Context /** * Constructor. * - * + * + * Remarks: + * @see Context#Context **/ public InterpolationContext(Map settings) throws Z3Exception { @@ -56,7 +58,7 @@ public class InterpolationContext extends Context /** * Create an expression that marks a formula position for interpolation. - * @throws Z3Exception + * @throws Z3Exception **/ public BoolExpr MkInterpolant(BoolExpr a) throws Z3Exception { @@ -66,9 +68,9 @@ public class InterpolationContext extends Context /** * Computes an interpolant. - * For more information on interpolation please refer + * Remarks: For more information on interpolation please refer * too the function Z3_get_interpolant in the C/C++ API, which is - * well documented. + * well documented. * @throws Z3Exception **/ Expr[] GetInterpolant(Expr pf, Expr pat, Params p) throws Z3Exception @@ -87,9 +89,9 @@ public class InterpolationContext extends Context /** * Computes an interpolant. - * For more information on interpolation please refer + * Remarks: For more information on interpolation please refer * too the function Z3_compute_interpolant in the C/C++ API, which is - * well documented. + * well documented. * @throws Z3Exception **/ Z3_lbool ComputeInterpolant(Expr pat, Params p, ASTVector interp, Model model) throws Z3Exception @@ -105,23 +107,23 @@ public class InterpolationContext extends Context return Z3_lbool.fromInt(r); } - /// + /// /// Return a string summarizing cumulative time used for interpolation. - /// - /// For more information on interpolation please refer + /// + /// Remarks: For more information on interpolation please refer /// too the function Z3_interpolation_profile in the C/C++ API, which is - /// well documented. + /// well documented. public String InterpolationProfile() throws Z3Exception { return Native.interpolationProfile(nCtx()); } - /// + /// /// Checks the correctness of an interpolant. - /// - /// For more information on interpolation please refer + /// + /// Remarks: For more information on interpolation please refer /// too the function Z3_check_interpolant in the C/C++ API, which is - /// well documented. + /// well documented. public int CheckInterpolant(Expr[] cnsts, int[] parents, Expr[] interps, String error, Expr[] theory) throws Z3Exception { Native.StringPtr n_err_str = new Native.StringPtr(); @@ -137,12 +139,12 @@ public class InterpolationContext extends Context return r; } - /// + /// /// Reads an interpolation problem from a file. - /// - /// For more information on interpolation please refer + /// + /// Remarks: For more information on interpolation please refer /// too the function Z3_read_interpolation_problem in the C/C++ API, which is - /// well documented. + /// well documented. public int ReadInterpolationProblem(String filename, Expr[] cnsts, int[] parents, String error, Expr[] theory) throws Z3Exception { Native.IntPtr n_num = new Native.IntPtr(); @@ -168,12 +170,12 @@ public class InterpolationContext extends Context return r; } - /// + /// /// Writes an interpolation problem to a file. - /// - /// For more information on interpolation please refer + /// + /// Remarks: For more information on interpolation please refer /// too the function Z3_write_interpolation_problem in the C/C++ API, which is - /// well documented. + /// well documented. public void WriteInterpolationProblem(String filename, Expr[] cnsts, int[] parents, String error, Expr[] theory) throws Z3Exception { Native.writeInterpolationProblem(nCtx(), cnsts.length, Expr.arrayToNative(cnsts), parents, filename, theory.length, Expr.arrayToNative(theory)); diff --git a/src/api/java/Log.java b/src/api/java/Log.java index 254da1bc6..3e8f0050b 100644 --- a/src/api/java/Log.java +++ b/src/api/java/Log.java @@ -18,17 +18,18 @@ Notes: package com.microsoft.z3; /** - * Interaction logging for Z3. Note that this is a global, static log + * Interaction logging for Z3. + * Remarks: Note that this is a global, static log * and if multiple Context objects are created, it logs the interaction with all - * of them. + * of them. **/ public final class Log { private static boolean m_is_open = false; /** - * Open an interaction log file. the name of the file - * to open + * Open an interaction log file. + * @param filename the name of the file to open * * @return True if opening the log file succeeds, false otherwise. **/ @@ -48,7 +49,7 @@ public final class Log } /** - * Appends the user-provided string to the interaction + * Appends the user-provided string {@code s} to the interaction * log. * @throws Z3Exception **/ diff --git a/src/api/java/Model.java b/src/api/java/Model.java index 11eed201e..70f0e91c5 100644 --- a/src/api/java/Model.java +++ b/src/api/java/Model.java @@ -25,8 +25,9 @@ import com.microsoft.z3.enumerations.Z3_sort_kind; public class Model extends Z3Object { /** - * Retrieves the interpretation (the assignment) of in - * the model. A Constant + * Retrieves the interpretation (the assignment) of {@code a} in + * the model. + * @param a A Constant * * @return An expression if the constant has an interpretation in the model, * null otherwise. @@ -39,8 +40,9 @@ public class Model extends Z3Object } /** - * Retrieves the interpretation (the assignment) of in - * the model. A function declaration of zero arity + * Retrieves the interpretation (the assignment) of {@code f} in + * the model. + * @param f A function declaration of zero arity * * @return An expression if the function has an interpretation in the model, * null otherwise. @@ -65,9 +67,8 @@ public class Model extends Z3Object } /** - * Retrieves the interpretation (the assignment) of a non-constant in the model. A function declaration of - * non-zero arity + * Retrieves the interpretation (the assignment) of a non-constant {@code f} in the model. + * @param f A function declaration of non-zero arity * * @return A FunctionInterpretation if the function has an interpretation in * the model, null otherwise. @@ -196,16 +197,15 @@ public class Model extends Z3Object } /** - * Evaluates the expression in the current model. - * This function may fail if contains - * quantifiers, is partial (MODEL_PARTIAL enabled), or if is not well-sorted. In this case a - * ModelEvaluationFailedException is thrown. An expression When this flag + * Evaluates the expression {@code t} in the current model. + * Remarks: This function may fail if {@code t} contains + * quantifiers, is partial (MODEL_PARTIAL enabled), or if {@code t} is not well-sorted. In this case a + * {@code ModelEvaluationFailedException} is thrown. + * @param t An expression {@code completion} When this flag * is enabled, a model value will be assigned to any constant or function - * that does not have an interpretation in the model. + * that does not have an interpretation in the model. * - * @return The evaluation of in the model. + * @return The evaluation of {@code t} in the model. * @throws Z3Exception **/ public Expr eval(Expr t, boolean completion) throws Z3Exception @@ -219,7 +219,7 @@ public class Model extends Z3Object } /** - * Alias for Eval. + * Alias for {@code Eval}. * * @throws Z3Exception **/ @@ -239,10 +239,12 @@ public class Model extends Z3Object /** * The uninterpreted sorts that the model has an interpretation for. - * Z3 also provides an intepretation for uninterpreted sorts used + * Remarks: Z3 also provides an intepretation for uninterpreted sorts used * in a formula. The interpretation for a sort is a finite set of distinct - * values. We say this finite set is the "universe" of the sort. - * + * values. We say this finite set is the "universe" of the sort. + * + * @see getNumSorts + * @see getSortUniverse * * @throws Z3Exception **/ @@ -259,11 +261,11 @@ public class Model extends Z3Object /** * The finite set of distinct values that represent the interpretation for - * sort . An - * uninterpreted sort + * sort {@code s}. + * @param s An uninterpreted sort * * @return An array of expressions, where each is an element of the universe - * of + * of {@code s} * @throws Z3Exception **/ public Expr[] getSortUniverse(Sort s) throws Z3Exception diff --git a/src/api/java/Probe.java b/src/api/java/Probe.java index 17ad81b5c..335bd038c 100644 --- a/src/api/java/Probe.java +++ b/src/api/java/Probe.java @@ -21,8 +21,8 @@ package com.microsoft.z3; * Probes are used to inspect a goal (aka problem) and collect information that * may be used to decide which solver and/or preprocessing step will be used. * The complete list of probes may be obtained using the procedures - * Context.NumProbes and Context.ProbeNames. It may - * also be obtained using the command (help-tactics) in the SMT 2.0 + * {@code Context.NumProbes} and {@code Context.ProbeNames}. It may + * also be obtained using the command {@code (help-tactics)} in the SMT 2.0 * front-end. **/ public class Probe extends Z3Object diff --git a/src/api/java/RatNum.java b/src/api/java/RatNum.java index f937ea593..2e92a9429 100644 --- a/src/api/java/RatNum.java +++ b/src/api/java/RatNum.java @@ -61,8 +61,9 @@ public class RatNum extends RealExpr } /** - * Returns a string representation in decimal notation. The result - * has at most decimal places. + * Returns a string representation in decimal notation. + * Remarks: The result + * has at most {@code precision} decimal places. **/ public String toDecimalString(int precision) throws Z3Exception { diff --git a/src/api/java/RealExpr.java b/src/api/java/RealExpr.java index 6188e2999..3352639bf 100644 --- a/src/api/java/RealExpr.java +++ b/src/api/java/RealExpr.java @@ -23,7 +23,7 @@ package com.microsoft.z3; public class RealExpr extends ArithExpr { /** - * Constructor for RealExpr + * Constructor for RealExpr **/ protected RealExpr(Context ctx) { diff --git a/src/api/java/Solver.java b/src/api/java/Solver.java index e129189f9..b9c9ebca6 100644 --- a/src/api/java/Solver.java +++ b/src/api/java/Solver.java @@ -56,8 +56,9 @@ public class Solver extends Z3Object } /** - * The current number of backtracking points (scopes). - * + * The current number of backtracking points (scopes). + * @see pop + * @see push **/ public int getNumScopes() throws Z3Exception { @@ -66,7 +67,8 @@ public class Solver extends Z3Object } /** - * Creates a backtracking point. + * Creates a backtracking point. + * @see pop **/ public void push() throws Z3Exception { @@ -74,7 +76,8 @@ public class Solver extends Z3Object } /** - * Backtracks one backtracking point. . + * Backtracks one backtracking point. + * Remarks: . **/ public void pop() throws Z3Exception { @@ -82,9 +85,11 @@ public class Solver extends Z3Object } /** - * Backtracks backtracking points. Note that - * an exception is thrown if is not smaller than - * NumScopes + * Backtracks {@code n} backtracking points. + * Remarks: Note that + * an exception is thrown if {@code n} is not smaller than + * {@code NumScopes} + * @see push **/ public void pop(int n) throws Z3Exception { @@ -92,8 +97,9 @@ public class Solver extends Z3Object } /** - * Resets the Solver. This removes all assertions from the - * solver. + * Resets the Solver. + * Remarks: This removes all assertions from the + * solver. **/ public void reset() throws Z3Exception { @@ -115,12 +121,12 @@ public class Solver extends Z3Object } } - // / + // / // / Assert multiple constraints into the solver, and track them (in the // unsat) core // / using the Boolean constants in ps. - // / - // / + // / + // / Remarks: // / This API is an alternative to with assumptions for // extracting unsat cores. // / Both APIs can be used in the same solver. The unsat core will contain a @@ -128,7 +134,7 @@ public class Solver extends Z3Object // / of the Boolean variables provided using // and the Boolean literals // / provided using with assumptions. - // / + // / public void assertAndTrack(BoolExpr[] constraints, BoolExpr[] ps) throws Z3Exception { getContext().checkContextMatch(constraints); @@ -141,11 +147,11 @@ public class Solver extends Z3Object constraints[i].getNativeObject(), ps[i].getNativeObject()); } - // / + // / // / Assert a constraint into the solver, and track it (in the unsat) core // / using the Boolean constant p. - // / - // / + // / + // / Remarks: // / This API is an alternative to with assumptions for // extracting unsat cores. // / Both APIs can be used in the same solver. The unsat core will contain a @@ -153,7 +159,7 @@ public class Solver extends Z3Object // / of the Boolean variables provided using // and the Boolean literals // / provided using with assumptions. - // / + // / public void assertAndTrack(BoolExpr constraint, BoolExpr p) throws Z3Exception { getContext().checkContextMatch(constraint); @@ -193,8 +199,10 @@ public class Solver extends Z3Object /** * Checks whether the assertions in the solver are consistent or not. - * + * Remarks: + * @see getModel + * @see getUnsatCore + * @see getProof **/ public Status check(Expr... assumptions) throws Z3Exception { @@ -219,8 +227,10 @@ public class Solver extends Z3Object /** * Checks whether the assertions in the solver are consistent or not. - * + * Remarks: + * @see getModel + * @see getUnsatCore + * @see getProof **/ public Status check() throws Z3Exception { @@ -228,10 +238,11 @@ public class Solver extends Z3Object } /** - * The model of the last Check. The result is - * null if Check was not invoked before, if its - * results was not SATISFIABLE, or if model production is not - * enabled. + * The model of the last {@code Check}. + * Remarks: The result is + * {@code null} if {@code Check} was not invoked before, if its + * results was not {@code SATISFIABLE}, or if model production is not + * enabled. * * @throws Z3Exception **/ @@ -245,10 +256,11 @@ public class Solver extends Z3Object } /** - * The proof of the last Check. The result is - * null if Check was not invoked before, if its - * results was not UNSATISFIABLE, or if proof production is - * disabled. + * The proof of the last {@code Check}. + * Remarks: The result is + * {@code null} if {@code Check} was not invoked before, if its + * results was not {@code UNSATISFIABLE}, or if proof production is + * disabled. * * @throws Z3Exception **/ @@ -262,10 +274,11 @@ public class Solver extends Z3Object } /** - * The unsat core of the last Check. The unsat core - * is a subset of Assertions The result is empty if - * Check was not invoked before, if its results was not - * UNSATISFIABLE, or if core production is disabled. + * The unsat core of the last {@code Check}. + * Remarks: The unsat core + * is a subset of {@code Assertions} The result is empty if + * {@code Check} was not invoked before, if its results was not + * {@code UNSATISFIABLE}, or if core production is disabled. * * @throws Z3Exception **/ @@ -282,8 +295,8 @@ public class Solver extends Z3Object } /** - * A brief justification of why the last call to Check returned - * UNKNOWN. + * A brief justification of why the last call to {@code Check} returned + * {@code UNKNOWN}. **/ public String getReasonUnknown() throws Z3Exception { diff --git a/src/api/java/Sort.java b/src/api/java/Sort.java index 7d89428c6..e8043b193 100644 --- a/src/api/java/Sort.java +++ b/src/api/java/Sort.java @@ -28,8 +28,8 @@ public class Sort extends AST /* Overloaded operators are not translated. */ /** - * Equality operator for objects of type Sort. - * + * Equality operator for objects of type Sort. + * @param o * @return **/ public boolean equals(Object o) diff --git a/src/api/java/Statistics.java b/src/api/java/Statistics.java index 315feeaa2..88a897d15 100644 --- a/src/api/java/Statistics.java +++ b/src/api/java/Statistics.java @@ -24,7 +24,7 @@ public class Statistics extends Z3Object { /** * Statistical data is organized into pairs of [Key, Entry], where every - * Entry is either a DoubleEntry or a UIntEntry + * Entry is either a {@code DoubleEntry} or a {@code UIntEntry} **/ public class Entry { @@ -176,8 +176,9 @@ public class Statistics extends Z3Object } /** - * The value of a particular statistical counter. Returns null if - * the key is unknown. + * The value of a particular statistical counter. + * Remarks: Returns null if + * the key is unknown. * * @throws Z3Exception **/ diff --git a/src/api/java/StringSymbol.java b/src/api/java/StringSymbol.java index 09273c946..4692b0fb9 100644 --- a/src/api/java/StringSymbol.java +++ b/src/api/java/StringSymbol.java @@ -25,8 +25,9 @@ import com.microsoft.z3.enumerations.Z3_symbol_kind; public class StringSymbol extends Symbol { /** - * The string value of the symbol. Throws an exception if the - * symbol is not of string kind. + * The string value of the symbol. + * Remarks: Throws an exception if the + * symbol is not of string kind. **/ public String getString() throws Z3Exception { diff --git a/src/api/java/Tactic.java b/src/api/java/Tactic.java index 6573a1407..0286e786d 100644 --- a/src/api/java/Tactic.java +++ b/src/api/java/Tactic.java @@ -20,8 +20,8 @@ package com.microsoft.z3; /** * Tactics are the basic building block for creating custom solvers for specific * problem domains. The complete list of tactics may be obtained using - * Context.NumTactics and Context.TacticNames. It may - * also be obtained using the command (help-tactics) in the SMT 2.0 + * {@code Context.NumTactics} and {@code Context.TacticNames}. It may + * also be obtained using the command {@code (help-tactics)} in the SMT 2.0 * front-end. **/ public class Tactic extends Z3Object @@ -73,8 +73,8 @@ public class Tactic extends Z3Object } /** - * Creates a solver that is implemented using the given tactic. + * Creates a solver that is implemented using the given tactic. + * @see Context#mkSolver(Tactic) * @throws Z3Exception **/ public Solver getSolver() throws Z3Exception diff --git a/src/api/java/Version.java b/src/api/java/Version.java index 3f019390b..6e2fe5084 100644 --- a/src/api/java/Version.java +++ b/src/api/java/Version.java @@ -18,7 +18,8 @@ Notes: package com.microsoft.z3; /** - * Version information. Note that this class is static. + * Version information. + * Remarks: Note that this class is static. **/ public class Version { From 6bfc9878fb90c73cb80b7b80f725f70c9db01238 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 3 Jan 2015 15:13:57 +0000 Subject: [PATCH 117/507] FPA API cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/api/z3_fpa.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 8208fbb2c..043d43e2f 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -821,18 +821,18 @@ extern "C" { \param s FloatingPoint sort. - def_API('Z3_mk_fpa_get_ebits', UINT, (_in(CONTEXT),_in(SORT))) + def_API('Z3_fpa_get_ebits', UINT, (_in(CONTEXT),_in(SORT))) */ - unsigned Z3_API Z3_mk_fpa_get_ebits(__in Z3_context c, __in Z3_sort s); + unsigned Z3_API Z3_fpa_get_ebits(__in Z3_context c, __in Z3_sort s); /** \brief Retrieves the number of bits reserved for the significand in a FloatingPoint sort. \param s FloatingPoint sort. - def_API('Z3_mk_fpa_get_sbits', UINT, (_in(CONTEXT),_in(SORT))) + def_API('Z3_fpa_get_sbits', UINT, (_in(CONTEXT),_in(SORT))) */ - unsigned Z3_API Z3_mk_fpa_get_sbits(__in Z3_context c, __in Z3_sort s); + unsigned Z3_API Z3_fpa_get_sbits(__in Z3_context c, __in Z3_sort s); /** \brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. From 3a2db1c793289014f2a8d487b9bbbbb23ea57e56 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 3 Jan 2015 15:15:55 +0000 Subject: [PATCH 118/507] FPA API cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/FPSort.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/dotnet/FPSort.cs b/src/api/dotnet/FPSort.cs index 8d8560e53..e1ad62d49 100644 --- a/src/api/dotnet/FPSort.cs +++ b/src/api/dotnet/FPSort.cs @@ -29,12 +29,12 @@ namespace Microsoft.Z3 /// /// The number of exponent bits. /// - public uint EBits { get { return Native.Z3_mk_fpa_get_ebits(Context.nCtx, NativeObject); } } + public uint EBits { get { return Native.Z3_fpa_get_ebits(Context.nCtx, NativeObject); } } /// /// The number of significand bits. /// - public uint SBits { get { return Native.Z3_mk_fpa_get_ebits(Context.nCtx, NativeObject); } } + public uint SBits { get { return Native.Z3_fpa_get_sbits(Context.nCtx, NativeObject); } } #region Internal internal FPSort(Context ctx, IntPtr obj) From cf4dc527c420a1e5e221f47aec7757fd1b0773ff Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 3 Jan 2015 16:49:42 +0000 Subject: [PATCH 119/507] .NET FPA API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 986efc94d..f3e6220cf 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3590,7 +3590,7 @@ namespace Microsoft.Z3 public FPSort MkFPSort32() { Contract.Ensures(Contract.Result() != null); - return new FPSort(this, Native.Z3_mk_fpa_sort_16(nCtx)); + return new FPSort(this, Native.Z3_mk_fpa_sort_32(nCtx)); } /// @@ -3617,7 +3617,7 @@ namespace Microsoft.Z3 public FPSort MkFPSortQuadruple() { Contract.Ensures(Contract.Result() != null); - return new FPSort(this, Native.Z3_mk_fpa_sort_double(nCtx)); + return new FPSort(this, Native.Z3_mk_fpa_sort_quadruple(nCtx)); } /// From fa26e2423ef6f6c674b06a4b465f54baef2d96bf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 3 Jan 2015 16:50:31 +0000 Subject: [PATCH 120/507] Java API: Added FPA Signed-off-by: Christoph M. Wintersteiger --- src/api/java/AST.java | 4 +- src/api/java/ASTMap.java | 4 +- src/api/java/ASTVector.java | 4 +- src/api/java/AlgebraicNum.java | 11 +- src/api/java/Context.java | 878 +++++++++++++++++++++++-- src/api/java/Expr.java | 10 +- src/api/java/Fixedpoint.java | 4 +- src/api/java/Global.java | 4 +- src/api/java/InterpolationContext.java | 2 +- src/api/java/Model.java | 8 +- src/api/java/Solver.java | 12 +- 11 files changed, 868 insertions(+), 73 deletions(-) diff --git a/src/api/java/AST.java b/src/api/java/AST.java index a201d5697..579d4b24d 100644 --- a/src/api/java/AST.java +++ b/src/api/java/AST.java @@ -28,7 +28,7 @@ public class AST extends Z3Object /** * Object comparison. - * another AST + * @param o another AST **/ public boolean equals(Object o) { @@ -46,7 +46,7 @@ public class AST extends Z3Object } /** - * Object Comparison. Another AST + * Object Comparison. @param other Another AST * * @return Negative if the object should be sorted before , positive if after else zero. diff --git a/src/api/java/ASTMap.java b/src/api/java/ASTMap.java index 6a4e6d56f..a26140a3d 100644 --- a/src/api/java/ASTMap.java +++ b/src/api/java/ASTMap.java @@ -39,7 +39,7 @@ class ASTMap extends Z3Object /** * Finds the value associated with the key . * This function signs an error when is not a key in - * the map. An AST + * the map. @param k An AST * * @throws Z3Exception **/ @@ -51,7 +51,7 @@ class ASTMap extends Z3Object /** * Stores or replaces a new key/value pair in the map. The - * key AST The value AST + * key AST @param v The value AST **/ public void insert(AST k, AST v) throws Z3Exception { diff --git a/src/api/java/ASTVector.java b/src/api/java/ASTVector.java index 07b7dbf56..99879848f 100644 --- a/src/api/java/ASTVector.java +++ b/src/api/java/ASTVector.java @@ -33,7 +33,7 @@ class ASTVector extends Z3Object /** * Retrieves the i-th object in the vector. May throw an * IndexOutOfBoundsException when is out of - * range. Index + * range. @param i Index * * @return An AST * @throws Z3Exception @@ -62,7 +62,7 @@ class ASTVector extends Z3Object /** * Add the AST to the back of the vector. The size is - * increased by 1. An AST + * increased by 1. @param a An AST **/ public void push(AST a) throws Z3Exception { diff --git a/src/api/java/AlgebraicNum.java b/src/api/java/AlgebraicNum.java index 340f37f80..a45e5a58e 100644 --- a/src/api/java/AlgebraicNum.java +++ b/src/api/java/AlgebraicNum.java @@ -25,7 +25,7 @@ public class AlgebraicNum extends ArithExpr /** * Return a upper bound for a given real algebraic number. The interval * isolating the number is smaller than 1/10^. - * the + * @see Expr.IsAlgebraicNumber the * precision of the result * * @return A numeral Expr of sort Real @@ -33,14 +33,17 @@ public class AlgebraicNum extends ArithExpr public RatNum toUpper(int precision) throws Z3Exception { - return new RatNum(getContext(), Native.getAlgebraicNumberUpper(getContext() - .nCtx(), getNativeObject(), precision)); + return new RatNum(getContext(), + Native.getAlgebraicNumberUpper( + getContext().nCtx(), + getNativeObject(), + precision)); } /** * Return a lower bound for the given real algebraic number. The interval * isolating the number is smaller than 1/10^. - * + * @see Expr.IsAlgebraicNumber @param precision * * @return A numeral Expr of sort Real **/ diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 4fbd79be2..cd3b9bebd 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -294,9 +294,9 @@ public class Context extends IDisposable } /** - * Create a datatype constructor. + * Create a datatype constructor. @param name @param fieldNames @param sortRefs * * @return **/ @@ -363,7 +363,7 @@ public class Context extends IDisposable } /** - * Create mutually recursive data-types. * * @return @@ -429,7 +429,7 @@ public class Context extends IDisposable /** * Creates a fresh function declaration with a name prefixed with . . @see MkFuncDecl(string,Sort,Sort) **/ public FuncDecl mkFreshFuncDecl(String prefix, Sort[] domain, Sort range) @@ -464,8 +464,8 @@ public class Context extends IDisposable /** * Creates a fresh constant function declaration with a name prefixed with - * . - * + * . @see MkFuncDecl(string,Sort,Sort) + * @see MkFuncDecl(string,Sort[],Sort) **/ public FuncDecl mkFreshConstDecl(String prefix, Sort range) throws Z3Exception @@ -477,7 +477,7 @@ public class Context extends IDisposable /** * Creates a new bound variable. The de-Bruijn index of - * the variable The sort of the variable + * the variable @param ty The sort of the variable **/ public Expr mkBound(int index, Sort ty) throws Z3Exception { @@ -686,7 +686,7 @@ public class Context extends IDisposable /** * Create an expression representing an if-then-else: * ite(t1, t2, t3). An expression with Boolean - * sort An expression An + * sort @param t2 An expression An * expression with the same sort as **/ public Expr mkITE(BoolExpr t1, Expr t2, Expr t3) throws Z3Exception @@ -1654,7 +1654,7 @@ public class Context extends IDisposable * The node a must have an array sort * [domain -> range], and i must have the sort * domain. The sort of the result is range. - * + * @see MkArraySort"/> + * cref="MkArraySort"/> @see MkSelect **/ public ArrayExpr mkStore(ArrayExpr a, Expr i, Expr v) throws Z3Exception { @@ -1693,7 +1693,7 @@ public class Context extends IDisposable /** * Create a constant array. The resulting term is an array, such * that a selecton an arbitrary index produces the value - * v. + * v. @see MkArraySort"/> + * [domain_i -> range]. @see MkArraySort @see MkStore **/ public ArrayExpr mkMap(FuncDecl f, ArrayExpr... args) throws Z3Exception { @@ -1899,7 +1899,7 @@ public class Context extends IDisposable * Create a Term of a given sort. This function can be use to create * numerals that fit in a machine integer. It is slightly faster than * MakeNumeral since it is not necessary to parse a string. - * Value of the numeral Sort of the + * @param v Value of the numeral Sort of the * numeral * * @return A Term with value and type MakeNumeral since it is not necessary to parse a string. - * Value of the numeral Sort of the + * @param v Value of the numeral Sort of the * numeral * * @return A Term with value and type numerator of - * rational. denominator of rational. + * rational. @param den denominator of rational. * * @return A Term with value / - * and sort Real + * and sort Real @see MkNumeral(string, Sort) **/ public RatNum mkReal(int num, int den) throws Z3Exception { @@ -1959,7 +1959,7 @@ public class Context extends IDisposable } /** - * Create a real numeral. value of the numeral. + * Create a real numeral. @param v value of the numeral. * * @return A Term with value and sort Real **/ @@ -1971,7 +1971,7 @@ public class Context extends IDisposable } /** - * Create a real numeral. value of the numeral. + * Create a real numeral. @param v value of the numeral. * * @return A Term with value and sort Real **/ @@ -1994,7 +1994,7 @@ public class Context extends IDisposable } /** - * Create an integer numeral. value of the numeral. + * Create an integer numeral. @param v value of the numeral. * * @return A Term with value and sort Integer **/ @@ -2006,7 +2006,7 @@ public class Context extends IDisposable } /** - * Create an integer numeral. value of the numeral. + * Create an integer numeral. @param v value of the numeral. * * @return A Term with value and sort Integer **/ @@ -2030,7 +2030,7 @@ public class Context extends IDisposable /** * Create a bit-vector numeral. value of the - * numeral. the size of the bit-vector + * numeral. @param size the size of the bit-vector **/ public BitVecNum mkBV(int v, int size) throws Z3Exception { @@ -2040,7 +2040,7 @@ public class Context extends IDisposable /** * Create a bit-vector numeral. value of the - * numeral. * the size of the bit-vector + * numeral. * @param size the size of the bit-vector **/ public BitVecNum mkBV(long v, int size) throws Z3Exception { @@ -2056,7 +2056,7 @@ public class Context extends IDisposable * 'names' of the bound variables, and is the body * of the quantifier. Quantifiers are associated with weights indicating the * importance of using the quantifier during instantiation. - * the sorts of the bound variables. names of the bound variables the * body of the quantifier. quantifiers are * associated with weights indicating the importance of using the quantifier @@ -2154,8 +2154,8 @@ public class Context extends IDisposable * subexpressions only once, use the Z3_PRINT_LOW_LEVEL mode. To print in * way that conforms to SMT-LIB standards and uses let expressions to share * common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + * cref="AST.ToString()"/> @see Pattern.ToString() @see Sort.ToString() **/ public void setPrintMode(Z3_ast_print_mode value) throws Z3Exception { @@ -2165,7 +2165,7 @@ public class Context extends IDisposable /** * Convert a benchmark into an SMT-LIB formatted string. Name of the benchmark. The argument is optional. - * The benchmark logic. The status string (sat, unsat, or unknown) Other attributes, such as source, difficulty or * category. Auxiliary @@ -2809,12 +2809,11 @@ public class Context extends IDisposable if (logic == null) return new Solver(this, Native.mkSolver(nCtx())); else - return new Solver(this, Native.mkSolverForLogic(nCtx(), - logic.getNativeObject())); + return new Solver(this, Native.mkSolverForLogic(nCtx(), logic.getNativeObject())); } /** - * Creates a new (incremental) solver. + * Creates a new (incremental) solver. @see MkSolver(Symbol) **/ public Solver mkSolver(String logic) throws Z3Exception { @@ -2839,8 +2838,7 @@ public class Context extends IDisposable public Solver mkSolver(Tactic t) throws Z3Exception { - return new Solver(this, Native.mkSolverFromTactic(nCtx(), - t.getNativeObject())); + return new Solver(this, Native.mkSolverFromTactic(nCtx(), t.getNativeObject())); } /** @@ -2851,15 +2849,807 @@ public class Context extends IDisposable return new Fixedpoint(this); } + + /** Begin Floating-Point Arithmetic **/ + + /** Rounding Modes: RoundingMode Sort **/ + + /** + * Create the floating-point RoundingMode sort. + * @throws Z3Exception on error + **/ + public FPRMSort mkFPRoundingModeSort() throws Z3Exception + { + return new FPRMSort(this); + } + + /** Rounding Modes: Numerals **/ + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. + * @throws Z3Exception on error + **/ + public FPRMNum mkFPRoundNearestTiesToEven() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundNearestTiesToEven(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRNE() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRne(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundNearestTiesToAway() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundNearestTiesToAway(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRNA() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRna(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundTowardPositive() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundTowardPositive(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRTP() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRtp(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundTowardNegative() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundTowardNegative(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRTN() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRtn(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundTowardZero() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundTowardZero(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRTZ() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRtz(nCtx())); + } + + /** FloatingPoint Sorts **/ + + /** + * Create a FloatingPoint sort. + * @param ebits exponent bits in the FloatingPoint sort. + * @param sbits significand bits in the FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort(int ebits, int sbits) throws Z3Exception + { + return new FPSort(this, ebits, sbits); + } + + /** + * Create the half-precision (16-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortHalf() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortHalf(nCtx())); + } + + /** + * Create the half-precision (16-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort16() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort16(nCtx())); + } + + /** + * Create the single-precision (32-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortSingle() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortSingle(nCtx())); + } + + /** + * Create the single-precision (32-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort32() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort16(nCtx())); + } + + /** + * Create the double-precision (64-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortDouble() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortDouble(nCtx())); + } + + /** + * Create the double-precision (64-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort64() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort64(nCtx())); + } + + /** + * Create the quadruple-precision (128-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortQuadruple() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortQuadruple(nCtx())); + } + + /** + * Create the quadruple-precision (128-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort128() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort128(nCtx())); + } + + /** FloatingPoint Numerals **/ + + /** + * Create a NaN of sort s. + * @throws Z3Exception + * @param s FloatingPoint sort. + **/ + public FPNum mkFPNaN(FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNan(nCtx(), s.getNativeObject())); + } + + /** + * Create a floating-point infinity of sort s. + * @throws Z3Exception + * @param s FloatingPoint sort. + * @param negative indicates whether the result should be negative. + **/ + public FPNum mkFPInf(FPSort s, boolean negative) throws Z3Exception + { + return new FPNum(this, Native.mkFpaInf(nCtx(), s.getNativeObject(), negative)); + } + + /** + * Create a floating-point zero of sort s. + * @throws Z3Exception + * @param s FloatingPoint sort. + * @param negative indicates whether the result should be negative. + **/ + public FPNum mkFPZero(FPSort s, boolean negative) throws Z3Exception + { + return new FPNum(this, Native.mkFpaZero(nCtx(), s.getNativeObject(), negative)); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @throws Z3Exception + * @param v numeral value. + * @param s FloatingPoint sort. + **/ + public FPNum mkFPNumeral(float v, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralFloat(nCtx(), v, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @throws Z3Exception + * @param v numeral value. + * @param s FloatingPoint sort. + **/ + public FPNum mkFPNumeral(double v, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralDouble(nCtx(), v, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from an int. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(int v, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralInt(nCtx(), v, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two integers. + * @param sgn the sign. + * @param sig the significand. + * @param exp the exponent. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(boolean sgn, int sig, int exp, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralUintInt(nCtx(), sgn, sig, exp, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two long integers. + * @param sgn the sign. + * @param sig the significand. + * @param exp the exponent. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(boolean sgn, long sig, long exp, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralUint64Int64(nCtx(), sgn, sig, exp, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(float v, FPSort s) throws Z3Exception + { + return mkFPNumeral(v, s); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(double v, FPSort s) throws Z3Exception + { + return mkFPNumeral(v, s); + } + + /** + * Create a numeral of FloatingPoint sort from an int. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(int v, FPSort s) throws Z3Exception + { + return mkFPNumeral(v, s); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two integers. + * @param sgn the sign. + * @param sig the significand. + * @param exp the exponent. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(boolean sgn, int sig, int exp, FPSort s) throws Z3Exception + { + return mkFPNumeral(sgn, sig, exp, s); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. + * @param sgn the sign. + * @param sig the significand. + * @param exp the exponent. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(boolean sgn, long sig, long exp, FPSort s) throws Z3Exception + { + return mkFPNumeral(sgn, sig, exp, s); + } + + /** FloatingPoint Operators **/ + + /** + * Floating-point absolute value + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPAbs(FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaAbs(nCtx(), t.getNativeObject())); + } + + /** + * Floating-point negation + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPNeg(FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaNeg(nCtx(), t.getNativeObject())); + } + + /** + * Floating-point addition + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaAdd(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point subtraction + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaSub(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point multiplication + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaMul(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point division + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaDiv(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point fused multiply-add + * + * Remarks: The result is round((t1 * t2) + t3) + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @param t3 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaFma(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject(), t3.getNativeObject())); + } + + /** + * Floating-point square root + * @param rm rounding mode term + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPSqrt(FPRMExpr rm, FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaSqrt(nCtx(), rm.getNativeObject(), t.getNativeObject())); + } + + /** + * Floating-point remainder + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPRem(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaRem(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } /** - * Wraps an AST. This function is used for transitions between + * Floating-point roundToIntegral. Rounds a floating-point number to + * the closest integer, again represented as a floating-point number. + * @param rm term of RoundingMode sort + * @param t2 floating-point term + * @throws Z3Exception + */ + public FPExpr mkFPRoundToIntegral(FPRMExpr rm, FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaRoundToIntegral(nCtx(), rm.getNativeObject(), t.getNativeObject())); + } + + /** + * Minimum of floating-point numbers. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPMin(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaMin(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Maximum of floating-point numbers. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPMax(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaMax(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point less than or equal. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPLEq(FPExpr t1, FPExpr t2) throws Z3Exception + { + + return new BoolExpr(this, Native.mkFpaLeq(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point less than. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPLt(FPExpr t1, FPExpr t2) throws Z3Exception + { + + return new BoolExpr(this, Native.mkFpaLt(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point greater than or equal. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPGEq(FPExpr t1, FPExpr t2) throws Z3Exception + { + + return new BoolExpr(this, Native.mkFpaGeq(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point greater than. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPGt(FPExpr t1, FPExpr t2) throws Z3Exception + { + + return new BoolExpr(this, Native.mkFpaGt(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point equality. + * + * Remarks: Note that this is IEEE 754 equality (as opposed to standard =). + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPEq(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaEq(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Predicate indicating whether t is a normal floating-point number. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsNormal(FPExpr t) throws Z3Exception + { + + return new BoolExpr(this, Native.mkFpaIsNormal(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a subnormal floating-point number. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsSubnormal(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsSubnormal(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a floating-point number with zero value, i.e., +0 or -0. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsZero(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsZero(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a floating-point number representing +oo or -oo. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsInfinite(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsInfinite(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a NaN. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsNaN(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsNan(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a negative floating-point number. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsNegative(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsNegative(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a positive floating-point number. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsPositive(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsPositive(nCtx(), t.getNativeObject())); + } + + /** Conversions to FloatingPoint terms **/ + + /** + * Create an expression of FloatingPoint sort from three bit-vector expressions. + * + * Remarks: This is the operator named `fp' in the SMT FP theory definition. + * Note that sgn is required to be a bit-vector of size 1. Significand and exponent + * are required to be greater than 1 and 2 respectively. The FloatingPoint sort + * of the resulting expression is automatically determined from the bit-vector sizes + * of the arguments. + * @param sgn bit-vector term (of size 1) representing the sign. + * @param sig bit-vector term representing the significand. + * @param exp bit-vector term representing the exponent. + * @throws Z3Exception + **/ + public FPExpr mkFP(BitVecExpr sgn, BitVecExpr sig, BitVecExpr exp) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaFp(nCtx(), sgn.getNativeObject(), sig.getNativeObject(), exp.getNativeObject())); + } + + /** + * Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. + * + * Remarks: Produces a term that represents the conversion of a bit-vector term bv to a + * floating-point term of sort s. The bit-vector size of bv (m) must be equal + * to ebits+sbits of s. The format of the bit-vector is as defined by the + * IEEE 754-2008 interchange format. + * @param bv bit-vector value (of size m). + * @param s FloatingPoint sort (ebits+sbits == m) + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(BitVecExpr bv, FPSort s) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpBv(nCtx(), bv.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a FloatingPoint term into another term of different FloatingPoint sort. + * + * Remarks: Produces a term that represents the conversion of a floating-point term t to a + * floating-point term of sort s. If necessary, the result will be rounded according + * to rounding mode rm. + * @param rm RoundingMode term. + * @param t FloatingPoint term. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPRMExpr rm, FPExpr t, FPSort s) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpFloat(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a term of real sort into a term of FloatingPoint sort. + * + * Remarks: Produces a term that represents the conversion of term t of real sort into a + * floating-point term of sort s. If necessary, the result will be rounded according + * to rounding mode rm. + * @param rm RoundingMode term. + * @param t term of Real sort. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPRMExpr rm, RealExpr t, FPSort s) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpReal(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. + * + * Remarks: Produces a term that represents the conversion of the bit-vector term t into a + * floating-point term of sort s. The bit-vector t is taken to be in signed + * 2's complement format (when signed==true, otherwise unsigned). If necessary, the + * result will be rounded according to rounding mode rm. + * @param rm RoundingMode term. + * @param t term of bit-vector sort. + * @param s FloatingPoint sort. + * @param signed flag indicating whether t is interpreted as signed or unsigned bit-vector. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPRMExpr rm, BitVecExpr t, FPSort s, boolean signed) throws Z3Exception + { + if (signed) + return new FPExpr(this, Native.mkFpaToFpSigned(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + else + return new FPExpr(this, Native.mkFpaToFpUnsigned(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a floating-point number to another FloatingPoint sort s. + * + * Remarks: Produces a term that represents the conversion of a floating-point term t to a different + * FloatingPoint sort s. If necessary, rounding according to rm is applied. + * @param s FloatingPoint sort + * @param rm floating-point rounding mode term + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPSort s, FPRMExpr rm, FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpFloat(nCtx(), s.getNativeObject(), rm.getNativeObject(), t.getNativeObject())); + } + + /** Conversions from FloatingPoint terms **/ + + /** + * Conversion of a floating-point term into a bit-vector. + * + * Remarks: Produces a term that represents the conversion of the floating-poiunt term t into a + * bit-vector term of size sz in 2's complement format (signed when signed==true). If necessary, + * the result will be rounded according to rounding mode rm. + * @param rm RoundingMode term. + * @param t FloatingPoint term + * @param sz Size of the resulting bit-vector. + * @param signed Indicates whether the result is a signed or unsigned bit-vector. + * @throws Z3Exception + **/ + public BitVecExpr mkFPToBV(FPRMExpr rm, FPExpr t, int sz, boolean signed) throws Z3Exception + { + if (signed) + return new BitVecExpr(this, Native.mkFpaToSbv(nCtx(), rm.getNativeObject(), t.getNativeObject(), sz)); + else + return new BitVecExpr(this, Native.mkFpaToUbv(nCtx(), rm.getNativeObject(), t.getNativeObject(), sz)); + } + + /** + * Conversion of a floating-point term into a real-numbered term. + * + * Remarks: Produces a term that represents the conversion of the floating-poiunt term t into a + * real number. Note that this type of conversion will often result in non-linear + * constraints over real terms. + * @param t FloatingPoint term + * @throws Z3Exception + **/ + public RealExpr mkFPToReal(FPExpr t) throws Z3Exception + { + return new RealExpr(this, Native.mkFpaToReal(nCtx(), t.getNativeObject())); + } + + /** Z3-specific extensions **/ + + /** + * Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. + * + * Remarks: The size of the resulting bit-vector is automatically determined. Note that + * IEEE 754-2008 allows multiple different representations of NaN. This conversion + * knows only one NaN and it will always produce the same bit-vector represenatation of + * that NaN. + * @param t FloatingPoint term. + * @throws Z3Exception + **/ + public BitVecExpr mkFPToIEEEBV(FPExpr t) throws Z3Exception + { + return new BitVecExpr(this, Native.mkFpaToIeeeBv(nCtx(), t.getNativeObject())); + } + + /** + * Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. + * + * Remarks: Produces a term that represents the conversion of sig * 2^exp into a + * floating-point term of sort s. If necessary, the result will be rounded + * according to rounding mode rm. + * @param rm RoundingMode term. + * @param sig Significand term of Real sort. + * @param exp Exponent term of Int sort. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public BitVecExpr mkFPToFP(FPRMExpr rm, RealExpr sig, IntExpr exp, FPSort s) throws Z3Exception + { + return new BitVecExpr(this, Native.mkFpaToFpRealInt(nCtx(), rm.getNativeObject(), sig.getNativeObject(), exp.getNativeObject(), s.getNativeObject())); + } + + /** End Floating-Point Arithmetic **/ + + /** + * Wraps an AST. + * Remarks: This function is used for transitions between * native and managed objects. Note that - * must be a native object obtained from Z3 (e.g., through ) and that it must have a correct reference count (see - * e.g., . The native pointer to - * wrap. + * must be a native object obtained from Z3 (e.g., through {@code unwrapAST}) + * and that it must have a correct reference count. + * @see Native.incRef + * @see wnwrapAST + * The native pointer to wrap. **/ public AST wrapAST(long nativeObject) throws Z3Exception { @@ -2868,13 +3658,15 @@ public class Context extends IDisposable } /** - * Unwraps an AST. This function is used for transitions between + * Unwraps an AST. + * Remarks: This function is used for transitions between * native and managed objects. It returns the native pointer to the AST. * Note that AST objects are reference counted and unwrapping an AST * disables automatic reference counting, i.e., all references to the IntPtr - * that is returned must be handled externally and through native calls (see - * e.g., ). The AST to unwrap. + * that is returned must be handled externally and through native calls + * @see Native.incRef + * @see wrapAST + * @param a The AST to unwrap. **/ public long unwrapAST(AST a) { diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index a4c669dad..6a7241e98 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -40,8 +40,8 @@ public class Expr extends AST /** * Returns a simplified version of the expression * A set of - * parameters a Params object to configure the simplifier - * + * parameters @param p a Params object to configure the simplifier + * @see Context.SimplifyHelp **/ public Expr simplify(Params p) throws Z3Exception { @@ -133,7 +133,7 @@ public class Expr extends AST /** * Substitute every occurrence of from in the expression with - * to. + * to. @see Substitute(Expr[],Expr[]) **/ public Expr substitute(Expr from, Expr to) throws Z3Exception { @@ -157,7 +157,7 @@ public class Expr extends AST /** * Translates (copies) the term to the Context . - * A context + * @param ctx A context * * @return A copy of the term which is associated with @@ -1682,7 +1682,7 @@ public class Expr extends AST * Indicates whether the term is a relational clone (copy) Create * a fresh copy (clone) of a relation. The function is logically the * identity, but in the context of a register machine allows for terms of - * kind to perform destructive updates to + * kind @see IsRelationUnion to perform destructive updates to * the first argument. **/ public boolean isRelationClone() throws Z3Exception diff --git a/src/api/java/Fixedpoint.java b/src/api/java/Fixedpoint.java index 57e1e105a..37653bbd0 100644 --- a/src/api/java/Fixedpoint.java +++ b/src/api/java/Fixedpoint.java @@ -163,7 +163,7 @@ public class Fixedpoint extends Z3Object } /** - * Creates a backtracking point. + * Creates a backtracking point. @see Pop **/ public void push() throws Z3Exception { @@ -173,7 +173,7 @@ public class Fixedpoint extends Z3Object /** * Backtrack one backtracking point. Note that an exception is * thrown if Pop is called without a corresponding Push - * + * @see Push **/ public void pop() throws Z3Exception { diff --git a/src/api/java/Global.java b/src/api/java/Global.java index c93f46c88..2fa3abbbe 100644 --- a/src/api/java/Global.java +++ b/src/api/java/Global.java @@ -50,7 +50,7 @@ public final class Global /** * Get a global (or module) parameter. * - * Returns null if the parameter parameter id does not exist. + * Returns null if the parameter @param id parameter id does not exist. * This function cannot be invoked simultaneously from different threads without synchronization. * The result string stored in param_value is stored in a shared location. * @@ -69,7 +69,7 @@ public final class Global * * This command will not affect already created objects (such as tactics and solvers) * - * + * @see SetParameter **/ public static void resetParameters() { diff --git a/src/api/java/InterpolationContext.java b/src/api/java/InterpolationContext.java index 05d99b305..43ae86162 100644 --- a/src/api/java/InterpolationContext.java +++ b/src/api/java/InterpolationContext.java @@ -42,7 +42,7 @@ public class InterpolationContext extends Context /** * Constructor. * - * + * @see Context.Context(Dictionary<string, string>) **/ public InterpolationContext(Map settings) throws Z3Exception { diff --git a/src/api/java/Model.java b/src/api/java/Model.java index 11eed201e..1ebe7973b 100644 --- a/src/api/java/Model.java +++ b/src/api/java/Model.java @@ -26,7 +26,7 @@ public class Model extends Z3Object { /** * Retrieves the interpretation (the assignment) of in - * the model. A Constant + * the model. @param a A Constant * * @return An expression if the constant has an interpretation in the model, * null otherwise. @@ -40,7 +40,7 @@ public class Model extends Z3Object /** * Retrieves the interpretation (the assignment) of in - * the model. A function declaration of zero arity + * the model. @param f A function declaration of zero arity * * @return An expression if the function has an interpretation in the model, * null otherwise. @@ -242,7 +242,7 @@ public class Model extends Z3Object * Z3 also provides an intepretation for uninterpreted sorts used * in a formula. The interpretation for a sort is a finite set of distinct * values. We say this finite set is the "universe" of the sort. - * + * @see NumSorts"/> . An + * sort . @see Sorts An * uninterpreted sort * * @return An array of expressions, where each is an element of the universe diff --git a/src/api/java/Solver.java b/src/api/java/Solver.java index e129189f9..4a7c1ed09 100644 --- a/src/api/java/Solver.java +++ b/src/api/java/Solver.java @@ -56,8 +56,8 @@ public class Solver extends Z3Object } /** - * The current number of backtracking points (scopes). - * + * The current number of backtracking points (scopes). @see Pop + * @see Push **/ public int getNumScopes() throws Z3Exception { @@ -66,7 +66,7 @@ public class Solver extends Z3Object } /** - * Creates a backtracking point. + * Creates a backtracking point. @see Pop **/ public void push() throws Z3Exception { @@ -84,7 +84,7 @@ public class Solver extends Z3Object /** * Backtracks backtracking points. Note that * an exception is thrown if is not smaller than - * NumScopes + * NumScopes @see Push **/ public void pop(int n) throws Z3Exception { @@ -193,7 +193,7 @@ public class Solver extends Z3Object /** * Checks whether the assertions in the solver are consistent or not. - * @see Model"/> **/ public Status check(Expr... assumptions) throws Z3Exception @@ -219,7 +219,7 @@ public class Solver extends Z3Object /** * Checks whether the assertions in the solver are consistent or not. - * @see Model"/> **/ public Status check() throws Z3Exception From 0faf329054fc64410f5d832ca4473678bf946604 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 3 Jan 2015 17:26:58 +0000 Subject: [PATCH 121/507] FPA API: bugfixes and examples for .NET and Java Signed-off-by: Christoph M. Wintersteiger --- examples/dotnet/Program.cs | 101 +++++++++++++++++++++------------ examples/java/JavaExample.java | 84 ++++++++++++++++++++++++++- src/api/api_fpa.cpp | 18 +++--- src/api/dotnet/Context.cs | 2 +- src/api/java/Expr.java | 8 +++ 5 files changed, 165 insertions(+), 48 deletions(-) diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index 3d2910c8f..b03cfd28c 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -2028,53 +2028,81 @@ namespace test_mapi // Console.WriteLine("{0}", ctx.MkEq(s1, t1)); } - public static void FloatingPointExample(Context ctx) + public static void FloatingPointExample1(Context ctx) { - Console.WriteLine("FloatingPointExample"); + Console.WriteLine("FloatingPointExample1"); FPSort s = ctx.MkFPSort(11, 53); Console.WriteLine("Sort: {0}", s); - FPNum x = (FPNum)ctx.MkNumeral("-1e1", s); - Console.WriteLine("Numeral: {0}", x.ToString()); - - FPNum y = (FPNum)ctx.MkNumeral("-10", s); - Console.WriteLine("Numeral: {0}", y.ToString()); - - FPNum z = (FPNum)ctx.MkNumeral("-1.25p3", s); - Console.WriteLine("Numeral: {0}", z.ToString()); + FPNum x = (FPNum)ctx.MkNumeral("-1e1", s); /* -1 * 10^1 = -10 */ + FPNum y = (FPNum)ctx.MkNumeral("-10", s); /* -10 */ + FPNum z = (FPNum)ctx.MkNumeral("-1.25p3", s); /* -1.25 * 2^3 = -1.25 * 8 = -10 */ + Console.WriteLine("x={0}; y={1}; z={2}", x.ToString(), y.ToString(), z.ToString()); BoolExpr a = ctx.MkAnd(ctx.MkFPEq(x, y), ctx.MkFPEq(y, z)); - Check(ctx, ctx.MkNot(a), Status.UNSATISFIABLE); - x = ctx.MkFPNaN(s); - FPExpr c = (FPExpr)ctx.MkConst("y", s); + /* nothing is equal to NaN according to floating-point + * equality, so NaN == k should be unsatisfiable. */ + FPExpr k = (FPExpr)ctx.MkConst("x", s); + FPExpr nan = ctx.MkFPNaN(s); - // Note: We need to use a special solver for QF_FPA here; the - // general solver does not support FPA yet. - - Solver slvr = ctx.MkSolver("QF_FPA"); - slvr.Add(ctx.MkFPEq(x, c)); - if (slvr.Check() != Status.UNSATISFIABLE) // nothing is equal to NaN according to floating-point equality. - throw new TestFailedException(); - - slvr = ctx.MkSolver("QF_FPA"); - slvr.Add(ctx.MkEq(x, c)); // NaN is equal to NaN according to normal equality. - if (slvr.Check() != Status.SATISFIABLE) - throw new TestFailedException(); - - - x = (FPNum)ctx.MkNumeral("-1e1", s); - y = (FPNum)ctx.MkNumeral("-10", s); - FPExpr q = (FPExpr)ctx.MkConst("q", s); - FPNum mh = (FPNum)ctx.MkNumeral("100", s); - slvr = ctx.MkSolver("QF_FPA"); - // Let's prove -1e1 * -10 == +100 - slvr.Add(ctx.MkEq(ctx.MkFPMul(ctx.MkFPRMNearestTiesToAway(), x, y), q)); - slvr.Add(ctx.MkNot(ctx.MkFPEq(q, mh))); + /* solver that runs the default tactic for QF_FP. */ + Solver slvr = ctx.MkSolver("QF_FP"); + slvr.Add(ctx.MkFPEq(nan, k)); if (slvr.Check() != Status.UNSATISFIABLE) throw new TestFailedException(); + Console.WriteLine("OK, unsat:" + Environment.NewLine + slvr); + + /* NaN is equal to NaN according to normal equality. */ + slvr = ctx.MkSolver("QF_FP"); + slvr.Add(ctx.MkEq(nan, nan)); + if (slvr.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + Console.WriteLine("OK, sat:" + Environment.NewLine + slvr); + + /* Let's prove -1e1 * -1.25e3 == +100 */ + x = (FPNum)ctx.MkNumeral("-1e1", s); + y = (FPNum)ctx.MkNumeral("-1.25p3", s); + FPExpr x_plus_y = (FPExpr)ctx.MkConst("x_plus_y", s); + FPNum r = (FPNum)ctx.MkNumeral("100", s); + slvr = ctx.MkSolver("QF_FP"); + + slvr.Add(ctx.MkEq(x_plus_y, ctx.MkFPMul(ctx.MkFPRoundNearestTiesToAway(), x, y))); + slvr.Add(ctx.MkNot(ctx.MkFPEq(x_plus_y, r))); + if (slvr.Check() != Status.UNSATISFIABLE) + throw new TestFailedException(); + Console.WriteLine("OK, unsat:" + Environment.NewLine + slvr); + } + + public static void FloatingPointExample2(Context ctx) + { + Console.WriteLine("FloatingPointExample2"); + FPSort double_sort = ctx.MkFPSort(11, 53); + FPRMSort rm_sort = ctx.MkFPRoundingModeSort(); + + FPRMExpr rm = (FPRMExpr)ctx.MkConst(ctx.MkSymbol("rm"), rm_sort); + BitVecExpr x = (BitVecExpr)ctx.MkConst(ctx.MkSymbol("x"), ctx.MkBitVecSort(64)); + FPExpr y = (FPExpr)ctx.MkConst(ctx.MkSymbol("y"), double_sort); + RealExpr real_val = ctx.MkReal(42); + BitVecExpr bv_val = ctx.MkBV(42, 64); + FPExpr fp_val = ctx.MkFP(42, double_sort); + + BoolExpr c1 = ctx.MkEq(x, ctx.MkFPToIEEEBV(fp_val)); + BoolExpr c2 = ctx.MkEq(x, ctx.MkBV(42, 64)); + BoolExpr c3 = ctx.MkEq(fp_val, ctx.MkFPToFP(rm, real_val, double_sort)); + BoolExpr c4 = ctx.MkAnd(c1, c2); + Console.WriteLine("c3 = " + c3); + + /* Generic solver */ + Solver s = ctx.MkSolver(); + s.Assert(c3); + + if (s.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + + Console.WriteLine("OK, model: ", s.Model.ToString()); } static void Main(string[] args) @@ -2118,7 +2146,8 @@ namespace test_mapi FindSmallModelExample(ctx); SimplifierExample(ctx); FiniteDomainExample(ctx); - FloatingPointExample(ctx); + FloatingPointExample1(ctx); + FloatingPointExample2(ctx); } // These examples need proof generation turned on. diff --git a/examples/java/JavaExample.java b/examples/java/JavaExample.java index 48395d8c2..878ec4693 100644 --- a/examples/java/JavaExample.java +++ b/examples/java/JavaExample.java @@ -1095,7 +1095,7 @@ class JavaExample // / Shows how to use Solver(logic) - // / + // / @param ctx void logicExample(Context ctx) throws Z3Exception, TestFailedException { System.out.println("LogicTest"); @@ -2157,6 +2157,86 @@ class JavaExample // System.out.println(ctx.mkEq(s1, t1)); } + public void floatingPointExample1(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("FloatingPointExample1"); + Log.append("FloatingPointExample1"); + + FPSort s = ctx.mkFPSort(11, 53); + System.out.println("Sort: " + s); + + FPNum x = (FPNum)ctx.mkNumeral("-1e1", s); /* -1 * 10^1 = -10 */ + FPNum y = (FPNum)ctx.mkNumeral("-10", s); /* -10 */ + FPNum z = (FPNum)ctx.mkNumeral("-1.25p3", s); /* -1.25 * 2^3 = -1.25 * 8 = -10 */ + System.out.println("x=" + x.toString() + + "; y=" + y.toString() + + "; z=" + z.toString()); + + BoolExpr a = ctx.mkAnd(ctx.mkFPEq(x, y), ctx.mkFPEq(y, z)); + check(ctx, ctx.mkNot(a), Status.UNSATISFIABLE); + + /* nothing is equal to NaN according to floating-point + * equality, so NaN == k should be unsatisfiable. */ + FPExpr k = (FPExpr)ctx.mkConst("x", s); + FPExpr nan = ctx.mkFPNaN(s); + + /* solver that runs the default tactic for QF_FP. */ + Solver slvr = ctx.mkSolver("QF_FP"); + slvr.add(ctx.mkFPEq(nan, k)); + if (slvr.check() != Status.UNSATISFIABLE) + throw new TestFailedException(); + System.out.println("OK, unsat:" + System.getProperty("line.separator") + slvr); + + /* NaN is equal to NaN according to normal equality. */ + slvr = ctx.mkSolver("QF_FP"); + slvr.add(ctx.mkEq(nan, nan)); + if (slvr.check() != Status.SATISFIABLE) + throw new TestFailedException(); + System.out.println("OK, sat:" + System.getProperty("line.separator") + slvr); + + /* Let's prove -1e1 * -1.25e3 == +100 */ + x = (FPNum)ctx.mkNumeral("-1e1", s); + y = (FPNum)ctx.mkNumeral("-1.25p3", s); + FPExpr x_plus_y = (FPExpr)ctx.mkConst("x_plus_y", s); + FPNum r = (FPNum)ctx.mkNumeral("100", s); + slvr = ctx.mkSolver("QF_FP"); + + slvr.add(ctx.mkEq(x_plus_y, ctx.mkFPMul(ctx.mkFPRoundNearestTiesToAway(), x, y))); + slvr.add(ctx.mkNot(ctx.mkFPEq(x_plus_y, r))); + if (slvr.check() != Status.UNSATISFIABLE) + throw new TestFailedException(); + System.out.println("OK, unsat:" + System.getProperty("line.separator") + slvr); + } + + public void floatingPointExample2(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("FloatingPointExample2"); + Log.append("FloatingPointExample2"); + + FPSort double_sort = ctx.mkFPSort(11, 53); + FPRMSort rm_sort = ctx.mkFPRoundingModeSort(); + + FPRMExpr rm = (FPRMExpr)ctx.mkConst(ctx.mkSymbol("rm"), rm_sort); + BitVecExpr x = (BitVecExpr)ctx.mkConst(ctx.mkSymbol("x"), ctx.mkBitVecSort(64)); + RealExpr real_val = ctx.mkReal(42); + FPExpr fp_val = ctx.mkFP(42, double_sort); + + BoolExpr c1 = ctx.mkEq(x, ctx.mkFPToIEEEBV(fp_val)); + BoolExpr c2 = ctx.mkEq(x, ctx.mkBV(42, 64)); + BoolExpr c3 = ctx.mkEq(fp_val, ctx.mkFPToFP(rm, real_val, double_sort)); + BoolExpr c4 = ctx.mkAnd(c1, c2); + System.out.println("c3 = " + c3); + + /* Generic solver */ + Solver s = ctx.mkSolver(); + s.add(c3); + + if (s.check() != Status.SATISFIABLE) + throw new TestFailedException(); + + System.out.println("OK, model: " + s.getModel().toString()); + } + public static void main(String[] args) { JavaExample p = new JavaExample(); @@ -2200,6 +2280,8 @@ class JavaExample p.findSmallModelExample(ctx); p.simplifierExample(ctx); p.finiteDomainExample(ctx); + p.floatingPointExample1(ctx); + p.floatingPointExample2(ctx); } { // These examples need proof generation turned on. diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index d2d4e7155..87568af09 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -649,23 +649,21 @@ extern "C" { Z3_CATCH_RETURN(0); } - unsigned int Z3_API Z3_mk_fpa_get_ebits(Z3_context c, Z3_sort s) { + unsigned Z3_API Z3_fpa_get_ebits(Z3_context c, Z3_sort s) { Z3_TRY; - LOG_Z3_mk_fpa_get_ebits(c, s); + LOG_Z3_fpa_get_ebits(c, s); RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); - unsigned r = ctx->float_util().get_ebits(to_sort(s)); - RETURN_Z3(r); + CHECK_NON_NULL(s, 0); + return mk_c(c)->float_util().get_ebits(to_sort(s)); Z3_CATCH_RETURN(0); } - unsigned Z3_API Z3_mk_fpa_get_sbits(Z3_context c, Z3_sort s) { + unsigned Z3_API Z3_fpa_get_sbits(Z3_context c, Z3_sort s) { Z3_TRY; - LOG_Z3_mk_fpa_get_sbits(c, s); + LOG_Z3_fpa_get_ebits(c, s); RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); - unsigned r = ctx->float_util().get_sbits(to_sort(s)); - RETURN_Z3(r); + CHECK_NON_NULL(s, 0); + return mk_c(c)->float_util().get_sbits(to_sort(s)); Z3_CATCH_RETURN(0); } diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index f3e6220cf..609db802d 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3895,7 +3895,7 @@ namespace Microsoft.Z3 /// the closest integer, again represented as a floating-point number. /// /// term of RoundingMode sort - /// floating-point term + /// floating-point term public FPExpr MkFPRoundToIntegral(FPRMExpr rm, FPExpr t) { Contract.Ensures(Contract.Result() != null); diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 6a7241e98..233076516 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -1791,6 +1791,10 @@ public class Expr extends AST return new RatNum(ctx, obj); case Z3_BV_SORT: return new BitVecNum(ctx, obj); + case Z3_FLOATING_POINT_SORT: + return new FPNum(ctx, obj); + case Z3_FLOATING_POINT_ROUNDING_MODE_SORT: + return new FPRMNum(ctx, obj); default: ; } } @@ -1809,6 +1813,10 @@ public class Expr extends AST return new ArrayExpr(ctx, obj); case Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); + case Z3_FLOATING_POINT_SORT: + return new FPExpr(ctx, obj); + case Z3_FLOATING_POINT_ROUNDING_MODE_SORT: + return new FPRMExpr(ctx, obj); default: ; } From 007ecb4ab29aa02b15569299db924ee4d8dca5c1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 4 Jan 2015 14:37:33 +0000 Subject: [PATCH 122/507] MPF bugfix Signed-off-by: Christoph M. Wintersteiger --- src/util/mpf.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index f5dcfc612..511bdb03c 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -196,13 +196,17 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode else { o.ebits = ebits; o.sbits = sbits; - o.sign = m_mpq_manager.is_neg(value); - + o.sign = m_mpq_manager.is_neg(value); + + scoped_mpq x(m_mpq_manager); + m_mpq_manager.set(x, value); + m_mpq_manager.abs(x); + m_mpz_manager.set(o.significand, 0); const mpz & p = m_powers2(sbits+3); scoped_mpq v(m_mpq_manager); - m_mpq_manager.set(v, value); + m_mpq_manager.set(v, x); o.exponent = 0; // Normalize From cf81f86c6741e09ed93abdf14ee7fe63fcbe0827 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 4 Jan 2015 18:52:23 +0000 Subject: [PATCH 123/507] build fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/z3_replayer.cpp | 7 +++++++ src/ast/fpa/fpa2bv_converter.cpp | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api/z3_replayer.cpp b/src/api/z3_replayer.cpp index 676ba0c69..cfd022124 100644 --- a/src/api/z3_replayer.cpp +++ b/src/api/z3_replayer.cpp @@ -225,6 +225,13 @@ struct z3_replayer::imp { return curr() == '-' || curr() == '.' || ('0' <= curr() && curr() <= '9') || curr() == 'e' || curr() == 'E'; } +#if (!defined(strtof)) + float strtof(const char * str, char ** end_ptr) { + // Note: This may introduce a double-rounding problem. + return (float)strtod(str, end_ptr); + } +#endif + void read_float() { m_string.reset(); while (is_double_char()) { diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index d51e34058..d6d1420e3 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -146,7 +146,6 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { app_ref bv(m); unsigned bv_sz = 1 + ebits + (sbits - 1); bv = mk_fresh_const(0, bv_sz); - m_fresh_bv_variables.insert(bv); sgn = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv); e = m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv); From 6d8587dff9ab55d4190607c118b1242303e72ef0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 4 Jan 2015 18:53:21 +0000 Subject: [PATCH 124/507] FPA fixes for internal func_decls Signed-off-by: Christoph M. Wintersteiger --- src/ast/float_decl_plugin.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index b019c7359..bdc0c6fb1 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -581,20 +581,21 @@ func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, p SASSERT(m_bv_plugin); if (arity != 2) m_manager->raise_exception("invalid number of arguments to fp.to_sbv"); - if (parameters[0].is_int()) - m_manager->raise_exception("invalid parameter type; fp.to_sbv expects an int parameter"); if (num_parameters != 1) m_manager->raise_exception("invalid number of parameters to fp.to_sbv"); - if (is_rm_sort(domain[0])) + if (!parameters[0].is_int()) + m_manager->raise_exception("invalid parameter type; fp.to_sbv expects an int parameter"); + if (!is_rm_sort(domain[0])) m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); if (parameters[0].get_int() <= 0) - m_manager->raise_exception("invalid parameter value; fp.to_ubv expects a parameter larger than 0"); + m_manager->raise_exception("invalid parameter value; fp.to_sbv expects a parameter larger than 0"); symbol name("fp.to_sbv"); sort * bvs = m_bv_plugin->mk_sort(BV_SORT, 1, parameters); return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k, num_parameters, parameters)); + } func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -674,11 +675,10 @@ func_decl * float_decl_plugin::mk_internal_to_sbv_unspecified( unsigned arity, sort * const * domain, sort * range) { if (arity != 0) m_manager->raise_exception("invalid number of arguments to internal_to_sbv_unspecified"); - if (!is_sort_of(domain[0], m_bv_fid, BV_SORT)) - m_manager->raise_exception("sort mismatch, expected argument of bitvector sort"); - if (!is_sort_of(range, m_bv_fid, BV_SORT)) - m_manager->raise_exception("sort mismatch, expected range of FloatingPoint sort"); - + if (num_parameters != 1) + m_manager->raise_exception("invalid number of parameters to fp.to_sbv_unspecified; expecting 1"); + if (!parameters[0].is_int()) + m_manager->raise_exception("invalid parameters type provided to fp.to_sbv_unspecified; expecting an integer"); sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, parameters); return m_manager->mk_func_decl(symbol("fp.to_sbv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } From 5ff923f5043a275d1ca36231f240fe3c17d11603 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 4 Jan 2015 19:01:02 +0000 Subject: [PATCH 125/507] Added fp.to_sbv Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 238 +++++++++++++++++++++++-------- 1 file changed, 178 insertions(+), 60 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index d6d1420e3..24e606cdc 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -1851,7 +1851,42 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args TRACE("fpa2bv_to_fp", for (unsigned i=0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl; ); - if (num == 3 && + if (num == 1 && + m_bv_util.is_bv(args[0])) { + sort * s = f->get_range(); + unsigned to_sbits = m_util.get_sbits(s); + unsigned to_ebits = m_util.get_ebits(s); + + expr * bv = args[0]; + int sz = m_bv_util.get_bv_size(bv); + SASSERT((unsigned)sz == to_sbits + to_ebits); + + mk_triple(m_bv_util.mk_extract(sz - 1, sz - 1, bv), + m_bv_util.mk_extract(sz - to_ebits - 2, 0, bv), + m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), + result); + } + else if (num == 2 && + m_bv_util.is_bv(args[0]) && + m_bv_util.get_bv_size(args[0]) == 3 && + m_util.is_float(m.get_sort(args[1]))) { + // float -> float conversion + mk_to_fp_float(f, f->get_range(), args[0], args[1], result); + } + else if (num == 2 && + m_bv_util.is_bv(args[0]) && + m_bv_util.get_bv_size(args[0]) == 3 && + m_arith_util.is_real(args[1])) { + // rm + real -> float + mk_to_fp_real(f, f->get_range(), args[0], args[1], result); + } + else if (num == 2 && + m_bv_util.is_bv(args[0]) && + m_bv_util.get_bv_size(args[0]) == 3 && + m_bv_util.is_bv(args[1])) { + mk_to_fp_signed(f, num, args, result); + } + else if (num == 3 && m_bv_util.is_bv(args[0]) && m_bv_util.is_bv(args[1]) && m_bv_util.is_bv(args[2])) { @@ -1860,13 +1895,6 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); mk_triple(args[0], args[2], args[1], result); } - else if (num == 2 && - m_bv_util.is_bv(args[0]) && - m_bv_util.get_bv_size(args[0]) == 3 && - m_bv_util.is_bv(args[1])) - { - mk_to_fp_signed(f, num, args, result); - } else if (num == 3 && m_bv_util.is_bv(args[0]) && m_arith_util.is_numeral(args[1]) && @@ -1921,34 +1949,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args mk_ite(c2, bv_tp, result, result); mk_ite(c3, bv_nta, result, result); mk_ite(c4, bv_nte, result, result); - } - else if (num == 1 && m_bv_util.is_bv(args[0])) { - sort * s = f->get_range(); - unsigned to_sbits = m_util.get_sbits(s); - unsigned to_ebits = m_util.get_ebits(s); - - expr * bv = args[0]; - int sz = m_bv_util.get_bv_size(bv); - SASSERT((unsigned)sz == to_sbits + to_ebits); - - mk_triple(m_bv_util.mk_extract(sz - 1, sz - 1, bv), - m_bv_util.mk_extract(sz - to_ebits - 2, 0, bv), - m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), - result); - } - else if (num == 2 && - m_util.is_rm(args[0]) && - is_app(args[1]) && - m_util.is_float(m.get_sort(args[1]))) { - // float -> float conversion - mk_to_fp_float(f, f->get_range(), args[0], args[1], result); } - else if (num == 2 && - m_util.is_rm(args[0]), - m_arith_util.is_real(args[1])) { - // rm + real -> float - mk_to_fp_real(f, f->get_range(), args[0], args[1], result); - } else UNREACHABLE(); @@ -2452,8 +2453,6 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg sort * xs = m.get_sort(x); sort * bv_srt = f->get_range(); - dbg_decouple("fpa2bv_to_ubv_x", expr_ref(x, m)); - unsigned ebits = m_util.get_ebits(xs); unsigned sbits = m_util.get_sbits(xs); unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); @@ -2470,7 +2469,7 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg mk_is_neg(x, x_is_neg); mk_is_nzero(x, x_is_nzero); - // NaN, Inf, or negative (except -0) -> undefined + // NaN, Inf, or negative (except -0) -> unspecified expr_ref c1(m), v1(m); c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); v1 = mk_to_ubv_unspecified(bv_sz); @@ -2513,7 +2512,7 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg dbg_decouple("fpa2bv_to_ubv_shift", shift); dbg_decouple("fpa2bv_to_ubv_shift_abs", shift_abs); - // sig is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long + // x is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long // [1][ ... sig ... ][r][g][ ... s ...] // [ ... ubv ... ][r][g][ ... s ... ] expr_ref max_shift(m); @@ -2546,18 +2545,17 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg dbg_decouple("fpa2bv_to_ubv_rounding_decision", rounding_decision); expr_ref unrounded_sig(m), pre_rounded(m), inc(m); - unrounded_sig = m_bv_util.mk_zero_extend(1, - m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz, shifted_sig)); - inc = m_bv_util.mk_zero_extend(1, - m_bv_util.mk_zero_extend(bv_sz - 1, rounding_decision)); + unrounded_sig = m_bv_util.mk_zero_extend(1, m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz, shifted_sig)); + inc = m_bv_util.mk_zero_extend(1, m_bv_util.mk_zero_extend(bv_sz - 1, rounding_decision)); pre_rounded = m_bv_util.mk_bv_add(unrounded_sig, inc); - expr_ref rnd_overflow(m), rounded(m), rnd_has_overflown(m); + expr_ref rnd_overflow(m), rnd(m), rnd_has_overflown(m); rnd_overflow = m_bv_util.mk_extract(bv_sz, bv_sz, pre_rounded); - rounded = m_bv_util.mk_extract(bv_sz - 1, 0, pre_rounded); + rnd = m_bv_util.mk_extract(bv_sz - 1, 0, pre_rounded); rnd_has_overflown = m.mk_eq(rnd_overflow, bv1); + dbg_decouple("fpa2bv_to_ubv_rnd_has_overflown", rnd_has_overflown); - result = m.mk_ite(rnd_has_overflown, mk_to_ubv_unspecified(bv_sz), rounded); + result = m.mk_ite(rnd_has_overflown, mk_to_ubv_unspecified(bv_sz), rnd); result = m.mk_ite(c_in_limits, result, mk_to_ubv_unspecified(bv_sz)); result = m.mk_ite(c2, v2, result); result = m.mk_ite(c1, v1, result); @@ -2568,24 +2566,138 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_sbv", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); - + SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_int()); SASSERT(num == 2); SASSERT(m_bv_util.get_bv_size(args[0]) == 3); SASSERT(m_util.is_float(args[1])); - //unsigned ebits = m_util.get_ebits(f->get_range()); - //unsigned sbits = m_util.get_sbits(f->get_range()); - //int width = f->get_parameter(0).get_int(); + expr * rm = args[0]; + expr * x = args[1]; + sort * xs = m.get_sort(x); + sort * bv_srt = f->get_range(); - //expr * rm = args[0]; - //expr * x = args[1]; + unsigned ebits = m_util.get_ebits(xs); + unsigned sbits = m_util.get_sbits(xs); + unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); + unsigned rounding_sz = bv_sz + 3; - //expr * sgn, *s, *e; - //split_triple(x, sgn, s, e); + expr_ref bv0(m), bv1(m), bv0_2(m), bv1_2(m), bv3_2(m); + bv0 = m_bv_util.mk_numeral(0, 1); + bv1 = m_bv_util.mk_numeral(1, 1); + bv0_2 = m_bv_util.mk_numeral(0, 2); + bv1_2 = m_bv_util.mk_numeral(1, 2); + bv3_2 = m_bv_util.mk_numeral(3, 2); - NOT_IMPLEMENTED_YET(); + expr_ref x_is_nan(m), x_is_inf(m), x_is_zero(m), x_is_neg(m), x_is_nzero(m); + mk_is_nan(x, x_is_nan); + mk_is_inf(x, x_is_inf); + mk_is_zero(x, x_is_zero); + mk_is_neg(x, x_is_neg); + mk_is_nzero(x, x_is_nzero); + + // NaN, Inf -> unspecified + expr_ref c1(m), v1(m); + c1 = m.mk_or(x_is_nan, x_is_inf); + v1 = mk_to_sbv_unspecified(bv_sz); + dbg_decouple("fpa2bv_to_sbv_c1", c1); + + // +-Zero -> 0 + expr_ref c2(m), v2(m); + c2 = x_is_zero; + v2 = m_bv_util.mk_numeral(rational(0), bv_srt); + dbg_decouple("fpa2bv_to_sbv_c2", c2); + + // Otherwise... + expr_ref sgn(m), sig(m), exp(m), lz(m); + unpack(x, sgn, sig, exp, lz, true); + + // x is of the form +- [1].[sig] * 2^(exp-lz) + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(sig) == sbits); + SASSERT(m_bv_util.get_bv_size(exp) == ebits); + SASSERT(m_bv_util.get_bv_size(lz) == ebits); + dbg_decouple("fpa2bv_to_sbv_sig", sig); + unsigned sig_sz = m_bv_util.get_bv_size(sig); + SASSERT(sig_sz == sbits); + if (sig_sz < (bv_sz + 3)) + sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, bv_sz - sig_sz + 3)); + sig_sz = m_bv_util.get_bv_size(sig); + SASSERT(sig_sz >= (bv_sz + 3)); + + expr_ref exp_m_lz(m), shift(m), shift_neg(m), bv0_e2(m), shift_abs(m); + exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp), + m_bv_util.mk_zero_extend(2, lz)); + shift = m_bv_util.mk_bv_sub(exp_m_lz, + m_bv_util.mk_numeral(bv_sz - 1, ebits + 2)); + shift_neg = m_bv_util.mk_bv_neg(shift); + bv0_e2 = m_bv_util.mk_numeral(0, ebits + 2); + shift_abs = m.mk_ite(m_bv_util.mk_sle(shift, bv0_e2), shift_neg, shift); + SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2); + SASSERT(m_bv_util.get_bv_size(shift_neg) == ebits + 2); + SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2); + dbg_decouple("fpa2bv_to_ubv_shift", shift); + dbg_decouple("fpa2bv_to_ubv_shift_abs", shift_abs); + + // sig is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long + // [1][ ... sig ... ][r][g][ ... s ...] + // [ ... ubv ... ][r][g][ ... s ... ] + expr_ref max_shift(m); + max_shift = m_bv_util.mk_numeral(sig_sz, sig_sz); + shift_abs = m_bv_util.mk_zero_extend(sig_sz - ebits - 2, shift_abs); + SASSERT(m_bv_util.get_bv_size(shift_abs) == sig_sz); + + expr_ref c_in_limits(m); + c_in_limits = m_bv_util.mk_sle(shift, m_bv_util.mk_numeral(0, ebits + 2)); + dbg_decouple("fpa2bv_to_sbv_in_limits", c_in_limits); + + expr_ref shifted_sig(m); + shifted_sig = m_bv_util.mk_bv_lshr(sig, shift_abs); + dbg_decouple("fpa2bv_to_sbv_shifted_sig", shifted_sig); + + expr_ref last(m), round(m), sticky(m); + last = m_bv_util.mk_extract(sig_sz - bv_sz - 0, sig_sz - bv_sz - 0, shifted_sig); + round = m_bv_util.mk_extract(sig_sz - bv_sz - 1, sig_sz - bv_sz - 1, shifted_sig); + sticky = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(sig_sz - bv_sz - 2, 0, shifted_sig), + m_bv_util.mk_numeral(0, sig_sz - (bv_sz + 3) + 2)), + bv0, + bv1); + dbg_decouple("fpa2bv_to_sbv_last", last); + dbg_decouple("fpa2bv_to_sbv_round", round); + dbg_decouple("fpa2bv_to_sbv_sticky", sticky); + + expr_ref rounding_decision(m); + rounding_decision = mk_rounding_decision(rm, sgn, last, round, sticky); + SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1); + dbg_decouple("fpa2bv_to_sbv_rounding_decision", rounding_decision); + + expr_ref unrounded_sig(m), pre_rounded(m), inc(m); + unrounded_sig = m_bv_util.mk_zero_extend(1, m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz, shifted_sig)); + inc = m_bv_util.mk_zero_extend(1, m_bv_util.mk_zero_extend(bv_sz - 1, rounding_decision)); + pre_rounded = m_bv_util.mk_bv_add(unrounded_sig, inc); + dbg_decouple("fpa2bv_to_sbv_inc", inc); + dbg_decouple("fpa2bv_to_sbv_unrounded_sig", unrounded_sig); + dbg_decouple("fpa2bv_to_sbv_pre_rounded", pre_rounded); + + expr_ref rnd_overflow(m), rnd_abs(m), rnd_signed(m), rnd_has_overflown(m), extra_neg(m); + rnd_overflow = m_bv_util.mk_extract(bv_sz, bv_sz - 1, pre_rounded); + rnd_abs = m_bv_util.mk_extract(bv_sz - 1, 0, pre_rounded); + rnd_signed = m.mk_ite(m.mk_eq(sgn, bv1), m_bv_util.mk_bv_neg(rnd_abs), rnd_abs); + extra_neg = m_bv_util.mk_numeral(fu().fm().m_powers2(bv_sz-1), bv_sz+1); + rnd_has_overflown = m.mk_and(m.mk_not(m.mk_eq(rnd_overflow, bv0_2)), + m.mk_not(m.mk_and(m.mk_eq(sgn, bv1), m.mk_eq(pre_rounded, extra_neg)))); + dbg_decouple("fpa2bv_to_sbv_extra_neg", extra_neg); + dbg_decouple("fpa2bv_to_sbv_rnd_overflow", rnd_overflow); + dbg_decouple("fpa2bv_to_sbv_rnd_abs", rnd_abs); + dbg_decouple("fpa2bv_to_sbv_rnd_has_overflown", rnd_has_overflown); + + result = m.mk_ite(rnd_has_overflown, mk_to_sbv_unspecified(bv_sz), rnd_signed); + result = m.mk_ite(c_in_limits, result, mk_to_sbv_unspecified(bv_sz)); + result = m.mk_ite(c2, v2, result); + result = m.mk_ite(c1, v1, result); + + SASSERT(is_well_sorted(m, result)); } void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -3030,7 +3142,7 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #ifdef Z3DEBUG - return; + // return; // CMW: This works only for quantifier-free formulas. expr_ref new_e(m); new_e = m.mk_fresh_const(prefix, m.get_sort(e)); @@ -3040,22 +3152,28 @@ void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { } expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky) { - expr_ref last_or_sticky(m), round_or_sticky(m), not_round(m), not_lors(m), not_rors(m), not_sgn(m); + expr_ref last_or_sticky(m), round_or_sticky(m), not_last(m), not_round(m), not_sticky(m), not_lors(m), not_rors(m), not_sgn(m); expr * last_sticky[2] = { last, sticky }; expr * round_sticky[2] = { round, sticky }; last_or_sticky = m_bv_util.mk_bv_or(2, last_sticky); round_or_sticky = m_bv_util.mk_bv_or(2, round_sticky); + not_last= m_bv_util.mk_bv_not(last); not_round = m_bv_util.mk_bv_not(round); + not_sticky = m_bv_util.mk_bv_not(sticky); not_lors = m_bv_util.mk_bv_not(last_or_sticky); not_rors = m_bv_util.mk_bv_not(round_or_sticky); not_sgn = m_bv_util.mk_bv_not(sgn); - expr * round_lors[2] = { not_round, not_lors }; + expr * nround_lors[2] = { not_round, not_lors }; expr * pos_args[2] = { sgn, not_rors }; expr * neg_args[2] = { not_sgn, not_rors }; + expr * nl_r[2] = { last, not_round }; + expr * nl_nr_sn[3] = { not_last, not_round, not_sticky }; expr_ref inc_teven(m), inc_taway(m), inc_pos(m), inc_neg(m); - inc_teven = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, round_lors)); - inc_taway = round; + inc_teven = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, nround_lors)); + expr *taway_args[2] = { m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, nl_r)), + m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(3, nl_nr_sn)) }; + inc_taway = m_bv_util.mk_bv_or(2, taway_args); inc_pos = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, pos_args)); inc_neg = m_bv_util.mk_bv_not(m_bv_util.mk_bv_or(2, neg_args)); From dd17f3c7d6802e5649a22d2ae7f93f2cf368d416 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 13:18:56 +0000 Subject: [PATCH 126/507] Renaming floats, float, Floats, Float -> FPA, fpa Signed-off-by: Christoph M. Wintersteiger --- src/api/api_ast.cpp | 62 ++- src/api/api_context.cpp | 2 +- src/api/api_context.h | 2 +- src/api/api_fpa.cpp | 2 +- src/api/api_numeral.cpp | 2 +- src/api/dotnet/Expr.cs | 4 +- src/api/z3_api.h | 53 +- src/ast/ast_smt2_pp.h | 2 +- src/ast/fpa/fpa2bv_converter.cpp | 373 ++++++++------ src/ast/fpa/fpa2bv_converter.h | 15 +- src/ast/fpa/fpa2bv_rewriter.h | 98 ++-- ...at_decl_plugin.cpp => fpa_decl_plugin.cpp} | 460 +++++++++--------- ...{float_decl_plugin.h => fpa_decl_plugin.h} | 216 ++++---- src/ast/reg_decl_plugins.cpp | 6 +- .../{float_rewriter.cpp => fpa_rewriter.cpp} | 154 +++--- .../{float_rewriter.h => fpa_rewriter.h} | 8 +- src/ast/rewriter/mk_simplified_app.cpp | 4 +- src/ast/rewriter/th_rewriter.cpp | 4 +- src/cmd_context/cmd_context.cpp | 8 +- src/cmd_context/cmd_context.h | 2 +- src/model/model_evaluator.cpp | 4 +- src/smt/theory_fpa.cpp | 27 +- src/tactic/fpa/fpa2bv_model_converter.cpp | 2 +- src/tactic/fpa/qffpa_tactic.cpp | 32 +- src/tactic/fpa/qffpa_tactic.h | 4 +- 25 files changed, 859 insertions(+), 687 deletions(-) rename src/ast/{float_decl_plugin.cpp => fpa_decl_plugin.cpp} (71%) rename src/ast/{float_decl_plugin.h => fpa_decl_plugin.h} (77%) rename src/ast/rewriter/{float_rewriter.cpp => fpa_rewriter.cpp} (69%) rename src/ast/rewriter/{float_rewriter.h => fpa_rewriter.h} (95%) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index 67358726c..c6b413dd4 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -648,11 +648,11 @@ extern "C" { else if (fid == mk_c(c)->get_datalog_fid() && k == datalog::DL_FINITE_SORT) { return Z3_FINITE_DOMAIN_SORT; } - else if (fid == mk_c(c)->get_fpa_fid() && k == FLOAT_SORT) { + else if (fid == mk_c(c)->get_fpa_fid() && k == FLOATING_POINT_SORT) { return Z3_FLOATING_POINT_SORT; } else if (fid == mk_c(c)->get_fpa_fid() && k == ROUNDING_MODE_SORT) { - return Z3_FLOATING_POINT_ROUNDING_MODE_SORT; + return Z3_ROUNDING_MODE_SORT; } else { return Z3_UNKNOWN_SORT; @@ -1119,6 +1119,64 @@ extern "C" { return Z3_OP_UNINTERPRETED; } } + + if (mk_c(c)->get_fpa_fid() == _d->get_family_id()) { + switch (_d->get_decl_kind()) { + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: return Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: return Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; + case OP_FPA_RM_TOWARD_POSITIVE: return Z3_OP_FPA_RM_TOWARD_POSITIVE; + case OP_FPA_RM_TOWARD_NEGATIVE: return Z3_OP_FPA_RM_TOWARD_NEGATIVE; + case OP_FPA_RM_TOWARD_ZERO: return Z3_OP_FPA_RM_TOWARD_ZERO; + case OP_FPA_VALUE: return Z3_OP_FPA_VALUE; + case OP_FPA_PLUS_INF: return Z3_OP_FPA_PLUS_INF; + case OP_FPA_MINUS_INF: return Z3_OP_FPA_MINUS_INF; + case OP_FPA_NAN: return Z3_OP_FPA_NAN; + case OP_FPA_MINUS_ZERO: return Z3_OP_FPA_MINUS_ZERO; + case OP_FPA_PLUS_ZERO: return Z3_OP_FPA_PLUS_ZERO; + case OP_FPA_ADD: return Z3_OP_FPA_ADD; + case OP_FPA_SUB: return Z3_OP_FPA_SUB; + case OP_FPA_NEG: return Z3_OP_FPA_NEG; + case OP_FPA_MUL: return Z3_OP_FPA_MUL; + case OP_FPA_DIV: return Z3_OP_FPA_DIV; + case OP_FPA_REM: return Z3_OP_FPA_REM; + case OP_FPA_ABS: return Z3_OP_FPA_ABS; + case OP_FPA_MIN: return Z3_OP_FPA_MIN; + case OP_FPA_MAX: return Z3_OP_FPA_MAX; + case OP_FPA_FMA: return Z3_OP_FPA_FMA; + case OP_FPA_SQRT: return Z3_OP_FPA_SQRT; + case OP_FPA_EQ: return Z3_OP_FPA_EQ; + case OP_FPA_ROUND_TO_INTEGRAL: return Z3_OP_FPA_ROUND_TO_INTEGRAL; + case OP_FPA_LT: return Z3_OP_FPA_LT; + case OP_FPA_GT: return Z3_OP_FPA_GT; + case OP_FPA_LE: return Z3_OP_FPA_LE; + case OP_FPA_GE: return Z3_OP_FPA_GE; + case OP_FPA_IS_NAN: return Z3_OP_FPA_IS_NAN; + case OP_FPA_IS_INF: return Z3_OP_FPA_IS_INF; + case OP_FPA_IS_ZERO: return Z3_OP_FPA_IS_ZERO; + case OP_FPA_IS_NORMAL: return Z3_OP_FPA_IS_NORMAL; + case OP_FPA_IS_SUBNORMAL: return Z3_OP_FPA_IS_SUBNORMAL; + case OP_FPA_IS_PZERO: return Z3_OP_FPA_IS_PZERO; + case OP_FPA_IS_NZERO: return Z3_OP_FPA_IS_NZERO; + case OP_FPA_IS_NEGATIVE: return Z3_OP_FPA_IS_NEGATIVE; + case OP_FPA_IS_POSITIVE: return Z3_OP_FPA_IS_POSITIVE; + case OP_FPA_FP: return Z3_OP_FPA_FP; + case OP_FPA_TO_FP: return Z3_OP_FPA_TO_FP; + case OP_FPA_TO_FP_UNSIGNED: return Z3_OP_FPA_TO_FP_UNSIGNED; + case OP_FPA_TO_UBV: return Z3_OP_FPA_TO_UBV; + case OP_FPA_TO_SBV: return Z3_OP_FPA_TO_SBV; + case OP_FPA_TO_REAL: return Z3_OP_FPA_TO_REAL; + case OP_FPA_TO_IEEE_BV: return Z3_OP_FPA_TO_IEEE_BV; + case OP_FPA_INTERNAL_BVWRAP: + case OP_FPA_INTERNAL_BVUNWRAP: + case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: + return Z3_OP_UNINTERPRETED; + default: + UNREACHABLE(); + return Z3_OP_UNINTERPRETED; + } + } if (mk_c(c)->m().get_label_family_id() == _d->get_family_id()) { switch(_d->get_decl_kind()) { diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index 5d11e5bce..b83b72e35 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -113,7 +113,7 @@ namespace api { m_array_fid = m().mk_family_id("array"); m_dt_fid = m().mk_family_id("datatype"); m_datalog_fid = m().mk_family_id("datalog_relation"); - m_fpa_fid = m().mk_family_id("float"); + m_fpa_fid = m().mk_family_id("fpa"); m_dt_plugin = static_cast(m().get_plugin(m_dt_fid)); if (!m_user_ref_count) { diff --git a/src/api/api_context.h b/src/api/api_context.h index f409a4ece..c71b88b61 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -27,7 +27,7 @@ Revision History: #include"bv_decl_plugin.h" #include"datatype_decl_plugin.h" #include"dl_decl_plugin.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" #include"smt_kernel.h" #include"smt_params.h" #include"event_handler.h" diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 87568af09..0f0f68ae1 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -20,7 +20,7 @@ Notes: #include"z3.h" #include"api_log_macros.h" #include"api_context.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" extern "C" { diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index d2829e990..17a743880 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -23,7 +23,7 @@ Revision History: #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" #include"algebraic_numbers.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" bool is_numeral_sort(Z3_context c, Z3_sort ty) { sort * _ty = to_sort(ty); diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index ec8beeac0..826860eec 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1543,7 +1543,7 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); - case Z3_sort_kind.Z3_FLOATING_POINT_ROUNDING_MODE_SORT: return new FPRMNum(ctx, obj); + case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMNum(ctx, obj); } } @@ -1556,7 +1556,7 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_ARRAY_SORT: return new ArrayExpr(ctx, obj); case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPExpr(ctx, obj); - case Z3_sort_kind.Z3_FLOATING_POINT_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj); + case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj); } return new Expr(ctx, obj); diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 776e4e9fe..3c3a5d1c2 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -195,7 +195,7 @@ typedef enum Z3_RELATION_SORT, Z3_FINITE_DOMAIN_SORT, Z3_FLOATING_POINT_SORT, - Z3_FLOATING_POINT_ROUNDING_MODE_SORT, + Z3_ROUNDING_MODE_SORT, Z3_UNKNOWN_SORT = 1000 } Z3_sort_kind; @@ -1058,6 +1058,57 @@ typedef enum { Z3_OP_DT_RECOGNISER, Z3_OP_DT_ACCESSOR, + // Floating-Point Arithmetic + Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN, + Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY, + Z3_OP_FPA_RM_TOWARD_POSITIVE, + Z3_OP_FPA_RM_TOWARD_NEGATIVE, + Z3_OP_FPA_RM_TOWARD_ZERO, + + Z3_OP_FPA_VALUE, + Z3_OP_FPA_PLUS_INF, + Z3_OP_FPA_MINUS_INF, + Z3_OP_FPA_NAN, + Z3_OP_FPA_PLUS_ZERO, + Z3_OP_FPA_MINUS_ZERO, + + Z3_OP_FPA_ADD, + Z3_OP_FPA_SUB, + Z3_OP_FPA_NEG, + Z3_OP_FPA_MUL, + Z3_OP_FPA_DIV, + Z3_OP_FPA_REM, + Z3_OP_FPA_ABS, + Z3_OP_FPA_MIN, + Z3_OP_FPA_MAX, + Z3_OP_FPA_FMA, + Z3_OP_FPA_SQRT, + Z3_OP_FPA_ROUND_TO_INTEGRAL, + + Z3_OP_FPA_EQ, + Z3_OP_FPA_LT, + Z3_OP_FPA_GT, + Z3_OP_FPA_LE, + Z3_OP_FPA_GE, + Z3_OP_FPA_IS_NAN, + Z3_OP_FPA_IS_INF, + Z3_OP_FPA_IS_ZERO, + Z3_OP_FPA_IS_NORMAL, + Z3_OP_FPA_IS_SUBNORMAL, + Z3_OP_FPA_IS_PZERO, + Z3_OP_FPA_IS_NZERO, + Z3_OP_FPA_IS_NEGATIVE, + Z3_OP_FPA_IS_POSITIVE, + + Z3_OP_FPA_FP, + Z3_OP_FPA_TO_FP, + Z3_OP_FPA_TO_FP_UNSIGNED, + Z3_OP_FPA_TO_UBV, + Z3_OP_FPA_TO_SBV, + Z3_OP_FPA_TO_REAL, + + Z3_OP_FPA_TO_IEEE_BV, + Z3_OP_UNINTERPRETED } Z3_decl_kind; diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index 37d13e57a..bc62448c7 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -27,7 +27,7 @@ Revision History: #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" #include"array_decl_plugin.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" #include"dl_decl_plugin.h" #include"smt2_util.h" diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 24e606cdc..dc1a255e8 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -16,8 +16,10 @@ Author: Notes: --*/ +#include #include"ast_smt2_pp.h" #include"well_sorted.h" +#include"th_rewriter.h" #include"fpa2bv_converter.h" @@ -34,7 +36,7 @@ fpa2bv_converter::fpa2bv_converter(ast_manager & m) : m_mpz_manager(m_mpf_manager.mpz_manager()), m_hi_fp_unspecified(true), m_extra_assertions(m) { - m_plugin = static_cast(m.get_plugin(m.mk_family_id("float"))); + m_plugin = static_cast(m.get_plugin(m.mk_family_id("fpa"))); } fpa2bv_converter::~fpa2bv_converter() { @@ -42,8 +44,8 @@ fpa2bv_converter::~fpa2bv_converter() { } void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { - SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); - SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_TO_FP)); expr_ref sgn(m), s(m), e(m); m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), sgn); @@ -62,8 +64,8 @@ void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { } void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { - SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); - SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_FPA_TO_FP)); expr *t_sgn, *t_sig, *t_exp; expr *f_sgn, *f_sig, *f_exp; @@ -1881,15 +1883,15 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args mk_to_fp_real(f, f->get_range(), args[0], args[1], result); } else if (num == 2 && - m_bv_util.is_bv(args[0]) && - m_bv_util.get_bv_size(args[0]) == 3 && - m_bv_util.is_bv(args[1])) { - mk_to_fp_signed(f, num, args, result); + m_bv_util.is_bv(args[0]) && + m_bv_util.get_bv_size(args[0]) == 3 && + m_bv_util.is_bv(args[1])) { + mk_to_fp_signed(f, num, args, result); } else if (num == 3 && - m_bv_util.is_bv(args[0]) && - m_bv_util.is_bv(args[1]) && - m_bv_util.is_bv(args[2])) { + m_bv_util.is_bv(args[0]) && + m_bv_util.is_bv(args[1]) && + m_bv_util.is_bv(args[2])) { SASSERT(m_bv_util.get_bv_size(args[0]) == 1); SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); @@ -1900,55 +1902,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args m_arith_util.is_numeral(args[1]) && m_arith_util.is_numeral(args[2])) { - // rm + real + int -> float - SASSERT(m_util.is_float(f->get_range())); - unsigned ebits = m_util.get_ebits(f->get_range()); - unsigned sbits = m_util.get_sbits(f->get_range()); - - expr * rm = args[0]; - - rational q; - if (!m_arith_util.is_numeral(args[1], q)) - UNREACHABLE(); - - rational e; - if (!m_arith_util.is_numeral(args[2], e)) - UNREACHABLE(); - - SASSERT(e.is_int64()); - SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1)); - - scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager); - m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator()); - m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator()); - m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator()); - m_mpf_manager.set(tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq(), e.to_mpq().numerator()); - m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator()); - - app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m); - a_nte = m_plugin->mk_value(nte); - a_nta = m_plugin->mk_value(nta); - a_tp = m_plugin->mk_value(tp); - a_tn = m_plugin->mk_value(tn); - a_tz = m_plugin->mk_value(tz); - - expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m); - mk_value(a_nte->get_decl(), 0, 0, bv_nte); - mk_value(a_nta->get_decl(), 0, 0, bv_nta); - mk_value(a_tp->get_decl(), 0, 0, bv_tp); - mk_value(a_tn->get_decl(), 0, 0, bv_tn); - mk_value(a_tz->get_decl(), 0, 0, bv_tz); - - expr_ref c1(m), c2(m), c3(m), c4(m); - c1 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); - c2 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); - c3 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)); - c4 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)); - - mk_ite(c1, bv_tn, bv_tz, result); - mk_ite(c2, bv_tp, result, result); - mk_ite(c3, bv_nta, result, result); - mk_ite(c4, bv_nte, result, result); + mk_to_fp_real_int(f, num, args, result); } else UNREACHABLE(); @@ -2104,11 +2058,13 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * } void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result) { + TRACE("fpa2bv_to_fp_real", tout << "rm: " << mk_ismt2_pp(rm, m) << std::endl << + "x: " << mk_ismt2_pp(x, m) << std::endl;); SASSERT(m_util.is_float(s)); unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); - if (m_bv_util.is_numeral(rm) && m_util.au().is_numeral(x)) { + if (false && m_bv_util.is_numeral(rm) && m_util.au().is_numeral(x)) { rational tmp_rat; unsigned sz; m_bv_util.is_numeral(to_expr(rm), tmp_rat, sz); SASSERT(tmp_rat.is_int32()); @@ -2140,19 +2096,201 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * mk_triple(sgn, s, e, result); } else { - NOT_IMPLEMENTED_YET(); + mpf_manager & fm = fu().fm(); + bv_util & bu = m_bv_util; + arith_util & au = m_arith_util; + + expr_ref bv0(m), bv1(m), zero(m), two(m); + bv0 = bu.mk_numeral(0, 1); + bv1 = bu.mk_numeral(1, 1); + zero = au.mk_numeral(rational(0), false); + two = au.mk_numeral(rational(2), false); + + expr_ref sgn(m), sig(m), exp(m); + sgn = m.mk_ite(au.mk_lt(x, zero), bv1, bv0); + sig = bu.mk_numeral(0, sbits + 4); + mpz const & max_normal_exponent = fm.m_powers2.m1(ebits-1); + exp = bu.mk_numeral(max_normal_exponent, ebits); + + //expr_ref cur_s(m), cur_d(m), cur_r(m), cur_s2(m), bv1_s4(m); + //bv1_s4 = bu.mk_numeral(1, sbits + 4); + //cur_s = x; + //std::string trace_name; + //for (unsigned i = 0; i < sbits + 3; i++) { + // std::stringstream dbg_name; + // dbg_name << "fpa2bv_to_float_real_sig_" << i; + // dbg_decouple(dbg_name.str().c_str(), sig); + + // cur_s = au.mk_div(cur_s, two); + // // cur_r = au.mk_rem(cur_s, two); + // cur_r = au.mk_mod(cur_s, two); + // cur_s2 = bu.mk_bv_shl(sig, bv1_s4); + // sig = m.mk_ite(au.mk_eq(cur_r, zero), + // cur_s2, + // bu.mk_bv_add(cur_s2, bv1_s4)); + //} + //dbg_decouple("fpa2bv_to_float_real_last_cur_s", cur_s); + //expr_ref inc(m); + //inc = m.mk_not(m.mk_eq(cur_s, zero)); + //dbg_decouple("fpa2bv_to_float_real_inc", inc); + //sig = m.mk_ite(inc, bu.mk_bv_add(sig, bv1_s4), sig); + + SASSERT(bu.get_bv_size(sgn) == 1); + SASSERT(bu.get_bv_size(sig) == sbits + 4); + SASSERT(bu.get_bv_size(exp) == ebits + 2); + + dbg_decouple("fpa2bv_to_float_real_sgn", sgn); + dbg_decouple("fpa2bv_to_float_real_sig", sig); + dbg_decouple("fpa2bv_to_float_real_exp", exp); + + expr_ref rmr(rm, m); + round(s, rmr, sgn, sig, exp, result); } SASSERT(is_well_sorted(m, result)); } +void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + // rm + real + int -> float + SASSERT(m_util.is_float(f->get_range())); + unsigned ebits = m_util.get_ebits(f->get_range()); + unsigned sbits = m_util.get_sbits(f->get_range()); + + expr * rm = args[0]; + + rational q; + if (!m_arith_util.is_numeral(args[1], q)) + UNREACHABLE(); + + rational e; + if (!m_arith_util.is_numeral(args[2], e)) + UNREACHABLE(); + + SASSERT(e.is_int64()); + SASSERT(m_mpz_manager.eq(e.to_mpq().denominator(), 1)); + + scoped_mpf nte(m_mpf_manager), nta(m_mpf_manager), tp(m_mpf_manager), tn(m_mpf_manager), tz(m_mpf_manager); + m_mpf_manager.set(nte, ebits, sbits, MPF_ROUND_NEAREST_TEVEN, q.to_mpq(), e.to_mpq().numerator()); + m_mpf_manager.set(nta, ebits, sbits, MPF_ROUND_NEAREST_TAWAY, q.to_mpq(), e.to_mpq().numerator()); + m_mpf_manager.set(tp, ebits, sbits, MPF_ROUND_TOWARD_POSITIVE, q.to_mpq(), e.to_mpq().numerator()); + m_mpf_manager.set(tn, ebits, sbits, MPF_ROUND_TOWARD_NEGATIVE, q.to_mpq(), e.to_mpq().numerator()); + m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator()); + + app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m); + a_nte = m_plugin->mk_value(nte); + a_nta = m_plugin->mk_value(nta); + a_tp = m_plugin->mk_value(tp); + a_tn = m_plugin->mk_value(tn); + a_tz = m_plugin->mk_value(tz); + + expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m); + mk_value(a_nte->get_decl(), 0, 0, bv_nte); + mk_value(a_nta->get_decl(), 0, 0, bv_nta); + mk_value(a_tp->get_decl(), 0, 0, bv_tp); + mk_value(a_tn->get_decl(), 0, 0, bv_tn); + mk_value(a_tz->get_decl(), 0, 0, bv_tz); + + expr_ref c1(m), c2(m), c3(m), c4(m); + c1 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); + c2 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); + c3 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3)); + c4 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3)); + + mk_ite(c1, bv_tn, bv_tz, result); + mk_ite(c2, bv_tp, result, result); + mk_ite(c3, bv_nta, result, result); + mk_ite(c4, bv_nte, result, result); +} +void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++) + tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); + SASSERT(num == 1); + SASSERT(f->get_num_parameters() == 0); + SASSERT(is_app_of(args[0], m_plugin->get_family_id(), OP_FPA_TO_FP)); + + expr * x = args[0]; + sort * s = m.get_sort(x); + unsigned ebits = m_util.get_ebits(s); + unsigned sbits = m_util.get_sbits(s); + + sort * rs = m_arith_util.mk_real(); + expr_ref x_is_nan(m), x_is_inf(m), x_is_zero(m); + mk_is_nan(x, x_is_nan); + mk_is_inf(x, x_is_inf); + mk_is_zero(x, x_is_zero); + + expr_ref sgn(m), sig(m), exp(m), lz(m); + unpack(x, sgn, sig, exp, lz, true); + // sig is of the form [1].[sigbits] + + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(sig) == sbits); + SASSERT(m_bv_util.get_bv_size(exp) == ebits); + + expr_ref rsig(m), bit(m), zero(m), one(m), two(m), bv0(m), bv1(m); + zero = m_arith_util.mk_numeral(rational(0), rs); + one = m_arith_util.mk_numeral(rational(1), rs); + two = m_arith_util.mk_numeral(rational(2), rs); + bv0 = m_bv_util.mk_numeral(0, 1); + bv1 = m_bv_util.mk_numeral(1, 1); + rsig = one; + for (unsigned i = sbits - 2; i != (unsigned)-1; i--) { + bit = m_bv_util.mk_extract(i, i, sig); + rsig = m_arith_util.mk_add(m_arith_util.mk_mul(rsig, two), + m.mk_ite(m.mk_eq(bit, bv1), one, zero)); + } + + const mpz & p2 = fu().fm().m_powers2(sbits - 1); + expr_ref ep2(m); + ep2 = m_arith_util.mk_numeral(rational(p2), false); + rsig = m_arith_util.mk_div(rsig, ep2); + dbg_decouple("fpa2bv_to_real_ep2", ep2); + dbg_decouple("fpa2bv_to_real_rsig", rsig); + + expr_ref exp_n(m), exp_p(m), exp_is_neg(m), exp_abs(m); + exp_is_neg = m.mk_eq(m_bv_util.mk_extract(ebits - 1, ebits - 1, exp), bv1); + dbg_decouple("fpa2bv_to_real_exp_is_neg", exp_is_neg); + exp_p = m_bv_util.mk_sign_extend(1, exp); + exp_n = m_bv_util.mk_bv_neg(exp_p); + exp_abs = m.mk_ite(exp_is_neg, exp_n, exp_p); + dbg_decouple("fpa2bv_to_real_exp_abs", exp); + SASSERT(m_bv_util.get_bv_size(exp_abs) == ebits + 1); + + expr_ref exp2(m), prev_bit(m); + exp2 = zero; + for (unsigned i = ebits; i != (unsigned)-1; i--) { + bit = m_bv_util.mk_extract(i, i, exp_abs); + exp2 = m_arith_util.mk_add(m_arith_util.mk_mul(exp2, two), + m.mk_ite(m.mk_eq(bit, bv1), one, zero)); + prev_bit = bit; + } + + exp2 = m.mk_ite(exp_is_neg, m_arith_util.mk_div(one, exp2), exp2); + dbg_decouple("fpa2bv_to_real_exp2", exp2); + + expr_ref res(m), two_exp2(m); + two_exp2 = m_arith_util.mk_power(two, exp2); + res = m_arith_util.mk_mul(rsig, two_exp2); + res = m.mk_ite(m.mk_eq(sgn, bv1), m_arith_util.mk_uminus(res), res); + dbg_decouple("fpa2bv_to_real_sig_times_exp2", res); + + TRACE("fpa2bv_to_real", tout << "rsig = " << mk_ismt2_pp(rsig, m) << std::endl; + tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;); + + result = m.mk_ite(x_is_zero, zero, res); + result = m.mk_ite(x_is_inf, mk_to_real_unspecified(), result); + result = m.mk_ite(x_is_nan, mk_to_real_unspecified(), result); + + SASSERT(is_well_sorted(m, result)); +} + void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_fp_signed", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); // This is a conversion from signed bitvector to float: // ; from signed machine integer, represented as a 2's complement bit vector - // ((_ to_fp eb sb) RoundingMode(_ BitVec m) (_ FloatingPoint eb sb)) + // ((_ to_fp eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb)) // Semantics: // Let b in[[(_ BitVec m)]] and let n be the signed integer represented by b (in 2's complement format). // [[(_ to_fp eb sb)]](r, b) = +/ -infinity if n is too large / too small to be represented as a finite @@ -2293,7 +2431,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); // This is a conversion from unsigned bitvector to float: - // ((_ to_fp_unsigned eb sb) RoundingMode(_ BitVec m) (_ FloatingPoint eb sb)) + // ((_ to_fp_unsigned eb sb) RoundingMode (_ BitVec m) (_ FloatingPoint eb sb)) // Semantics: // Let b in[[(_ BitVec m)]] and let n be the unsigned integer represented by b. // [[(_ to_fp_unsigned eb sb)]](r, x) = +infinity if n is too large to be @@ -2700,91 +2838,6 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg SASSERT(is_well_sorted(m, result)); } -void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - TRACE("fpa2bv_to_real", for (unsigned i = 0; i < num; i++) - tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); - SASSERT(num == 1); - SASSERT(f->get_num_parameters() == 0); - SASSERT(is_app_of(args[0], m_plugin->get_family_id(), OP_FLOAT_TO_FP)); - - expr * x = args[0]; - sort * s = m.get_sort(x); - unsigned ebits = m_util.get_ebits(s); - unsigned sbits = m_util.get_sbits(s); - - sort * rs = m_arith_util.mk_real(); - expr_ref x_is_nan(m), x_is_inf(m), x_is_zero(m); - mk_is_nan(x, x_is_nan); - mk_is_inf(x, x_is_inf); - mk_is_zero(x, x_is_zero); - - expr_ref sgn(m), sig(m), exp(m), lz(m); - unpack(x, sgn, sig, exp, lz, true); - // sig is of the form [1].[sigbits] - - SASSERT(m_bv_util.get_bv_size(sgn) == 1); - SASSERT(m_bv_util.get_bv_size(sig) == sbits); - SASSERT(m_bv_util.get_bv_size(exp) == ebits); - - expr_ref rsig(m), bit(m), zero(m), one(m), two(m), bv0(m), bv1(m); - zero = m_arith_util.mk_numeral(rational(0), rs); - one = m_arith_util.mk_numeral(rational(1), rs); - two = m_arith_util.mk_numeral(rational(2), rs); - bv0 = m_bv_util.mk_numeral(0, 1); - bv1 = m_bv_util.mk_numeral(1, 1); - rsig = one; - for (unsigned i = sbits-2; i != (unsigned)-1; i--) - { - bit = m_bv_util.mk_extract(i, i, sig); - rsig = m_arith_util.mk_add(m_arith_util.mk_mul(rsig, two), - m.mk_ite(m.mk_eq(bit, bv1), one, zero)); - } - - const mpz & p2 = fu().fm().m_powers2(sbits-1); - expr_ref ep2(m); - ep2 = m_arith_util.mk_numeral(rational(p2), false); - rsig = m_arith_util.mk_div(rsig, ep2); - dbg_decouple("fpa2bv_to_real_ep2", ep2); - dbg_decouple("fpa2bv_to_real_rsig", rsig); - - expr_ref exp_n(m), exp_p(m), exp_is_neg(m), exp_abs(m); - exp_is_neg = m.mk_eq(m_bv_util.mk_extract(ebits - 1, ebits - 1, exp), bv1); - dbg_decouple("fpa2bv_to_real_exp_is_neg", exp_is_neg); - exp_p = m_bv_util.mk_sign_extend(1, exp); - exp_n = m_bv_util.mk_bv_neg(exp_p); - exp_abs = m.mk_ite(exp_is_neg, exp_n, exp_p); - dbg_decouple("fpa2bv_to_real_exp_abs", exp); - SASSERT(m_bv_util.get_bv_size(exp_abs) == ebits + 1); - - expr_ref exp2(m), prev_bit(m); - exp2 = zero; - for (unsigned i = ebits; i != (unsigned)-1; i--) - { - bit = m_bv_util.mk_extract(i, i, exp_abs); - exp2 = m_arith_util.mk_add(m_arith_util.mk_mul(exp2, two), - m.mk_ite(m.mk_eq(bit, bv1), one, zero)); - prev_bit = bit; - } - - exp2 = m.mk_ite(exp_is_neg, m_arith_util.mk_div(one, exp2), exp2); - dbg_decouple("fpa2bv_to_real_exp2", exp2); - - expr_ref res(m), two_exp2(m); - two_exp2 = m_arith_util.mk_power(two, exp2); - res = m_arith_util.mk_mul(rsig, two_exp2); - res = m.mk_ite(m.mk_eq(sgn, bv1), m_arith_util.mk_uminus(res), res); - dbg_decouple("fpa2bv_to_real_sig_times_exp2", res); - - TRACE("fpa2bv_to_real", tout << "rsig = " << mk_ismt2_pp(rsig, m) << std::endl; - tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;); - - result = m.mk_ite(x_is_zero, zero, res); - result = m.mk_ite(x_is_inf, mk_to_real_unspecified(), result); - result = m.mk_ite(x_is_nan, mk_to_real_unspecified(), result); - - SASSERT(is_well_sorted(m, result)); -} - expr_ref fpa2bv_converter::mk_to_ubv_unspecified(unsigned width) { if (m_hi_fp_unspecified) return expr_ref(m_bv_util.mk_numeral(0, width), m); @@ -2807,7 +2860,7 @@ expr_ref fpa2bv_converter::mk_to_real_unspecified() { } void fpa2bv_converter::split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); sgn = to_app(e)->get_arg(0); @@ -2816,7 +2869,7 @@ void fpa2bv_converter::split_triple(expr * e, expr * & sgn, expr * & sig, expr * } void fpa2bv_converter::split_triple(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp) const { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr *e_sgn, *e_sig, *e_exp; split_triple(e, e_sgn, e_sig, e_exp); @@ -2866,7 +2919,7 @@ void fpa2bv_converter::mk_is_ninf(expr * e, expr_ref & result) { } void fpa2bv_converter::mk_is_pos(expr * e, expr_ref & result) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr * a0 = to_app(e)->get_arg(0); expr_ref zero(m); @@ -2875,7 +2928,7 @@ void fpa2bv_converter::mk_is_pos(expr * e, expr_ref & result) { } void fpa2bv_converter::mk_is_neg(expr * e, expr_ref & result) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr * a0 = to_app(e)->get_arg(0); expr_ref one(m); @@ -3038,7 +3091,7 @@ void fpa2bv_converter::mk_unbias(expr * e, expr_ref & result) { } void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & lz, bool normalize) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(to_app(e)->get_num_args() == 3); sort * srt = to_app(e)->get_decl()->get_range(); @@ -3131,11 +3184,11 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) { switch(f->get_decl_kind()) { - case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; - case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); break; - case OP_FLOAT_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; - case OP_FLOAT_RM_TOWARD_POSITIVE: result = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); break; - case OP_FLOAT_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); break; + case OP_FPA_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; + case OP_FPA_RM_TOWARD_POSITIVE: result = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); break; + case OP_FPA_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; default: UNREACHABLE(); } } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 6a7b6e92f..f81edb653 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -22,7 +22,7 @@ Notes: #include"ast.h" #include"obj_hashtable.h" #include"ref_util.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" #include"bv_decl_plugin.h" #include"basic_simplifier_plugin.h" @@ -50,7 +50,7 @@ protected: arith_util m_arith_util; mpf_manager & m_mpf_manager; unsynch_mpz_manager & m_mpz_manager; - float_decl_plugin * m_plugin; + fpa_decl_plugin * m_plugin; bool m_hi_fp_unspecified; obj_map m_const2bv; @@ -76,7 +76,7 @@ public: SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); SASSERT(m_bv_util.is_bv(significand)); SASSERT(m_bv_util.is_bv(exponent)); - result = m.mk_app(m_util.get_family_id(), OP_FLOAT_TO_FP, sign, exponent, significand); + result = m.mk_app(m_util.get_family_id(), OP_FPA_TO_FP, sign, exponent, significand); } void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const; @@ -130,15 +130,16 @@ public: void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); - void mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); + void mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); void mk_to_fp_signed(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_fp_unsigned(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - + void mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); + void mk_to_fp_real_int(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_sbv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_real(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void set_unspecified_fp_hi(bool v) { m_hi_fp_unspecified = v; } expr_ref mk_to_ubv_unspecified(unsigned width); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 797f681e7..cbbd9e8a7 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -115,55 +115,55 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { if (m_conv.is_float_family(f)) { switch (f->get_decl_kind()) { - case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: - case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: - case OP_FLOAT_RM_TOWARD_NEGATIVE: - case OP_FLOAT_RM_TOWARD_POSITIVE: - case OP_FLOAT_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE; - case OP_FLOAT_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE; - case OP_FLOAT_PLUS_INF: m_conv.mk_pinf(f, result); return BR_DONE; - case OP_FLOAT_MINUS_INF: m_conv.mk_ninf(f, result); return BR_DONE; - case OP_FLOAT_PLUS_ZERO: m_conv.mk_pzero(f, result); return BR_DONE; - case OP_FLOAT_MINUS_ZERO: m_conv.mk_nzero(f, result); return BR_DONE; - case OP_FLOAT_NAN: m_conv.mk_nan(f, result); return BR_DONE; - case OP_FLOAT_ADD: m_conv.mk_add(f, num, args, result); return BR_DONE; - case OP_FLOAT_SUB: m_conv.mk_sub(f, num, args, result); return BR_DONE; - case OP_FLOAT_NEG: m_conv.mk_neg(f, num, args, result); return BR_DONE; - case OP_FLOAT_MUL: m_conv.mk_mul(f, num, args, result); return BR_DONE; - case OP_FLOAT_DIV: m_conv.mk_div(f, num, args, result); return BR_DONE; - case OP_FLOAT_REM: m_conv.mk_rem(f, num, args, result); return BR_DONE; - case OP_FLOAT_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE; - case OP_FLOAT_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE; - case OP_FLOAT_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE; - case OP_FLOAT_FMA: m_conv.mk_fma(f, num, args, result); return BR_DONE; - case OP_FLOAT_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE; - case OP_FLOAT_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE; - case OP_FLOAT_EQ: m_conv.mk_float_eq(f, num, args, result); return BR_DONE; - case OP_FLOAT_LT: m_conv.mk_float_lt(f, num, args, result); return BR_DONE; - case OP_FLOAT_GT: m_conv.mk_float_gt(f, num, args, result); return BR_DONE; - case OP_FLOAT_LE: m_conv.mk_float_le(f, num, args, result); return BR_DONE; - case OP_FLOAT_GE: m_conv.mk_float_ge(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_ZERO: m_conv.mk_is_zero(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_NZERO: m_conv.mk_is_nzero(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_PZERO: m_conv.mk_is_pzero(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_NAN: m_conv.mk_is_nan(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_INF: m_conv.mk_is_inf(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_NORMAL: m_conv.mk_is_normal(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_POSITIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; - case OP_FLOAT_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_FP: m_conv.mk_to_fp(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_FP_UNSIGNED: m_conv.mk_to_fp_unsigned(f, num, args, result); return BR_DONE; - case OP_FLOAT_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; - case OP_FLOAT_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; - case OP_FLOAT_INTERNAL_BVWRAP: - case OP_FLOAT_INTERNAL_BVUNWRAP: - case OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED: - case OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED: - case OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED: return BR_FAILED; + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: + case OP_FPA_RM_TOWARD_NEGATIVE: + case OP_FPA_RM_TOWARD_POSITIVE: + case OP_FPA_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE; + case OP_FPA_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE; + case OP_FPA_PLUS_INF: m_conv.mk_pinf(f, result); return BR_DONE; + case OP_FPA_MINUS_INF: m_conv.mk_ninf(f, result); return BR_DONE; + case OP_FPA_PLUS_ZERO: m_conv.mk_pzero(f, result); return BR_DONE; + case OP_FPA_MINUS_ZERO: m_conv.mk_nzero(f, result); return BR_DONE; + case OP_FPA_NAN: m_conv.mk_nan(f, result); return BR_DONE; + case OP_FPA_ADD: m_conv.mk_add(f, num, args, result); return BR_DONE; + case OP_FPA_SUB: m_conv.mk_sub(f, num, args, result); return BR_DONE; + case OP_FPA_NEG: m_conv.mk_neg(f, num, args, result); return BR_DONE; + case OP_FPA_MUL: m_conv.mk_mul(f, num, args, result); return BR_DONE; + case OP_FPA_DIV: m_conv.mk_div(f, num, args, result); return BR_DONE; + case OP_FPA_REM: m_conv.mk_rem(f, num, args, result); return BR_DONE; + case OP_FPA_ABS: m_conv.mk_abs(f, num, args, result); return BR_DONE; + case OP_FPA_MIN: m_conv.mk_min(f, num, args, result); return BR_DONE; + case OP_FPA_MAX: m_conv.mk_max(f, num, args, result); return BR_DONE; + case OP_FPA_FMA: m_conv.mk_fma(f, num, args, result); return BR_DONE; + case OP_FPA_SQRT: m_conv.mk_sqrt(f, num, args, result); return BR_DONE; + case OP_FPA_ROUND_TO_INTEGRAL: m_conv.mk_round_to_integral(f, num, args, result); return BR_DONE; + case OP_FPA_EQ: m_conv.mk_float_eq(f, num, args, result); return BR_DONE; + case OP_FPA_LT: m_conv.mk_float_lt(f, num, args, result); return BR_DONE; + case OP_FPA_GT: m_conv.mk_float_gt(f, num, args, result); return BR_DONE; + case OP_FPA_LE: m_conv.mk_float_le(f, num, args, result); return BR_DONE; + case OP_FPA_GE: m_conv.mk_float_ge(f, num, args, result); return BR_DONE; + case OP_FPA_IS_ZERO: m_conv.mk_is_zero(f, num, args, result); return BR_DONE; + case OP_FPA_IS_NZERO: m_conv.mk_is_nzero(f, num, args, result); return BR_DONE; + case OP_FPA_IS_PZERO: m_conv.mk_is_pzero(f, num, args, result); return BR_DONE; + case OP_FPA_IS_NAN: m_conv.mk_is_nan(f, num, args, result); return BR_DONE; + case OP_FPA_IS_INF: m_conv.mk_is_inf(f, num, args, result); return BR_DONE; + case OP_FPA_IS_NORMAL: m_conv.mk_is_normal(f, num, args, result); return BR_DONE; + case OP_FPA_IS_SUBNORMAL: m_conv.mk_is_subnormal(f, num, args, result); return BR_DONE; + case OP_FPA_IS_POSITIVE: m_conv.mk_is_positive(f, num, args, result); return BR_DONE; + case OP_FPA_IS_NEGATIVE: m_conv.mk_is_negative(f, num, args, result); return BR_DONE; + case OP_FPA_TO_FP: m_conv.mk_to_fp(f, num, args, result); return BR_DONE; + case OP_FPA_TO_FP_UNSIGNED: m_conv.mk_to_fp_unsigned(f, num, args, result); return BR_DONE; + case OP_FPA_FP: m_conv.mk_fp(f, num, args, result); return BR_DONE; + case OP_FPA_TO_UBV: m_conv.mk_to_ubv(f, num, args, result); return BR_DONE; + case OP_FPA_TO_SBV: m_conv.mk_to_sbv(f, num, args, result); return BR_DONE; + case OP_FPA_TO_REAL: m_conv.mk_to_real(f, num, args, result); return BR_DONE; + case OP_FPA_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; + case OP_FPA_INTERNAL_BVWRAP: + case OP_FPA_INTERNAL_BVUNWRAP: + case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: return BR_FAILED; default: TRACE("fpa2bv", tout << "unsupported operator: " << f->get_name() << "\n"; for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << std::endl;); diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp similarity index 71% rename from src/ast/float_decl_plugin.cpp rename to src/ast/fpa_decl_plugin.cpp index bdc0c6fb1..be3e5f3ec 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -3,7 +3,7 @@ Copyright (c) 2012 Microsoft Corporation Module Name: - float_decl_plugin.cpp + fpa_decl_plugin.cpp Abstract: @@ -16,11 +16,11 @@ Author: Revision History: --*/ -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" -float_decl_plugin::float_decl_plugin(): +fpa_decl_plugin::fpa_decl_plugin(): m_values(m_fm), m_value_table(mpf_hash_proc(m_values), mpf_eq_proc(m_values)) { m_real_sort = 0; @@ -28,16 +28,16 @@ float_decl_plugin::float_decl_plugin(): m_bv_plugin = 0; } -void float_decl_plugin::set_manager(ast_manager * m, family_id id) { +void fpa_decl_plugin::set_manager(ast_manager * m, family_id id) { decl_plugin::set_manager(m, id); m_arith_fid = m_manager->mk_family_id("arith"); m_real_sort = m_manager->mk_sort(m_arith_fid, REAL_SORT); - SASSERT(m_real_sort != 0); // arith_decl_plugin must be installed before float_decl_plugin. + SASSERT(m_real_sort != 0); // arith_decl_plugin must be installed before fpa_decl_plugin. m_manager->inc_ref(m_real_sort); m_int_sort = m_manager->mk_sort(m_arith_fid, INT_SORT); - SASSERT(m_int_sort != 0); // arith_decl_plugin must be installed before float_decl_plugin. + SASSERT(m_int_sort != 0); // arith_decl_plugin must be installed before fpa_decl_plugin. m_manager->inc_ref(m_int_sort); // BV is not optional anymore. @@ -46,10 +46,10 @@ void float_decl_plugin::set_manager(ast_manager * m, family_id id) { m_bv_plugin = static_cast(m_manager->get_plugin(m_bv_fid)); } -float_decl_plugin::~float_decl_plugin() { +fpa_decl_plugin::~fpa_decl_plugin() { } -unsigned float_decl_plugin::mk_id(mpf const & v) { +unsigned fpa_decl_plugin::mk_id(mpf const & v) { unsigned new_id = m_id_gen.mk(); m_values.reserve(new_id+1); m_fm.set(m_values[new_id], v); @@ -61,54 +61,54 @@ unsigned float_decl_plugin::mk_id(mpf const & v) { return old_id; } -void float_decl_plugin::recycled_id(unsigned id) { +void fpa_decl_plugin::recycled_id(unsigned id) { SASSERT(m_value_table.contains(id)); m_value_table.erase(id); m_id_gen.recycle(id); m_fm.del(m_values[id]); } -func_decl * float_decl_plugin::mk_value_decl(mpf const & v) { +func_decl * fpa_decl_plugin::mk_value_decl(mpf const & v) { parameter p(mk_id(v), true); SASSERT(p.is_external()); sort * s = mk_float_sort(v.get_ebits(), v.get_sbits()); - return m_manager->mk_const_decl(symbol("float"), s, func_decl_info(m_family_id, OP_FLOAT_VALUE, 1, &p)); + return m_manager->mk_const_decl(symbol("fpa"), s, func_decl_info(m_family_id, OP_FPA_VALUE, 1, &p)); } -app * float_decl_plugin::mk_value(mpf const & v) { +app * fpa_decl_plugin::mk_value(mpf const & v) { return m_manager->mk_const(mk_value_decl(v)); } -bool float_decl_plugin::is_value(expr * n, mpf & val) { - if (is_app_of(n, m_family_id, OP_FLOAT_VALUE)) { +bool fpa_decl_plugin::is_value(expr * n, mpf & val) { + if (is_app_of(n, m_family_id, OP_FPA_VALUE)) { m_fm.set(val, m_values[to_app(n)->get_decl()->get_parameter(0).get_ext_id()]); return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_MINUS_INF)) { + else if (is_app_of(n, m_family_id, OP_FPA_MINUS_INF)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_ninf(ebits, sbits, val); return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_PLUS_INF)) { + else if (is_app_of(n, m_family_id, OP_FPA_PLUS_INF)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_pinf(ebits, sbits, val); return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_NAN)) { + else if (is_app_of(n, m_family_id, OP_FPA_NAN)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_nan(ebits, sbits, val); return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_PLUS_ZERO)) { + else if (is_app_of(n, m_family_id, OP_FPA_PLUS_ZERO)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_pzero(ebits, sbits, val); return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_MINUS_ZERO)) { + else if (is_app_of(n, m_family_id, OP_FPA_MINUS_ZERO)) { unsigned ebits = to_app(n)->get_decl()->get_range()->get_parameter(0).get_int(); unsigned sbits = to_app(n)->get_decl()->get_range()->get_parameter(1).get_int(); m_fm.mk_nzero(ebits, sbits, val); @@ -117,24 +117,24 @@ bool float_decl_plugin::is_value(expr * n, mpf & val) { return false; } -bool float_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) { - if (is_app_of(n, m_family_id, OP_FLOAT_RM_NEAREST_TIES_TO_AWAY)) { +bool fpa_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) { + if (is_app_of(n, m_family_id, OP_FPA_RM_NEAREST_TIES_TO_AWAY)) { val = MPF_ROUND_NEAREST_TAWAY; return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_RM_NEAREST_TIES_TO_EVEN)) { + else if (is_app_of(n, m_family_id, OP_FPA_RM_NEAREST_TIES_TO_EVEN)) { val = MPF_ROUND_NEAREST_TEVEN; return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_RM_TOWARD_NEGATIVE)) { + else if (is_app_of(n, m_family_id, OP_FPA_RM_TOWARD_NEGATIVE)) { val = MPF_ROUND_TOWARD_NEGATIVE; return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_RM_TOWARD_POSITIVE)) { + else if (is_app_of(n, m_family_id, OP_FPA_RM_TOWARD_POSITIVE)) { val = MPF_ROUND_TOWARD_POSITIVE; return true; } - else if (is_app_of(n, m_family_id, OP_FLOAT_RM_TOWARD_ZERO)) { + else if (is_app_of(n, m_family_id, OP_FPA_RM_TOWARD_ZERO)) { val = MPF_ROUND_TOWARD_ZERO; return true; } @@ -142,27 +142,27 @@ bool float_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) { return 0; } -void float_decl_plugin::del(parameter const & p) { +void fpa_decl_plugin::del(parameter const & p) { SASSERT(p.is_external()); recycled_id(p.get_ext_id()); } -parameter float_decl_plugin::translate(parameter const & p, decl_plugin & target) { +parameter fpa_decl_plugin::translate(parameter const & p, decl_plugin & target) { SASSERT(p.is_external()); - float_decl_plugin & _target = static_cast(target); + fpa_decl_plugin & _target = static_cast(target); return parameter(_target.mk_id(m_values[p.get_ext_id()]), true); } -void float_decl_plugin::finalize() { +void fpa_decl_plugin::finalize() { if (m_real_sort) { m_manager->dec_ref(m_real_sort); } if (m_int_sort) { m_manager->dec_ref(m_int_sort); } } -decl_plugin * float_decl_plugin::mk_fresh() { - return alloc(float_decl_plugin); +decl_plugin * fpa_decl_plugin::mk_fresh() { + return alloc(fpa_decl_plugin); } -sort * float_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) { +sort * fpa_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) { if (sbits < 2) m_manager->raise_exception("minimum number of significand bits is 1"); if (ebits < 2) @@ -172,16 +172,16 @@ sort * float_decl_plugin::mk_float_sort(unsigned ebits, unsigned sbits) { parameter ps[2] = { p1, p2 }; sort_size sz; sz = sort_size::mk_very_big(); // TODO: refine - return m_manager->mk_sort(symbol("FloatingPoint"), sort_info(m_family_id, FLOAT_SORT, sz, 2, ps)); + return m_manager->mk_sort(symbol("FloatingPoint"), sort_info(m_family_id, FLOATING_POINT_SORT, sz, 2, ps)); } -sort * float_decl_plugin::mk_rm_sort() { +sort * fpa_decl_plugin::mk_rm_sort() { return m_manager->mk_sort(symbol("RoundingMode"), sort_info(m_family_id, ROUNDING_MODE_SORT)); } -sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { +sort * fpa_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { switch (k) { - case FLOAT_SORT: + case FLOATING_POINT_SORT: if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) m_manager->raise_exception("expecting two integer parameters to floating point sort (ebits, sbits)"); return mk_float_sort(parameters[0].get_int(), parameters[1].get_int()); @@ -201,7 +201,7 @@ sort * float_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, paramete } } -func_decl * float_decl_plugin::mk_rm_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_rm_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (num_parameters != 0) m_manager->raise_exception("rounding mode constant does not have parameters"); @@ -210,15 +210,15 @@ func_decl * float_decl_plugin::mk_rm_const_decl(decl_kind k, unsigned num_parame sort * s = mk_rm_sort(); func_decl_info finfo(m_family_id, k); switch (k) { - case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: return m_manager->mk_const_decl(symbol("roundNearestTiesToEven"), s, finfo); - case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: return m_manager->mk_const_decl(symbol("roundNearestTiesToAway"), s, finfo); - case OP_FLOAT_RM_TOWARD_POSITIVE: + case OP_FPA_RM_TOWARD_POSITIVE: return m_manager->mk_const_decl(symbol("roundTowardPositive"), s, finfo); - case OP_FLOAT_RM_TOWARD_NEGATIVE: + case OP_FPA_RM_TOWARD_NEGATIVE: return m_manager->mk_const_decl(symbol("roundTowardNegative"), s, finfo); - case OP_FLOAT_RM_TOWARD_ZERO: + case OP_FPA_RM_TOWARD_ZERO: return m_manager->mk_const_decl(symbol("roundTowardZero"), s, finfo); default: UNREACHABLE(); @@ -226,7 +226,7 @@ func_decl * float_decl_plugin::mk_rm_const_decl(decl_kind k, unsigned num_parame } } -func_decl * float_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { sort * s; if (num_parameters == 1 && parameters[0].is_ast() && is_sort(parameters[0].get_ast()) && is_float_sort(to_sort(parameters[0].get_ast()))) { @@ -243,7 +243,7 @@ func_decl * float_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_par UNREACHABLE(); } - SASSERT(is_sort_of(s, m_family_id, FLOAT_SORT)); + SASSERT(is_sort_of(s, m_family_id, FLOATING_POINT_SORT)); unsigned ebits = s->get_parameter(0).get_int(); unsigned sbits = s->get_parameter(1).get_int(); @@ -251,19 +251,19 @@ func_decl * float_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_par switch (k) { - case OP_FLOAT_NAN: m_fm.mk_nan(ebits, sbits, val); + case OP_FPA_NAN: m_fm.mk_nan(ebits, sbits, val); SASSERT(m_fm.is_nan(val)); break; - case OP_FLOAT_MINUS_INF: m_fm.mk_ninf(ebits, sbits, val); break; - case OP_FLOAT_PLUS_INF: m_fm.mk_pinf(ebits, sbits, val); break; - case OP_FLOAT_MINUS_ZERO: m_fm.mk_nzero(ebits, sbits, val); break; - case OP_FLOAT_PLUS_ZERO: m_fm.mk_pzero(ebits, sbits, val); break; + case OP_FPA_MINUS_INF: m_fm.mk_ninf(ebits, sbits, val); break; + case OP_FPA_PLUS_INF: m_fm.mk_pinf(ebits, sbits, val); break; + case OP_FPA_MINUS_ZERO: m_fm.mk_nzero(ebits, sbits, val); break; + case OP_FPA_PLUS_ZERO: m_fm.mk_pzero(ebits, sbits, val); break; } return mk_value_decl(val); } -func_decl * float_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 2) m_manager->raise_exception("invalid number of arguments to floating point relation"); @@ -271,11 +271,11 @@ func_decl * float_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_paramet m_manager->raise_exception("sort mismatch, expected equal FloatingPoint sorts as arguments"); symbol name; switch (k) { - case OP_FLOAT_EQ: name = "fp.eq"; break; - case OP_FLOAT_LT: name = "fp.lt"; break; - case OP_FLOAT_GT: name = "fp.gt"; break; - case OP_FLOAT_LE: name = "fp.leq"; break; - case OP_FLOAT_GE: name = "fp.geq"; break; + case OP_FPA_EQ: name = "fp.eq"; break; + case OP_FPA_LT: name = "fp.lt"; break; + case OP_FPA_GT: name = "fp.gt"; break; + case OP_FPA_LE: name = "fp.leq"; break; + case OP_FPA_GE: name = "fp.geq"; break; default: UNREACHABLE(); break; @@ -285,7 +285,7 @@ func_decl * float_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_paramet return m_manager->mk_func_decl(name, arity, domain, m_manager->mk_bool_sort(), finfo); } -func_decl * float_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to floating point relation"); @@ -293,15 +293,15 @@ func_decl * float_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_param m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort"); symbol name; switch (k) { - case OP_FLOAT_IS_ZERO: name = "fp.isZero"; break; - case OP_FLOAT_IS_NZERO: name = "fp.isNZero"; break; - case OP_FLOAT_IS_PZERO: name = "fp.isPZero"; break; - case OP_FLOAT_IS_NEGATIVE: name = "fp.isNegative"; break; - case OP_FLOAT_IS_POSITIVE: name = "fp.isPositive"; break; - case OP_FLOAT_IS_NAN: name = "fp.isNaN"; break; - case OP_FLOAT_IS_INF: name = "fp.isInfinite"; break; - case OP_FLOAT_IS_NORMAL: name = "fp.isNormal"; break; - case OP_FLOAT_IS_SUBNORMAL: name = "fp.isSubnormal"; break; + case OP_FPA_IS_ZERO: name = "fp.isZero"; break; + case OP_FPA_IS_NZERO: name = "fp.isNZero"; break; + case OP_FPA_IS_PZERO: name = "fp.isPZero"; break; + case OP_FPA_IS_NEGATIVE: name = "fp.isNegative"; break; + case OP_FPA_IS_POSITIVE: name = "fp.isPositive"; break; + case OP_FPA_IS_NAN: name = "fp.isNaN"; break; + case OP_FPA_IS_INF: name = "fp.isInfinite"; break; + case OP_FPA_IS_NORMAL: name = "fp.isNormal"; break; + case OP_FPA_IS_SUBNORMAL: name = "fp.isSubnormal"; break; default: UNREACHABLE(); break; @@ -309,7 +309,7 @@ func_decl * float_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_param return m_manager->mk_func_decl(name, arity, domain, m_manager->mk_bool_sort(), func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to floating point operator"); @@ -317,8 +317,8 @@ func_decl * float_decl_plugin::mk_unary_decl(decl_kind k, unsigned num_parameter m_manager->raise_exception("sort mismatch, expected argument of FloatingPoint sort"); symbol name; switch (k) { - case OP_FLOAT_ABS: name = "fp.abs"; break; - case OP_FLOAT_NEG: name = "fp.neg"; break; + case OP_FPA_ABS: name = "fp.abs"; break; + case OP_FPA_NEG: name = "fp.neg"; break; default: UNREACHABLE(); break; @@ -326,7 +326,7 @@ func_decl * float_decl_plugin::mk_unary_decl(decl_kind k, unsigned num_parameter return m_manager->mk_func_decl(name, arity, domain, domain[0], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 2) m_manager->raise_exception("invalid number of arguments to floating point operator"); @@ -334,9 +334,9 @@ func_decl * float_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_paramete m_manager->raise_exception("sort mismatch, expected arguments of equal FloatingPoint sorts"); symbol name; switch (k) { - case OP_FLOAT_REM: name = "fp.rem"; break; - case OP_FLOAT_MIN: name = "fp.min"; break; - case OP_FLOAT_MAX: name = "fp.max"; break; + case OP_FPA_REM: name = "fp.rem"; break; + case OP_FPA_MIN: name = "fp.min"; break; + case OP_FPA_MAX: name = "fp.max"; break; default: UNREACHABLE(); break; @@ -344,7 +344,7 @@ func_decl * float_decl_plugin::mk_binary_decl(decl_kind k, unsigned num_paramete return m_manager->mk_func_decl(name, arity, domain, domain[0], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_rm_binary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_rm_binary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 3) m_manager->raise_exception("invalid number of arguments to floating point operator"); @@ -354,10 +354,10 @@ func_decl * float_decl_plugin::mk_rm_binary_decl(decl_kind k, unsigned num_param m_manager->raise_exception("sort mismatch, expected arguments 1 and 2 of equal FloatingPoint sorts"); symbol name; switch (k) { - case OP_FLOAT_ADD: name = "fp.add"; break; - case OP_FLOAT_SUB: name = "fp.sub"; break; - case OP_FLOAT_MUL: name = "fp.mul"; break; - case OP_FLOAT_DIV: name = "fp.div"; break; + case OP_FPA_ADD: name = "fp.add"; break; + case OP_FPA_SUB: name = "fp.sub"; break; + case OP_FPA_MUL: name = "fp.mul"; break; + case OP_FPA_DIV: name = "fp.div"; break; default: UNREACHABLE(); break; @@ -365,7 +365,7 @@ func_decl * float_decl_plugin::mk_rm_binary_decl(decl_kind k, unsigned num_param return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 2) m_manager->raise_exception("invalid number of arguments to floating point operator"); @@ -375,8 +375,8 @@ func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parame m_manager->raise_exception("sort mismatch, expected FloatingPoint as second argument"); symbol name; switch (k) { - case OP_FLOAT_SQRT: name = "fp.sqrt"; break; - case OP_FLOAT_ROUND_TO_INTEGRAL: name = "fp.roundToIntegral"; break; + case OP_FPA_SQRT: name = "fp.sqrt"; break; + case OP_FPA_ROUND_TO_INTEGRAL: name = "fp.roundToIntegral"; break; default: UNREACHABLE(); break; @@ -384,7 +384,7 @@ func_decl * float_decl_plugin::mk_rm_unary_decl(decl_kind k, unsigned num_parame return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 4) m_manager->raise_exception("invalid number of arguments to fused_ma operator"); @@ -396,7 +396,7 @@ func_decl * float_decl_plugin::mk_fma(decl_kind k, unsigned num_parameters, para return m_manager->mk_func_decl(name, arity, domain, domain[1], func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (m_bv_plugin && arity == 3 && is_sort_of(domain[0], m_bv_fid, BV_SORT) && @@ -444,7 +444,7 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa } else if (arity == 2 && is_sort_of(domain[0], m_family_id, ROUNDING_MODE_SORT) && - is_sort_of(domain[1], m_family_id, FLOAT_SORT)) { + is_sort_of(domain[1], m_family_id, FLOATING_POINT_SORT)) { // Rounding + 1 FP -> 1 FP if (num_parameters != 2) m_manager->raise_exception("invalid number of parameters to to_fp"); @@ -454,7 +454,7 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa int sbits = parameters[1].get_int(); if (!is_rm_sort(domain[0])) m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); - if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) + if (!is_sort_of(domain[1], m_family_id, FLOATING_POINT_SORT)) m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); sort * fp = mk_float_sort(ebits, sbits); @@ -514,7 +514,7 @@ func_decl * float_decl_plugin::mk_to_fp(decl_kind k, unsigned num_parameters, pa return 0; } -func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { SASSERT(m_bv_plugin); if (arity != 2) @@ -538,7 +538,7 @@ func_decl * float_decl_plugin::mk_to_fp_unsigned(decl_kind k, unsigned num_param return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * float_decl_plugin::mk_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_fp(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 3) m_manager->raise_exception("invalid number of arguments to fp"); @@ -555,7 +555,7 @@ func_decl * float_decl_plugin::mk_fp(decl_kind k, unsigned num_parameters, param return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { SASSERT(m_bv_plugin); if (arity != 2) @@ -566,7 +566,7 @@ func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, p m_manager->raise_exception("invalid parameter type; fp.to_ubv expects an int parameter"); if (!is_rm_sort(domain[0])) m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); - if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) + if (!is_sort_of(domain[1], m_family_id, FLOATING_POINT_SORT)) m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); if (parameters[0].get_int() <= 0) m_manager->raise_exception("invalid parameter value; fp.to_ubv expects a parameter larger than 0"); @@ -576,7 +576,7 @@ func_decl * float_decl_plugin::mk_to_ubv(decl_kind k, unsigned num_parameters, p return m_manager->mk_func_decl(name, arity, domain, bvs, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { SASSERT(m_bv_plugin); if (arity != 2) @@ -587,7 +587,7 @@ func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, p m_manager->raise_exception("invalid parameter type; fp.to_sbv expects an int parameter"); if (!is_rm_sort(domain[0])) m_manager->raise_exception("sort mismatch, expected first argument of RoundingMode sort"); - if (!is_sort_of(domain[1], m_family_id, FLOAT_SORT)) + if (!is_sort_of(domain[1], m_family_id, FLOATING_POINT_SORT)) m_manager->raise_exception("sort mismatch, expected second argument of FloatingPoint sort"); if (parameters[0].get_int() <= 0) m_manager->raise_exception("invalid parameter value; fp.to_sbv expects a parameter larger than 0"); @@ -598,7 +598,7 @@ func_decl * float_decl_plugin::mk_to_sbv(decl_kind k, unsigned num_parameters, p } -func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to fp.to_real"); @@ -609,7 +609,7 @@ func_decl * float_decl_plugin::mk_to_real(decl_kind k, unsigned num_parameters, return m_manager->mk_func_decl(name, 1, domain, m_real_sort, func_decl_info(m_family_id, k)); } -func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to asIEEEBV"); @@ -623,7 +623,7 @@ func_decl * float_decl_plugin::mk_float_to_ieee_bv(decl_kind k, unsigned num_par return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * float_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to internal_bv_wrap"); @@ -644,7 +644,7 @@ func_decl * float_decl_plugin::mk_internal_bv_wrap(decl_kind k, unsigned num_par } } -func_decl * float_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 1) m_manager->raise_exception("invalid number of arguments to internal_bv_unwrap"); @@ -656,7 +656,7 @@ func_decl * float_decl_plugin::mk_internal_bv_unwrap(decl_kind k, unsigned num_p return m_manager->mk_func_decl(symbol("bv_unwrap"), 1, domain, range, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * float_decl_plugin::mk_internal_to_ubv_unspecified( +func_decl * fpa_decl_plugin::mk_internal_to_ubv_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -670,7 +670,7 @@ func_decl * float_decl_plugin::mk_internal_to_ubv_unspecified( return m_manager->mk_func_decl(symbol("fp.to_ubv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * float_decl_plugin::mk_internal_to_sbv_unspecified( +func_decl * fpa_decl_plugin::mk_internal_to_sbv_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -683,7 +683,7 @@ func_decl * float_decl_plugin::mk_internal_to_sbv_unspecified( return m_manager->mk_func_decl(symbol("fp.to_sbv_unspecified"), 0, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); } -func_decl * float_decl_plugin::mk_internal_to_real_unspecified( +func_decl * fpa_decl_plugin::mk_internal_to_real_unspecified( decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { if (arity != 0) @@ -695,81 +695,81 @@ func_decl * float_decl_plugin::mk_internal_to_real_unspecified( } -func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, +func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { switch (k) { - case OP_FLOAT_MINUS_INF: - case OP_FLOAT_PLUS_INF: - case OP_FLOAT_NAN: - case OP_FLOAT_MINUS_ZERO: - case OP_FLOAT_PLUS_ZERO: + case OP_FPA_MINUS_INF: + case OP_FPA_PLUS_INF: + case OP_FPA_NAN: + case OP_FPA_MINUS_ZERO: + case OP_FPA_PLUS_ZERO: return mk_float_const_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: - case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: - case OP_FLOAT_RM_TOWARD_POSITIVE: - case OP_FLOAT_RM_TOWARD_NEGATIVE: - case OP_FLOAT_RM_TOWARD_ZERO: + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: + case OP_FPA_RM_TOWARD_POSITIVE: + case OP_FPA_RM_TOWARD_NEGATIVE: + case OP_FPA_RM_TOWARD_ZERO: return mk_rm_const_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_EQ: - case OP_FLOAT_LT: - case OP_FLOAT_GT: - case OP_FLOAT_LE: - case OP_FLOAT_GE: + case OP_FPA_EQ: + case OP_FPA_LT: + case OP_FPA_GT: + case OP_FPA_LE: + case OP_FPA_GE: return mk_bin_rel_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_IS_ZERO: - case OP_FLOAT_IS_NZERO: - case OP_FLOAT_IS_PZERO: - case OP_FLOAT_IS_NEGATIVE: - case OP_FLOAT_IS_POSITIVE: - case OP_FLOAT_IS_NAN: - case OP_FLOAT_IS_INF: - case OP_FLOAT_IS_NORMAL: - case OP_FLOAT_IS_SUBNORMAL: + case OP_FPA_IS_ZERO: + case OP_FPA_IS_NZERO: + case OP_FPA_IS_PZERO: + case OP_FPA_IS_NEGATIVE: + case OP_FPA_IS_POSITIVE: + case OP_FPA_IS_NAN: + case OP_FPA_IS_INF: + case OP_FPA_IS_NORMAL: + case OP_FPA_IS_SUBNORMAL: return mk_unary_rel_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_ABS: - case OP_FLOAT_NEG: + case OP_FPA_ABS: + case OP_FPA_NEG: return mk_unary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_REM: - case OP_FLOAT_MIN: - case OP_FLOAT_MAX: + case OP_FPA_REM: + case OP_FPA_MIN: + case OP_FPA_MAX: return mk_binary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_ADD: - case OP_FLOAT_MUL: - case OP_FLOAT_DIV: + case OP_FPA_ADD: + case OP_FPA_MUL: + case OP_FPA_DIV: return mk_rm_binary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_SUB: + case OP_FPA_SUB: if (arity == 1) - return mk_unary_decl(OP_FLOAT_NEG, num_parameters, parameters, arity, domain, range); + return mk_unary_decl(OP_FPA_NEG, num_parameters, parameters, arity, domain, range); else return mk_rm_binary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_SQRT: - case OP_FLOAT_ROUND_TO_INTEGRAL: + case OP_FPA_SQRT: + case OP_FPA_ROUND_TO_INTEGRAL: return mk_rm_unary_decl(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_FMA: + case OP_FPA_FMA: return mk_fma(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_FP: + case OP_FPA_FP: return mk_fp(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_UBV: + case OP_FPA_TO_UBV: return mk_to_ubv(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_SBV: + case OP_FPA_TO_SBV: return mk_to_sbv(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_REAL: + case OP_FPA_TO_REAL: return mk_to_real(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_FP: + case OP_FPA_TO_FP: return mk_to_fp(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_FP_UNSIGNED: + case OP_FPA_TO_FP_UNSIGNED: return mk_to_fp_unsigned(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_TO_IEEE_BV: + case OP_FPA_TO_IEEE_BV: return mk_float_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_INTERNAL_BVWRAP: + case OP_FPA_INTERNAL_BVWRAP: return mk_internal_bv_wrap(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_INTERNAL_BVUNWRAP: + case OP_FPA_INTERNAL_BVUNWRAP: return mk_internal_bv_unwrap(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED: return mk_internal_to_ubv_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED: return mk_internal_to_sbv_unspecified(k, num_parameters, parameters, arity, domain, range); - case OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED: + case OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED: return mk_internal_to_real_unspecified(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); @@ -777,66 +777,66 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters } } -void float_decl_plugin::get_op_names(svector & op_names, symbol const & logic) { +void fpa_decl_plugin::get_op_names(svector & op_names, symbol const & logic) { // These are the operators from the final draft of the SMT FloatingPoint standard - op_names.push_back(builtin_name("+oo", OP_FLOAT_PLUS_INF)); - op_names.push_back(builtin_name("-oo", OP_FLOAT_MINUS_INF)); - op_names.push_back(builtin_name("+zero", OP_FLOAT_PLUS_ZERO)); - op_names.push_back(builtin_name("-zero", OP_FLOAT_MINUS_ZERO)); - op_names.push_back(builtin_name("NaN", OP_FLOAT_NAN)); + op_names.push_back(builtin_name("+oo", OP_FPA_PLUS_INF)); + op_names.push_back(builtin_name("-oo", OP_FPA_MINUS_INF)); + op_names.push_back(builtin_name("+zero", OP_FPA_PLUS_ZERO)); + op_names.push_back(builtin_name("-zero", OP_FPA_MINUS_ZERO)); + op_names.push_back(builtin_name("NaN", OP_FPA_NAN)); - op_names.push_back(builtin_name("roundNearestTiesToEven", OP_FLOAT_RM_NEAREST_TIES_TO_EVEN)); - op_names.push_back(builtin_name("roundNearestTiesToAway", OP_FLOAT_RM_NEAREST_TIES_TO_AWAY)); - op_names.push_back(builtin_name("roundTowardPositive", OP_FLOAT_RM_TOWARD_POSITIVE)); - op_names.push_back(builtin_name("roundTowardNegative", OP_FLOAT_RM_TOWARD_NEGATIVE)); - op_names.push_back(builtin_name("roundTowardZero", OP_FLOAT_RM_TOWARD_ZERO)); + op_names.push_back(builtin_name("roundNearestTiesToEven", OP_FPA_RM_NEAREST_TIES_TO_EVEN)); + op_names.push_back(builtin_name("roundNearestTiesToAway", OP_FPA_RM_NEAREST_TIES_TO_AWAY)); + op_names.push_back(builtin_name("roundTowardPositive", OP_FPA_RM_TOWARD_POSITIVE)); + op_names.push_back(builtin_name("roundTowardNegative", OP_FPA_RM_TOWARD_NEGATIVE)); + op_names.push_back(builtin_name("roundTowardZero", OP_FPA_RM_TOWARD_ZERO)); - op_names.push_back(builtin_name("RNE", OP_FLOAT_RM_NEAREST_TIES_TO_EVEN)); - op_names.push_back(builtin_name("RNA", OP_FLOAT_RM_NEAREST_TIES_TO_AWAY)); - op_names.push_back(builtin_name("RTP", OP_FLOAT_RM_TOWARD_POSITIVE)); - op_names.push_back(builtin_name("RTN", OP_FLOAT_RM_TOWARD_NEGATIVE)); - op_names.push_back(builtin_name("RTZ", OP_FLOAT_RM_TOWARD_ZERO)); + op_names.push_back(builtin_name("RNE", OP_FPA_RM_NEAREST_TIES_TO_EVEN)); + op_names.push_back(builtin_name("RNA", OP_FPA_RM_NEAREST_TIES_TO_AWAY)); + op_names.push_back(builtin_name("RTP", OP_FPA_RM_TOWARD_POSITIVE)); + op_names.push_back(builtin_name("RTN", OP_FPA_RM_TOWARD_NEGATIVE)); + op_names.push_back(builtin_name("RTZ", OP_FPA_RM_TOWARD_ZERO)); - op_names.push_back(builtin_name("fp.abs", OP_FLOAT_ABS)); - op_names.push_back(builtin_name("fp.neg", OP_FLOAT_NEG)); - op_names.push_back(builtin_name("fp.add", OP_FLOAT_ADD)); - op_names.push_back(builtin_name("fp.sub", OP_FLOAT_SUB)); - op_names.push_back(builtin_name("fp.mul", OP_FLOAT_MUL)); - op_names.push_back(builtin_name("fp.div", OP_FLOAT_DIV)); - op_names.push_back(builtin_name("fp.fma", OP_FLOAT_FMA)); - op_names.push_back(builtin_name("fp.sqrt", OP_FLOAT_SQRT)); - op_names.push_back(builtin_name("fp.rem", OP_FLOAT_REM)); - op_names.push_back(builtin_name("fp.roundToIntegral", OP_FLOAT_ROUND_TO_INTEGRAL)); - op_names.push_back(builtin_name("fp.min", OP_FLOAT_MIN)); - op_names.push_back(builtin_name("fp.max", OP_FLOAT_MAX)); - op_names.push_back(builtin_name("fp.leq", OP_FLOAT_LE)); - op_names.push_back(builtin_name("fp.lt", OP_FLOAT_LT)); - op_names.push_back(builtin_name("fp.geq", OP_FLOAT_GE)); - op_names.push_back(builtin_name("fp.gt", OP_FLOAT_GT)); - op_names.push_back(builtin_name("fp.eq", OP_FLOAT_EQ)); + op_names.push_back(builtin_name("fp.abs", OP_FPA_ABS)); + op_names.push_back(builtin_name("fp.neg", OP_FPA_NEG)); + op_names.push_back(builtin_name("fp.add", OP_FPA_ADD)); + op_names.push_back(builtin_name("fp.sub", OP_FPA_SUB)); + op_names.push_back(builtin_name("fp.mul", OP_FPA_MUL)); + op_names.push_back(builtin_name("fp.div", OP_FPA_DIV)); + op_names.push_back(builtin_name("fp.fma", OP_FPA_FMA)); + op_names.push_back(builtin_name("fp.sqrt", OP_FPA_SQRT)); + op_names.push_back(builtin_name("fp.rem", OP_FPA_REM)); + op_names.push_back(builtin_name("fp.roundToIntegral", OP_FPA_ROUND_TO_INTEGRAL)); + op_names.push_back(builtin_name("fp.min", OP_FPA_MIN)); + op_names.push_back(builtin_name("fp.max", OP_FPA_MAX)); + op_names.push_back(builtin_name("fp.leq", OP_FPA_LE)); + op_names.push_back(builtin_name("fp.lt", OP_FPA_LT)); + op_names.push_back(builtin_name("fp.geq", OP_FPA_GE)); + op_names.push_back(builtin_name("fp.gt", OP_FPA_GT)); + op_names.push_back(builtin_name("fp.eq", OP_FPA_EQ)); - op_names.push_back(builtin_name("fp.isNormal", OP_FLOAT_IS_NORMAL)); - op_names.push_back(builtin_name("fp.isSubnormal", OP_FLOAT_IS_SUBNORMAL)); - op_names.push_back(builtin_name("fp.isZero", OP_FLOAT_IS_ZERO)); - op_names.push_back(builtin_name("fp.isInfinite", OP_FLOAT_IS_INF)); - op_names.push_back(builtin_name("fp.isNaN", OP_FLOAT_IS_NAN)); - op_names.push_back(builtin_name("fp.isNegative", OP_FLOAT_IS_NEGATIVE)); - op_names.push_back(builtin_name("fp.isPositive", OP_FLOAT_IS_POSITIVE)); + op_names.push_back(builtin_name("fp.isNormal", OP_FPA_IS_NORMAL)); + op_names.push_back(builtin_name("fp.isSubnormal", OP_FPA_IS_SUBNORMAL)); + op_names.push_back(builtin_name("fp.isZero", OP_FPA_IS_ZERO)); + op_names.push_back(builtin_name("fp.isInfinite", OP_FPA_IS_INF)); + op_names.push_back(builtin_name("fp.isNaN", OP_FPA_IS_NAN)); + op_names.push_back(builtin_name("fp.isNegative", OP_FPA_IS_NEGATIVE)); + op_names.push_back(builtin_name("fp.isPositive", OP_FPA_IS_POSITIVE)); - op_names.push_back(builtin_name("fp", OP_FLOAT_FP)); - op_names.push_back(builtin_name("fp.to_ubv", OP_FLOAT_TO_UBV)); - op_names.push_back(builtin_name("fp.to_sbv", OP_FLOAT_TO_SBV)); - op_names.push_back(builtin_name("fp.to_real", OP_FLOAT_TO_REAL)); + op_names.push_back(builtin_name("fp", OP_FPA_FP)); + op_names.push_back(builtin_name("fp.to_ubv", OP_FPA_TO_UBV)); + op_names.push_back(builtin_name("fp.to_sbv", OP_FPA_TO_SBV)); + op_names.push_back(builtin_name("fp.to_real", OP_FPA_TO_REAL)); - op_names.push_back(builtin_name("to_fp", OP_FLOAT_TO_FP)); - op_names.push_back(builtin_name("to_fp_unsigned", OP_FLOAT_TO_FP_UNSIGNED)); + op_names.push_back(builtin_name("to_fp", OP_FPA_TO_FP)); + op_names.push_back(builtin_name("to_fp_unsigned", OP_FPA_TO_FP_UNSIGNED)); /* Extensions */ - op_names.push_back(builtin_name("to_ieee_bv", OP_FLOAT_TO_IEEE_BV)); + op_names.push_back(builtin_name("to_ieee_bv", OP_FPA_TO_IEEE_BV)); } -void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { - sort_names.push_back(builtin_name("FloatingPoint", FLOAT_SORT)); +void fpa_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { + sort_names.push_back(builtin_name("FloatingPoint", FLOATING_POINT_SORT)); sort_names.push_back(builtin_name("RoundingMode", ROUNDING_MODE_SORT)); // The final theory supports three common FloatingPoint sorts @@ -846,8 +846,8 @@ void float_decl_plugin::get_sort_names(svector & sort_names, symbo sort_names.push_back(builtin_name("Float128", FLOAT128_SORT)); } -expr * float_decl_plugin::get_some_value(sort * s) { - SASSERT(s->is_sort_of(m_family_id, FLOAT_SORT)); +expr * fpa_decl_plugin::get_some_value(sort * s) { + SASSERT(s->is_sort_of(m_family_id, FLOATING_POINT_SORT)); mpf tmp; m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp); expr * res = this->mk_value(tmp); @@ -855,23 +855,23 @@ expr * float_decl_plugin::get_some_value(sort * s) { return res; } -bool float_decl_plugin::is_value(app * e) const { +bool fpa_decl_plugin::is_value(app * e) const { if (e->get_family_id() != m_family_id) return false; switch (e->get_decl_kind()) { - case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: - case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: - case OP_FLOAT_RM_TOWARD_POSITIVE: - case OP_FLOAT_RM_TOWARD_NEGATIVE: - case OP_FLOAT_RM_TOWARD_ZERO: - case OP_FLOAT_VALUE: - case OP_FLOAT_PLUS_INF: - case OP_FLOAT_MINUS_INF: - case OP_FLOAT_PLUS_ZERO: - case OP_FLOAT_MINUS_ZERO: - case OP_FLOAT_NAN: + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: + case OP_FPA_RM_TOWARD_POSITIVE: + case OP_FPA_RM_TOWARD_NEGATIVE: + case OP_FPA_RM_TOWARD_ZERO: + case OP_FPA_VALUE: + case OP_FPA_PLUS_INF: + case OP_FPA_MINUS_INF: + case OP_FPA_PLUS_ZERO: + case OP_FPA_MINUS_ZERO: + case OP_FPA_NAN: return true; - case OP_FLOAT_FP: + case OP_FPA_FP: return m_manager->is_value(e->get_arg(0)) && m_manager->is_value(e->get_arg(1)) && m_manager->is_value(e->get_arg(2)); @@ -880,24 +880,24 @@ bool float_decl_plugin::is_value(app * e) const { } } -bool float_decl_plugin::is_unique_value(app* e) const { +bool fpa_decl_plugin::is_unique_value(app* e) const { if (e->get_family_id() != m_family_id) return false; switch (e->get_decl_kind()) { - case OP_FLOAT_RM_NEAREST_TIES_TO_EVEN: - case OP_FLOAT_RM_NEAREST_TIES_TO_AWAY: - case OP_FLOAT_RM_TOWARD_POSITIVE: - case OP_FLOAT_RM_TOWARD_NEGATIVE: - case OP_FLOAT_RM_TOWARD_ZERO: + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: + case OP_FPA_RM_TOWARD_POSITIVE: + case OP_FPA_RM_TOWARD_NEGATIVE: + case OP_FPA_RM_TOWARD_ZERO: return true; - case OP_FLOAT_PLUS_INF: /* No; +oo == fp(#b0 #b11 #b00) */ - case OP_FLOAT_MINUS_INF: /* No; -oo == fp #b1 #b11 #b00) */ - case OP_FLOAT_PLUS_ZERO: /* No; +zero == fp #b0 #b00 #b000) */ - case OP_FLOAT_MINUS_ZERO: /* No; -zero == fp #b1 #b00 #b000) */ - case OP_FLOAT_NAN: /* No; NaN == (fp #b0 #b111111 #b0000001) */ - case OP_FLOAT_VALUE: /* see NaN */ + case OP_FPA_PLUS_INF: /* No; +oo == fp(#b0 #b11 #b00) */ + case OP_FPA_MINUS_INF: /* No; -oo == fp #b1 #b11 #b00) */ + case OP_FPA_PLUS_ZERO: /* No; +zero == fp #b0 #b00 #b000) */ + case OP_FPA_MINUS_ZERO: /* No; -zero == fp #b1 #b00 #b000) */ + case OP_FPA_NAN: /* No; NaN == (fp #b0 #b111111 #b0000001) */ + case OP_FPA_VALUE: /* see NaN */ return false; - case OP_FLOAT_FP: + case OP_FPA_FP: return m_manager->is_unique_value(e->get_arg(0)) && m_manager->is_unique_value(e->get_arg(1)) && m_manager->is_unique_value(e->get_arg(2)); @@ -908,10 +908,10 @@ bool float_decl_plugin::is_unique_value(app* e) const { float_util::float_util(ast_manager & m): m_manager(m), - m_fid(m.mk_family_id("float")), + m_fid(m.mk_family_id("fpa")), m_a_util(m), m_bv_util(m) { - m_plugin = static_cast(m.get_plugin(m_fid)); + m_plugin = static_cast(m.get_plugin(m_fid)); } float_util::~float_util() { @@ -919,7 +919,7 @@ float_util::~float_util() { sort * float_util::mk_float_sort(unsigned ebits, unsigned sbits) { parameter ps[2] = { parameter(ebits), parameter(sbits) }; - return m().mk_sort(m_fid, FLOAT_SORT, 2, ps); + return m().mk_sort(m_fid, FLOATING_POINT_SORT, 2, ps); } unsigned float_util::get_ebits(sort * s) { @@ -965,16 +965,16 @@ app * float_util::mk_nzero(unsigned ebits, unsigned sbits) { app * float_util::mk_internal_to_ubv_unspecified(unsigned width) { parameter ps[] = { parameter(width) }; sort * range = m_bv_util.mk_sort(width); - return m().mk_app(get_family_id(), OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED, 1, ps, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, 1, ps, 0, 0, range); } app * float_util::mk_internal_to_sbv_unspecified(unsigned width) { parameter ps[] = { parameter(width) }; sort * range = m_bv_util.mk_sort(width); - return m().mk_app(get_family_id(), OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED, 1, ps, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED, 1, ps, 0, 0, range); } app * float_util::mk_internal_to_real_unspecified() { sort * range = m_a_util.mk_real(); - return m().mk_app(get_family_id(), OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED, 0, 0, 0, 0, range); + return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED, 0, 0, 0, 0, range); } \ No newline at end of file diff --git a/src/ast/float_decl_plugin.h b/src/ast/fpa_decl_plugin.h similarity index 77% rename from src/ast/float_decl_plugin.h rename to src/ast/fpa_decl_plugin.h index cbcd706cd..b7d59a6af 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -3,7 +3,7 @@ Copyright (c) 2012 Microsoft Corporation Module Name: - float_decl_plugin.h + fpa_decl_plugin.h Abstract: @@ -16,8 +16,8 @@ Author: Revision History: --*/ -#ifndef _FLOAT_DECL_PLUGIN_H_ -#define _FLOAT_DECL_PLUGIN_H_ +#ifndef _fpa_decl_plugin_H_ +#define _fpa_decl_plugin_H_ #include"ast.h" #include"id_gen.h" @@ -25,8 +25,8 @@ Revision History: #include"bv_decl_plugin.h" #include"mpf.h" -enum float_sort_kind { - FLOAT_SORT, +enum fpa_sort_kind { + FLOATING_POINT_SORT, ROUNDING_MODE_SORT, FLOAT16_SORT, FLOAT32_SORT, @@ -34,69 +34,69 @@ enum float_sort_kind { FLOAT128_SORT }; -enum float_op_kind { - OP_FLOAT_RM_NEAREST_TIES_TO_EVEN, - OP_FLOAT_RM_NEAREST_TIES_TO_AWAY, - OP_FLOAT_RM_TOWARD_POSITIVE, - OP_FLOAT_RM_TOWARD_NEGATIVE, - OP_FLOAT_RM_TOWARD_ZERO, +enum fpa_op_kind { + OP_FPA_RM_NEAREST_TIES_TO_EVEN, + OP_FPA_RM_NEAREST_TIES_TO_AWAY, + OP_FPA_RM_TOWARD_POSITIVE, + OP_FPA_RM_TOWARD_NEGATIVE, + OP_FPA_RM_TOWARD_ZERO, - OP_FLOAT_VALUE, - OP_FLOAT_PLUS_INF, - OP_FLOAT_MINUS_INF, - OP_FLOAT_NAN, - OP_FLOAT_PLUS_ZERO, - OP_FLOAT_MINUS_ZERO, + OP_FPA_VALUE, + OP_FPA_PLUS_INF, + OP_FPA_MINUS_INF, + OP_FPA_NAN, + OP_FPA_PLUS_ZERO, + OP_FPA_MINUS_ZERO, - OP_FLOAT_ADD, - OP_FLOAT_SUB, - OP_FLOAT_NEG, - OP_FLOAT_MUL, - OP_FLOAT_DIV, - OP_FLOAT_REM, - OP_FLOAT_ABS, - OP_FLOAT_MIN, - OP_FLOAT_MAX, - OP_FLOAT_FMA, // x*y + z - OP_FLOAT_SQRT, - OP_FLOAT_ROUND_TO_INTEGRAL, + OP_FPA_ADD, + OP_FPA_SUB, + OP_FPA_NEG, + OP_FPA_MUL, + OP_FPA_DIV, + OP_FPA_REM, + OP_FPA_ABS, + OP_FPA_MIN, + OP_FPA_MAX, + OP_FPA_FMA, // x*y + z + OP_FPA_SQRT, + OP_FPA_ROUND_TO_INTEGRAL, - OP_FLOAT_EQ, - OP_FLOAT_LT, - OP_FLOAT_GT, - OP_FLOAT_LE, - OP_FLOAT_GE, - OP_FLOAT_IS_NAN, - OP_FLOAT_IS_INF, - OP_FLOAT_IS_ZERO, - OP_FLOAT_IS_NORMAL, - OP_FLOAT_IS_SUBNORMAL, - OP_FLOAT_IS_PZERO, - OP_FLOAT_IS_NZERO, - OP_FLOAT_IS_NEGATIVE, - OP_FLOAT_IS_POSITIVE, + OP_FPA_EQ, + OP_FPA_LT, + OP_FPA_GT, + OP_FPA_LE, + OP_FPA_GE, + OP_FPA_IS_NAN, + OP_FPA_IS_INF, + OP_FPA_IS_ZERO, + OP_FPA_IS_NORMAL, + OP_FPA_IS_SUBNORMAL, + OP_FPA_IS_PZERO, + OP_FPA_IS_NZERO, + OP_FPA_IS_NEGATIVE, + OP_FPA_IS_POSITIVE, - OP_FLOAT_FP, - OP_FLOAT_TO_FP, - OP_FLOAT_TO_FP_UNSIGNED, - OP_FLOAT_TO_UBV, - OP_FLOAT_TO_SBV, - OP_FLOAT_TO_REAL, + OP_FPA_FP, + OP_FPA_TO_FP, + OP_FPA_TO_FP_UNSIGNED, + OP_FPA_TO_UBV, + OP_FPA_TO_SBV, + OP_FPA_TO_REAL, /* Extensions */ - OP_FLOAT_TO_IEEE_BV, + OP_FPA_TO_IEEE_BV, /* Internal use only */ - OP_FLOAT_INTERNAL_BVWRAP, - OP_FLOAT_INTERNAL_BVUNWRAP, - OP_FLOAT_INTERNAL_TO_UBV_UNSPECIFIED, - OP_FLOAT_INTERNAL_TO_SBV_UNSPECIFIED, - OP_FLOAT_INTERNAL_TO_REAL_UNSPECIFIED, + OP_FPA_INTERNAL_BVWRAP, + OP_FPA_INTERNAL_BVUNWRAP, + OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, + OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED, + OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED, LAST_FLOAT_OP }; -class float_decl_plugin : public decl_plugin { +class fpa_decl_plugin : public decl_plugin { struct mpf_hash_proc { scoped_mpf_vector const & m_values; mpf_hash_proc(scoped_mpf_vector const & values):m_values(values) {} @@ -172,12 +172,12 @@ class float_decl_plugin : public decl_plugin { unsigned mk_id(mpf const & v); void recycled_id(unsigned id); public: - float_decl_plugin(); + fpa_decl_plugin(); - bool is_float_sort(sort * s) const { return is_sort_of(s, m_family_id, FLOAT_SORT); } + bool is_float_sort(sort * s) const { return is_sort_of(s, m_family_id, FLOATING_POINT_SORT); } bool is_rm_sort(sort * s) const { return is_sort_of(s, m_family_id, ROUNDING_MODE_SORT); } - virtual ~float_decl_plugin(); + virtual ~fpa_decl_plugin(); virtual void finalize(); virtual decl_plugin * mk_fresh(); @@ -193,7 +193,7 @@ public: mpf_manager & fm() { return m_fm; } func_decl * mk_value_decl(mpf const & v); app * mk_value(mpf const & v); - bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FLOAT_VALUE); } + bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FPA_VALUE); } bool is_value(expr * n, mpf & val); bool is_rm_value(expr * n, mpf_rounding_mode & val); bool is_rm_value(expr * n) { mpf_rounding_mode t; return is_rm_value(n, t); } @@ -209,7 +209,7 @@ public: class float_util { ast_manager & m_manager; - float_decl_plugin * m_plugin; + fpa_decl_plugin * m_plugin; family_id m_fid; arith_util m_a_util; bv_util m_bv_util; @@ -222,22 +222,22 @@ public: family_id get_fid() const { return m_fid; } family_id get_family_id() const { return m_fid; } arith_util & au() { return m_a_util; } - float_decl_plugin & plugin() { return *m_plugin; } + fpa_decl_plugin & plugin() { return *m_plugin; } sort * mk_float_sort(unsigned ebits, unsigned sbits); sort * mk_rm_sort() { return m().mk_sort(m_fid, ROUNDING_MODE_SORT); } - bool is_float(sort * s) { return is_sort_of(s, m_fid, FLOAT_SORT); } + bool is_float(sort * s) { return is_sort_of(s, m_fid, FLOATING_POINT_SORT); } bool is_rm(sort * s) { return is_sort_of(s, m_fid, ROUNDING_MODE_SORT); } bool is_float(expr * e) { return is_float(m_manager.get_sort(e)); } bool is_rm(expr * e) { return is_rm(m_manager.get_sort(e)); } unsigned get_ebits(sort * s); unsigned get_sbits(sort * s); - app * mk_round_nearest_ties_to_even() { return m().mk_const(m_fid, OP_FLOAT_RM_NEAREST_TIES_TO_EVEN); } - app * mk_round_nearest_ties_to_away() { return m().mk_const(m_fid, OP_FLOAT_RM_NEAREST_TIES_TO_AWAY); } - app * mk_round_toward_positive() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_POSITIVE); } - app * mk_round_toward_negative() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_NEGATIVE); } - app * mk_round_toward_zero() { return m().mk_const(m_fid, OP_FLOAT_RM_TOWARD_ZERO); } + app * mk_round_nearest_ties_to_even() { return m().mk_const(m_fid, OP_FPA_RM_NEAREST_TIES_TO_EVEN); } + app * mk_round_nearest_ties_to_away() { return m().mk_const(m_fid, OP_FPA_RM_NEAREST_TIES_TO_AWAY); } + app * mk_round_toward_positive() { return m().mk_const(m_fid, OP_FPA_RM_TOWARD_POSITIVE); } + app * mk_round_toward_negative() { return m().mk_const(m_fid, OP_FPA_RM_TOWARD_NEGATIVE); } + app * mk_round_toward_zero() { return m().mk_const(m_fid, OP_FPA_RM_TOWARD_ZERO); } app * mk_nan(unsigned ebits, unsigned sbits); app * mk_pinf(unsigned ebits, unsigned sbits); @@ -264,83 +264,83 @@ public: bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } - app * mk_fp(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_FP, arg1, arg2, arg3); } + app * mk_fp(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FPA_FP, arg1, arg2, arg3); } app * mk_to_fp(sort * s, expr * bv_t) { SASSERT(is_float(s) && s->get_num_parameters() == 2); - return m().mk_app(m_fid, OP_FLOAT_TO_FP, 2, s->get_parameters(), 1, &bv_t); + return m().mk_app(m_fid, OP_FPA_TO_FP, 2, s->get_parameters(), 1, &bv_t); } app * mk_to_fp(sort * s, expr * rm, expr * t) { SASSERT(is_float(s) && s->get_num_parameters() == 2); expr * args[] = { rm, t }; - return m().mk_app(m_fid, OP_FLOAT_TO_FP, 2, s->get_parameters(), 2, args); + return m().mk_app(m_fid, OP_FPA_TO_FP, 2, s->get_parameters(), 2, args); } app * mk_to_fp(sort * s, expr * rm, expr * sig, expr * exp) { SASSERT(is_float(s) && s->get_num_parameters() == 2); expr * args[] = { rm, sig, exp }; - return m().mk_app(m_fid, OP_FLOAT_TO_FP, 2, s->get_parameters(), 3, args); + return m().mk_app(m_fid, OP_FPA_TO_FP, 2, s->get_parameters(), 3, args); } app * mk_to_fp_unsigned(sort * s, expr * rm, expr * t) { SASSERT(is_float(s) && s->get_num_parameters() == 2); expr * args[] = { rm, t }; - return m().mk_app(m_fid, OP_FLOAT_TO_FP_UNSIGNED, 2, s->get_parameters(), 2, args); + return m().mk_app(m_fid, OP_FPA_TO_FP_UNSIGNED, 2, s->get_parameters(), 2, args); } - bool is_to_fp(expr * n) { return is_app_of(n, m_fid, OP_FLOAT_TO_FP); } + bool is_to_fp(expr * n) { return is_app_of(n, m_fid, OP_FPA_TO_FP); } app * mk_to_ubv(expr * rm, expr * t, unsigned sz) { parameter ps[] = { parameter(sz) }; expr * args[] = { rm, t }; - return m().mk_app(m_fid, OP_FLOAT_TO_UBV, 1, ps, 2, args); } + return m().mk_app(m_fid, OP_FPA_TO_UBV, 1, ps, 2, args); } app * mk_to_sbv(expr * rm, expr * t, unsigned sz) { parameter ps[] = { parameter(sz) }; expr * args[] = { rm, t }; - return m().mk_app(m_fid, OP_FLOAT_TO_SBV, 1, ps, 2, args); + return m().mk_app(m_fid, OP_FPA_TO_SBV, 1, ps, 2, args); } - app * mk_to_real(expr * t) { return m().mk_app(m_fid, OP_FLOAT_TO_REAL, t); } + app * mk_to_real(expr * t) { return m().mk_app(m_fid, OP_FPA_TO_REAL, t); } - app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); } - app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } - app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); } - app * mk_div(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_DIV, arg1, arg2, arg3); } - app * mk_neg(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_NEG, arg1); } - app * mk_rem(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_REM, arg1, arg2); } - app * mk_max(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MAX, arg1, arg2); } - app * mk_min(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_MIN, arg1, arg2); } - app * mk_abs(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_ABS, arg1); } - app * mk_sqrt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_SQRT, arg1, arg2); } - app * mk_round_to_integral(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_ROUND_TO_INTEGRAL, arg1, arg2); } + app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FPA_ADD, arg1, arg2, arg3); } + app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FPA_MUL, arg1, arg2, arg3); } + app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FPA_SUB, arg1, arg2, arg3); } + app * mk_div(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FPA_DIV, arg1, arg2, arg3); } + app * mk_neg(expr * arg1) { return m().mk_app(m_fid, OP_FPA_NEG, arg1); } + app * mk_rem(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_REM, arg1, arg2); } + app * mk_max(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_MAX, arg1, arg2); } + app * mk_min(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_MIN, arg1, arg2); } + app * mk_abs(expr * arg1) { return m().mk_app(m_fid, OP_FPA_ABS, arg1); } + app * mk_sqrt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_SQRT, arg1, arg2); } + app * mk_round_to_integral(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_ROUND_TO_INTEGRAL, arg1, arg2); } app * mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4) { expr * args[4] = { arg1, arg2, arg3, arg4 }; - return m().mk_app(m_fid, OP_FLOAT_FMA, 4, args); + return m().mk_app(m_fid, OP_FPA_FMA, 4, args); } - app * mk_float_eq(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_EQ, arg1, arg2); } - app * mk_lt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_LT, arg1, arg2); } - app * mk_gt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_GT, arg1, arg2); } - app * mk_le(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_LE, arg1, arg2); } - app * mk_ge(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FLOAT_GE, arg1, arg2); } + app * mk_float_eq(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_EQ, arg1, arg2); } + app * mk_lt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_LT, arg1, arg2); } + app * mk_gt(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_GT, arg1, arg2); } + app * mk_le(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_LE, arg1, arg2); } + app * mk_ge(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_FPA_GE, arg1, arg2); } - app * mk_is_nan(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NAN, arg1); } - app * mk_is_inf(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_INF, arg1); } - app * mk_is_zero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_ZERO, arg1); } - app * mk_is_normal(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NORMAL, arg1); } - app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SUBNORMAL, arg1); } - app * mk_is_nzero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NZERO, arg1); } - app * mk_is_pzero(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_PZERO, arg1); } - app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); } - app * mk_is_positive(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_POSITIVE, arg1); } - app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_NEGATIVE, arg1); } + app * mk_is_nan(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NAN, arg1); } + app * mk_is_inf(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_INF, arg1); } + app * mk_is_zero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_ZERO, arg1); } + app * mk_is_normal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NORMAL, arg1); } + app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_SUBNORMAL, arg1); } + app * mk_is_nzero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NZERO, arg1); } + app * mk_is_pzero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_PZERO, arg1); } + app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NEGATIVE, arg1); } + app * mk_is_positive(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_POSITIVE, arg1); } + app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NEGATIVE, arg1); } - bool is_neg(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_NEG); } + bool is_neg(expr * a) { return is_app_of(a, m_fid, OP_FPA_NEG); } - app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_TO_IEEE_BV, arg1); } + app * mk_float_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_FPA_TO_IEEE_BV, arg1); } app * mk_internal_to_ubv_unspecified(unsigned width); app * mk_internal_to_sbv_unspecified(unsigned width); app * mk_internal_to_real_unspecified(); - bool is_wrap(expr * e) const { return is_app_of(e, get_family_id(), OP_FLOAT_INTERNAL_BVWRAP); } - bool is_unwrap(expr * e) const { return is_app_of(e, get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP); } + bool is_wrap(expr * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_BVWRAP); } + bool is_unwrap(expr * e) const { return is_app_of(e, get_family_id(), OP_FPA_INTERNAL_BVUNWRAP); } }; #endif diff --git a/src/ast/reg_decl_plugins.cpp b/src/ast/reg_decl_plugins.cpp index ab1844e07..f46dd76d4 100644 --- a/src/ast/reg_decl_plugins.cpp +++ b/src/ast/reg_decl_plugins.cpp @@ -24,7 +24,7 @@ Revision History: #include"datatype_decl_plugin.h" #include"dl_decl_plugin.h" #include"seq_decl_plugin.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" void reg_decl_plugins(ast_manager & m) { if (!m.get_plugin(m.mk_family_id(symbol("arith")))) { @@ -45,7 +45,7 @@ void reg_decl_plugins(ast_manager & m) { if (!m.get_plugin(m.mk_family_id(symbol("seq")))) { m.register_plugin(symbol("seq"), alloc(seq_decl_plugin)); } - if (!m.get_plugin(m.mk_family_id(symbol("float")))) { - m.register_plugin(symbol("float"), alloc(float_decl_plugin)); + if (!m.get_plugin(m.mk_family_id(symbol("fpa")))) { + m.register_plugin(symbol("fpa"), alloc(fpa_decl_plugin)); } } diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp similarity index 69% rename from src/ast/rewriter/float_rewriter.cpp rename to src/ast/rewriter/fpa_rewriter.cpp index 96561395e..2977b7ab2 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -3,7 +3,7 @@ Copyright (c) 2012 Microsoft Corporation Module Name: - float_rewriter.cpp + fpa_rewriter.cpp Abstract: @@ -16,65 +16,65 @@ Author: Notes: --*/ -#include"float_rewriter.h" +#include"fpa_rewriter.h" -float_rewriter::float_rewriter(ast_manager & m, params_ref const & p): +fpa_rewriter::fpa_rewriter(ast_manager & m, params_ref const & p): m_util(m) { updt_params(p); } -float_rewriter::~float_rewriter() { +fpa_rewriter::~fpa_rewriter() { } -void float_rewriter::updt_params(params_ref const & p) { +void fpa_rewriter::updt_params(params_ref const & p) { } -void float_rewriter::get_param_descrs(param_descrs & r) { +void fpa_rewriter::get_param_descrs(param_descrs & r) { } -br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { +br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { br_status st = BR_FAILED; SASSERT(f->get_family_id() == get_fid()); switch (f->get_decl_kind()) { - case OP_FLOAT_TO_FP: st = mk_to_fp(f, num_args, args, result); break; - case OP_FLOAT_TO_FP_UNSIGNED: st = mk_to_fp_unsigned(f, num_args, args, result); break; - case OP_FLOAT_ADD: SASSERT(num_args == 3); st = mk_add(args[0], args[1], args[2], result); break; - case OP_FLOAT_SUB: SASSERT(num_args == 3); st = mk_sub(args[0], args[1], args[2], result); break; - case OP_FLOAT_NEG: SASSERT(num_args == 1); st = mk_neg(args[0], result); break; - case OP_FLOAT_MUL: SASSERT(num_args == 3); st = mk_mul(args[0], args[1], args[2], result); break; - case OP_FLOAT_DIV: SASSERT(num_args == 3); st = mk_div(args[0], args[1], args[2], result); break; - case OP_FLOAT_REM: SASSERT(num_args == 2); st = mk_rem(args[0], args[1], result); break; - case OP_FLOAT_ABS: SASSERT(num_args == 1); st = mk_abs(args[0], result); break; - case OP_FLOAT_MIN: SASSERT(num_args == 2); st = mk_min(args[0], args[1], result); break; - case OP_FLOAT_MAX: SASSERT(num_args == 2); st = mk_max(args[0], args[1], result); break; - case OP_FLOAT_FMA: SASSERT(num_args == 4); st = mk_fma(args[0], args[1], args[2], args[3], result); break; - case OP_FLOAT_SQRT: SASSERT(num_args == 2); st = mk_sqrt(args[0], args[1], result); break; - case OP_FLOAT_ROUND_TO_INTEGRAL: SASSERT(num_args == 2); st = mk_round(args[0], args[1], result); break; + case OP_FPA_TO_FP: st = mk_to_fp(f, num_args, args, result); break; + case OP_FPA_TO_FP_UNSIGNED: st = mk_to_fp_unsigned(f, num_args, args, result); break; + case OP_FPA_ADD: SASSERT(num_args == 3); st = mk_add(args[0], args[1], args[2], result); break; + case OP_FPA_SUB: SASSERT(num_args == 3); st = mk_sub(args[0], args[1], args[2], result); break; + case OP_FPA_NEG: SASSERT(num_args == 1); st = mk_neg(args[0], result); break; + case OP_FPA_MUL: SASSERT(num_args == 3); st = mk_mul(args[0], args[1], args[2], result); break; + case OP_FPA_DIV: SASSERT(num_args == 3); st = mk_div(args[0], args[1], args[2], result); break; + case OP_FPA_REM: SASSERT(num_args == 2); st = mk_rem(args[0], args[1], result); break; + case OP_FPA_ABS: SASSERT(num_args == 1); st = mk_abs(args[0], result); break; + case OP_FPA_MIN: SASSERT(num_args == 2); st = mk_min(args[0], args[1], result); break; + case OP_FPA_MAX: SASSERT(num_args == 2); st = mk_max(args[0], args[1], result); break; + case OP_FPA_FMA: SASSERT(num_args == 4); st = mk_fma(args[0], args[1], args[2], args[3], result); break; + case OP_FPA_SQRT: SASSERT(num_args == 2); st = mk_sqrt(args[0], args[1], result); break; + case OP_FPA_ROUND_TO_INTEGRAL: SASSERT(num_args == 2); st = mk_round(args[0], args[1], result); break; - case OP_FLOAT_EQ: SASSERT(num_args == 2); st = mk_float_eq(args[0], args[1], result); break; - case OP_FLOAT_LT: SASSERT(num_args == 2); st = mk_lt(args[0], args[1], result); break; - case OP_FLOAT_GT: SASSERT(num_args == 2); st = mk_gt(args[0], args[1], result); break; - case OP_FLOAT_LE: SASSERT(num_args == 2); st = mk_le(args[0], args[1], result); break; - case OP_FLOAT_GE: SASSERT(num_args == 2); st = mk_ge(args[0], args[1], result); break; - case OP_FLOAT_IS_ZERO: SASSERT(num_args == 1); st = mk_is_zero(args[0], result); break; - case OP_FLOAT_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break; - case OP_FLOAT_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break; - case OP_FLOAT_IS_NAN: SASSERT(num_args == 1); st = mk_is_nan(args[0], result); break; - case OP_FLOAT_IS_INF: SASSERT(num_args == 1); st = mk_is_inf(args[0], result); break; - case OP_FLOAT_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break; - case OP_FLOAT_IS_SUBNORMAL: SASSERT(num_args == 1); st = mk_is_subnormal(args[0], result); break; - case OP_FLOAT_IS_NEGATIVE: SASSERT(num_args == 1); st = mk_is_negative(args[0], result); break; - case OP_FLOAT_IS_POSITIVE: SASSERT(num_args == 1); st = mk_is_positive(args[0], result); break; - case OP_FLOAT_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break; - case OP_FLOAT_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(args[0], args[1], result); break; - case OP_FLOAT_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(args[0], args[1], result); break; - case OP_FLOAT_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; - case OP_FLOAT_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; + case OP_FPA_EQ: SASSERT(num_args == 2); st = mk_float_eq(args[0], args[1], result); break; + case OP_FPA_LT: SASSERT(num_args == 2); st = mk_lt(args[0], args[1], result); break; + case OP_FPA_GT: SASSERT(num_args == 2); st = mk_gt(args[0], args[1], result); break; + case OP_FPA_LE: SASSERT(num_args == 2); st = mk_le(args[0], args[1], result); break; + case OP_FPA_GE: SASSERT(num_args == 2); st = mk_ge(args[0], args[1], result); break; + case OP_FPA_IS_ZERO: SASSERT(num_args == 1); st = mk_is_zero(args[0], result); break; + case OP_FPA_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break; + case OP_FPA_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break; + case OP_FPA_IS_NAN: SASSERT(num_args == 1); st = mk_is_nan(args[0], result); break; + case OP_FPA_IS_INF: SASSERT(num_args == 1); st = mk_is_inf(args[0], result); break; + case OP_FPA_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break; + case OP_FPA_IS_SUBNORMAL: SASSERT(num_args == 1); st = mk_is_subnormal(args[0], result); break; + case OP_FPA_IS_NEGATIVE: SASSERT(num_args == 1); st = mk_is_negative(args[0], result); break; + case OP_FPA_IS_POSITIVE: SASSERT(num_args == 1); st = mk_is_positive(args[0], result); break; + case OP_FPA_FP: SASSERT(num_args == 3); st = mk_fp(args[0], args[1], args[2], result); break; + case OP_FPA_TO_UBV: SASSERT(num_args == 2); st = mk_to_ubv(args[0], args[1], result); break; + case OP_FPA_TO_SBV: SASSERT(num_args == 2); st = mk_to_sbv(args[0], args[1], result); break; + case OP_FPA_TO_REAL: SASSERT(num_args == 1); st = mk_to_real(args[0], result); break; + case OP_FPA_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; } return st; } -br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { +br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); SASSERT(f->get_parameter(1).is_int()); @@ -159,7 +159,7 @@ br_status float_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * cons return BR_FAILED; } -br_status float_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { +br_status fpa_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); SASSERT(f->get_parameter(1).is_int()); @@ -169,7 +169,7 @@ br_status float_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, ex return BR_FAILED; } -br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { +br_status fpa_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()); @@ -184,13 +184,13 @@ br_status float_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref return BR_FAILED; } -br_status float_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { +br_status fpa_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { // a - b = a + (-b) result = m_util.mk_add(arg1, arg2, m_util.mk_neg(arg3)); return BR_REWRITE2; } -br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { +br_status fpa_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()); @@ -205,7 +205,7 @@ br_status float_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref return BR_FAILED; } -br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { +br_status fpa_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()); @@ -220,7 +220,7 @@ br_status float_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref return BR_FAILED; } -br_status float_rewriter::mk_neg(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_neg(expr * arg1, expr_ref & result) { if (m_util.is_nan(arg1)) { // -nan --> nan result = arg1; @@ -253,7 +253,7 @@ br_status float_rewriter::mk_neg(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_rem(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_rem(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { scoped_mpf t(m_util.fm()); @@ -265,7 +265,7 @@ br_status float_rewriter::mk_rem(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_abs(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_abs(expr * arg1, expr_ref & result) { if (m_util.is_nan(arg1)) { result = arg1; return BR_DONE; @@ -276,7 +276,7 @@ br_status float_rewriter::mk_abs(expr * arg1, expr_ref & result) { return BR_REWRITE2; } -br_status float_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { if (m_util.is_nan(arg1)) { result = arg2; return BR_DONE; @@ -296,7 +296,7 @@ br_status float_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { return BR_REWRITE_FULL; } -br_status float_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { if (m_util.is_nan(arg1)) { result = arg2; return BR_DONE; @@ -316,7 +316,7 @@ br_status float_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { return BR_REWRITE_FULL; } -br_status float_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { +br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm()); @@ -331,7 +331,7 @@ br_status float_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * a return BR_FAILED; } -br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()); @@ -346,7 +346,7 @@ br_status float_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) { mpf_rounding_mode rm; if (m_util.is_rm_value(arg1, rm)) { scoped_mpf v2(m_util.fm()); @@ -362,7 +362,7 @@ br_status float_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) } // This the floating point theory == -br_status float_rewriter::mk_float_eq(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_float_eq(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { result = (m_util.fm().eq(v1, v2)) ? m().mk_true() : m().mk_false(); @@ -373,16 +373,16 @@ br_status float_rewriter::mk_float_eq(expr * arg1, expr * arg2, expr_ref & resul } // Return (= arg NaN) -app * float_rewriter::mk_eq_nan(expr * arg) { +app * fpa_rewriter::mk_eq_nan(expr * arg) { return m().mk_eq(arg, m_util.mk_nan(m().get_sort(arg))); } // Return (not (= arg NaN)) -app * float_rewriter::mk_neq_nan(expr * arg) { +app * fpa_rewriter::mk_neq_nan(expr * arg) { return m().mk_not(mk_eq_nan(arg)); } -br_status float_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { if (m_util.is_nan(arg1) || m_util.is_nan(arg2)) { result = m().mk_false(); return BR_DONE; @@ -418,12 +418,12 @@ br_status float_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_gt(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_gt(expr * arg1, expr * arg2, expr_ref & result) { result = m_util.mk_lt(arg2, arg1); return BR_REWRITE1; } -br_status float_rewriter::mk_le(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_le(expr * arg1, expr * arg2, expr_ref & result) { if (m_util.is_nan(arg1) || m_util.is_nan(arg2)) { result = m().mk_false(); return BR_DONE; @@ -437,12 +437,12 @@ br_status float_rewriter::mk_le(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_ge(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_ge(expr * arg1, expr * arg2, expr_ref & result) { result = m_util.mk_le(arg2, arg1); return BR_REWRITE1; } -br_status float_rewriter::mk_is_zero(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_zero(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_zero(v)) ? m().mk_true() : m().mk_false(); @@ -452,7 +452,7 @@ br_status float_rewriter::mk_is_zero(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_nzero(v)) ? m().mk_true() : m().mk_false(); @@ -462,7 +462,7 @@ br_status float_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_pzero(v)) ? m().mk_true() : m().mk_false(); @@ -472,7 +472,7 @@ br_status float_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_nan(v)) ? m().mk_true() : m().mk_false(); @@ -482,7 +482,7 @@ br_status float_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_inf(v)) ? m().mk_true() : m().mk_false(); @@ -492,7 +492,7 @@ br_status float_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_normal(v)) ? m().mk_true() : m().mk_false(); @@ -502,7 +502,7 @@ br_status float_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_denormal(v)) ? m().mk_true() : m().mk_false(); @@ -512,7 +512,7 @@ br_status float_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_neg(v)) ? m().mk_true() : m().mk_false(); @@ -522,7 +522,7 @@ br_status float_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); if (m_util.is_value(arg1, v)) { result = (m_util.fm().is_neg(v) || m_util.fm().is_nan(v)) ? m().mk_false() : m().mk_true(); @@ -534,7 +534,7 @@ br_status float_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { // This the SMT = -br_status float_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { // Note: == is the floats-equality, here we need normal equality. @@ -548,11 +548,11 @@ br_status float_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result return BR_FAILED; } -br_status float_rewriter::mk_to_ieee_bv(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_to_ieee_bv(expr * arg1, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { +br_status fpa_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { bv_util bu(m()); rational r1, r2, r3; unsigned bvs1, bvs2, bvs3; @@ -575,15 +575,15 @@ br_status float_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref return BR_FAILED; } -br_status float_rewriter::mk_to_ubv(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_to_ubv(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_to_sbv(expr * arg1, expr * arg2, expr_ref & result) { +br_status fpa_rewriter::mk_to_sbv(expr * arg1, expr * arg2, expr_ref & result) { return BR_FAILED; } -br_status float_rewriter::mk_to_real(expr * arg1, expr_ref & result) { +br_status fpa_rewriter::mk_to_real(expr * arg1, expr_ref & result) { scoped_mpf fv(m_util.fm()); if (m_util.is_value(arg1, fv)) { @@ -599,4 +599,4 @@ br_status float_rewriter::mk_to_real(expr * arg1, expr_ref & result) { } return BR_FAILED; -} \ No newline at end of file +} diff --git a/src/ast/rewriter/float_rewriter.h b/src/ast/rewriter/fpa_rewriter.h similarity index 95% rename from src/ast/rewriter/float_rewriter.h rename to src/ast/rewriter/fpa_rewriter.h index 31c571f32..34a34b293 100644 --- a/src/ast/rewriter/float_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -22,10 +22,10 @@ Notes: #include"ast.h" #include"rewriter.h" #include"params.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" #include"mpf.h" -class float_rewriter { +class fpa_rewriter { float_util m_util; mpf_manager m_fm; @@ -33,8 +33,8 @@ class float_rewriter { app * mk_neq_nan(expr * arg); public: - float_rewriter(ast_manager & m, params_ref const & p = params_ref()); - ~float_rewriter(); + fpa_rewriter(ast_manager & m, params_ref const & p = params_ref()); + ~fpa_rewriter(); ast_manager & m() const { return m_util.m(); } family_id get_fid() const { return m_util.get_fid(); } diff --git a/src/ast/rewriter/mk_simplified_app.cpp b/src/ast/rewriter/mk_simplified_app.cpp index a46e71582..45245ce1b 100644 --- a/src/ast/rewriter/mk_simplified_app.cpp +++ b/src/ast/rewriter/mk_simplified_app.cpp @@ -22,7 +22,7 @@ Notes: #include"bv_rewriter.h" #include"datatype_rewriter.h" #include"array_rewriter.h" -#include"float_rewriter.h" +#include"fpa_rewriter.h" struct mk_simplified_app::imp { ast_manager & m; @@ -31,7 +31,7 @@ struct mk_simplified_app::imp { bv_rewriter m_bv_rw; array_rewriter m_ar_rw; datatype_rewriter m_dt_rw; - float_rewriter m_f_rw; + fpa_rewriter m_f_rw; imp(ast_manager & _m, params_ref const & p): m(_m), diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index 0e2c8e781..f35c3b134 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -23,7 +23,7 @@ Notes: #include"bv_rewriter.h" #include"datatype_rewriter.h" #include"array_rewriter.h" -#include"float_rewriter.h" +#include"fpa_rewriter.h" #include"dl_rewriter.h" #include"rewriter_def.h" #include"expr_substitution.h" @@ -39,7 +39,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg { bv_rewriter m_bv_rw; array_rewriter m_ar_rw; datatype_rewriter m_dt_rw; - float_rewriter m_f_rw; + fpa_rewriter m_f_rw; dl_rewriter m_dl_rw; arith_util m_a_util; bv_util m_bv_util; diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index 4dd0cc614..d5ee9ff88 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -24,7 +24,7 @@ Notes: #include"array_decl_plugin.h" #include"datatype_decl_plugin.h" #include"seq_decl_plugin.h" -#include"float_decl_plugin.h" +#include"fpa_decl_plugin.h" #include"ast_pp.h" #include"var_subst.h" #include"pp.h" @@ -556,7 +556,7 @@ bool cmd_context::logic_has_seq() const { return !has_logic() || logic_has_seq_core(m_logic); } -bool cmd_context::logic_has_floats() const { +bool cmd_context::logic_has_fpa() const { return !has_logic() || m_logic == "QF_FP" || m_logic == "QF_FPBV"; } @@ -601,7 +601,7 @@ void cmd_context::init_manager_core(bool new_manager) { register_plugin(symbol("array"), alloc(array_decl_plugin), logic_has_array()); register_plugin(symbol("datatype"), alloc(datatype_decl_plugin), logic_has_datatype()); register_plugin(symbol("seq"), alloc(seq_decl_plugin), logic_has_seq()); - register_plugin(symbol("float"), alloc(float_decl_plugin), logic_has_floats()); + register_plugin(symbol("fpa"), alloc(fpa_decl_plugin), logic_has_fpa()); } else { // the manager was created by an external module @@ -614,7 +614,7 @@ void cmd_context::init_manager_core(bool new_manager) { load_plugin(symbol("array"), logic_has_array(), fids); load_plugin(symbol("datatype"), logic_has_datatype(), fids); load_plugin(symbol("seq"), logic_has_seq(), fids); - load_plugin(symbol("float"), logic_has_floats(), fids); + load_plugin(symbol("fpa"), logic_has_fpa(), fids); svector::iterator it = fids.begin(); svector::iterator end = fids.end(); diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index 1c8dba21a..f9e50e611 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -241,7 +241,7 @@ protected: bool logic_has_seq() const; bool logic_has_array() const; bool logic_has_datatype() const; - bool logic_has_floats() const; + bool logic_has_fpa() const; bool supported_logic(symbol const & s) const; void print_unsupported_msg() { regular_stream() << "unsupported" << std::endl; } diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index 41bca940d..02c43eaad 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -25,7 +25,7 @@ Revision History: #include"bv_rewriter.h" #include"datatype_rewriter.h" #include"array_rewriter.h" -#include"float_rewriter.h" +#include"fpa_rewriter.h" #include"rewriter_def.h" #include"cooperate.h" @@ -36,7 +36,7 @@ struct evaluator_cfg : public default_rewriter_cfg { bv_rewriter m_bv_rw; array_rewriter m_ar_rw; datatype_rewriter m_dt_rw; - float_rewriter m_f_rw; + fpa_rewriter m_f_rw; unsigned long long m_max_memory; unsigned m_max_steps; bool m_model_completion; diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index bec9cf235..7c4fce5cd 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -82,7 +82,7 @@ namespace smt { } theory_fpa::theory_fpa(ast_manager & m) : - theory(m.mk_family_id("float")), + theory(m.mk_family_id("fpa")), m_converter(m, this), m_rw(m, m_converter, params_ref()), m_th_rw(m), @@ -91,6 +91,9 @@ namespace smt { m_bv_util(m_converter.bu()), m_arith_util(m_converter.au()) { + params_ref p; + p.set_bool("arith_lhs", true); + m_th_rw.updt_params(p); } theory_fpa::~theory_fpa() @@ -207,7 +210,7 @@ namespace smt { bv_srt = m_bv_util.mk_sort(ebits + sbits); } - w = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVWRAP, 0, 0, 1, &e_srt, bv_srt); + w = m.mk_func_decl(get_family_id(), OP_FPA_INTERNAL_BVWRAP, 0, 0, 1, &e_srt, bv_srt); m_wraps.insert(e_srt, w); m.inc_ref(w); } @@ -226,7 +229,7 @@ namespace smt { if (!m_unwraps.find(e_srt, u)) { SASSERT(!m_unwraps.contains(e_srt)); sort * bv_srt = m.get_sort(e); - u = m.mk_func_decl(get_family_id(), OP_FLOAT_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); + u = m.mk_func_decl(get_family_id(), OP_FPA_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); m_unwraps.insert(s, u); m.inc_ref(u); } @@ -268,10 +271,10 @@ namespace smt { } else if (m_float_util.is_float(e)) { SASSERT(eca->get_family_id() == get_family_id()); - float_op_kind k = (float_op_kind)(eca->get_decl_kind()); - SASSERT(k == OP_FLOAT_TO_FP || k == OP_FLOAT_INTERNAL_BVUNWRAP); + fpa_op_kind k = (fpa_op_kind)(eca->get_decl_kind()); + SASSERT(k == OP_FPA_TO_FP || k == OP_FPA_INTERNAL_BVUNWRAP); switch (k) { - case OP_FLOAT_TO_FP: { + case OP_FPA_TO_FP: { SASSERT(eca->get_num_args() == 3); SASSERT(is_sort_of(m.get_sort(eca->get_arg(0)), m_bv_util.get_family_id(), BV_SORT)); SASSERT(is_sort_of(m.get_sort(eca->get_arg(1)), m_bv_util.get_family_id(), BV_SORT)); @@ -388,6 +391,8 @@ namespace smt { res = m.mk_and(res, t); } m_converter.m_extra_assertions.reset(); + + m_th_rw(res); CTRACE("t_fpa", !m.is_true(res), tout << "side condition: " << mk_ismt2_pp(res, m) << "\n";); return res; @@ -460,11 +465,11 @@ namespace smt { // The corresponding constraints will not be translated and added // via convert(...) and assert_cnstr(...) in initialize_atom(...). // Therefore, we translate and assert them here. - float_op_kind k = (float_op_kind)term->get_decl_kind(); + fpa_op_kind k = (fpa_op_kind)term->get_decl_kind(); switch (k) { - case OP_FLOAT_TO_UBV: - case OP_FLOAT_TO_SBV: - case OP_FLOAT_TO_REAL: { + case OP_FPA_TO_UBV: + case OP_FPA_TO_SBV: + case OP_FPA_TO_REAL: { expr_ref conv(m); conv = convert(term); assert_cnstr(m.mk_eq(term, conv)); @@ -546,7 +551,7 @@ namespace smt { c = m.mk_and(m.mk_eq(x_sgn, y_sgn), m.mk_eq(x_sig, y_sig), - m.mk_eq(x_exp, y_exp)); + m.mk_eq(x_exp, y_exp)); } else c = m.mk_eq(xc, yc); diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 989ad64ff..78ba64111 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -116,7 +116,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { bv_mdl->eval(a->get_arg(1), exp, true); bv_mdl->eval(a->get_arg(2), sig, true); - SASSERT(a->is_app_of(fu.get_family_id(), OP_FLOAT_TO_FP)); + SASSERT(a->is_app_of(fu.get_family_id(), OP_FPA_TO_FP)); #ifdef Z3DEBUG SASSERT(to_app(a->get_arg(0))->get_decl()->get_arity() == 0); diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffpa_tactic.cpp index 919cf0c1b..c02166c18 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffpa_tactic.cpp @@ -26,21 +26,23 @@ Notes: #include"qffpa_tactic.h" tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { - params_ref sat_simp_p = p; - sat_simp_p .set_bool("elim_and", true); + params_ref simp_p = p; + simp_p.set_bool("arith_lhs", true); + simp_p.set_bool("elim_and", true); - tactic * st = - cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), - and_then(mk_simplify_tactic(m), - mk_smt_tactic()), - and_then( - mk_simplify_tactic(m, p), - mk_fpa2bv_tactic(m, p), - using_params(mk_simplify_tactic(m, p), sat_simp_p), - mk_bit_blaster_tactic(m, p), - using_params(mk_simplify_tactic(m, p), sat_simp_p), - mk_sat_tactic(m, p), - mk_fail_if_undecided_tactic())); + tactic * st = cond( mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), + and_then(mk_simplify_tactic(m, simp_p), + mk_smt_tactic()), + and_then( + mk_simplify_tactic(m, p), + mk_fpa2bv_tactic(m, p), + using_params(mk_simplify_tactic(m, p), simp_p), + mk_bit_blaster_tactic(m, p), + using_params(mk_simplify_tactic(m, p), simp_p), + cond(mk_is_propositional_probe(), + mk_sat_tactic(m, p), + mk_smt_tactic(p)), + mk_fail_if_undecided_tactic())); st->updt_params(p); return st; @@ -70,6 +72,8 @@ struct is_non_qffp_predicate { return; if (is_uninterp_const(n)) return; + if (au.is_real(s) && au.is_numeral(n)) + return; throw found(); } diff --git a/src/tactic/fpa/qffpa_tactic.h b/src/tactic/fpa/qffpa_tactic.h index 660622fb8..3ab95798f 100644 --- a/src/tactic/fpa/qffpa_tactic.h +++ b/src/tactic/fpa/qffpa_tactic.h @@ -3,11 +3,11 @@ Copyright (c) 2012 Microsoft Corporation Module Name: - qffpa_tactic.h + qffp_tactic.h Abstract: - Tactic QF_FPA benchmarks. + Tactic for QF_FP benchmarks. Author: From 5e5758bb25e080cb45ae0bd7c6e0a3593e1f6606 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 13:37:18 +0000 Subject: [PATCH 127/507] More float -> fpa renaming Signed-off-by: Christoph M. Wintersteiger --- src/api/api_context.cpp | 2 +- src/api/api_context.h | 4 +- src/api/api_fpa.cpp | 146 +++++++++--------- src/api/api_numeral.cpp | 10 +- src/ast/ast_smt2_pp.h | 6 +- src/ast/fpa_decl_plugin.cpp | 26 ++-- src/ast/fpa_decl_plugin.h | 6 +- src/ast/rewriter/fpa_rewriter.h | 2 +- src/cmd_context/cmd_context.cpp | 4 +- src/smt/theory_fpa.cpp | 68 ++++---- src/smt/theory_fpa.h | 14 +- src/tactic/fpa/fpa2bv_model_converter.cpp | 2 +- .../fpa/{qffpa_tactic.cpp => qffp_tactic.cpp} | 8 +- .../fpa/{qffpa_tactic.h => qffp_tactic.h} | 8 +- src/tactic/portfolio/default_tactic.cpp | 2 +- src/tactic/portfolio/smt_strategic_solver.cpp | 6 +- 16 files changed, 158 insertions(+), 156 deletions(-) rename src/tactic/fpa/{qffpa_tactic.cpp => qffp_tactic.cpp} (96%) rename src/tactic/fpa/{qffpa_tactic.h => qffp_tactic.h} (82%) diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index b83b72e35..3408cdf3c 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -88,7 +88,7 @@ namespace api { m_arith_util(m()), m_bv_util(m()), m_datalog_util(m()), - m_float_util(m()), + m_fpa_util(m()), m_last_result(m()), m_ast_trail(m()), m_replay_stack() { diff --git a/src/api/api_context.h b/src/api/api_context.h index c71b88b61..6312b3f69 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -57,7 +57,7 @@ namespace api { arith_util m_arith_util; bv_util m_bv_util; datalog::dl_decl_util m_datalog_util; - float_util m_float_util; + fpa_util m_fpa_util; // Support for old solver API smt_params m_fparams; @@ -118,7 +118,7 @@ namespace api { arith_util & autil() { return m_arith_util; } bv_util & bvutil() { return m_bv_util; } datalog::dl_decl_util & datalog_util() { return m_datalog_util; } - float_util & float_util() { return m_float_util; } + fpa_util & fpa_util() { return m_fpa_util; } family_id get_basic_fid() const { return m_basic_fid; } family_id get_array_fid() const { return m_array_fid; } family_id get_arith_fid() const { return m_arith_fid; } diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 0f0f68ae1..94dfaaa68 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -29,7 +29,7 @@ extern "C" { LOG_Z3_mk_fpa_rounding_mode_sort(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_sort r = of_sort(ctx->float_util().mk_rm_sort()); + Z3_sort r = of_sort(ctx->fpa_util().mk_rm_sort()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -40,7 +40,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_even()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_even()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -50,7 +50,7 @@ extern "C" { LOG_Z3_mk_fpa_rne(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_even()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_even()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -61,7 +61,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_away(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_away()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_away()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -71,7 +71,7 @@ extern "C" { LOG_Z3_mk_fpa_rna(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_nearest_ties_to_away()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_away()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -82,7 +82,7 @@ extern "C" { LOG_Z3_mk_fpa_round_toward_positive(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_toward_positive()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_positive()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -92,7 +92,7 @@ extern "C" { LOG_Z3_mk_fpa_rtp(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_toward_positive()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_positive()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -103,7 +103,7 @@ extern "C" { LOG_Z3_mk_fpa_round_toward_negative(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_toward_negative()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_negative()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -113,7 +113,7 @@ extern "C" { LOG_Z3_mk_fpa_rtn(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_toward_negative()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_negative()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -124,7 +124,7 @@ extern "C" { LOG_Z3_mk_fpa_round_toward_zero(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_toward_zero()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_zero()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -134,7 +134,7 @@ extern "C" { LOG_Z3_mk_fpa_rtz(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_toward_zero()); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_zero()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -148,7 +148,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); } api::context * ctx = mk_c(c); - Z3_sort r = of_sort(ctx->float_util().mk_float_sort(ebits, sbits)); + Z3_sort r = of_sort(ctx->fpa_util().mk_float_sort(ebits, sbits)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -190,7 +190,7 @@ extern "C" { LOG_Z3_mk_fpa_nan(c, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_nan(to_sort(s))); + Z3_ast r = of_ast(ctx->fpa_util().mk_nan(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -200,7 +200,7 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->float_util().mk_ninf(to_sort(s)) : ctx->float_util().mk_pinf(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_ninf(to_sort(s)) : ctx->fpa_util().mk_pinf(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -210,7 +210,7 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->float_util().mk_nzero(to_sort(s)) : ctx->float_util().mk_pzero(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_nzero(to_sort(s)) : ctx->fpa_util().mk_pzero(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -220,7 +220,7 @@ extern "C" { LOG_Z3_mk_fpa_fp(c, sgn, sig, exp); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp))); + Z3_ast r = of_ast(ctx->fpa_util().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -230,9 +230,9 @@ extern "C" { LOG_Z3_mk_fpa_numeral_float(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->float_util().fm()); - ctx->float_util().fm().set(tmp, ctx->float_util().get_ebits(to_sort(ty)), ctx->float_util().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + scoped_mpf tmp(ctx->fpa_util().fm()); + ctx->fpa_util().fm().set(tmp, ctx->fpa_util().get_ebits(to_sort(ty)), ctx->fpa_util().get_sbits(to_sort(ty)), v); + Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -242,9 +242,9 @@ extern "C" { LOG_Z3_mk_fpa_numeral_double(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->float_util().fm()); - ctx->float_util().fm().set(tmp, ctx->float_util().get_ebits(to_sort(ty)), ctx->float_util().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + scoped_mpf tmp(ctx->fpa_util().fm()); + ctx->fpa_util().fm().set(tmp, ctx->fpa_util().get_ebits(to_sort(ty)), ctx->fpa_util().get_sbits(to_sort(ty)), v); + Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -254,12 +254,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_int(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->float_util().fm()); - ctx->float_util().fm().set(tmp, - ctx->float_util().get_ebits(to_sort(ty)), - ctx->float_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpa_util().fm()); + ctx->fpa_util().fm().set(tmp, + ctx->fpa_util().get_ebits(to_sort(ty)), + ctx->fpa_util().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -269,12 +269,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->float_util().fm()); - ctx->float_util().fm().set(tmp, - ctx->float_util().get_ebits(to_sort(ty)), - ctx->float_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpa_util().fm()); + ctx->fpa_util().fm().set(tmp, + ctx->fpa_util().get_ebits(to_sort(ty)), + ctx->fpa_util().get_sbits(to_sort(ty)), sgn != 0, sig, exp); - Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -284,12 +284,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->float_util().fm()); - ctx->float_util().fm().set(tmp, - ctx->float_util().get_ebits(to_sort(ty)), - ctx->float_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpa_util().fm()); + ctx->fpa_util().fm().set(tmp, + ctx->fpa_util().get_ebits(to_sort(ty)), + ctx->fpa_util().get_sbits(to_sort(ty)), sgn != 0, sig, exp); - Z3_ast r = of_ast(ctx->float_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -299,7 +299,7 @@ extern "C" { LOG_Z3_mk_fpa_abs(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_abs(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_abs(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -309,7 +309,7 @@ extern "C" { LOG_Z3_mk_fpa_neg(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_neg(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_neg(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -319,7 +319,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -329,7 +329,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -339,7 +339,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -349,7 +349,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -359,7 +359,7 @@ extern "C" { LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); + Z3_ast r = of_ast(ctx->fpa_util().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -369,7 +369,7 @@ extern "C" { LOG_Z3_mk_fpa_sqrt(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_sqrt(to_expr(rm), to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_sqrt(to_expr(rm), to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -379,7 +379,7 @@ extern "C" { LOG_Z3_mk_fpa_rem(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_rem(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_rem(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -389,7 +389,7 @@ extern "C" { LOG_Z3_mk_fpa_round_to_integral(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_round_to_integral(to_expr(rm), to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_round_to_integral(to_expr(rm), to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -399,7 +399,7 @@ extern "C" { LOG_Z3_mk_fpa_min(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_min(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_min(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -409,7 +409,7 @@ extern "C" { LOG_Z3_mk_fpa_max(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_max(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_max(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -419,7 +419,7 @@ extern "C" { LOG_Z3_mk_fpa_leq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_le(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_le(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -429,7 +429,7 @@ extern "C" { LOG_Z3_mk_fpa_lt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_lt(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_lt(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -439,7 +439,7 @@ extern "C" { LOG_Z3_mk_fpa_geq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_ge(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_ge(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -449,7 +449,7 @@ extern "C" { LOG_Z3_mk_fpa_gt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_gt(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_gt(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -459,7 +459,7 @@ extern "C" { LOG_Z3_mk_fpa_eq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_float_eq(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpa_util().mk_float_eq(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -469,7 +469,7 @@ extern "C" { LOG_Z3_mk_fpa_is_normal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_normal(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_normal(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -479,7 +479,7 @@ extern "C" { LOG_Z3_mk_fpa_is_subnormal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_subnormal(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_subnormal(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -489,7 +489,7 @@ extern "C" { LOG_Z3_mk_fpa_is_zero(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_zero(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_zero(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -499,7 +499,7 @@ extern "C" { LOG_Z3_mk_fpa_is_infinite(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_inf(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_inf(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -509,7 +509,7 @@ extern "C" { LOG_Z3_mk_fpa_is_nan(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_nan(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_nan(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -519,7 +519,7 @@ extern "C" { LOG_Z3_mk_fpa_is_negative(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_negative(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_negative(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -529,7 +529,7 @@ extern "C" { LOG_Z3_mk_fpa_is_positive(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_is_positive(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_is_positive(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -540,7 +540,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_bv(c, bv, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util & fu = ctx->float_util(); + fpa_util & fu = ctx->fpa_util(); if (!ctx->bvutil().is_bv(to_expr(bv)) || !fu.is_float(to_sort(s))) { SET_ERROR_CODE(Z3_INVALID_ARG); @@ -556,7 +556,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_float(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util & fu = ctx->float_util(); + fpa_util & fu = ctx->fpa_util(); if (!fu.is_rm(to_expr(rm)) || !fu.is_float(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -573,7 +573,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_real(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util & fu = ctx->float_util(); + fpa_util & fu = ctx->fpa_util(); if (!fu.is_rm(to_expr(rm)) || !ctx->autil().is_real(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -590,7 +590,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_signed(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util & fu = ctx->float_util(); + fpa_util & fu = ctx->fpa_util(); if (!fu.is_rm(to_expr(rm)) || !ctx->bvutil().is_bv(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -607,7 +607,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_unsigned(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util & fu = ctx->float_util(); + fpa_util & fu = ctx->fpa_util(); if (!fu.is_rm(to_expr(rm)) || !ctx->bvutil().is_bv(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -624,7 +624,7 @@ extern "C" { LOG_Z3_mk_fpa_to_ubv(c, rm, t, sz); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_to_ubv(to_expr(rm), to_expr(t), sz)); + Z3_ast r = of_ast(ctx->fpa_util().mk_to_ubv(to_expr(rm), to_expr(t), sz)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -634,7 +634,7 @@ extern "C" { LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_to_sbv(to_expr(rm), to_expr(t), sz)); + Z3_ast r = of_ast(ctx->fpa_util().mk_to_sbv(to_expr(rm), to_expr(t), sz)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -644,7 +644,7 @@ extern "C" { LOG_Z3_mk_fpa_to_real(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_to_real(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_to_real(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -654,7 +654,7 @@ extern "C" { LOG_Z3_fpa_get_ebits(c, s); RESET_ERROR_CODE(); CHECK_NON_NULL(s, 0); - return mk_c(c)->float_util().get_ebits(to_sort(s)); + return mk_c(c)->fpa_util().get_ebits(to_sort(s)); Z3_CATCH_RETURN(0); } @@ -663,7 +663,7 @@ extern "C" { LOG_Z3_fpa_get_ebits(c, s); RESET_ERROR_CODE(); CHECK_NON_NULL(s, 0); - return mk_c(c)->float_util().get_sbits(to_sort(s)); + return mk_c(c)->fpa_util().get_sbits(to_sort(s)); Z3_CATCH_RETURN(0); } @@ -672,7 +672,7 @@ extern "C" { LOG_Z3_mk_fpa_to_ieee_bv(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->float_util().mk_float_to_ieee_bv(to_expr(t))); + Z3_ast r = of_ast(ctx->fpa_util().mk_float_to_ieee_bv(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -682,7 +682,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_real_int(c, rm, sig, exp, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - float_util & fu = ctx->float_util(); + fpa_util & fu = ctx->fpa_util(); if (!fu.is_rm(to_expr(rm)) || !ctx->autil().is_real(to_expr(sig)) || !ctx->autil().is_int(to_expr(exp)) || diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 17a743880..89f01707e 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -59,7 +59,7 @@ extern "C" { RETURN_Z3(0); } sort * _ty = to_sort(ty); - bool is_float = mk_c(c)->float_util().is_float(_ty); + bool is_float = mk_c(c)->fpa_util().is_float(_ty); std::string fixed_num; char const* m = n; while (*m) { @@ -79,7 +79,7 @@ extern "C" { if (_ty->get_family_id() == mk_c(c)->get_fpa_fid()) { // avoid expanding floats into huge rationals. - float_util & fu = mk_c(c)->float_util(); + fpa_util & fu = mk_c(c)->fpa_util(); scoped_mpf t(fu.fm()); fu.fm().set(t, fu.get_ebits(_ty), fu.get_sbits(_ty), MPF_ROUND_TOWARD_ZERO, n); a = fu.mk_value(t); @@ -149,7 +149,7 @@ extern "C" { return mk_c(c)->autil().is_numeral(e) || mk_c(c)->bvutil().is_numeral(e) || - mk_c(c)->float_util().is_value(e); + mk_c(c)->fpa_util().is_value(e); Z3_CATCH_RETURN(Z3_FALSE); } @@ -191,9 +191,9 @@ extern "C" { } else { // floats are separated from all others to avoid huge rationals. - float_util & fu = mk_c(c)->float_util(); + fpa_util & fu = mk_c(c)->fpa_util(); scoped_mpf tmp(fu.fm()); - if (mk_c(c)->float_util().is_value(to_expr(a), tmp)) { + if (mk_c(c)->fpa_util().is_value(to_expr(a), tmp)) { return mk_c(c)->mk_external_string(fu.fm().to_string(tmp)); } else { diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index bc62448c7..8aac71b8c 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -46,7 +46,7 @@ public: virtual arith_util & get_autil() = 0; virtual bv_util & get_bvutil() = 0; virtual array_util & get_arutil() = 0; - virtual float_util & get_futil() = 0; + virtual fpa_util & get_futil() = 0; virtual datalog::dl_decl_util& get_dlutil() = 0; virtual bool uses(symbol const & s) const = 0; virtual format_ns::format * pp_fdecl(func_decl * f, unsigned & len); @@ -69,7 +69,7 @@ class smt2_pp_environment_dbg : public smt2_pp_environment { arith_util m_autil; bv_util m_bvutil; array_util m_arutil; - float_util m_futil; + fpa_util m_futil; datalog::dl_decl_util m_dlutil; public: smt2_pp_environment_dbg(ast_manager & m):m_manager(m), m_autil(m), m_bvutil(m), m_arutil(m), m_futil(m), m_dlutil(m) {} @@ -77,7 +77,7 @@ public: virtual arith_util & get_autil() { return m_autil; } virtual bv_util & get_bvutil() { return m_bvutil; } virtual array_util & get_arutil() { return m_arutil; } - virtual float_util & get_futil() { return m_futil; } + virtual fpa_util & get_futil() { return m_futil; } virtual datalog::dl_decl_util& get_dlutil() { return m_dlutil; } virtual bool uses(symbol const & s) const { return false; } }; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index be3e5f3ec..90bbd4901 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -906,7 +906,7 @@ bool fpa_decl_plugin::is_unique_value(app* e) const { } } -float_util::float_util(ast_manager & m): +fpa_util::fpa_util(ast_manager & m): m_manager(m), m_fid(m.mk_family_id("fpa")), m_a_util(m), @@ -914,67 +914,67 @@ float_util::float_util(ast_manager & m): m_plugin = static_cast(m.get_plugin(m_fid)); } -float_util::~float_util() { +fpa_util::~fpa_util() { } -sort * float_util::mk_float_sort(unsigned ebits, unsigned sbits) { +sort * fpa_util::mk_float_sort(unsigned ebits, unsigned sbits) { parameter ps[2] = { parameter(ebits), parameter(sbits) }; return m().mk_sort(m_fid, FLOATING_POINT_SORT, 2, ps); } -unsigned float_util::get_ebits(sort * s) { +unsigned fpa_util::get_ebits(sort * s) { SASSERT(is_float(s)); return static_cast(s->get_parameter(0).get_int()); } -unsigned float_util::get_sbits(sort * s) { +unsigned fpa_util::get_sbits(sort * s) { SASSERT(is_float(s)); return static_cast(s->get_parameter(1).get_int()); } -app * float_util::mk_nan(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_nan(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_nan(ebits, sbits, v); return mk_value(v); } -app * float_util::mk_pinf(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_pinf(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_pinf(ebits, sbits, v); return mk_value(v); } -app * float_util::mk_ninf(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_ninf(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_ninf(ebits, sbits, v); return mk_value(v); } -app * float_util::mk_pzero(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_pzero(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_pzero(ebits, sbits, v); return mk_value(v); } -app * float_util::mk_nzero(unsigned ebits, unsigned sbits) { +app * fpa_util::mk_nzero(unsigned ebits, unsigned sbits) { scoped_mpf v(fm()); fm().mk_nzero(ebits, sbits, v); return mk_value(v); } -app * float_util::mk_internal_to_ubv_unspecified(unsigned width) { +app * fpa_util::mk_internal_to_ubv_unspecified(unsigned width) { parameter ps[] = { parameter(width) }; sort * range = m_bv_util.mk_sort(width); return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_UBV_UNSPECIFIED, 1, ps, 0, 0, range); } -app * float_util::mk_internal_to_sbv_unspecified(unsigned width) { +app * fpa_util::mk_internal_to_sbv_unspecified(unsigned width) { parameter ps[] = { parameter(width) }; sort * range = m_bv_util.mk_sort(width); return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_SBV_UNSPECIFIED, 1, ps, 0, 0, range); } -app * float_util::mk_internal_to_real_unspecified() { +app * fpa_util::mk_internal_to_real_unspecified() { sort * range = m_a_util.mk_real(); return m().mk_app(get_family_id(), OP_FPA_INTERNAL_TO_REAL_UNSPECIFIED, 0, 0, 0, 0, range); } \ No newline at end of file diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index b7d59a6af..b8d0c0c3e 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -207,15 +207,15 @@ public: virtual parameter translate(parameter const & p, decl_plugin & target); }; -class float_util { +class fpa_util { ast_manager & m_manager; fpa_decl_plugin * m_plugin; family_id m_fid; arith_util m_a_util; bv_util m_bv_util; public: - float_util(ast_manager & m); - ~float_util(); + fpa_util(ast_manager & m); + ~fpa_util(); ast_manager & m() const { return m_manager; } mpf_manager & fm() const { return m_plugin->fm(); } diff --git a/src/ast/rewriter/fpa_rewriter.h b/src/ast/rewriter/fpa_rewriter.h index 34a34b293..a10df95ca 100644 --- a/src/ast/rewriter/fpa_rewriter.h +++ b/src/ast/rewriter/fpa_rewriter.h @@ -26,7 +26,7 @@ Notes: #include"mpf.h" class fpa_rewriter { - float_util m_util; + fpa_util m_util; mpf_manager m_fm; app * mk_eq_nan(expr * arg); diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index d5ee9ff88..f5937955d 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -240,7 +240,7 @@ protected: arith_util m_autil; bv_util m_bvutil; array_util m_arutil; - float_util m_futil; + fpa_util m_futil; datalog::dl_decl_util m_dlutil; format_ns::format * pp_fdecl_name(symbol const & s, func_decls const & fs, func_decl * f, unsigned & len) { @@ -267,7 +267,7 @@ public: virtual arith_util & get_autil() { return m_autil; } virtual bv_util & get_bvutil() { return m_bvutil; } virtual array_util & get_arutil() { return m_arutil; } - virtual float_util & get_futil() { return m_futil; } + virtual fpa_util & get_futil() { return m_futil; } virtual datalog::dl_decl_util& get_dlutil() { return m_dlutil; } virtual bool uses(symbol const & s) const { return diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 7c4fce5cd..055f79b9d 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -51,8 +51,8 @@ namespace smt { expr_ref bv(m); bv = m_th.wrap(m.mk_const(f)); unsigned bv_sz = m_th.m_bv_util.get_bv_size(bv); - unsigned ebits = m_th.m_float_util.get_ebits(s); - unsigned sbits = m_th.m_float_util.get_sbits(s); + unsigned ebits = m_th.m_fpa_util.get_ebits(s); + unsigned sbits = m_th.m_fpa_util.get_sbits(s); SASSERT(bv_sz == ebits + sbits); m_th.m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), m_bv_util.mk_extract(sbits - 2, 0, bv), @@ -87,7 +87,7 @@ namespace smt { m_rw(m, m_converter, params_ref()), m_th_rw(m), m_trail_stack(*this), - m_float_util(m_converter.fu()), + m_fpa_util(m_converter.fu()), m_bv_util(m_converter.bu()), m_arith_util(m_converter.au()) { @@ -189,7 +189,7 @@ namespace smt { } app_ref theory_fpa::wrap(expr * e) { - SASSERT(!m_float_util.is_wrap(e)); + SASSERT(!m_fpa_util.is_wrap(e)); ast_manager & m = get_manager(); context & ctx = get_context(); sort * e_srt = m.get_sort(e); @@ -205,8 +205,8 @@ namespace smt { bv_srt = m_bv_util.mk_sort(3); else { SASSERT(m_converter.is_float(e_srt)); - unsigned ebits = m_float_util.get_ebits(e_srt); - unsigned sbits = m_float_util.get_sbits(e_srt); + unsigned ebits = m_fpa_util.get_ebits(e_srt); + unsigned sbits = m_fpa_util.get_sbits(e_srt); bv_srt = m_bv_util.mk_sort(ebits + sbits); } @@ -219,7 +219,7 @@ namespace smt { } app_ref theory_fpa::unwrap(expr * e, sort * s) { - SASSERT(!m_float_util.is_unwrap(e)); + SASSERT(!m_fpa_util.is_unwrap(e)); ast_manager & m = get_manager(); context & ctx = get_context(); sort * e_srt = m.get_sort(e); @@ -261,7 +261,7 @@ namespace smt { app_ref eca(to_app(ec), m); TRACE("t_fpa_detail", tout << "eca = " << mk_ismt2_pp(eca, m) << " sort is: " << mk_ismt2_pp(m.get_sort(eca), m) << std::endl;); - if (m_float_util.is_rm(e)) { + if (m_fpa_util.is_rm(e)) { expr_ref bv_rm(m); bv_rm = eca; TRACE("t_fpa_detail", tout << "bvrm = " << mk_ismt2_pp(bv_rm, m) << " sort is: " << mk_ismt2_pp(m.get_sort(bv_rm), m) << std::endl;); @@ -269,7 +269,7 @@ namespace smt { SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); m_th_rw(bv_rm, res); } - else if (m_float_util.is_float(e)) { + else if (m_fpa_util.is_float(e)) { SASSERT(eca->get_family_id() == get_family_id()); fpa_op_kind k = (fpa_op_kind)(eca->get_decl_kind()); SASSERT(k == OP_FPA_TO_FP || k == OP_FPA_INTERNAL_BVUNWRAP); @@ -316,17 +316,17 @@ namespace smt { } expr_ref theory_fpa::convert_unwrap(expr * e) { - SASSERT(m_float_util.is_unwrap(e)); + SASSERT(m_fpa_util.is_unwrap(e)); ast_manager & m = get_manager(); sort * srt = m.get_sort(e); expr_ref res(m); - if (m_float_util.is_rm(srt)) { + if (m_fpa_util.is_rm(srt)) { res = to_app(e)->get_arg(0); } else { - SASSERT(m_float_util.is_float(srt)); - unsigned ebits = m_float_util.get_ebits(srt); - unsigned sbits = m_float_util.get_sbits(srt); + SASSERT(m_fpa_util.is_float(srt)); + unsigned ebits = m_fpa_util.get_ebits(srt); + unsigned sbits = m_fpa_util.get_sbits(srt); expr * bv = to_app(e)->get_arg(0); unsigned bv_sz = m_bv_util.get_bv_size(bv); m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), @@ -351,11 +351,11 @@ namespace smt { return res; } else { - if (m_float_util.is_unwrap(e)) + if (m_fpa_util.is_unwrap(e)) res = convert_unwrap(e); else if (m.is_bool(e)) res = convert_atom(e); - else if (m_float_util.is_float(e) || m_float_util.is_rm(e)) + else if (m_fpa_util.is_float(e) || m_fpa_util.is_rm(e)) res = convert_term(e); else if (m_arith_util.is_real(e) || m_bv_util.is_bv(e)) res = convert_conversion_term(e); @@ -499,10 +499,10 @@ namespace smt { owner = n->get_owner(); owner_sort = m.get_sort(owner); - if (m_float_util.is_rm(owner_sort)) { + if (m_fpa_util.is_rm(owner_sort)) { // For every RM term, we need to make sure that it's // associated bit-vector is within the valid range. - if (!m_float_util.is_unwrap(owner)) + if (!m_fpa_util.is_unwrap(owner)) { expr_ref valid(m), limit(m); limit = m_bv_util.mk_numeral(4, 3); @@ -511,7 +511,7 @@ namespace smt { } } - if (!ctx.relevancy() && !m_float_util.is_unwrap(owner)) + if (!ctx.relevancy() && !m_fpa_util.is_unwrap(owner)) assert_cnstr(m.mk_eq(unwrap(wrap(owner), owner_sort), owner)); } @@ -523,7 +523,7 @@ namespace smt { mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); context & ctx = get_context(); - float_util & fu = m_float_util; + fpa_util & fu = m_fpa_util; bv_util & bu = m_bv_util; mpf_manager & mpfm = fu.fm(); @@ -570,7 +570,7 @@ namespace smt { mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); context & ctx = get_context(); - mpf_manager & mpfm = m_float_util.fm(); + mpf_manager & mpfm = m_fpa_util.fm(); app * xe = get_enode(x)->get_owner(); app * ye = get_enode(y)->get_owner(); @@ -587,7 +587,7 @@ namespace smt { expr_ref c(m); - if (m_float_util.is_float(xe) && m_float_util.is_float(ye)) + if (m_fpa_util.is_float(xe) && m_fpa_util.is_float(ye)) { expr *x_sgn, *x_sig, *x_exp; m_converter.split_triple(xc, x_sgn, x_sig, x_exp); @@ -636,22 +636,22 @@ namespace smt { ast_manager & m = get_manager(); TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, m) << "\n";); - mpf_manager & mpfm = m_float_util.fm(); + mpf_manager & mpfm = m_fpa_util.fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); - if (m_float_util.is_float(n) || m_float_util.is_rm(n)) { + if (m_fpa_util.is_float(n) || m_fpa_util.is_rm(n)) { sort * s = m.get_sort(n); - if (!m_float_util.is_unwrap(n)) { + if (!m_fpa_util.is_unwrap(n)) { expr_ref wrapped(m), c(m); wrapped = wrap(n); mpf_rounding_mode rm; scoped_mpf val(mpfm); - if (m_float_util.is_rm_value(n, rm)) { + if (m_fpa_util.is_rm_value(n, rm)) { c = m.mk_eq(wrapped, m_bv_util.mk_numeral(rm, 3)); assert_cnstr(c); } - else if (m_float_util.is_value(n, val)) { + else if (m_fpa_util.is_value(n, val)) { unsigned sz = val.get().get_ebits() + val.get().get_sbits(); expr_ref bv_val_e(m); bv_val_e = convert(n); @@ -670,7 +670,7 @@ namespace smt { } } else if (n->get_family_id() == get_family_id()) { - SASSERT(!m_float_util.is_float(n) && !m_float_util.is_rm(n)); + SASSERT(!m_fpa_util.is_float(n) && !m_fpa_util.is_rm(n)); // These are the conversion functions fp.to_* */ } else @@ -714,8 +714,8 @@ namespace smt { // If the owner is not internalized, it doesn't have an enode associated. SASSERT(ctx.e_internalized(owner)); - if (m_float_util.is_rm_value(owner) || - m_float_util.is_value(owner)) + if (m_fpa_util.is_rm_value(owner) || + m_fpa_util.is_value(owner)) return alloc(expr_wrapper_proc, owner); model_value_proc * res = 0; @@ -729,14 +729,14 @@ namespace smt { " (owner " << (!ctx.e_internalized(owner) ? "not" : "is") << " internalized)" << std::endl;); - if (m_float_util.is_rm(owner)) { + if (m_fpa_util.is_rm(owner)) { fpa_rm_value_proc * vp = alloc(fpa_rm_value_proc, this); vp->add_dependency(ctx.get_enode(wrapped)); res = vp; } - else if (m_float_util.is_float(owner)) { - unsigned ebits = m_float_util.get_ebits(m.get_sort(owner)); - unsigned sbits = m_float_util.get_sbits(m.get_sort(owner)); + else if (m_fpa_util.is_float(owner)) { + unsigned ebits = m_fpa_util.get_ebits(m.get_sort(owner)); + unsigned sbits = m_fpa_util.get_sbits(m.get_sort(owner)); fpa_value_proc * vp = alloc(fpa_value_proc, this, ebits, sbits); vp->add_dependency(ctx.get_enode(wrapped)); res = vp; diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index c51b02c28..58af5ad1c 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -29,8 +29,8 @@ Revision History: namespace smt { - class fpa_factory : public value_factory { - float_util m_util; + class fpa_value_actory : public value_factory { + fpa_util m_util; virtual app * mk_value_core(mpf const & val, sort * s) { SASSERT(m_util.get_ebits(s) == val.get_ebits()); @@ -39,11 +39,11 @@ namespace smt { } public: - fpa_factory(ast_manager & m, family_id fid) : + fpa_value_actory(ast_manager & m, family_id fid) : value_factory(m, fid), m_util(m) {} - virtual ~fpa_factory() {} + virtual ~fpa_value_actory() {} virtual expr * get_some_value(sort * s) { mpf_manager & mpfm = m_util.fm(); @@ -87,10 +87,10 @@ namespace smt { class fpa_value_proc : public model_value_proc { protected: - theory_fpa & m_th; + theory_fpa & m_th; ast_manager & m; - float_util & m_fu; - bv_util & m_bu; + fpa_util & m_fu; + bv_util & m_bu; buffer m_deps; unsigned m_ebits; unsigned m_sbits; diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index 78ba64111..dfddfd12f 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -85,7 +85,7 @@ model_converter * fpa2bv_model_converter::translate(ast_translation & translator } void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { - float_util fu(m); + fpa_util fu(m); bv_util bu(m); mpf fp_val; unsynch_mpz_manager & mpzm = fu.fm().mpz_manager(); diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffp_tactic.cpp similarity index 96% rename from src/tactic/fpa/qffpa_tactic.cpp rename to src/tactic/fpa/qffp_tactic.cpp index c02166c18..e205a6c5e 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffp_tactic.cpp @@ -7,7 +7,7 @@ Module Name: Abstract: - Tactic for QF_FPA benchmarks. + Tactic for QF_FP benchmarks. Author: @@ -23,7 +23,7 @@ Notes: #include"fpa2bv_tactic.h" #include"smt_tactic.h" -#include"qffpa_tactic.h" +#include"qffp_tactic.h" tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { params_ref simp_p = p; @@ -52,7 +52,7 @@ struct is_non_qffp_predicate { struct found {}; ast_manager & m; bv_util bu; - float_util fu; + fpa_util fu; arith_util au; is_non_qffp_predicate(ast_manager & _m) : m(_m), bu(m), fu(m), au(m) {} @@ -89,4 +89,4 @@ public: probe * mk_is_qffp_probe() { return alloc(is_qffp_probe); } - \ No newline at end of file + diff --git a/src/tactic/fpa/qffpa_tactic.h b/src/tactic/fpa/qffp_tactic.h similarity index 82% rename from src/tactic/fpa/qffpa_tactic.h rename to src/tactic/fpa/qffp_tactic.h index 3ab95798f..2842e3f73 100644 --- a/src/tactic/fpa/qffpa_tactic.h +++ b/src/tactic/fpa/qffp_tactic.h @@ -17,8 +17,8 @@ Notes: --*/ -#ifndef _QFFPA_TACTIC_H_ -#define _QFFPA_TACTIC_H_ +#ifndef _QFFP_TACTIC_H_ +#define _QFFP_TACTIC_H_ #include"params.h" class ast_manager; @@ -27,14 +27,14 @@ class tactic; tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p = params_ref()); /* ADD_TACTIC("qffp", "(try to) solve goal using the tactic for QF_FP.", "mk_qffp_tactic(m, p)") - ADD_TACTIC("qffpbv", "(try to) solve goal using the tactic for QF_FPBV (floats+bit-vectors).", "mk_qffp_tactic(m, p)") + ADD_TACTIC("qffpbv", "(try to) solve goal using the tactic for QF_FPBV (floats+bit-vectors).", "mk_qffpbv_tactic(m, p)") */ probe * mk_is_qffp_probe(); probe * mk_is_qffpbv_probe(); /* ADD_PROBE("is-qffp", "true if the goal is in QF_FP (floats).", "mk_is_qffp_probe()") - ADD_PROBE("is-qffpbv", "true if the goal is in QF_FPBV (floats+bit-vectors).", "mk_is_qffp_probe()") + ADD_PROBE("is-qffpbv", "true if the goal is in QF_FPBV (floats+bit-vectors).", "mk_is_qffpbv_probe()") */ #endif diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index a01b547df..79b3e0e95 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -27,7 +27,7 @@ Notes: #include"nra_tactic.h" #include"probe_arith.h" #include"quant_tactics.h" -#include"qffpa_tactic.h" +#include"qffp_tactic.h" tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index 9e0ce6e89..3c62bc80c 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -33,7 +33,7 @@ Notes: #include"qfidl_tactic.h" #include"default_tactic.h" #include"ufbv_tactic.h" -#include"qffpa_tactic.h" +#include"qffp_tactic.h" #include"horn_tactic.h" #include"smt_solver.h" @@ -78,8 +78,10 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const return mk_ufbv_tactic(m, p); else if (logic=="BV") return mk_ufbv_tactic(m, p); - else if (logic=="QF_FP" || logic=="QF_FPBV") + else if (logic=="QF_FP") return mk_qffp_tactic(m, p); + else if (logic == "QF_FPBV") + return mk_qffpbv_tactic(m, p); else if (logic=="HORN") return mk_horn_tactic(m, p); else From 0cedd32ea2663961d2f439d3858e525ff7a9f9dc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 13:47:26 +0000 Subject: [PATCH 128/507] More renaming floats -> fpa Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.h | 4 ++-- src/smt/theory_fpa.cpp | 2 +- src/smt/theory_fpa.h | 20 ++++++++++---------- src/tactic/fpa/qffp_tactic.cpp | 7 +++++++ src/tactic/fpa/qffp_tactic.h | 1 + 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index f81edb653..efc4d9179 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -45,7 +45,7 @@ class fpa2bv_converter { protected: ast_manager & m; basic_simplifier_plugin m_simp; - float_util m_util; + fpa_util m_util; bv_util m_bv_util; arith_util m_arith_util; mpf_manager & m_mpf_manager; @@ -62,7 +62,7 @@ public: fpa2bv_converter(ast_manager & m); ~fpa2bv_converter(); - float_util & fu() { return m_util; } + fpa_util & fu() { return m_util; } bv_util & bu() { return m_bv_util; } arith_util & au() { return m_arith_util; } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 055f79b9d..487908173 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -700,7 +700,7 @@ namespace smt { void theory_fpa::init_model(model_generator & mg) { TRACE("t_fpa", tout << "initializing model" << std::endl; display(tout);); - m_factory = alloc(fpa_factory, get_manager(), get_family_id()); + m_factory = alloc(fpa_value_factory, get_manager(), get_family_id()); mg.register_factory(m_factory); } diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 58af5ad1c..33733d7d9 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -29,7 +29,7 @@ Revision History: namespace smt { - class fpa_value_actory : public value_factory { + class fpa_value_factory : public value_factory { fpa_util m_util; virtual app * mk_value_core(mpf const & val, sort * s) { @@ -39,11 +39,11 @@ namespace smt { } public: - fpa_value_actory(ast_manager & m, family_id fid) : + fpa_value_factory(ast_manager & m, family_id fid) : value_factory(m, fid), m_util(m) {} - virtual ~fpa_value_actory() {} + virtual ~fpa_value_factory() {} virtual expr * get_some_value(sort * s) { mpf_manager & mpfm = m_util.fm(); @@ -97,7 +97,7 @@ namespace smt { public: fpa_value_proc(theory_fpa * th, unsigned ebits, unsigned sbits) : - m_th(*th), m_fu(th->m_float_util), m_bu(th->m_bv_util), m(th->get_manager()), + m_th(*th), m_fu(th->m_fpa_util), m_bu(th->m_bv_util), m(th->get_manager()), m_ebits(ebits), m_sbits(sbits) {} virtual ~fpa_value_proc() {} @@ -112,15 +112,15 @@ namespace smt { }; class fpa_rm_value_proc : public model_value_proc { - theory_fpa & m_th; + theory_fpa & m_th; ast_manager & m; - float_util & m_fu; - bv_util & m_bu; + fpa_util & m_fu; + bv_util & m_bu; buffer m_deps; public: fpa_rm_value_proc(theory_fpa * th) : - m_th(*th), m_fu(th->m_float_util), m_bu(th->m_bv_util), m(th->get_manager()) {} + m_th(*th), m_fu(th->m_fpa_util), m_bu(th->m_bv_util), m(th->get_manager()) {} void add_dependency(enode * e) { m_deps.push_back(model_value_dependency(e)); } @@ -137,8 +137,8 @@ namespace smt { fpa2bv_rewriter m_rw; th_rewriter m_th_rw; th_trail_stack m_trail_stack; - fpa_factory * m_factory; - float_util & m_float_util; + fpa_value_factory * m_factory; + fpa_util & m_fpa_util; bv_util & m_bv_util; arith_util & m_arith_util; obj_map m_wraps; diff --git a/src/tactic/fpa/qffp_tactic.cpp b/src/tactic/fpa/qffp_tactic.cpp index e205a6c5e..5bc006f00 100644 --- a/src/tactic/fpa/qffp_tactic.cpp +++ b/src/tactic/fpa/qffp_tactic.cpp @@ -48,6 +48,10 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { return st; } +tactic * mk_qffpbv_tactic(ast_manager & m, params_ref const & p) { + return mk_qffp_tactic(m, p); +} + struct is_non_qffp_predicate { struct found {}; ast_manager & m; @@ -90,3 +94,6 @@ probe * mk_is_qffp_probe() { return alloc(is_qffp_probe); } +probe * mk_is_qffpbv_probe() { + return alloc(is_qffp_probe); +} diff --git a/src/tactic/fpa/qffp_tactic.h b/src/tactic/fpa/qffp_tactic.h index 2842e3f73..5c8caba2b 100644 --- a/src/tactic/fpa/qffp_tactic.h +++ b/src/tactic/fpa/qffp_tactic.h @@ -25,6 +25,7 @@ class ast_manager; class tactic; tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p = params_ref()); +tactic * mk_qffpbv_tactic(ast_manager & m, params_ref const & p = params_ref()); /* ADD_TACTIC("qffp", "(try to) solve goal using the tactic for QF_FP.", "mk_qffp_tactic(m, p)") ADD_TACTIC("qffpbv", "(try to) solve goal using the tactic for QF_FPBV (floats+bit-vectors).", "mk_qffpbv_tactic(m, p)") From c0a027fc809ba2f205b60571f4d5c16115379835 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 14:07:47 +0000 Subject: [PATCH 129/507] FPA: Elminated nzero/pzero AST kinds Signed-off-by: Christoph M. Wintersteiger --- src/api/api_ast.cpp | 2 -- src/ast/fpa/fpa2bv_rewriter.h | 4 +--- src/ast/fpa_decl_plugin.cpp | 4 ---- src/ast/fpa_decl_plugin.h | 4 ---- src/ast/rewriter/fpa_rewriter.cpp | 2 -- 5 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index c6b413dd4..eed5f7553 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -1155,8 +1155,6 @@ extern "C" { case OP_FPA_IS_ZERO: return Z3_OP_FPA_IS_ZERO; case OP_FPA_IS_NORMAL: return Z3_OP_FPA_IS_NORMAL; case OP_FPA_IS_SUBNORMAL: return Z3_OP_FPA_IS_SUBNORMAL; - case OP_FPA_IS_PZERO: return Z3_OP_FPA_IS_PZERO; - case OP_FPA_IS_NZERO: return Z3_OP_FPA_IS_NZERO; case OP_FPA_IS_NEGATIVE: return Z3_OP_FPA_IS_NEGATIVE; case OP_FPA_IS_POSITIVE: return Z3_OP_FPA_IS_POSITIVE; case OP_FPA_FP: return Z3_OP_FPA_FP; diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index cbbd9e8a7..c7a987b83 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -143,9 +143,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FPA_GT: m_conv.mk_float_gt(f, num, args, result); return BR_DONE; case OP_FPA_LE: m_conv.mk_float_le(f, num, args, result); return BR_DONE; case OP_FPA_GE: m_conv.mk_float_ge(f, num, args, result); return BR_DONE; - case OP_FPA_IS_ZERO: m_conv.mk_is_zero(f, num, args, result); return BR_DONE; - case OP_FPA_IS_NZERO: m_conv.mk_is_nzero(f, num, args, result); return BR_DONE; - case OP_FPA_IS_PZERO: m_conv.mk_is_pzero(f, num, args, result); return BR_DONE; + case OP_FPA_IS_ZERO: m_conv.mk_is_zero(f, num, args, result); return BR_DONE; case OP_FPA_IS_NAN: m_conv.mk_is_nan(f, num, args, result); return BR_DONE; case OP_FPA_IS_INF: m_conv.mk_is_inf(f, num, args, result); return BR_DONE; case OP_FPA_IS_NORMAL: m_conv.mk_is_normal(f, num, args, result); return BR_DONE; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 90bbd4901..52a1a95f7 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -294,8 +294,6 @@ func_decl * fpa_decl_plugin::mk_unary_rel_decl(decl_kind k, unsigned num_paramet symbol name; switch (k) { case OP_FPA_IS_ZERO: name = "fp.isZero"; break; - case OP_FPA_IS_NZERO: name = "fp.isNZero"; break; - case OP_FPA_IS_PZERO: name = "fp.isPZero"; break; case OP_FPA_IS_NEGATIVE: name = "fp.isNegative"; break; case OP_FPA_IS_POSITIVE: name = "fp.isPositive"; break; case OP_FPA_IS_NAN: name = "fp.isNaN"; break; @@ -717,8 +715,6 @@ func_decl * fpa_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, case OP_FPA_GE: return mk_bin_rel_decl(k, num_parameters, parameters, arity, domain, range); case OP_FPA_IS_ZERO: - case OP_FPA_IS_NZERO: - case OP_FPA_IS_PZERO: case OP_FPA_IS_NEGATIVE: case OP_FPA_IS_POSITIVE: case OP_FPA_IS_NAN: diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index b8d0c0c3e..44f0e62c4 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -71,8 +71,6 @@ enum fpa_op_kind { OP_FPA_IS_ZERO, OP_FPA_IS_NORMAL, OP_FPA_IS_SUBNORMAL, - OP_FPA_IS_PZERO, - OP_FPA_IS_NZERO, OP_FPA_IS_NEGATIVE, OP_FPA_IS_POSITIVE, @@ -325,8 +323,6 @@ public: app * mk_is_zero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_ZERO, arg1); } app * mk_is_normal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NORMAL, arg1); } app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_SUBNORMAL, arg1); } - app * mk_is_nzero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NZERO, arg1); } - app * mk_is_pzero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_PZERO, arg1); } app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NEGATIVE, arg1); } app * mk_is_positive(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_POSITIVE, arg1); } app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NEGATIVE, arg1); } diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 2977b7ab2..e7b8c7b34 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -57,8 +57,6 @@ br_status fpa_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * con case OP_FPA_LE: SASSERT(num_args == 2); st = mk_le(args[0], args[1], result); break; case OP_FPA_GE: SASSERT(num_args == 2); st = mk_ge(args[0], args[1], result); break; case OP_FPA_IS_ZERO: SASSERT(num_args == 1); st = mk_is_zero(args[0], result); break; - case OP_FPA_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break; - case OP_FPA_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break; case OP_FPA_IS_NAN: SASSERT(num_args == 1); st = mk_is_nan(args[0], result); break; case OP_FPA_IS_INF: SASSERT(num_args == 1); st = mk_is_inf(args[0], result); break; case OP_FPA_IS_NORMAL: SASSERT(num_args == 1); st = mk_is_normal(args[0], result); break; From c5b220cc124739d0a5498bed7b079a14975d5af5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 14:07:59 +0000 Subject: [PATCH 130/507] FPA: Added AST kind descriptions Signed-off-by: Christoph M. Wintersteiger --- src/api/z3_api.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 3c3a5d1c2..c719354b6 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -877,6 +877,90 @@ typedef enum - Z3_OP_DT_ACCESSOR: datatype accessor. + - Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN: Floating-point rounding mode RNE + + - Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY: Floating-point rounding mode RNA + + - Z3_OP_FPA_RM_TOWARD_POSITIVE: Floating-point rounding mode RTP + + - Z3_OP_FPA_RM_TOWARD_NEGATIVE: Floating-point rounding mode RTN + + - Z3_OP_FPA_RM_TOWARD_ZERO: Floating-point rounding mode RTZ + + - Z3_OP_FPA_VALUE: Floating-point value + + - Z3_OP_FPA_PLUS_INF: Floating-point +oo + + - Z3_OP_FPA_MINUS_INF: Floating-point -oo + + - Z3_OP_FPA_NAN: Floating-point NaN + + - Z3_OP_FPA_PLUS_ZERO: Floating-point +zero + + - Z3_OP_FPA_MINUS_ZERO: Floating-point -zero + + - Z3_OP_FPA_ADD: Floating-point addition + + - Z3_OP_FPA_SUB: Floating-point subtraction + + - Z3_OP_FPA_NEG: Floating-point negation + + - Z3_OP_FPA_MUL: Floating-point multiplication + + - Z3_OP_FPA_DIV: Floating-point division + + - Z3_OP_FPA_REM: Floating-point remainder + + - Z3_OP_FPA_ABS: Floating-point absolute value + + - Z3_OP_FPA_MIN: Floating-point minimum + + - Z3_OP_FPA_MAX: Floating-point maximum + + - Z3_OP_FPA_FMA: Floating-point fused multiply-add + + - Z3_OP_FPA_SQRT: Floating-point square root + + - Z3_OP_FPA_ROUND_TO_INTEGRAL: Floating-point round to integral + + - Z3_OP_FPA_EQ: Floating-point equality + + - Z3_OP_FPA_LT: Floating-point less than + + - Z3_OP_FPA_GT: Floating-point greater than + + - Z3_OP_FPA_LE: Floating-point less than or equal + + - Z3_OP_FPA_GE: Floating-point greater than or equal + + - Z3_OP_FPA_IS_NAN: Floating-point isNaN + + - Z3_OP_FPA_IS_INF: Floating-point isInfinite + + - Z3_OP_FPA_IS_ZERO: Floating-point isZero + + - Z3_OP_FPA_IS_NORMAL: Floating-point isNormal + + - Z3_OP_FPA_IS_SUBNORMAL: Floating-point isSubnormal + + - Z3_OP_FPA_IS_NEGATIVE: Floating-point isNegative + + - Z3_OP_FPA_IS_POSITIVE: Floating-point isPositive + + - Z3_OP_FPA_FP: Floating-point constructor from 3 bit-vectors + + - Z3_OP_FPA_TO_FP: Floating-point conversion (various) + + - Z3_OP_FPA_TO_FP_UNSIGNED: Floating-point conversion from unsigend bit-vector + + - Z3_OP_FPA_TO_UBV: Floating-point conversion to unsigned bit-vector + + - Z3_OP_FPA_TO_SBV: Floating-point conversion to signed bit-vector + + - Z3_OP_FPA_TO_REAL: Floating-point conversion to real number + + - Z3_OP_FPA_TO_IEEE_BV: Floating-point conversion to IEEE-754 bit-vector + - Z3_OP_UNINTERPRETED: kind used for uninterpreted symbols. */ typedef enum { @@ -1095,8 +1179,6 @@ typedef enum { Z3_OP_FPA_IS_ZERO, Z3_OP_FPA_IS_NORMAL, Z3_OP_FPA_IS_SUBNORMAL, - Z3_OP_FPA_IS_PZERO, - Z3_OP_FPA_IS_NZERO, Z3_OP_FPA_IS_NEGATIVE, Z3_OP_FPA_IS_POSITIVE, From c0bc2518b007184ad18aa486f8e4f4e61d800fcc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 14:22:44 +0000 Subject: [PATCH 131/507] Renaming for consistency mk_value -> mk_numeral Signed-off-by: Christoph M. Wintersteiger --- src/api/api_ast.cpp | 2 +- src/api/api_numeral.cpp | 4 +- src/api/z3_api.h | 4 +- src/ast/fpa/fpa2bv_converter.cpp | 22 +++++------ src/ast/fpa_decl_plugin.cpp | 8 ++-- src/ast/fpa_decl_plugin.h | 36 +++++++++--------- src/ast/rewriter/fpa_rewriter.cpp | 62 +++++++++++++++---------------- src/smt/theory_fpa.cpp | 8 ++-- 8 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index eed5f7553..b9c6230b7 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -1127,7 +1127,7 @@ extern "C" { case OP_FPA_RM_TOWARD_POSITIVE: return Z3_OP_FPA_RM_TOWARD_POSITIVE; case OP_FPA_RM_TOWARD_NEGATIVE: return Z3_OP_FPA_RM_TOWARD_NEGATIVE; case OP_FPA_RM_TOWARD_ZERO: return Z3_OP_FPA_RM_TOWARD_ZERO; - case OP_FPA_VALUE: return Z3_OP_FPA_VALUE; + case OP_FPA_NUM: return Z3_OP_FPA_NUM; case OP_FPA_PLUS_INF: return Z3_OP_FPA_PLUS_INF; case OP_FPA_MINUS_INF: return Z3_OP_FPA_MINUS_INF; case OP_FPA_NAN: return Z3_OP_FPA_NAN; diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 89f01707e..7789f1157 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -149,7 +149,7 @@ extern "C" { return mk_c(c)->autil().is_numeral(e) || mk_c(c)->bvutil().is_numeral(e) || - mk_c(c)->fpa_util().is_value(e); + mk_c(c)->fpa_util().is_numeral(e); Z3_CATCH_RETURN(Z3_FALSE); } @@ -193,7 +193,7 @@ extern "C" { // floats are separated from all others to avoid huge rationals. fpa_util & fu = mk_c(c)->fpa_util(); scoped_mpf tmp(fu.fm()); - if (mk_c(c)->fpa_util().is_value(to_expr(a), tmp)) { + if (mk_c(c)->fpa_util().is_numeral(to_expr(a), tmp)) { return mk_c(c)->mk_external_string(fu.fm().to_string(tmp)); } else { diff --git a/src/api/z3_api.h b/src/api/z3_api.h index c719354b6..a4ad8d90d 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -887,7 +887,7 @@ typedef enum - Z3_OP_FPA_RM_TOWARD_ZERO: Floating-point rounding mode RTZ - - Z3_OP_FPA_VALUE: Floating-point value + - Z3_OP_FPA_NUM: Floating-point value - Z3_OP_FPA_PLUS_INF: Floating-point +oo @@ -1149,7 +1149,7 @@ typedef enum { Z3_OP_FPA_RM_TOWARD_NEGATIVE, Z3_OP_FPA_RM_TOWARD_ZERO, - Z3_OP_FPA_VALUE, + Z3_OP_FPA_NUM, Z3_OP_FPA_PLUS_INF, Z3_OP_FPA_MINUS_INF, Z3_OP_FPA_NAN, diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index dc1a255e8..4c570c1ba 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -80,7 +80,7 @@ void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { mk_triple(sgn, s, e, result); } -void fpa2bv_converter::mk_value(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { +void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 0); SASSERT(f->get_num_parameters() == 1); SASSERT(f->get_parameter(0).is_external()); @@ -2177,18 +2177,18 @@ void fpa2bv_converter::mk_to_fp_real_int(func_decl * f, unsigned num, expr * con m_mpf_manager.set(tz, ebits, sbits, MPF_ROUND_TOWARD_ZERO, q.to_mpq(), e.to_mpq().numerator()); app_ref a_nte(m), a_nta(m), a_tp(m), a_tn(m), a_tz(m); - a_nte = m_plugin->mk_value(nte); - a_nta = m_plugin->mk_value(nta); - a_tp = m_plugin->mk_value(tp); - a_tn = m_plugin->mk_value(tn); - a_tz = m_plugin->mk_value(tz); + a_nte = m_plugin->mk_numeral(nte); + a_nta = m_plugin->mk_numeral(nta); + a_tp = m_plugin->mk_numeral(tp); + a_tn = m_plugin->mk_numeral(tn); + a_tz = m_plugin->mk_numeral(tz); expr_ref bv_nte(m), bv_nta(m), bv_tp(m), bv_tn(m), bv_tz(m); - mk_value(a_nte->get_decl(), 0, 0, bv_nte); - mk_value(a_nta->get_decl(), 0, 0, bv_nta); - mk_value(a_tp->get_decl(), 0, 0, bv_tp); - mk_value(a_tn->get_decl(), 0, 0, bv_tn); - mk_value(a_tz->get_decl(), 0, 0, bv_tz); + mk_numeral(a_nte->get_decl(), 0, 0, bv_nte); + mk_numeral(a_nta->get_decl(), 0, 0, bv_nta); + mk_numeral(a_tp->get_decl(), 0, 0, bv_tp); + mk_numeral(a_tn->get_decl(), 0, 0, bv_tn); + mk_numeral(a_tz->get_decl(), 0, 0, bv_tz); expr_ref c1(m), c2(m), c3(m), c4(m); c1 = m.mk_eq(rm, m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3)); diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 52a1a95f7..7d4a77d1c 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -72,7 +72,7 @@ func_decl * fpa_decl_plugin::mk_value_decl(mpf const & v) { parameter p(mk_id(v), true); SASSERT(p.is_external()); sort * s = mk_float_sort(v.get_ebits(), v.get_sbits()); - return m_manager->mk_const_decl(symbol("fpa"), s, func_decl_info(m_family_id, OP_FPA_VALUE, 1, &p)); + return m_manager->mk_const_decl(symbol("fpa"), s, func_decl_info(m_family_id, OP_FPA_NUM, 1, &p)); } app * fpa_decl_plugin::mk_value(mpf const & v) { @@ -80,7 +80,7 @@ app * fpa_decl_plugin::mk_value(mpf const & v) { } bool fpa_decl_plugin::is_value(expr * n, mpf & val) { - if (is_app_of(n, m_family_id, OP_FPA_VALUE)) { + if (is_app_of(n, m_family_id, OP_FPA_NUM)) { m_fm.set(val, m_values[to_app(n)->get_decl()->get_parameter(0).get_ext_id()]); return true; } @@ -860,7 +860,7 @@ bool fpa_decl_plugin::is_value(app * e) const { case OP_FPA_RM_TOWARD_POSITIVE: case OP_FPA_RM_TOWARD_NEGATIVE: case OP_FPA_RM_TOWARD_ZERO: - case OP_FPA_VALUE: + case OP_FPA_NUM: case OP_FPA_PLUS_INF: case OP_FPA_MINUS_INF: case OP_FPA_PLUS_ZERO: @@ -891,7 +891,7 @@ bool fpa_decl_plugin::is_unique_value(app* e) const { case OP_FPA_PLUS_ZERO: /* No; +zero == fp #b0 #b00 #b000) */ case OP_FPA_MINUS_ZERO: /* No; -zero == fp #b1 #b00 #b000) */ case OP_FPA_NAN: /* No; NaN == (fp #b0 #b111111 #b0000001) */ - case OP_FPA_VALUE: /* see NaN */ + case OP_FPA_NUM: /* see NaN */ return false; case OP_FPA_FP: return m_manager->is_unique_value(e->get_arg(0)) && diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 44f0e62c4..24481d348 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -41,7 +41,7 @@ enum fpa_op_kind { OP_FPA_RM_TOWARD_NEGATIVE, OP_FPA_RM_TOWARD_ZERO, - OP_FPA_VALUE, + OP_FPA_NUM, OP_FPA_PLUS_INF, OP_FPA_MINUS_INF, OP_FPA_NAN, @@ -189,12 +189,12 @@ public: virtual bool is_unique_value(app* e) const; mpf_manager & fm() { return m_fm; } - func_decl * mk_value_decl(mpf const & v); - app * mk_value(mpf const & v); - bool is_value(expr * n) { return is_app_of(n, m_family_id, OP_FPA_VALUE); } - bool is_value(expr * n, mpf & val); - bool is_rm_value(expr * n, mpf_rounding_mode & val); - bool is_rm_value(expr * n) { mpf_rounding_mode t; return is_rm_value(n, t); } + func_decl * mk_numeral_decl(mpf const & v); + app * mk_numeral(mpf const & v); + bool is_numeral(expr * n) { return is_app_of(n, m_family_id, OP_FPA_NUM); } + bool is_numeral(expr * n, mpf & val); + bool is_rm_numeral(expr * n, mpf_rounding_mode & val); + bool is_rm_numeral(expr * n) { mpf_rounding_mode t; return is_rm_numeral(n, t); } mpf const & get_value(unsigned id) const { SASSERT(m_value_table.contains(id)); @@ -244,23 +244,23 @@ public: app * mk_pinf(sort * s) { return mk_pinf(get_ebits(s), get_sbits(s)); } app * mk_ninf(sort * s) { return mk_ninf(get_ebits(s), get_sbits(s)); } - app * mk_value(mpf const & v) { return m_plugin->mk_value(v); } - bool is_value(expr * n) { return m_plugin->is_value(n); } - bool is_value(expr * n, mpf & v) { return m_plugin->is_value(n, v); } - bool is_rm_value(expr * n) { return m_plugin->is_rm_value(n); } - bool is_rm_value(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm_value(n, v); } + app * mk_value(mpf const & v) { return m_plugin->mk_numeral(v); } + bool is_numeral(expr * n) { return m_plugin->is_numeral(n); } + bool is_numeral(expr * n, mpf & v) { return m_plugin->is_numeral(n, v); } + bool is_rm_numeral(expr * n) { return m_plugin->is_rm_numeral(n); } + bool is_rm_numeral(expr * n, mpf_rounding_mode & v) { return m_plugin->is_rm_numeral(n, v); } app * mk_pzero(unsigned ebits, unsigned sbits); app * mk_nzero(unsigned ebits, unsigned sbits); app * mk_pzero(sort * s) { return mk_pzero(get_ebits(s), get_sbits(s)); } app * mk_nzero(sort * s) { return mk_nzero(get_ebits(s), get_sbits(s)); } - bool is_nan(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nan(v); } - bool is_pinf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pinf(v); } - bool is_ninf(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_ninf(v); } - bool is_zero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_zero(v); } - bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_pzero(v); } - bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_value(n, v) && fm().is_nzero(v); } + bool is_nan(expr * n) { scoped_mpf v(fm()); return is_numeral(n, v) && fm().is_nan(v); } + bool is_pinf(expr * n) { scoped_mpf v(fm()); return is_numeral(n, v) && fm().is_pinf(v); } + bool is_ninf(expr * n) { scoped_mpf v(fm()); return is_numeral(n, v) && fm().is_ninf(v); } + bool is_zero(expr * n) { scoped_mpf v(fm()); return is_numeral(n, v) && fm().is_zero(v); } + bool is_pzero(expr * n) { scoped_mpf v(fm()); return is_numeral(n, v) && fm().is_pzero(v); } + bool is_nzero(expr * n) { scoped_mpf v(fm()); return is_numeral(n, v) && fm().is_nzero(v); } app * mk_fp(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FPA_FP, arg1, arg2, arg3); } app * mk_to_fp(sort * s, expr * bv_t) { diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index e7b8c7b34..915d25e50 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -81,7 +81,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const if (num_args == 2) { mpf_rounding_mode rm; - if (!m_util.is_rm_value(args[0], rm)) + if (!m_util.is_rm_numeral(args[0], rm)) return BR_FAILED; rational q; @@ -95,7 +95,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const // TRACE("fp_rewriter", tout << "result: " << result << std::endl; ); return BR_DONE; } - else if (m_util.is_value(args[1], q_mpf)) { + else if (m_util.is_numeral(args[1], q_mpf)) { TRACE("fp_rewriter", tout << "q: " << m_util.fm().to_string(q_mpf) << std::endl; ); scoped_mpf v(m_util.fm()); m_util.fm().set(v, ebits, sbits, rm, q_mpf); @@ -116,7 +116,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const m_util.au().is_real(args[1]) && m_util.au().is_int(args[2])) { mpf_rounding_mode rm; - if (!m_util.is_rm_value(args[0], rm)) + if (!m_util.is_rm_numeral(args[0], rm)) return BR_FAILED; rational q; @@ -169,9 +169,9 @@ br_status fpa_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr br_status fpa_rewriter::mk_add(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; - if (m_util.is_rm_value(arg1, rm)) { + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()); - if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) { + if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3)) { scoped_mpf t(m_util.fm()); m_util.fm().add(rm, v2, v3, t); result = m_util.mk_value(t); @@ -190,9 +190,9 @@ br_status fpa_rewriter::mk_sub(expr * arg1, expr * arg2, expr * arg3, expr_ref & br_status fpa_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; - if (m_util.is_rm_value(arg1, rm)) { + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()); - if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) { + if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3)) { scoped_mpf t(m_util.fm()); m_util.fm().mul(rm, v2, v3, t); result = m_util.mk_value(t); @@ -205,9 +205,9 @@ br_status fpa_rewriter::mk_mul(expr * arg1, expr * arg2, expr * arg3, expr_ref & br_status fpa_rewriter::mk_div(expr * arg1, expr * arg2, expr * arg3, expr_ref & result) { mpf_rounding_mode rm; - if (m_util.is_rm_value(arg1, rm)) { + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()); - if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3)) { + if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3)) { scoped_mpf t(m_util.fm()); m_util.fm().div(rm, v2, v3, t); result = m_util.mk_value(t); @@ -241,7 +241,7 @@ br_status fpa_rewriter::mk_neg(expr * arg1, expr_ref & result) { } scoped_mpf v1(m_util.fm()); - if (m_util.is_value(arg1, v1)) { + if (m_util.is_numeral(arg1, v1)) { m_util.fm().neg(v1); result = m_util.mk_value(v1); return BR_DONE; @@ -253,7 +253,7 @@ br_status fpa_rewriter::mk_neg(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_rem(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); - if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { scoped_mpf t(m_util.fm()); m_util.fm().rem(v1, v2, t); result = m_util.mk_value(t); @@ -316,9 +316,9 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg4, expr_ref & result) { mpf_rounding_mode rm; - if (m_util.is_rm_value(arg1, rm)) { + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_util.fm()), v3(m_util.fm()), v4(m_util.fm()); - if (m_util.is_value(arg2, v2) && m_util.is_value(arg3, v3) && m_util.is_value(arg4, v4)) { + if (m_util.is_numeral(arg2, v2) && m_util.is_numeral(arg3, v3) && m_util.is_numeral(arg4, v4)) { scoped_mpf t(m_util.fm()); m_util.fm().fused_mul_add(rm, v2, v3, v4, t); result = m_util.mk_value(t); @@ -331,9 +331,9 @@ br_status fpa_rewriter::mk_fma(expr * arg1, expr * arg2, expr * arg3, expr * arg br_status fpa_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { mpf_rounding_mode rm; - if (m_util.is_rm_value(arg1, rm)) { + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_util.fm()); - if (m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg2, v2)) { scoped_mpf t(m_util.fm()); m_util.fm().sqrt(rm, v2, t); result = m_util.mk_value(t); @@ -346,9 +346,9 @@ br_status fpa_rewriter::mk_sqrt(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) { mpf_rounding_mode rm; - if (m_util.is_rm_value(arg1, rm)) { + if (m_util.is_rm_numeral(arg1, rm)) { scoped_mpf v2(m_util.fm()); - if (m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg2, v2)) { scoped_mpf t(m_util.fm()); m_util.fm().round_to_integral(rm, v2, t); result = m_util.mk_value(t); @@ -362,7 +362,7 @@ br_status fpa_rewriter::mk_round(expr * arg1, expr * arg2, expr_ref & result) { // This the floating point theory == br_status fpa_rewriter::mk_float_eq(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); - if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { result = (m_util.fm().eq(v1, v2)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -407,7 +407,7 @@ br_status fpa_rewriter::mk_lt(expr * arg1, expr * arg2, expr_ref & result) { } scoped_mpf v1(m_util.fm()), v2(m_util.fm()); - if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { result = (m_util.fm().lt(v1, v2)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -427,7 +427,7 @@ br_status fpa_rewriter::mk_le(expr * arg1, expr * arg2, expr_ref & result) { return BR_DONE; } scoped_mpf v1(m_util.fm()), v2(m_util.fm()); - if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { result = (m_util.fm().le(v1, v2)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -442,7 +442,7 @@ br_status fpa_rewriter::mk_ge(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_is_zero(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_zero(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -452,7 +452,7 @@ br_status fpa_rewriter::mk_is_zero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_nzero(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -462,7 +462,7 @@ br_status fpa_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_pzero(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -472,7 +472,7 @@ br_status fpa_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_nan(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -482,7 +482,7 @@ br_status fpa_rewriter::mk_is_nan(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_inf(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -492,7 +492,7 @@ br_status fpa_rewriter::mk_is_inf(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_normal(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -502,7 +502,7 @@ br_status fpa_rewriter::mk_is_normal(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_denormal(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -512,7 +512,7 @@ br_status fpa_rewriter::mk_is_subnormal(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_neg(v)) ? m().mk_true() : m().mk_false(); return BR_DONE; } @@ -522,7 +522,7 @@ br_status fpa_rewriter::mk_is_negative(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { scoped_mpf v(m_util.fm()); - if (m_util.is_value(arg1, v)) { + if (m_util.is_numeral(arg1, v)) { result = (m_util.fm().is_neg(v) || m_util.fm().is_nan(v)) ? m().mk_false() : m().mk_true(); return BR_DONE; } @@ -534,7 +534,7 @@ br_status fpa_rewriter::mk_is_positive(expr * arg1, expr_ref & result) { // This the SMT = br_status fpa_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result) { scoped_mpf v1(m_util.fm()), v2(m_util.fm()); - if (m_util.is_value(arg1, v1) && m_util.is_value(arg2, v2)) { + if (m_util.is_numeral(arg1, v1) && m_util.is_numeral(arg2, v2)) { // Note: == is the floats-equality, here we need normal equality. result = (m_fm.is_nan(v1) && m_fm.is_nan(v2)) ? m().mk_true() : (m_fm.is_zero(v1) && m_fm.is_zero(v2) && m_fm.sgn(v1)!=m_fm.sgn(v2)) ? m().mk_false() : @@ -584,7 +584,7 @@ br_status fpa_rewriter::mk_to_sbv(expr * arg1, expr * arg2, expr_ref & result) { br_status fpa_rewriter::mk_to_real(expr * arg1, expr_ref & result) { scoped_mpf fv(m_util.fm()); - if (m_util.is_value(arg1, fv)) { + if (m_util.is_numeral(arg1, fv)) { if (m_fm.is_nan(fv) || m_fm.is_inf(fv)) { result = m_util.mk_internal_to_real_unspecified(); } diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 487908173..158622428 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -647,11 +647,11 @@ namespace smt { wrapped = wrap(n); mpf_rounding_mode rm; scoped_mpf val(mpfm); - if (m_fpa_util.is_rm_value(n, rm)) { + if (m_fpa_util.is_rm_numeral(n, rm)) { c = m.mk_eq(wrapped, m_bv_util.mk_numeral(rm, 3)); assert_cnstr(c); } - else if (m_fpa_util.is_value(n, val)) { + else if (m_fpa_util.is_numeral(n, val)) { unsigned sz = val.get().get_ebits() + val.get().get_sbits(); expr_ref bv_val_e(m); bv_val_e = convert(n); @@ -714,8 +714,8 @@ namespace smt { // If the owner is not internalized, it doesn't have an enode associated. SASSERT(ctx.e_internalized(owner)); - if (m_fpa_util.is_rm_value(owner) || - m_fpa_util.is_value(owner)) + if (m_fpa_util.is_rm_numeral(owner) || + m_fpa_util.is_numeral(owner)) return alloc(expr_wrapper_proc, owner); model_value_proc * res = 0; From 33dc6340e16ef1ae15b47495b5472a98edcb2128 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 14:23:13 +0000 Subject: [PATCH 132/507] More renaming mk_value -> mk_numeral Signed-off-by: Christoph M. Wintersteiger --- src/ast/ast_smt2_pp.cpp | 4 ++-- src/ast/fpa/fpa2bv_converter.h | 4 ++-- src/ast/fpa/fpa2bv_rewriter.h | 2 +- src/ast/fpa_decl_plugin.cpp | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index 982b80d37..035e228fb 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -228,7 +228,7 @@ format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits, bool u ast_manager & m = get_manager(); format * body = 0; string_buffer<> buf; - VERIFY(get_futil().is_value(t, v)); + VERIFY(get_futil().is_numeral(t, v)); if (fm.is_nan(v)) { buf << "(_ NaN " << v.get().get_ebits() << " " << v.get().get_sbits() << ")"; return mk_string(m, buf.c_str()); @@ -575,7 +575,7 @@ class smt2_printer { else if (m_env.get_bvutil().is_numeral(c)) { f = m_env.pp_bv_literal(c, m_pp_bv_lits, m_pp_bv_neg); } - else if (m_env.get_futil().is_value(c)) { + else if (m_env.get_futil().is_numeral(c)) { f = m_env.pp_float_literal(c, m_pp_bv_lits, m_pp_float_real_lits); } else if (m_env.get_dlutil().is_numeral(c)) { diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index efc4d9179..062c56ef2 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -50,7 +50,7 @@ protected: arith_util m_arith_util; mpf_manager & m_mpf_manager; unsynch_mpz_manager & m_mpz_manager; - fpa_decl_plugin * m_plugin; + fpa_decl_plugin * m_plugin; bool m_hi_fp_unspecified; obj_map m_const2bv; @@ -86,7 +86,7 @@ public: void mk_ite(expr * c, expr * t, expr * f, expr_ref & result); void mk_rounding_mode(func_decl * f, expr_ref & result); - void mk_value(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result); virtual void mk_const(func_decl * f, expr_ref & result); virtual void mk_rm_const(func_decl * f, expr_ref & result); void mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index c7a987b83..75176c9c4 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -120,7 +120,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FPA_RM_TOWARD_NEGATIVE: case OP_FPA_RM_TOWARD_POSITIVE: case OP_FPA_RM_TOWARD_ZERO: m_conv.mk_rounding_mode(f, result); return BR_DONE; - case OP_FPA_VALUE: m_conv.mk_value(f, num, args, result); return BR_DONE; + case OP_FPA_NUM: m_conv.mk_numeral(f, num, args, result); return BR_DONE; case OP_FPA_PLUS_INF: m_conv.mk_pinf(f, result); return BR_DONE; case OP_FPA_MINUS_INF: m_conv.mk_ninf(f, result); return BR_DONE; case OP_FPA_PLUS_ZERO: m_conv.mk_pzero(f, result); return BR_DONE; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 7d4a77d1c..a8e805066 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -68,18 +68,18 @@ void fpa_decl_plugin::recycled_id(unsigned id) { m_fm.del(m_values[id]); } -func_decl * fpa_decl_plugin::mk_value_decl(mpf const & v) { +func_decl * fpa_decl_plugin::mk_numeral_decl(mpf const & v) { parameter p(mk_id(v), true); SASSERT(p.is_external()); sort * s = mk_float_sort(v.get_ebits(), v.get_sbits()); return m_manager->mk_const_decl(symbol("fpa"), s, func_decl_info(m_family_id, OP_FPA_NUM, 1, &p)); } -app * fpa_decl_plugin::mk_value(mpf const & v) { - return m_manager->mk_const(mk_value_decl(v)); +app * fpa_decl_plugin::mk_numeral(mpf const & v) { + return m_manager->mk_const(mk_numeral_decl(v)); } -bool fpa_decl_plugin::is_value(expr * n, mpf & val) { +bool fpa_decl_plugin::is_numeral(expr * n, mpf & val) { if (is_app_of(n, m_family_id, OP_FPA_NUM)) { m_fm.set(val, m_values[to_app(n)->get_decl()->get_parameter(0).get_ext_id()]); return true; @@ -117,7 +117,7 @@ bool fpa_decl_plugin::is_value(expr * n, mpf & val) { return false; } -bool fpa_decl_plugin::is_rm_value(expr * n, mpf_rounding_mode & val) { +bool fpa_decl_plugin::is_rm_numeral(expr * n, mpf_rounding_mode & val) { if (is_app_of(n, m_family_id, OP_FPA_RM_NEAREST_TIES_TO_AWAY)) { val = MPF_ROUND_NEAREST_TAWAY; return true; @@ -260,7 +260,7 @@ func_decl * fpa_decl_plugin::mk_float_const_decl(decl_kind k, unsigned num_param case OP_FPA_PLUS_ZERO: m_fm.mk_pzero(ebits, sbits, val); break; } - return mk_value_decl(val); + return mk_numeral_decl(val); } func_decl * fpa_decl_plugin::mk_bin_rel_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, @@ -846,7 +846,7 @@ expr * fpa_decl_plugin::get_some_value(sort * s) { SASSERT(s->is_sort_of(m_family_id, FLOATING_POINT_SORT)); mpf tmp; m_fm.mk_nan(s->get_parameter(0).get_int(), s->get_parameter(1).get_int(), tmp); - expr * res = this->mk_value(tmp); + expr * res = this->mk_numeral(tmp); m_fm.del(tmp); return res; } From bcbce8f190d93117abaaefe0a6de94cccda468a7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 16:31:09 +0000 Subject: [PATCH 133/507] FPA Java and .NET API updates Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 1 - src/api/dotnet/Expr.cs | 270 ++++++++++++++++++++++++++++ src/api/dotnet/FPExpr.cs | 12 +- src/api/dotnet/FPNum.cs | 1 - src/api/dotnet/FPRMNum.cs | 49 +++++ src/api/java/Expr.java | 366 +++++++++++++++++++++++++++++++++++++- 6 files changed, 693 insertions(+), 6 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 609db802d..9eb544f8a 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -4161,7 +4161,6 @@ namespace Microsoft.Z3 Contract.Ensures(Contract.Result() != null); return new FPExpr(this, Native.Z3_mk_fpa_to_fp_float(this.nCtx, s.NativeObject, rm.NativeObject, t.NativeObject)); } - #endregion #region Conversions from FloatingPoint terms diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index 826860eec..5f0c4218c 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1448,6 +1448,276 @@ namespace Microsoft.Z3 /// Indicates whether the term is a less than predicate over a finite domain. /// public bool IsFiniteDomainLT { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FD_LT; } } + #endregion + + #region Floating-point terms + /// + /// Indicates whether the terms is of floating-point sort. + /// + public bool IsFP + { + get { return Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_FLOATING_POINT_SORT; } + } + + /// + /// Indicates whether the terms is of floating-point rounding mode sort. + /// + public bool IsFPRM + { + get { return Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_ROUNDING_MODE_SORT; } + } + + /// + /// Indicates whether the term is a floating-point numeral + /// + public bool IsFPNumeral { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_NUM; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool IsFPRMNumRoundNearestTiesToEven{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool IsFPRMNumRoundNearestTiesToAway{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool IsFPRMNumRoundTowardNegative{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool IsFPRMNumRoundTowardPositive{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool IsFPRMNumRoundTowardZero{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool IsFPRMNumRNE{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool IsFPRMNumRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool IsFPRMNumRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool IsFPRMNumRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool IsFPRMNumRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + + /// + /// Indicates whether the term is a floating-point rounding mode numeral + /// + public bool IsFPRMNum { + get { + return IsApp && + (FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY|| + FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN || + FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE || + FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE || + FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO); + } + } + + /// + /// Indicates whether the term is a floating-point +oo + /// + public bool IsFPPlusInfinity{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_PLUS_INF; } } + + /// + /// Indicates whether the term is a floating-point -oo + /// + public bool IsFPMinusInfinity{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_MINUS_INF; } } + + /// + /// Indicates whether the term is a floating-point NaN + /// + public bool IsFPNaN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_NAN; } } + + /// + /// Indicates whether the term is a floating-point +zero + /// + public bool IsFPPlusZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_PLUS_ZERO; } } + + /// + /// Indicates whether the term is a floating-point -zero + /// + public bool IsFPMinusZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_MINUS_ZERO; } } + + /// + /// Indicates whether the term is a floating-point addition term + /// + public bool IsFPAdd { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_ADD; } } + + + /// + /// Indicates whether the term is a floating-point subtraction term + /// + public bool IsFPSub { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_SUB; } } + + /// + /// Indicates whether the term is a floating-point negation term + /// + public bool IsFPNeg { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_NEG; } } + + /// + /// Indicates whether the term is a floating-point multiplication term + /// + public bool IsFPMul { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_MUL; } } + + /// + /// Indicates whether the term is a floating-point divison term + /// + public bool IsFPDiv { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_DIV; } } + + /// + /// Indicates whether the term is a floating-point remainder term + /// + public bool IsFPRem { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_REM; } } + + /// + /// Indicates whether the term is a floating-point term absolute value term + /// + public bool IsFPAbs { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_ABS; } } + + /// + /// Indicates whether the term is a floating-point minimum term + /// + public bool IsFPMin { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_MIN; } } + + /// + /// Indicates whether the term is a floating-point maximum term + /// + public bool IsFPMax { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_MAX; } } + + /// + /// Indicates whether the term is a floating-point fused multiply-add term + /// + public bool IsFPFMA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_FMA; } } + + /// + /// Indicates whether the term is a floating-point square root term + /// + public bool IsFPSqrt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_SQRT; } } + + /// + /// Indicates whether the term is a floating-point roundToIntegral term + /// + public bool IsFPRoundToIntegral { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_ROUND_TO_INTEGRAL; } } + + /// + /// Indicates whether the term is a floating-point equality term + /// + public bool IsFPEq { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_EQ; } } + + /// + /// Indicates whether the term is a floating-point less-than term + /// + public bool IsFPLt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_LT; } } + + /// + /// Indicates whether the term is a floating-point greater-than term + /// + public bool IsFPGt { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_GT; } } + + /// + /// Indicates whether the term is a floating-point less-than or equal term + /// + public bool IsFPLe { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_LE; } } + + /// + /// Indicates whether the term is a floating-point greater-than or erqual term + /// + public bool IsFPGe { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_GE; } } + + /// + /// Indicates whether the term is a floating-point isNaN predicate term + /// + public bool IsFPisNaN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_NAN; } } + + /// + /// Indicates whether the term is a floating-point isInf predicate term + /// + public bool IsFPisInf { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_INF; } } + + /// + /// Indicates whether the term is a floating-point isZero predicate term + /// + public bool IsFPisZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_ZERO; } } + + /// + /// Indicates whether the term is a floating-point isNormal term + /// + public bool IsFPisNormal { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_NORMAL; } } + + /// + /// Indicates whether the term is a floating-point isSubnormal predicate term + /// + public bool IsFPisSubnormal { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_SUBNORMAL; } } + + /// + /// Indicates whether the term is a floating-point isNegative predicate term + /// + public bool IsFPisNegative { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_NEGATIVE; } } + + /// + /// Indicates whether the term is a floating-point isPositive predicate term + /// + public bool IsFPisPositive { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_IS_POSITIVE; } } + + /// + /// Indicates whether the term is a floating-point constructor term + /// + public bool IsFPFP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_FP; } } + + /// + /// Indicates whether the term is a floating-point conversion term + /// + public bool IsFPToFp { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_TO_FP; } } + + /// + /// Indicates whether the term is a floating-point conversion from unsigned bit-vector term + /// + public bool IsFPToFpUnsigned { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_TO_FP_UNSIGNED; } } + + /// + /// Indicates whether the term is a floating-point conversion to unsigned bit-vector term + /// + public bool IsFPToUBV { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_TO_UBV; } } + + /// + /// Indicates whether the term is a floating-point conversion to signed bit-vector term + /// + public bool IsFPToSBV { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_TO_SBV; } } + + /// + /// Indicates whether the term is a floating-point conversion to real term + /// + public bool IsFPToReal { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_TO_REAL; } } + + + /// + /// Indicates whether the term is a floating-point conversion to IEEE-754 bit-vector term + /// + public bool IsFPToIEEEBV { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_TO_IEEE_BV; } } + #endregion #endregion diff --git a/src/api/dotnet/FPExpr.cs b/src/api/dotnet/FPExpr.cs index cbba272d1..bbd557017 100644 --- a/src/api/dotnet/FPExpr.cs +++ b/src/api/dotnet/FPExpr.cs @@ -24,12 +24,22 @@ using System.Text; using System.Diagnostics.Contracts; namespace Microsoft.Z3 -{ +{ /// /// FloatingPoint Expressions /// public class FPExpr : Expr { + /// + /// The number of exponent bits. + /// + public uint EBits { get { return ((FPSort)Sort).EBits; } } + + /// + /// The number of significand bits. + /// + public uint SBits { get { return ((FPSort)Sort).EBits; } } + #region Internal /// Constructor for FPExpr internal protected FPExpr(Context ctx) diff --git a/src/api/dotnet/FPNum.cs b/src/api/dotnet/FPNum.cs index ab57d57c3..14c089198 100644 --- a/src/api/dotnet/FPNum.cs +++ b/src/api/dotnet/FPNum.cs @@ -27,7 +27,6 @@ namespace Microsoft.Z3 [ContractVerification(true)] public class FPNum : FPExpr { - #region Internal internal FPNum(Context ctx, IntPtr obj) : base(ctx, obj) diff --git a/src/api/dotnet/FPRMNum.cs b/src/api/dotnet/FPRMNum.cs index 7caa56f9f..628480d96 100644 --- a/src/api/dotnet/FPRMNum.cs +++ b/src/api/dotnet/FPRMNum.cs @@ -27,6 +27,55 @@ namespace Microsoft.Z3 [ContractVerification(true)] public class FPRMNum : FPRMExpr { + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool isRoundNearestTiesToEven { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool isRNE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool isRoundNearestTiesToAway { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool isRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool isRoundTowardPositive { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool isRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool isRoundTowardNegative { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool isRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool isRoundTowardZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool isRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } #region Internal internal FPRMNum(Context ctx, IntPtr obj) diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 233076516..4bd522b51 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -1709,6 +1709,366 @@ public class Expr extends AST return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FD_LT; } + + /** + * Indicates whether the terms is of floating-point sort. + * @throws Z3Exception + */ + public boolean IsFP() throws Z3Exception { return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_FLOATING_POINT_SORT; } + + /** + * Indicates whether the terms is of floating-point rounding mode sort. + * @return + * @throws Z3Exception + */ + public boolean IsFPRM() throws Z3Exception { return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_ROUNDING_MODE_SORT; } + + /** + * Indicates whether the term is a floating-point numeral + * @return + * @throws Z3Exception + */ + public boolean IsFPNumeral() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NUM; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRoundNearestTiesToEven() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRoundNearestTiesToAway() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardNegative + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRoundTowardNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardPositive + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRoundTowardPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardZero + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRoundTowardZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRNE() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRNA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardNegative + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRTN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardPositive + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRTP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardZero + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNumRTZ() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } + + /** + * Indicates whether the term is a floating-point rounding mode numeral + * @return + * @throws Z3Exception + */ + public boolean IsFPRMNum() throws Z3Exception { + return isApp() && + (getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY || + getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN || + getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE || + getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE || + getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO); + } + + /** + * Indicates whether the term is a floating-point +oo + * @return + * @throws Z3Exception + */ + public boolean IsFPPlusInfinity() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_PLUS_INF; } + + /** + * Indicates whether the term is a floating-point -oo + * @return + * @throws Z3Exception + */ + public boolean IsFPMinusInfinity() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MINUS_INF; } + + /** + * Indicates whether the term is a floating-point NaN + * @return + * @throws Z3Exception + */ + public boolean IsFPNaN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NAN; } + + /** + * Indicates whether the term is a floating-point +zero + * @return + * @throws Z3Exception + */ + public boolean IsFPPlusZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_PLUS_ZERO; } + + /** + * Indicates whether the term is a floating-point -zero + * @return + * @throws Z3Exception + */ + public boolean IsFPMinusZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MINUS_ZERO; } + + /** + * Indicates whether the term is a floating-point addition term + * @return + * @throws Z3Exception + */ + public boolean IsFPAdd() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ADD; } + + + /** + * Indicates whether the term is a floating-point subtraction term + * @return + * @throws Z3Exception + */ + public boolean IsFPSub() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_SUB; } + + /** + * Indicates whether the term is a floating-point negation term + * @return + * @throws Z3Exception + */ + public boolean IsFPNeg() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NEG; } + + /** + * Indicates whether the term is a floating-point multiplication term + * @return + * @throws Z3Exception + */ + public boolean IsFPMul() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MUL; } + + /** + * Indicates whether the term is a floating-point divison term + * @return + * @throws Z3Exception + */ + public boolean IsFPDiv() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_DIV; } + + /** + * Indicates whether the term is a floating-point remainder term + * @return + * @throws Z3Exception + */ + public boolean IsFPRem() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_REM; } + + /** + * Indicates whether the term is a floating-point term absolute value term + * @return + * @throws Z3Exception + */ + public boolean IsFPAbs() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ABS; } + + /** + * Indicates whether the term is a floating-point minimum term + * @return + * @throws Z3Exception + */ + public boolean IsFPMin() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MIN; } + + /** + * Indicates whether the term is a floating-point maximum term + * @return + * @throws Z3Exception + */ + public boolean IsFPMax() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MAX; } + + /** + * Indicates whether the term is a floating-point fused multiply-add term + * @return + * @throws Z3Exception + */ + public boolean IsFPFMA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_FMA; } + + /** + * Indicates whether the term is a floating-point square root term + * @return + * @throws Z3Exception + */ + public boolean IsFPSqrt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_SQRT; } + + /** + * Indicates whether the term is a floating-point roundToIntegral term + * @return + * @throws Z3Exception + */ + public boolean IsFPRoundToIntegral() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ROUND_TO_INTEGRAL; } + + /** + * Indicates whether the term is a floating-point equality term + * @return + * @throws Z3Exception + */ + public boolean IsFPEq() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_EQ; } + + /** + * Indicates whether the term is a floating-point less-than term + * @return + * @throws Z3Exception + */ + public boolean IsFPLt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_LT; } + + /** + * Indicates whether the term is a floating-point greater-than term + * @return + * @throws Z3Exception + */ + public boolean IsFPGt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_GT; } + + /** + * Indicates whether the term is a floating-point less-than or equal term + * @return + * @throws Z3Exception + */ + public boolean IsFPLe() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_LE; } + + /** + * Indicates whether the term is a floating-point greater-than or erqual term + * @return + * @throws Z3Exception + */ + public boolean IsFPGe() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_GE; } + + /** + * Indicates whether the term is a floating-point isNaN predicate term + * @return + * @throws Z3Exception + */ + public boolean IsFPisNaN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NAN; } + + /** + * Indicates whether the term is a floating-point isInf predicate term + * @return + * @throws Z3Exception + */ + public boolean IsFPisInf() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_INF; } + + /** + * Indicates whether the term is a floating-point isZero predicate term + * @return + * @throws Z3Exception + */ + public boolean IsFPisZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_ZERO; } + + /** + * Indicates whether the term is a floating-point isNormal term + * @return + * @throws Z3Exception + */ + public boolean IsFPisNormal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NORMAL; } + + /** + * Indicates whether the term is a floating-point isSubnormal predicate term + * @return + * @throws Z3Exception + */ + public boolean IsFPisSubnormal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_SUBNORMAL; } + + /** + * Indicates whether the term is a floating-point isNegative predicate term + * @return + * @throws Z3Exception + */ + public boolean IsFPisNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NEGATIVE; } + + /** + * Indicates whether the term is a floating-point isPositive predicate term + * @return + * @throws Z3Exception + */ + public boolean IsFPisPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_POSITIVE; } + + /** + * Indicates whether the term is a floating-point constructor term + * @return + * @throws Z3Exception + */ + public boolean IsFPFP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_FP; } + + /** + * Indicates whether the term is a floating-point conversion term + * @return + * @throws Z3Exception + */ + public boolean IsFPToFp() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_FP; } + + /** + * Indicates whether the term is a floating-point conversion from unsigned bit-vector term + * @return + * @throws Z3Exception + */ + public boolean IsFPToFpUnsigned() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_FP_UNSIGNED; } + + /** + * Indicates whether the term is a floating-point conversion to unsigned bit-vector term + * @return + * @throws Z3Exception + */ + public boolean IsFPToUBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_UBV; } + + /** + * Indicates whether the term is a floating-point conversion to signed bit-vector term + * @return + * @throws Z3Exception + */ + public boolean IsFPToSBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_SBV; } + + /** + * Indicates whether the term is a floating-point conversion to real term + * @return + * @throws Z3Exception + */ + public boolean IsFPToReal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_REAL; } + + + /** + * Indicates whether the term is a floating-point conversion to IEEE-754 bit-vector term1 + * @return + * @throws Z3Exception + */ + public boolean IsFPToIEEEBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_IEEE_BV; } + + /** * The de-Burijn index of a bound variable. Bound variables are * indexed by de-Bruijn indices. It is perhaps easiest to explain the @@ -1793,8 +2153,8 @@ public class Expr extends AST return new BitVecNum(ctx, obj); case Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); - case Z3_FLOATING_POINT_ROUNDING_MODE_SORT: - return new FPRMNum(ctx, obj); + case Z3_ROUNDING_MODE_SORT: + return new FPRMNum(ctx, obj); default: ; } } @@ -1815,7 +2175,7 @@ public class Expr extends AST return new DatatypeExpr(ctx, obj); case Z3_FLOATING_POINT_SORT: return new FPExpr(ctx, obj); - case Z3_FLOATING_POINT_ROUNDING_MODE_SORT: + case Z3_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj); default: ; } From ee2c9095c67bd8fee43b1d92a2b1db4d32b0d29c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 17:21:29 +0000 Subject: [PATCH 134/507] .NET FPA API overhaul Signed-off-by: Christoph M. Wintersteiger --- examples/dotnet/Program.cs | 21 +++++++++++---------- src/api/dotnet/AST.cs | 12 ++++-------- src/api/dotnet/ArithExpr.cs | 5 ----- src/api/dotnet/ArrayExpr.cs | 5 ----- src/api/dotnet/BitVecExpr.cs | 1 - src/api/dotnet/BoolExpr.cs | 2 -- src/api/dotnet/DatatypeExpr.cs | 5 ----- src/api/dotnet/EnumSort.cs | 2 +- src/api/dotnet/Expr.cs | 4 ---- src/api/dotnet/FPExpr.cs | 5 ----- src/api/dotnet/FPRMExpr.cs | 5 ----- src/api/dotnet/IntExpr.cs | 5 ----- src/api/dotnet/ListSort.cs | 4 ++-- src/api/dotnet/Quantifier.cs | 4 ++-- src/api/dotnet/RealExpr.cs | 5 ----- src/api/dotnet/Sort.cs | 5 +++-- src/api/dotnet/TupleSort.cs | 2 +- 17 files changed, 24 insertions(+), 68 deletions(-) diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index b03cfd28c..0c33d6793 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -2084,25 +2084,26 @@ namespace test_mapi FPRMExpr rm = (FPRMExpr)ctx.MkConst(ctx.MkSymbol("rm"), rm_sort); BitVecExpr x = (BitVecExpr)ctx.MkConst(ctx.MkSymbol("x"), ctx.MkBitVecSort(64)); - FPExpr y = (FPExpr)ctx.MkConst(ctx.MkSymbol("y"), double_sort); - RealExpr real_val = ctx.MkReal(42); - BitVecExpr bv_val = ctx.MkBV(42, 64); + FPExpr y = (FPExpr)ctx.MkConst(ctx.MkSymbol("y"), double_sort); FPExpr fp_val = ctx.MkFP(42, double_sort); - BoolExpr c1 = ctx.MkEq(x, ctx.MkFPToIEEEBV(fp_val)); - BoolExpr c2 = ctx.MkEq(x, ctx.MkBV(42, 64)); - BoolExpr c3 = ctx.MkEq(fp_val, ctx.MkFPToFP(rm, real_val, double_sort)); - BoolExpr c4 = ctx.MkAnd(c1, c2); - Console.WriteLine("c3 = " + c3); + BoolExpr c1 = ctx.MkEq(y, fp_val); + BoolExpr c2 = ctx.MkEq(x, ctx.MkFPToBV(rm, y, 64, false)); + BoolExpr c3 = ctx.MkEq(x, ctx.MkBV(42, 64)); + BoolExpr c4 = ctx.MkEq(ctx.MkNumeral(42, ctx.RealSort), ctx.MkFPToReal(fp_val)); + BoolExpr c5 = ctx.MkAnd(c1, c2, c3, c4); + Console.WriteLine("c5 = " + c5); /* Generic solver */ Solver s = ctx.MkSolver(); - s.Assert(c3); + s.Assert(c5); + + Console.WriteLine(s); if (s.Check() != Status.SATISFIABLE) throw new TestFailedException(); - Console.WriteLine("OK, model: ", s.Model.ToString()); + Console.WriteLine("OK, model: {0}", s.Model.ToString()); } static void Main(string[] args) diff --git a/src/api/dotnet/AST.cs b/src/api/dotnet/AST.cs index 7bc4f6dfb..d3b31a325 100644 --- a/src/api/dotnet/AST.cs +++ b/src/api/dotnet/AST.cs @@ -227,10 +227,8 @@ namespace Microsoft.Z3 internal override void IncRef(IntPtr o) { // Console.WriteLine("AST IncRef()"); - if (Context == null) - throw new Z3Exception("inc() called on null context"); - if (o == IntPtr.Zero) - throw new Z3Exception("inc() called on null AST"); + if (Context == null || o == IntPtr.Zero) + return; Context.AST_DRQ.IncAndClear(Context, o); base.IncRef(o); } @@ -238,10 +236,8 @@ namespace Microsoft.Z3 internal override void DecRef(IntPtr o) { // Console.WriteLine("AST DecRef()"); - if (Context == null) - throw new Z3Exception("dec() called on null context"); - if (o == IntPtr.Zero) - throw new Z3Exception("dec() called on null AST"); + if (Context == null || o == IntPtr.Zero) + return; Context.AST_DRQ.Add(o); base.DecRef(o); } diff --git a/src/api/dotnet/ArithExpr.cs b/src/api/dotnet/ArithExpr.cs index bdfa7a3f0..7858ff3e1 100644 --- a/src/api/dotnet/ArithExpr.cs +++ b/src/api/dotnet/ArithExpr.cs @@ -32,11 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for ArithExpr - internal protected ArithExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal ArithExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/ArrayExpr.cs b/src/api/dotnet/ArrayExpr.cs index 915bfd0f1..e14bb1083 100644 --- a/src/api/dotnet/ArrayExpr.cs +++ b/src/api/dotnet/ArrayExpr.cs @@ -32,11 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for ArrayExpr - internal protected ArrayExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal ArrayExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/BitVecExpr.cs b/src/api/dotnet/BitVecExpr.cs index a146e7a19..b019f8845 100644 --- a/src/api/dotnet/BitVecExpr.cs +++ b/src/api/dotnet/BitVecExpr.cs @@ -41,7 +41,6 @@ namespace Microsoft.Z3 #region Internal /// Constructor for BitVecExpr - internal protected BitVecExpr(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } internal BitVecExpr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } #endregion } diff --git a/src/api/dotnet/BoolExpr.cs b/src/api/dotnet/BoolExpr.cs index cbe3b1868..a9a15e4dc 100644 --- a/src/api/dotnet/BoolExpr.cs +++ b/src/api/dotnet/BoolExpr.cs @@ -32,8 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for BoolExpr - internal protected BoolExpr(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } - /// Constructor for BoolExpr internal BoolExpr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } #endregion } diff --git a/src/api/dotnet/DatatypeExpr.cs b/src/api/dotnet/DatatypeExpr.cs index 93cea54f5..ba3a9d478 100644 --- a/src/api/dotnet/DatatypeExpr.cs +++ b/src/api/dotnet/DatatypeExpr.cs @@ -32,11 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for DatatypeExpr - internal protected DatatypeExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal DatatypeExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/EnumSort.cs b/src/api/dotnet/EnumSort.cs index e62043078..f7ba98222 100644 --- a/src/api/dotnet/EnumSort.cs +++ b/src/api/dotnet/EnumSort.cs @@ -78,7 +78,7 @@ namespace Microsoft.Z3 #region Internal internal EnumSort(Context ctx, Symbol name, Symbol[] enumNames) - : base(ctx) + : base(ctx, IntPtr.Zero) { Contract.Requires(ctx != null); Contract.Requires(name != null); diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index 5f0c4218c..97e57b920 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1759,10 +1759,6 @@ namespace Microsoft.Z3 /// /// Constructor for Expr /// - internal protected Expr(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } - /// - /// Constructor for Expr - /// internal protected Expr(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } #if DEBUG diff --git a/src/api/dotnet/FPExpr.cs b/src/api/dotnet/FPExpr.cs index bbd557017..85fdf2603 100644 --- a/src/api/dotnet/FPExpr.cs +++ b/src/api/dotnet/FPExpr.cs @@ -42,11 +42,6 @@ namespace Microsoft.Z3 #region Internal /// Constructor for FPExpr - internal protected FPExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal FPExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/FPRMExpr.cs b/src/api/dotnet/FPRMExpr.cs index 92fea1ad4..896c3e6b9 100644 --- a/src/api/dotnet/FPRMExpr.cs +++ b/src/api/dotnet/FPRMExpr.cs @@ -32,11 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for FPRMExpr - internal protected FPRMExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal FPRMExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/IntExpr.cs b/src/api/dotnet/IntExpr.cs index 58bf1b973..622be7bd5 100644 --- a/src/api/dotnet/IntExpr.cs +++ b/src/api/dotnet/IntExpr.cs @@ -32,11 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for IntExpr - internal protected IntExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal IntExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/ListSort.cs b/src/api/dotnet/ListSort.cs index 7dbafb385..e860e4d4b 100644 --- a/src/api/dotnet/ListSort.cs +++ b/src/api/dotnet/ListSort.cs @@ -113,9 +113,9 @@ namespace Microsoft.Z3 } } - #region Internal + #region Internal internal ListSort(Context ctx, Symbol name, Sort elemSort) - : base(ctx) + : base(ctx, IntPtr.Zero) { Contract.Requires(ctx != null); Contract.Requires(name != null); diff --git a/src/api/dotnet/Quantifier.cs b/src/api/dotnet/Quantifier.cs index f59d0bda2..38e435309 100644 --- a/src/api/dotnet/Quantifier.cs +++ b/src/api/dotnet/Quantifier.cs @@ -160,7 +160,7 @@ namespace Microsoft.Z3 #region Internal [ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug internal Quantifier(Context ctx, bool isForall, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - : base(ctx) + : base(ctx, IntPtr.Zero) { Contract.Requires(ctx != null); Contract.Requires(sorts != null); @@ -203,7 +203,7 @@ namespace Microsoft.Z3 [ContractVerification(false)] // F: Clousot ForAll decompilation gets confused below. Setting verification off until I fixed the bug internal Quantifier(Context ctx, bool isForall, Expr[] bound, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - : base(ctx) + : base(ctx, IntPtr.Zero) { Contract.Requires(ctx != null); Contract.Requires(body != null); diff --git a/src/api/dotnet/RealExpr.cs b/src/api/dotnet/RealExpr.cs index 26adc1fc6..8ee8c8e76 100644 --- a/src/api/dotnet/RealExpr.cs +++ b/src/api/dotnet/RealExpr.cs @@ -32,11 +32,6 @@ namespace Microsoft.Z3 { #region Internal /// Constructor for RealExpr - internal protected RealExpr(Context ctx) - : base(ctx) - { - Contract.Requires(ctx != null); - } internal RealExpr(Context ctx, IntPtr obj) : base(ctx, obj) { diff --git a/src/api/dotnet/Sort.cs b/src/api/dotnet/Sort.cs index 9dc23ea09..412398ddd 100644 --- a/src/api/dotnet/Sort.cs +++ b/src/api/dotnet/Sort.cs @@ -116,8 +116,7 @@ namespace Microsoft.Z3 #region Internal /// /// Sort constructor - /// - internal protected Sort(Context ctx) : base(ctx) { Contract.Requires(ctx != null); } + /// internal Sort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } #if DEBUG @@ -146,6 +145,8 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_UNINTERPRETED_SORT: return new UninterpretedSort(ctx, obj); case Z3_sort_kind.Z3_FINITE_DOMAIN_SORT: return new FiniteDomainSort(ctx, obj); case Z3_sort_kind.Z3_RELATION_SORT: return new RelationSort(ctx, obj); + case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPSort(ctx, obj); + case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMSort(ctx, obj); default: throw new Z3Exception("Unknown sort kind"); } diff --git a/src/api/dotnet/TupleSort.cs b/src/api/dotnet/TupleSort.cs index 81a0eaf60..ea99f3855 100644 --- a/src/api/dotnet/TupleSort.cs +++ b/src/api/dotnet/TupleSort.cs @@ -68,7 +68,7 @@ namespace Microsoft.Z3 #region Internal internal TupleSort(Context ctx, Symbol name, uint numFields, Symbol[] fieldNames, Sort[] fieldSorts) - : base(ctx) + : base(ctx, IntPtr.Zero) { Contract.Requires(ctx != null); Contract.Requires(name != null); From 7fe9ad5cb4a7829374e04f318d8b1b7bfd8b5b21 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 17:22:02 +0000 Subject: [PATCH 135/507] Java FPA API overhaul Signed-off-by: Christoph M. Wintersteiger --- examples/java/JavaExample.java | 20 ++++++++++---------- src/api/java/AST.java | 12 ++++-------- src/api/java/ArithExpr.java | 5 ----- src/api/java/ArrayExpr.java | 5 ----- src/api/java/BitVecExpr.java | 5 ----- src/api/java/BoolExpr.java | 8 -------- src/api/java/Context.java | 6 +----- src/api/java/DatatypeExpr.java | 5 ----- src/api/java/EnumSort.java | 2 +- src/api/java/Expr.java | 15 +-------------- src/api/java/IntExpr.java | 5 ----- src/api/java/ListSort.java | 2 +- src/api/java/Quantifier.java | 4 ++-- src/api/java/RealExpr.java | 5 ----- src/api/java/Sort.java | 13 ++++--------- src/api/java/TupleSort.java | 2 +- 16 files changed, 25 insertions(+), 89 deletions(-) diff --git a/examples/java/JavaExample.java b/examples/java/JavaExample.java index 878ec4693..af8662700 100644 --- a/examples/java/JavaExample.java +++ b/examples/java/JavaExample.java @@ -2212,29 +2212,29 @@ class JavaExample { System.out.println("FloatingPointExample2"); Log.append("FloatingPointExample2"); - FPSort double_sort = ctx.mkFPSort(11, 53); FPRMSort rm_sort = ctx.mkFPRoundingModeSort(); FPRMExpr rm = (FPRMExpr)ctx.mkConst(ctx.mkSymbol("rm"), rm_sort); BitVecExpr x = (BitVecExpr)ctx.mkConst(ctx.mkSymbol("x"), ctx.mkBitVecSort(64)); - RealExpr real_val = ctx.mkReal(42); + FPExpr y = (FPExpr)ctx.mkConst(ctx.mkSymbol("y"), double_sort); FPExpr fp_val = ctx.mkFP(42, double_sort); - - BoolExpr c1 = ctx.mkEq(x, ctx.mkFPToIEEEBV(fp_val)); - BoolExpr c2 = ctx.mkEq(x, ctx.mkBV(42, 64)); - BoolExpr c3 = ctx.mkEq(fp_val, ctx.mkFPToFP(rm, real_val, double_sort)); - BoolExpr c4 = ctx.mkAnd(c1, c2); - System.out.println("c3 = " + c3); + + BoolExpr c1 = ctx.mkEq(y, fp_val); + BoolExpr c2 = ctx.mkEq(x, ctx.mkFPToBV(rm, y, 64, false)); + BoolExpr c3 = ctx.mkEq(x, ctx.mkBV(42, 64)); + BoolExpr c4 = ctx.mkEq(ctx.mkNumeral(42, ctx.getRealSort()), ctx.mkFPToReal(fp_val)); + BoolExpr c5 = ctx.mkAnd(c1, c2, c3, c4); + System.out.println("c5 = " + c5); /* Generic solver */ Solver s = ctx.mkSolver(); - s.add(c3); + s.add(c5); if (s.check() != Status.SATISFIABLE) throw new TestFailedException(); - System.out.println("OK, model: " + s.getModel().toString()); + System.out.println("OK, model: " + s.getModel().toString()); } public static void main(String[] args) diff --git a/src/api/java/AST.java b/src/api/java/AST.java index 579d4b24d..5bea58054 100644 --- a/src/api/java/AST.java +++ b/src/api/java/AST.java @@ -213,10 +213,8 @@ public class AST extends Z3Object void incRef(long o) throws Z3Exception { // Console.WriteLine("AST IncRef()"); - if (getContext() == null) - throw new Z3Exception("inc() called on null context"); - if (o == 0) - throw new Z3Exception("inc() called on null AST"); + if (getContext() == null || o == 0) + return; getContext().ast_DRQ().incAndClear(getContext(), o); super.incRef(o); } @@ -224,10 +222,8 @@ public class AST extends Z3Object void decRef(long o) throws Z3Exception { // Console.WriteLine("AST DecRef()"); - if (getContext() == null) - throw new Z3Exception("dec() called on null context"); - if (o == 0) - throw new Z3Exception("dec() called on null AST"); + if (getContext() == null || o == 0) + return; getContext().ast_DRQ().add(o); super.decRef(o); } diff --git a/src/api/java/ArithExpr.java b/src/api/java/ArithExpr.java index 83ec35d01..97873f0b0 100644 --- a/src/api/java/ArithExpr.java +++ b/src/api/java/ArithExpr.java @@ -25,11 +25,6 @@ public class ArithExpr extends Expr /** * Constructor for ArithExpr **/ - protected ArithExpr(Context ctx) - { - super(ctx); - } - ArithExpr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); diff --git a/src/api/java/ArrayExpr.java b/src/api/java/ArrayExpr.java index 2d5a5a273..2985d19a2 100644 --- a/src/api/java/ArrayExpr.java +++ b/src/api/java/ArrayExpr.java @@ -26,11 +26,6 @@ public class ArrayExpr extends Expr /** * Constructor for ArrayExpr **/ - protected ArrayExpr(Context ctx) - { - super(ctx); - } - ArrayExpr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); diff --git a/src/api/java/BitVecExpr.java b/src/api/java/BitVecExpr.java index 24b1cfdf3..a7c704497 100644 --- a/src/api/java/BitVecExpr.java +++ b/src/api/java/BitVecExpr.java @@ -35,11 +35,6 @@ public class BitVecExpr extends Expr /** * Constructor for BitVecExpr **/ - BitVecExpr(Context ctx) - { - super(ctx); - } - BitVecExpr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); diff --git a/src/api/java/BoolExpr.java b/src/api/java/BoolExpr.java index 99453496a..8f9d10d18 100644 --- a/src/api/java/BoolExpr.java +++ b/src/api/java/BoolExpr.java @@ -22,14 +22,6 @@ package com.microsoft.z3; **/ public class BoolExpr extends Expr { - /** - * Constructor for BoolExpr - **/ - protected BoolExpr(Context ctx) - { - super(ctx); - } - /** * Constructor for BoolExpr * @throws Z3Exception diff --git a/src/api/java/Context.java b/src/api/java/Context.java index cd3b9bebd..cfbd7c2c8 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -504,14 +504,10 @@ public class Context extends IDisposable **/ public Expr mkConst(Symbol name, Sort range) throws Z3Exception { - checkContextMatch(name); checkContextMatch(range); - return Expr.create( - this, - Native.mkConst(nCtx(), name.getNativeObject(), - range.getNativeObject())); + return Expr.create(this, Native.mkConst(nCtx(), name.getNativeObject(), range.getNativeObject())); } /** diff --git a/src/api/java/DatatypeExpr.java b/src/api/java/DatatypeExpr.java index 806ceacab..d4612e6ff 100644 --- a/src/api/java/DatatypeExpr.java +++ b/src/api/java/DatatypeExpr.java @@ -25,11 +25,6 @@ public class DatatypeExpr extends Expr /** * Constructor for DatatypeExpr **/ - protected DatatypeExpr(Context ctx) - { - super(ctx); - } - DatatypeExpr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); diff --git a/src/api/java/EnumSort.java b/src/api/java/EnumSort.java index 9715b9a97..51bdfe0e8 100644 --- a/src/api/java/EnumSort.java +++ b/src/api/java/EnumSort.java @@ -60,7 +60,7 @@ public class EnumSort extends Sort EnumSort(Context ctx, Symbol name, Symbol[] enumNames) throws Z3Exception { - super(ctx); + super(ctx, 0); int n = enumNames.length; long[] n_constdecls = new long[n]; diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 4bd522b51..886c69f08 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -2092,24 +2092,12 @@ public class Expr extends AST return Native.getIndexValue(getContext().nCtx(), getNativeObject()); } - /** - * Constructor for Expr - **/ - protected Expr(Context ctx) - { - super(ctx); - { - } - } - /** * Constructor for Expr **/ protected Expr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); - { - } } void checkNativeObject(long obj) throws Z3Exception @@ -2135,8 +2123,7 @@ public class Expr extends AST if (k == Z3_ast_kind.Z3_QUANTIFIER_AST) return new Quantifier(ctx, obj); long s = Native.getSort(ctx.nCtx(), obj); - Z3_sort_kind sk = Z3_sort_kind - .fromInt(Native.getSortKind(ctx.nCtx(), s)); + Z3_sort_kind sk = Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), s)); if (Native.isAlgebraicNumber(ctx.nCtx(), obj)) // is this a numeral ast? return new AlgebraicNum(ctx, obj); diff --git a/src/api/java/IntExpr.java b/src/api/java/IntExpr.java index 2e90c3cbf..de3ae222a 100644 --- a/src/api/java/IntExpr.java +++ b/src/api/java/IntExpr.java @@ -25,11 +25,6 @@ public class IntExpr extends ArithExpr /** * Constructor for IntExpr **/ - protected IntExpr(Context ctx) throws Z3Exception - { - super(ctx); - } - IntExpr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); diff --git a/src/api/java/ListSort.java b/src/api/java/ListSort.java index 52cb1a179..a7ad0403b 100644 --- a/src/api/java/ListSort.java +++ b/src/api/java/ListSort.java @@ -88,7 +88,7 @@ public class ListSort extends Sort ListSort(Context ctx, Symbol name, Sort elemSort) throws Z3Exception { - super(ctx); + super(ctx, 0); Native.LongPtr inil = new Native.LongPtr(), iisnil = new Native.LongPtr(); Native.LongPtr icons = new Native.LongPtr(), iiscons = new Native.LongPtr(); diff --git a/src/api/java/Quantifier.java b/src/api/java/Quantifier.java index e9aeefcca..58245d723 100644 --- a/src/api/java/Quantifier.java +++ b/src/api/java/Quantifier.java @@ -149,7 +149,7 @@ public class Quantifier extends BoolExpr Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { - super(ctx); + super(ctx, 0); getContext().checkContextMatch(patterns); getContext().checkContextMatch(noPatterns); @@ -185,7 +185,7 @@ public class Quantifier extends BoolExpr int weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) throws Z3Exception { - super(ctx); + super(ctx, 0); getContext().checkContextMatch(noPatterns); getContext().checkContextMatch(patterns); diff --git a/src/api/java/RealExpr.java b/src/api/java/RealExpr.java index 6188e2999..c699e13e2 100644 --- a/src/api/java/RealExpr.java +++ b/src/api/java/RealExpr.java @@ -25,11 +25,6 @@ public class RealExpr extends ArithExpr /** * Constructor for RealExpr **/ - protected RealExpr(Context ctx) - { - super(ctx); - } - RealExpr(Context ctx, long obj) throws Z3Exception { super(ctx, obj); diff --git a/src/api/java/Sort.java b/src/api/java/Sort.java index 7d89428c6..fa556e67f 100644 --- a/src/api/java/Sort.java +++ b/src/api/java/Sort.java @@ -98,18 +98,9 @@ public class Sort extends AST /** * Sort constructor **/ - protected Sort(Context ctx) throws Z3Exception - { - super(ctx); - { - } - } - Sort(Context ctx, long obj) throws Z3Exception { super(ctx, obj); - { - } } void checkNativeObject(long obj) throws Z3Exception @@ -143,6 +134,10 @@ public class Sort extends AST return new FiniteDomainSort(ctx, obj); case Z3_RELATION_SORT: return new RelationSort(ctx, obj); + case Z3_FLOATING_POINT_SORT: + return new FPSort(ctx, obj); + case Z3_ROUNDING_MODE_SORT: + return new FPRMSort(ctx, obj); default: throw new Z3Exception("Unknown sort kind"); } diff --git a/src/api/java/TupleSort.java b/src/api/java/TupleSort.java index 523f8d676..87572b9ee 100644 --- a/src/api/java/TupleSort.java +++ b/src/api/java/TupleSort.java @@ -59,7 +59,7 @@ public class TupleSort extends Sort TupleSort(Context ctx, Symbol name, int numFields, Symbol[] fieldNames, Sort[] fieldSorts) throws Z3Exception { - super(ctx); + super(ctx, 0); Native.LongPtr t = new Native.LongPtr(); setNativeObject(Native.mkTupleSort(ctx.nCtx(), name.getNativeObject(), From cad841cff46cd380cec19fff5fc2a66dbef4aa29 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 17:23:13 +0000 Subject: [PATCH 136/507] to_fp_real marked as NIY for now Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 4c570c1ba..743434341 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2064,7 +2064,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); - if (false && m_bv_util.is_numeral(rm) && m_util.au().is_numeral(x)) { + if (m_bv_util.is_numeral(rm) && m_util.au().is_numeral(x)) { rational tmp_rat; unsigned sz; m_bv_util.is_numeral(to_expr(rm), tmp_rat, sz); SASSERT(tmp_rat.is_int32()); @@ -2096,6 +2096,8 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * mk_triple(sgn, s, e, result); } else { + NOT_IMPLEMENTED_YET(); + mpf_manager & fm = fu().fm(); bv_util & bu = m_bv_util; arith_util & au = m_arith_util; @@ -2135,16 +2137,16 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * //dbg_decouple("fpa2bv_to_float_real_inc", inc); //sig = m.mk_ite(inc, bu.mk_bv_add(sig, bv1_s4), sig); - SASSERT(bu.get_bv_size(sgn) == 1); - SASSERT(bu.get_bv_size(sig) == sbits + 4); - SASSERT(bu.get_bv_size(exp) == ebits + 2); + //SASSERT(bu.get_bv_size(sgn) == 1); + //SASSERT(bu.get_bv_size(sig) == sbits + 4); + //SASSERT(bu.get_bv_size(exp) == ebits + 2); - dbg_decouple("fpa2bv_to_float_real_sgn", sgn); - dbg_decouple("fpa2bv_to_float_real_sig", sig); - dbg_decouple("fpa2bv_to_float_real_exp", exp); + //dbg_decouple("fpa2bv_to_float_real_sgn", sgn); + //dbg_decouple("fpa2bv_to_float_real_sig", sig); + //dbg_decouple("fpa2bv_to_float_real_exp", exp); - expr_ref rmr(rm, m); - round(s, rmr, sgn, sig, exp, result); + //expr_ref rmr(rm, m); + //round(s, rmr, sgn, sig, exp, result); } SASSERT(is_well_sorted(m, result)); From 0381e4317ab7e5e2212ac4b36c1ed384456adf39 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 17:54:04 +0000 Subject: [PATCH 137/507] Formatting, mostly tabs. Signed-off-by: Christoph M. Wintersteiger --- src/api/api_numeral.cpp | 2 +- src/ast/ast.cpp | 52 +- src/ast/fpa/fpa2bv_converter.cpp | 2 +- src/ast/rewriter/dl_rewriter.cpp | 48 +- src/duality/duality_profiling.cpp | 22 +- src/duality/duality_rpfp.cpp | 2686 +++++++++++----------- src/muz/base/dl_context.cpp | 12 +- src/muz/duality/duality_dl_interface.cpp | 86 +- src/muz/transforms/dl_transforms.cpp | 2 +- src/tactic/aig/aig.cpp | 14 +- 10 files changed, 1448 insertions(+), 1478 deletions(-) diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 7789f1157..0745a8709 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -173,7 +173,7 @@ extern "C" { if (mk_c(c)->datalog_util().is_numeral(e, v)) { r = rational(v, rational::ui64()); return Z3_TRUE; - } + } return Z3_FALSE; Z3_CATCH_RETURN(Z3_FALSE); } diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 09965be85..5679c951b 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -413,16 +413,16 @@ sort * get_sort(expr const * n) { // // ----------------------------------- -unsigned get_node_size(ast const * n) { - switch(n->get_kind()) { - case AST_SORT: return to_sort(n)->get_size(); - case AST_FUNC_DECL: return to_func_decl(n)->get_size(); - case AST_APP: return to_app(n)->get_size(); - case AST_VAR: return to_var(n)->get_size(); - case AST_QUANTIFIER: return to_quantifier(n)->get_size(); - default: UNREACHABLE(); - } - return 0; +unsigned get_node_size(ast const * n) { + switch(n->get_kind()) { + case AST_SORT: return to_sort(n)->get_size(); + case AST_FUNC_DECL: return to_func_decl(n)->get_size(); + case AST_APP: return to_app(n)->get_size(); + case AST_VAR: return to_var(n)->get_size(); + case AST_QUANTIFIER: return to_quantifier(n)->get_size(); + default: UNREACHABLE(); + } + return 0; } bool compare_nodes(ast const * n1, ast const * n2) { @@ -737,7 +737,7 @@ func_decl * basic_decl_plugin::mk_proof_decl( for (unsigned i = 0; i < num_parents; i++) domain.push_back(m_proof_sort); domain.push_back(m_bool_sort); - func_decl_info info(m_family_id, k, num_parameters, params); + func_decl_info info(m_family_id, k, num_parameters, params); return m_manager->mk_func_decl(symbol(name), num_parents+1, domain.c_ptr(), m_proof_sort, info); } @@ -1643,12 +1643,12 @@ ast * ast_manager::register_node_core(ast * n) { to_func_decl(n)->m_info = alloc(func_decl_info, *(to_func_decl(n)->get_info())); to_func_decl(n)->m_info->init_eh(*this); } - inc_array_ref(to_func_decl(n)->get_arity(), to_func_decl(n)->get_domain()); - inc_ref(to_func_decl(n)->get_range()); - break; + inc_array_ref(to_func_decl(n)->get_arity(), to_func_decl(n)->get_domain()); + inc_ref(to_func_decl(n)->get_range()); + break; case AST_APP: { app * t = to_app(n); - inc_ref(t->get_decl()); + inc_ref(t->get_decl()); unsigned num_args = t->get_num_args(); if (num_args > 0) { app_flags * f = t->flags(); @@ -1696,19 +1696,19 @@ ast * ast_manager::register_node_core(ast * n) { f->m_depth = depth; SASSERT(t->get_depth() == depth); } - break; + break; } case AST_VAR: inc_ref(to_var(n)->get_sort()); break; 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_array_ref(to_quantifier(n)->get_num_decls(), to_quantifier(n)->get_decl_sorts()); + inc_ref(to_quantifier(n)->get_expr()); 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; + break; default: - break; + break; } return n; } @@ -1721,7 +1721,7 @@ void ast_manager::delete_node(ast * n) { while (!worklist.empty()) { n = worklist.back(); worklist.pop_back(); - + TRACE("ast", tout << "Deleting object " << n->m_id << " " << n << "\n";); CTRACE("del_quantifier", is_quantifier(n), tout << "deleting quantifier " << n->m_id << " " << n << "\n";); TRACE("mk_var_bug", tout << "del_ast: " << n->m_id << "\n";); @@ -1770,8 +1770,8 @@ void ast_manager::delete_node(ast * n) { 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; - default: - break; + default: + break; } if (m_debug_ref_count) { m_debug_free_indices.insert(n->m_id,0); @@ -2567,9 +2567,9 @@ proof * ast_manager::mk_transitivity(proof * p1, proof * p2) { (is_eq(get_fact(p2)) || is_oeq(get_fact(p2))))); CTRACE("mk_transitivity", to_app(get_fact(p1))->get_arg(1) != to_app(get_fact(p2))->get_arg(0), tout << mk_pp(get_fact(p1), *this) << "\n\n" << mk_pp(get_fact(p2), *this) << "\n"; - tout << mk_bounded_pp(p1, *this, 5) << "\n\n"; - tout << mk_bounded_pp(p2, *this, 5) << "\n\n"; - ); + tout << mk_bounded_pp(p1, *this, 5) << "\n\n"; + tout << mk_bounded_pp(p2, *this, 5) << "\n\n"; + ); SASSERT(to_app(get_fact(p1))->get_arg(1) == to_app(get_fact(p2))->get_arg(0)); if (is_reflexivity(p1)) return p2; diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 743434341..f6ce259f2 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3197,7 +3197,7 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #ifdef Z3DEBUG - // return; + return; // CMW: This works only for quantifier-free formulas. expr_ref new_e(m); new_e = m.mk_fresh_const(prefix, m.get_sort(e)); diff --git a/src/ast/rewriter/dl_rewriter.cpp b/src/ast/rewriter/dl_rewriter.cpp index 9b79775d5..ddae6c9eb 100644 --- a/src/ast/rewriter/dl_rewriter.cpp +++ b/src/ast/rewriter/dl_rewriter.cpp @@ -24,31 +24,31 @@ Revision History: ast_manager& m = result.get_manager(); uint64 v1, v2; switch(f->get_decl_kind()) { - case datalog::OP_DL_LT: - if (m_util.is_numeral_ext(args[0], v1) && - m_util.is_numeral_ext(args[1], v2)) { - result = (v1 < v2)?m.mk_true():m.mk_false(); - return BR_DONE; - } - // x < x <=> false - if (args[0] == args[1]) { - result = m.mk_false(); - return BR_DONE; - } - // x < 0 <=> false - if (m_util.is_numeral_ext(args[1], v2) && v2 == 0) { - result = m.mk_false(); - return BR_DONE; - } - // 0 < x <=> 0 != x - if (m_util.is_numeral_ext(args[1], v1) && v1 == 0) { - result = m.mk_not(m.mk_eq(args[0], args[1])); - return BR_DONE; - } - break; + case datalog::OP_DL_LT: + if (m_util.is_numeral_ext(args[0], v1) && + m_util.is_numeral_ext(args[1], v2)) { + result = (v1 < v2)?m.mk_true():m.mk_false(); + return BR_DONE; + } + // x < x <=> false + if (args[0] == args[1]) { + result = m.mk_false(); + return BR_DONE; + } + // x < 0 <=> false + if (m_util.is_numeral_ext(args[1], v2) && v2 == 0) { + result = m.mk_false(); + return BR_DONE; + } + // 0 < x <=> 0 != x + if (m_util.is_numeral_ext(args[1], v1) && v1 == 0) { + result = m.mk_not(m.mk_eq(args[0], args[1])); + return BR_DONE; + } + break; - default: - break; + default: + break; } return BR_FAILED; } diff --git a/src/duality/duality_profiling.cpp b/src/duality/duality_profiling.cpp index 5bcda972a..13a379946 100755 --- a/src/duality/duality_profiling.cpp +++ b/src/duality/duality_profiling.cpp @@ -124,20 +124,20 @@ namespace Duality { } void timer_stop(const char *name){ - if(current->name != name || !current->parent){ + if (current->name != name || !current->parent) { #if 0 - std::cerr << "imbalanced timer_start and timer_stop"; - exit(1); + std::cerr << "imbalanced timer_start and timer_stop"; + exit(1); #endif - // in case we lost a timer stop due to an exception - while(current->name != name && current->parent) - current = current->parent; - if(current->parent){ - current->time += (current_time() - current->start_time); - current = current->parent; + // in case we lost a timer stop due to an exception + while (current->name != name && current->parent) + current = current->parent; + if (current->parent) { + current->time += (current_time() - current->start_time); + current = current->parent; + } + return; } - return; - } current->time += (current_time() - current->start_time); current = current->parent; } diff --git a/src/duality/duality_rpfp.cpp b/src/duality/duality_rpfp.cpp index cdc8fb3b2..6ef6d623a 100755 --- a/src/duality/duality_rpfp.cpp +++ b/src/duality/duality_rpfp.cpp @@ -97,12 +97,12 @@ namespace Duality { memo.insert(t); if(t.is_app()){ decl_kind k = t.decl().get_decl_kind(); - if(k == And || k == Or || k == Not || k == Implies || k == Iff){ - ops++; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - SummarizeRec(memo,lits,ops,t.arg(i)); - return; + if (k == And || k == Or || k == Not || k == Implies || k == Iff) { + ops++; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + SummarizeRec(memo, lits, ops, t.arg(i)); + return; } } lits.push_back(t); @@ -137,12 +137,12 @@ namespace Duality { memo.insert(t); if(t.is_app()){ decl_kind k = t.decl().get_decl_kind(); - if(k == And || k == Or){ - int count = 1; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - count += CountOperatorsRec(memo,t.arg(i)); - return count; + if (k == And || k == Or) { + int count = 1; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + count += CountOperatorsRec(memo, t.arg(i)); + return count; } return 0; } @@ -172,13 +172,12 @@ namespace Duality { Term b(ctx); std::vector v; RedVars(child, b, v); - for (unsigned i = 0; i < args.size(); i++) - { - if (eq(args[i].get_sort(),ctx.bool_sort())) - args[i] = ctx.make(Iff,args[i], v[i]); - else - args[i] = args[i] == v[i]; - } + for (unsigned i = 0; i < args.size(); i++) { + if (eq(args[i].get_sort(), ctx.bool_sort())) + args[i] = ctx.make(Iff, args[i], v[i]); + else + args[i] = args[i] == v[i]; + } return args.size() > 0 ? (b && conjoin(args)) : b; } @@ -202,18 +201,18 @@ namespace Duality { names.push_back(Z3_get_quantifier_bound_name(c,a,i)); } Z3_ast foo = Z3_mk_quantifier_ex(c, - Z3_is_quantifier_forall(c,a), - Z3_get_quantifier_weight(c,a), - 0, - 0, - num_pats, - &pats[0], - num_no_pats, - &no_pats[0], - bound, - &sorts[0], - &names[0], - new_body); + Z3_is_quantifier_forall(c,a), + Z3_get_quantifier_weight(c,a), + 0, + 0, + num_pats, + &pats[0], + num_no_pats, + &no_pats[0], + bound, + &sorts[0], + &names[0], + new_body); return expr(ctx,foo); #endif return clone_quantifier(t,new_body); @@ -231,36 +230,32 @@ namespace Duality { res = it->second; return res; } - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - args.push_back(LocalizeRec(e, memo, t.arg(i))); - hash_map::iterator rit = e->relMap.find(f); - if(rit != e->relMap.end()) - res = RedDualRela(e,args,(rit->second)); - else { - if (args.size() == 0 && f.get_decl_kind() == Uninterpreted && !ls->is_constant(f)) - { - res = HideVariable(t,e->number); - } - else - { - res = f(args.size(),&args[0]); - } - } - } - else if (t.is_quantifier()) - { - std::vector pats; - t.get_patterns(pats); - for(unsigned i = 0; i < pats.size(); i++) - pats[i] = LocalizeRec(e,memo,pats[i]); - Term body = LocalizeRec(e,memo,t.body()); - res = clone_quantifier(t, body, pats); - } + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + args.push_back(LocalizeRec(e, memo, t.arg(i))); + hash_map::iterator rit = e->relMap.find(f); + if (rit != e->relMap.end()) + res = RedDualRela(e, args, (rit->second)); + else { + if (args.size() == 0 && f.get_decl_kind() == Uninterpreted && !ls->is_constant(f)) { + res = HideVariable(t, e->number); + } + else { + res = f(args.size(), &args[0]); + } + } + } + else if (t.is_quantifier()) { + std::vector pats; + t.get_patterns(pats); + for (unsigned i = 0; i < pats.size(); i++) + pats[i] = LocalizeRec(e, memo, pats[i]); + Term body = LocalizeRec(e, memo, t.body()); + res = clone_quantifier(t, body, pats); + } else res = t; return res; } @@ -353,24 +348,22 @@ namespace Duality { std::pair::iterator, bool> bar = memo.insert(foo); Term &res = bar.first->second; if(!bar.second) return res; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - args.push_back(SubstRec(memo, t.arg(i))); - res = f(args.size(),&args[0]); - } - else if (t.is_quantifier()) - { - std::vector pats; - t.get_patterns(pats); - for(unsigned i = 0; i < pats.size(); i++) - pats[i] = SubstRec(memo,pats[i]); - Term body = SubstRec(memo,t.body()); - res = clone_quantifier(t, body, pats); - } + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + args.push_back(SubstRec(memo, t.arg(i))); + res = f(args.size(), &args[0]); + } + else if (t.is_quantifier()) { + std::vector pats; + t.get_patterns(pats); + for (unsigned i = 0; i < pats.size(); i++) + pats[i] = SubstRec(memo, pats[i]); + Term body = SubstRec(memo, t.body()); + res = clone_quantifier(t, body, pats); + } // res = CloneQuantifier(t,SubstRec(memo, t.body())); else res = t; return res; @@ -382,27 +375,25 @@ namespace Duality { std::pair::iterator, bool> bar = memo.insert(foo); Term &res = bar.first->second; if(!bar.second) return res; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - args.push_back(SubstRec(memo, map, t.arg(i))); - hash_map::iterator it = map.find(f); - if(it != map.end()) - f = it->second; - res = f(args.size(),&args[0]); - } - else if (t.is_quantifier()) - { - std::vector pats; - t.get_patterns(pats); - for(unsigned i = 0; i < pats.size(); i++) - pats[i] = SubstRec(memo, map, pats[i]); - Term body = SubstRec(memo, map, t.body()); - res = clone_quantifier(t, body, pats); - } + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + args.push_back(SubstRec(memo, map, t.arg(i))); + hash_map::iterator it = map.find(f); + if (it != map.end()) + f = it->second; + res = f(args.size(), &args[0]); + } + else if (t.is_quantifier()) { + std::vector pats; + t.get_patterns(pats); + for (unsigned i = 0; i < pats.size(); i++) + pats[i] = SubstRec(memo, map, pats[i]); + Term body = SubstRec(memo, map, t.body()); + res = clone_quantifier(t, body, pats); + } // res = CloneQuantifier(t,SubstRec(memo, t.body())); else res = t; return res; @@ -415,20 +406,20 @@ namespace Duality { Term &res = bar.first->second; if(!bar.second) return res; if (t.is_app()) { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - args.push_back(ExtractStores(memo, t.arg(i),cnstrs,renaming)); - res = f(args.size(),&args[0]); - if(f.get_decl_kind() == Store){ - func_decl fresh = ctx.fresh_func_decl("@arr", res.get_sort()); - expr y = fresh(); - expr equ = ctx.make(Equal,y,res); - cnstrs.push_back(equ); - renaming[y] = res; - res = y; - } + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + args.push_back(ExtractStores(memo, t.arg(i), cnstrs, renaming)); + res = f(args.size(), &args[0]); + if (f.get_decl_kind() == Store) { + func_decl fresh = ctx.fresh_func_decl("@arr", res.get_sort()); + expr y = fresh(); + expr equ = ctx.make(Equal, y, res); + cnstrs.push_back(equ); + renaming[y] = res; + res = y; + } } else res = t; return res; @@ -436,20 +427,20 @@ namespace Duality { bool Z3User::IsLiteral(const expr &lit, expr &atom, expr &val){ - if(!(lit.is_quantifier() && IsClosedFormula(lit))){ - if(!lit.is_app()) - return false; - decl_kind k = lit.decl().get_decl_kind(); - if(k == Not){ - if(IsLiteral(lit.arg(0),atom,val)){ - val = eq(val,ctx.bool_val(true)) ? ctx.bool_val(false) : ctx.bool_val(true); - return true; - } - return false; + if (!(lit.is_quantifier() && IsClosedFormula(lit))) { + if (!lit.is_app()) + return false; + decl_kind k = lit.decl().get_decl_kind(); + if (k == Not) { + if (IsLiteral(lit.arg(0), atom, val)) { + val = eq(val, ctx.bool_val(true)) ? ctx.bool_val(false) : ctx.bool_val(true); + return true; + } + return false; + } + if (k == And || k == Or || k == Iff || k == Implies) + return false; } - if(k == And || k == Or || k == Iff || k == Implies) - return false; - } atom = lit; val = ctx.bool_val(true); return true; @@ -467,11 +458,11 @@ namespace Duality { expr Z3User::ReduceAndOr(const std::vector &args, bool is_and, std::vector &res){ for(unsigned i = 0; i < args.size(); i++) - if(!eq(args[i],ctx.bool_val(is_and))){ - if(eq(args[i],ctx.bool_val(!is_and))) - return ctx.bool_val(!is_and); - res.push_back(args[i]); - } + if (!eq(args[i], ctx.bool_val(is_and))) { + if (eq(args[i], ctx.bool_val(!is_and))) + return ctx.bool_val(!is_and); + res.push_back(args[i]); + } return expr(); } @@ -495,36 +486,36 @@ namespace Duality { // first check if there's anything to do... if(args.size() < 2) return FinishAndOr(args,is_and); - for(unsigned i = 0; i < args.size(); i++){ - const expr &a = args[i]; - if(!(a.is_app() && a.decl().get_decl_kind() == (is_and ? Or : And))) - return FinishAndOr(args,is_and); + for (unsigned i = 0; i < args.size(); i++) { + const expr &a = args[i]; + if (!(a.is_app() && a.decl().get_decl_kind() == (is_and ? Or : And))) + return FinishAndOr(args, is_and); } std::vector common; - for(unsigned i = 0; i < args.size(); i++){ - unsigned n = args[i].num_args(); - std::vector v(n),w; - for(unsigned j = 0; j < n; j++) - v[j] = args[i].arg(j); - std::less comp; - std::sort(v.begin(),v.end(),comp); - if(i == 0) - common.swap(v); - else { - std::set_intersection(common.begin(),common.end(),v.begin(),v.end(),std::inserter(w,w.begin()),comp); - common.swap(w); - } - } + for (unsigned i = 0; i < args.size(); i++) { + unsigned n = args[i].num_args(); + std::vector v(n), w; + for (unsigned j = 0; j < n; j++) + v[j] = args[i].arg(j); + std::less comp; + std::sort(v.begin(), v.end(), comp); + if (i == 0) + common.swap(v); + else { + std::set_intersection(common.begin(), common.end(), v.begin(), v.end(), std::inserter(w, w.begin()), comp); + common.swap(w); + } + } if(common.empty()) return FinishAndOr(args,is_and); std::set common_set(common.begin(),common.end()); for(unsigned i = 0; i < args.size(); i++){ unsigned n = args[i].num_args(); std::vector lits; - for(unsigned j = 0; j < n; j++){ - const expr b = args[i].arg(j); - if(common_set.find(b) == common_set.end()) - lits.push_back(b); + for (unsigned j = 0; j < n; j++) { + const expr b = args[i].arg(j); + if (common_set.find(b) == common_set.end()) + lits.push_back(b); } args[i] = SimplifyAndOr(lits,!is_and); } @@ -549,148 +540,145 @@ namespace Duality { } Z3User::Term Z3User::PushQuantifier(const expr &t, const expr &body, bool is_forall){ - if(t.get_quantifier_num_bound() == 1){ - std::vector fmlas,free,not_free; - CollectJuncts(body,fmlas, is_forall ? Or : And, false); - for(unsigned i = 0; i < fmlas.size(); i++){ - const expr &fmla = fmlas[i]; - if(fmla.has_free(0)) - free.push_back(fmla); - else - not_free.push_back(fmla); + if (t.get_quantifier_num_bound() == 1) { + std::vector fmlas, free, not_free; + CollectJuncts(body, fmlas, is_forall ? Or : And, false); + for (unsigned i = 0; i < fmlas.size(); i++) { + const expr &fmla = fmlas[i]; + if (fmla.has_free(0)) + free.push_back(fmla); + else + not_free.push_back(fmla); + } + decl_kind op = is_forall ? Or : And; + if (free.empty()) + return DeleteBound(0, 1, SimplifyAndOr(not_free, op == And)); + expr q = clone_quantifier(is_forall ? Forall : Exists, t, SimplifyAndOr(free, op == And)); + if (!not_free.empty()) + q = ctx.make(op, q, DeleteBound(0, 1, SimplifyAndOr(not_free, op == And))); + return q; } - decl_kind op = is_forall ? Or : And; - if(free.empty()) - return DeleteBound(0,1,SimplifyAndOr(not_free,op == And)); - expr q = clone_quantifier(is_forall ? Forall : Exists,t, SimplifyAndOr(free, op == And)); - if(!not_free.empty()) - q = ctx.make(op,q,DeleteBound(0,1,SimplifyAndOr(not_free, op == And))); - return q; - } return clone_quantifier(is_forall ? Forall : Exists,t,body); } - Z3User::Term Z3User::CloneQuantAndSimp(const expr &t, const expr &body, bool is_forall){ - if(body.is_app()){ - if(body.decl().get_decl_kind() == (is_forall ? And : Or)){ // quantifier distributes - int nargs = body.num_args(); - std::vector args(nargs); - for(int i = 0; i < nargs; i++) - args[i] = CloneQuantAndSimp(t, body.arg(i), is_forall); - return SimplifyAndOr(args, body.decl().get_decl_kind() == And); + Z3User::Term Z3User::CloneQuantAndSimp(const expr &t, const expr &body, bool is_forall) { + if (body.is_app()) { + if (body.decl().get_decl_kind() == (is_forall ? And : Or)) { // quantifier distributes + int nargs = body.num_args(); + std::vector args(nargs); + for (int i = 0; i < nargs; i++) + args[i] = CloneQuantAndSimp(t, body.arg(i), is_forall); + return SimplifyAndOr(args, body.decl().get_decl_kind() == And); + } + else if (body.decl().get_decl_kind() == (is_forall ? Or : And)) { // quantifier distributes + return PushQuantifier(t, body, is_forall); // may distribute partially + } + else if (body.decl().get_decl_kind() == Not) { + return ctx.make(Not, CloneQuantAndSimp(t, body.arg(0), !is_forall)); + } } - else if(body.decl().get_decl_kind() == (is_forall ? Or : And)){ // quantifier distributes - return PushQuantifier(t,body,is_forall); // may distribute partially - } - else if(body.decl().get_decl_kind() == Not){ - return ctx.make(Not,CloneQuantAndSimp(t,body.arg(0),!is_forall)); - } - } - if(t.get_quantifier_num_bound() == 1 && !body.has_free(0)) - return DeleteBound(0,1,body); // drop the quantifier - return clone_quantifier(is_forall ? Forall : Exists,t,body); + if (t.get_quantifier_num_bound() == 1 && !body.has_free(0)) + return DeleteBound(0, 1, body); // drop the quantifier + return clone_quantifier(is_forall ? Forall : Exists, t, body); } Z3User::Term Z3User::CloneQuantAndSimp(const expr &t, const expr &body){ return CloneQuantAndSimp(t,body,t.is_quantifier_forall()); } - Z3User::Term Z3User::SubstAtom(hash_map &memo, const expr &t, const expr &atom, const expr &val){ - std::pair foo(t,expr(ctx)); - std::pair::iterator, bool> bar = memo.insert(foo); - Term &res = bar.first->second; - if(!bar.second) return res; - if (t.is_app()){ - func_decl f = t.decl(); - decl_kind k = f.get_decl_kind(); - - // TODO: recur here, but how much? We don't want to be quadractic in formula size - - if(k == And || k == Or){ - int nargs = t.num_args(); - std::vector args(nargs); - for(int i = 0; i < nargs; i++) - args[i] = SubstAtom(memo,t.arg(i),atom,val); - res = ReallySimplifyAndOr(args, k==And); - return res; + Z3User::Term Z3User::SubstAtom(hash_map &memo, const expr &t, const expr &atom, const expr &val) { + std::pair foo(t, expr(ctx)); + std::pair::iterator, bool> bar = memo.insert(foo); + Term &res = bar.first->second; + if (!bar.second) return res; + if (t.is_app()) { + func_decl f = t.decl(); + decl_kind k = f.get_decl_kind(); + + // TODO: recur here, but how much? We don't want to be quadractic in formula size + + if (k == And || k == Or) { + int nargs = t.num_args(); + std::vector args(nargs); + for (int i = 0; i < nargs; i++) + args[i] = SubstAtom(memo, t.arg(i), atom, val); + res = ReallySimplifyAndOr(args, k == And); + return res; + } } - } - else if(t.is_quantifier() && atom.is_quantifier()){ - if(eq(t,atom)) - res = val; - else - res = clone_quantifier(t,SubstAtom(memo,t.body(),atom,val)); + else if (t.is_quantifier() && atom.is_quantifier()) { + if (eq(t, atom)) + res = val; + else + res = clone_quantifier(t, SubstAtom(memo, t.body(), atom, val)); + return res; + } + res = SubstAtomTriv(t, atom, val); return res; - } - res = SubstAtomTriv(t,atom,val); - return res; } - void Z3User::RemoveRedundancyOp(bool pol, std::vector &args, hash_map &smemo){ - for(unsigned i = 0; i < args.size(); i++){ - const expr &lit = args[i]; - expr atom, val; - if(IsLiteral(lit,atom,val)){ - if(atom.is_app() && atom.decl().get_decl_kind() == Equal) - if(pol ? eq(val,ctx.bool_val(true)) : eq(val,ctx.bool_val(false))){ - expr lhs = atom.arg(0), rhs = atom.arg(1); - if(lhs.is_numeral()) - std::swap(lhs,rhs); - if(rhs.is_numeral() && lhs.is_app()){ - for(unsigned j = 0; j < args.size(); j++) - if(j != i){ - smemo.clear(); - smemo[lhs] = rhs; - args[j] = SubstRec(smemo,args[j]); - } - } - } - for(unsigned j = 0; j < args.size(); j++) - if(j != i){ - smemo.clear(); - args[j] = SubstAtom(smemo,args[j],atom,pol ? val : !val); - } + void Z3User::RemoveRedundancyOp(bool pol, std::vector &args, hash_map &smemo) { + for (unsigned i = 0; i < args.size(); i++) { + const expr &lit = args[i]; + expr atom, val; + if (IsLiteral(lit, atom, val)) { + if (atom.is_app() && atom.decl().get_decl_kind() == Equal) + if (pol ? eq(val, ctx.bool_val(true)) : eq(val, ctx.bool_val(false))) { + expr lhs = atom.arg(0), rhs = atom.arg(1); + if (lhs.is_numeral()) + std::swap(lhs, rhs); + if (rhs.is_numeral() && lhs.is_app()) { + for (unsigned j = 0; j < args.size(); j++) + if (j != i) { + smemo.clear(); + smemo[lhs] = rhs; + args[j] = SubstRec(smemo, args[j]); + } + } + } + for (unsigned j = 0; j < args.size(); j++) + if (j != i) { + smemo.clear(); + args[j] = SubstAtom(smemo, args[j], atom, pol ? val : !val); + } + } } - } } - Z3User::Term Z3User::RemoveRedundancyRec(hash_map &memo, hash_map &smemo, const Term &t) - { - std::pair foo(t,expr(ctx)); - std::pair::iterator, bool> bar = memo.insert(foo); - Term &res = bar.first->second; - if(!bar.second) return res; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - args.push_back(RemoveRedundancyRec(memo, smemo, t.arg(i))); + Z3User::Term Z3User::RemoveRedundancyRec(hash_map &memo, hash_map &smemo, const Term &t) { + std::pair foo(t, expr(ctx)); + std::pair::iterator, bool> bar = memo.insert(foo); + Term &res = bar.first->second; + if (!bar.second) return res; + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + args.push_back(RemoveRedundancyRec(memo, smemo, t.arg(i))); - decl_kind k = f.get_decl_kind(); - if(k == And){ - RemoveRedundancyOp(true,args,smemo); - res = ReallySimplifyAndOr(args, true); - } - else if(k == Or){ - RemoveRedundancyOp(false,args,smemo); - res = ReallySimplifyAndOr(args, false); - } - else { - if(k == Equal && args[0].get_id() > args[1].get_id()) - std::swap(args[0],args[1]); - res = f(args.size(),&args[0]); - } + decl_kind k = f.get_decl_kind(); + if (k == And) { + RemoveRedundancyOp(true, args, smemo); + res = ReallySimplifyAndOr(args, true); + } + else if (k == Or) { + RemoveRedundancyOp(false, args, smemo); + res = ReallySimplifyAndOr(args, false); + } + else { + if (k == Equal && args[0].get_id() > args[1].get_id()) + std::swap(args[0], args[1]); + res = f(args.size(), &args[0]); + } } - else if (t.is_quantifier()) - { - Term body = RemoveRedundancyRec(memo,smemo,t.body()); - res = CloneQuantAndSimp(t, body); + else if (t.is_quantifier()) { + Term body = RemoveRedundancyRec(memo, smemo, t.body()); + res = CloneQuantAndSimp(t, body); } - else res = t; - return res; + else res = t; + return res; } Z3User::Term Z3User::RemoveRedundancy(const Term &t){ @@ -706,43 +694,40 @@ namespace Duality { return t; } - Z3User::Term Z3User::IneqToEqRec(hash_map &memo, const Term &t) - { - std::pair foo(t,expr(ctx)); - std::pair::iterator, bool> bar = memo.insert(foo); - Term &res = bar.first->second; - if(!bar.second) return res; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - args.push_back(IneqToEqRec(memo, t.arg(i))); + Z3User::Term Z3User::IneqToEqRec(hash_map &memo, const Term &t) { + std::pair foo(t, expr(ctx)); + std::pair::iterator, bool> bar = memo.insert(foo); + Term &res = bar.first->second; + if (!bar.second) return res; + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + args.push_back(IneqToEqRec(memo, t.arg(i))); - decl_kind k = f.get_decl_kind(); - if(k == And){ - for(int i = 0; i < nargs-1; i++){ - if((args[i].is_app() && args[i].decl().get_decl_kind() == Geq && - args[i+1].is_app() && args[i+1].decl().get_decl_kind() == Leq) - || - (args[i].is_app() && args[i].decl().get_decl_kind() == Leq && - args[i+1].is_app() && args[i+1].decl().get_decl_kind() == Geq)) - if(eq(args[i].arg(0),args[i+1].arg(0)) && eq(args[i].arg(1),args[i+1].arg(1))){ - args[i] = ctx.make(Equal,args[i].arg(0),args[i].arg(1)); - args[i+1] = ctx.bool_val(true); - } - } - } - res = f(args.size(),&args[0]); + decl_kind k = f.get_decl_kind(); + if (k == And) { + for (int i = 0; i < nargs - 1; i++) { + if ((args[i].is_app() && args[i].decl().get_decl_kind() == Geq && + args[i + 1].is_app() && args[i + 1].decl().get_decl_kind() == Leq) + || + (args[i].is_app() && args[i].decl().get_decl_kind() == Leq && + args[i + 1].is_app() && args[i + 1].decl().get_decl_kind() == Geq)) + if (eq(args[i].arg(0), args[i + 1].arg(0)) && eq(args[i].arg(1), args[i + 1].arg(1))) { + args[i] = ctx.make(Equal, args[i].arg(0), args[i].arg(1)); + args[i + 1] = ctx.bool_val(true); + } + } + } + res = f(args.size(), &args[0]); } - else if (t.is_quantifier()) - { - Term body = IneqToEqRec(memo,t.body()); - res = clone_quantifier(t, body); + else if (t.is_quantifier()) { + Term body = IneqToEqRec(memo, t.body()); + res = clone_quantifier(t, body); } - else res = t; - return res; + else res = t; + return res; } Z3User::Term Z3User::IneqToEq(const Term &t){ @@ -750,87 +735,85 @@ namespace Duality { return IneqToEqRec(memo,t); } - Z3User::Term Z3User::SubstRecHide(hash_map &memo, const Term &t, int number) - { - std::pair foo(t,expr(ctx)); - std::pair::iterator, bool> bar = memo.insert(foo); - Term &res = bar.first->second; - if(!bar.second) return res; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - if (nargs == 0 && f.get_decl_kind() == Uninterpreted){ - std::string name = std::string("@q_") + t.decl().name().str() + "_" + string_of_int(number); - res = ctx.constant(name.c_str(), t.get_sort()); - return res; - } - for(int i = 0; i < nargs; i++) - args.push_back(SubstRec(memo, t.arg(i))); - res = f(args.size(),&args[0]); + Z3User::Term Z3User::SubstRecHide(hash_map &memo, const Term &t, int number) { + std::pair foo(t, expr(ctx)); + std::pair::iterator, bool> bar = memo.insert(foo); + Term &res = bar.first->second; + if (!bar.second) return res; + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + if (nargs == 0 && f.get_decl_kind() == Uninterpreted) { + std::string name = std::string("@q_") + t.decl().name().str() + "_" + string_of_int(number); + res = ctx.constant(name.c_str(), t.get_sort()); + return res; + } + for (int i = 0; i < nargs; i++) + args.push_back(SubstRec(memo, t.arg(i))); + res = f(args.size(), &args[0]); } - else if (t.is_quantifier()) - res = CloneQuantifier(t,SubstRec(memo, t.body())); - else res = t; - return res; + else if (t.is_quantifier()) + res = CloneQuantifier(t, SubstRec(memo, t.body())); + else res = t; + return res; } RPFP::Term RPFP::SubstParams(const std::vector &from, - const std::vector &to, const Term &t){ - hash_map memo; - bool some_diff = false; - for(unsigned i = 0; i < from.size(); i++) - if(i < to.size() && !eq(from[i],to[i])){ - memo[from[i]] = to[i]; - some_diff = true; - } - return some_diff ? SubstRec(memo,t) : t; + const std::vector &to, const Term &t) { + hash_map memo; + bool some_diff = false; + for (unsigned i = 0; i < from.size(); i++) + if (i < to.size() && !eq(from[i], to[i])) { + memo[from[i]] = to[i]; + some_diff = true; + } + return some_diff ? SubstRec(memo, t) : t; } RPFP::Term RPFP::SubstParamsNoCapture(const std::vector &from, - const std::vector &to, const Term &t){ - hash_map memo; - bool some_diff = false; - for(unsigned i = 0; i < from.size(); i++) - if(i < to.size() && !eq(from[i],to[i])){ - memo[from[i]] = to[i]; - // if the new param is not being mapped to anything else, we need to rename it to prevent capture - // note, if the new param *is* mapped later in the list, it will override this substitution - const expr &w = to[i]; - if(memo.find(w) == memo.end()){ - std::string old_name = w.decl().name().str(); - func_decl fresh = ctx.fresh_func_decl(old_name.c_str(), w.get_sort()); - expr y = fresh(); - memo[w] = y; - } - some_diff = true; - } - return some_diff ? SubstRec(memo,t) : t; + const std::vector &to, const Term &t) { + hash_map memo; + bool some_diff = false; + for (unsigned i = 0; i < from.size(); i++) + if (i < to.size() && !eq(from[i], to[i])) { + memo[from[i]] = to[i]; + // if the new param is not being mapped to anything else, we need to rename it to prevent capture + // note, if the new param *is* mapped later in the list, it will override this substitution + const expr &w = to[i]; + if (memo.find(w) == memo.end()) { + std::string old_name = w.decl().name().str(); + func_decl fresh = ctx.fresh_func_decl(old_name.c_str(), w.get_sort()); + expr y = fresh(); + memo[w] = y; + } + some_diff = true; + } + return some_diff ? SubstRec(memo, t) : t; } - RPFP::Transformer RPFP::Fuse(const std::vector &trs){ - assert(!trs.empty()); - const std::vector ¶ms = trs[0]->IndParams; - std::vector fmlas(trs.size()); - fmlas[0] = trs[0]->Formula; - for(unsigned i = 1; i < trs.size(); i++) - fmlas[i] = SubstParamsNoCapture(trs[i]->IndParams,params,trs[i]->Formula); - std::vector rel_params = trs[0]->RelParams; - for(unsigned i = 1; i < trs.size(); i++){ - const std::vector ¶ms2 = trs[i]->RelParams; - hash_map map; - for(unsigned j = 0; j < params2.size(); j++){ - func_decl rel = RenumberPred(params2[j],rel_params.size()); - rel_params.push_back(rel); - map[params2[j]] = rel; + RPFP::Transformer RPFP::Fuse(const std::vector &trs) { + assert(!trs.empty()); + const std::vector ¶ms = trs[0]->IndParams; + std::vector fmlas(trs.size()); + fmlas[0] = trs[0]->Formula; + for (unsigned i = 1; i < trs.size(); i++) + fmlas[i] = SubstParamsNoCapture(trs[i]->IndParams, params, trs[i]->Formula); + std::vector rel_params = trs[0]->RelParams; + for (unsigned i = 1; i < trs.size(); i++) { + const std::vector ¶ms2 = trs[i]->RelParams; + hash_map map; + for (unsigned j = 0; j < params2.size(); j++) { + func_decl rel = RenumberPred(params2[j], rel_params.size()); + rel_params.push_back(rel); + map[params2[j]] = rel; + } + hash_map memo; + fmlas[i] = SubstRec(memo, map, fmlas[i]); } - hash_map memo; - fmlas[i] = SubstRec(memo,map,fmlas[i]); - } - return Transformer(rel_params,params,ctx.make(Or,fmlas),trs[0]->owner); + return Transformer(rel_params, params, ctx.make(Or, fmlas), trs[0]->owner); } @@ -855,19 +838,17 @@ namespace Duality { root->Annotation.Formula = annot; } - void RPFP::DecodeTree(Node *root, TermTree *interp, int persist) - { - std::vector &ic = interp->getChildren(); - if (ic.size() > 0) - { - std::vector &nc = root->Outgoing->Children; - for (unsigned i = 0; i < nc.size(); i++) - DecodeTree(nc[i], ic[i], persist); + void RPFP::DecodeTree(Node *root, TermTree *interp, int persist) { + std::vector &ic = interp->getChildren(); + if (ic.size() > 0) { + std::vector &nc = root->Outgoing->Children; + for (unsigned i = 0; i < nc.size(); i++) + DecodeTree(nc[i], ic[i], persist); } - SetAnnotation(root,interp->getTerm()); + SetAnnotation(root, interp->getTerm()); #if 0 - if(persist != 0) - Z3_persist_ast(ctx,root->Annotation.Formula,persist); + if(persist != 0) + Z3_persist_ast(ctx,root->Annotation.Formula,persist); #endif } @@ -926,31 +907,30 @@ namespace Duality { #endif - expr RPFP::GetEdgeFormula(Edge *e, int persist, bool with_children, bool underapprox) - { - if (e->dual.null()) { - timer_start("ReducedDualEdge"); - e->dual = ReducedDualEdge(e); - timer_stop("ReducedDualEdge"); - timer_start("getting children"); - if(underapprox){ - std::vector cus(e->Children.size()); - for(unsigned i = 0; i < e->Children.size(); i++) - cus[i] = !UnderapproxFlag(e->Children[i]) || GetUnderapprox(e->Children[i]); - expr cnst = conjoin(cus); - e->dual = e->dual && cnst; + expr RPFP::GetEdgeFormula(Edge *e, int persist, bool with_children, bool underapprox) { + if (e->dual.null()) { + timer_start("ReducedDualEdge"); + e->dual = ReducedDualEdge(e); + timer_stop("ReducedDualEdge"); + timer_start("getting children"); + if (underapprox) { + std::vector cus(e->Children.size()); + for (unsigned i = 0; i < e->Children.size(); i++) + cus[i] = !UnderapproxFlag(e->Children[i]) || GetUnderapprox(e->Children[i]); + expr cnst = conjoin(cus); + e->dual = e->dual && cnst; + } + timer_stop("getting children"); + timer_start("Persisting"); + std::list::reverse_iterator it = stack.rbegin(); + for (int i = 0; i < persist && it != stack.rend(); i++) + it++; + if (it != stack.rend()) + it->edges.push_back(e); + timer_stop("Persisting"); + //Console.WriteLine("{0}", cnst); } - timer_stop("getting children"); - timer_start("Persisting"); - std::list::reverse_iterator it = stack.rbegin(); - for(int i = 0; i < persist && it != stack.rend(); i++) - it++; - if(it != stack.rend()) - it->edges.push_back(e); - timer_stop("Persisting"); - //Console.WriteLine("{0}", cnst); - } - return e->dual; + return e->dual; } /** For incremental solving, asserts the constraint associated @@ -970,47 +950,46 @@ namespace Duality { * */ - void RPFP::AssertEdge(Edge *e, int persist, bool with_children, bool underapprox) - { - if(eq(e->F.Formula,ctx.bool_val(true)) && (!with_children || e->Children.empty())) - return; - expr fmla = GetEdgeFormula(e, persist, with_children, underapprox); - timer_start("solver add"); - slvr_add(e->dual); - timer_stop("solver add"); - if(with_children) - for(unsigned i = 0; i < e->Children.size(); i++) - ConstrainParent(e,e->Children[i]); + void RPFP::AssertEdge(Edge *e, int persist, bool with_children, bool underapprox) { + if (eq(e->F.Formula, ctx.bool_val(true)) && (!with_children || e->Children.empty())) + return; + expr fmla = GetEdgeFormula(e, persist, with_children, underapprox); + timer_start("solver add"); + slvr_add(e->dual); + timer_stop("solver add"); + if (with_children) + for (unsigned i = 0; i < e->Children.size(); i++) + ConstrainParent(e, e->Children[i]); } #ifdef LIMIT_STACK_WEIGHT void RPFP_caching::AssertEdge(Edge *e, int persist, bool with_children, bool underapprox) { - unsigned old_new_alits = new_alits.size(); - if(eq(e->F.Formula,ctx.bool_val(true)) && (!with_children || e->Children.empty())) - return; - expr fmla = GetEdgeFormula(e, persist, with_children, underapprox); - timer_start("solver add"); - slvr_add(e->dual); - timer_stop("solver add"); - if(old_new_alits < new_alits.size()) - weight_added.val++; - if(with_children) - for(unsigned i = 0; i < e->Children.size(); i++) - ConstrainParent(e,e->Children[i]); + unsigned old_new_alits = new_alits.size(); + if(eq(e->F.Formula,ctx.bool_val(true)) && (!with_children || e->Children.empty())) + return; + expr fmla = GetEdgeFormula(e, persist, with_children, underapprox); + timer_start("solver add"); + slvr_add(e->dual); + timer_stop("solver add"); + if(old_new_alits < new_alits.size()) + weight_added.val++; + if(with_children) + for(unsigned i = 0; i < e->Children.size(); i++) + ConstrainParent(e,e->Children[i]); } #endif // caching verion of above - void RPFP_caching::AssertEdgeCache(Edge *e, std::vector &lits, bool with_children){ - if(eq(e->F.Formula,ctx.bool_val(true)) && (!with_children || e->Children.empty())) - return; - expr fmla = GetEdgeFormula(e, 0, with_children, false); - GetAssumptionLits(fmla,lits); - if(with_children) - for(unsigned i = 0; i < e->Children.size(); i++) - ConstrainParentCache(e,e->Children[i],lits); + void RPFP_caching::AssertEdgeCache(Edge *e, std::vector &lits, bool with_children) { + if (eq(e->F.Formula, ctx.bool_val(true)) && (!with_children || e->Children.empty())) + return; + expr fmla = GetEdgeFormula(e, 0, with_children, false); + GetAssumptionLits(fmla, lits); + if (with_children) + for (unsigned i = 0; i < e->Children.size(); i++) + ConstrainParentCache(e, e->Children[i], lits); } void RPFP::slvr_add(const expr &e){ @@ -1032,23 +1011,23 @@ namespace Duality { void RPFP_caching::slvr_pop(int i){ for(int j = 0; j < i; j++){ #ifdef LIMIT_STACK_WEIGHT - if(alit_stack_sizes.empty()){ - if(big_stack.empty()) - throw "stack underflow"; - for(unsigned k = 0; k < new_alits.size(); k++){ - if(AssumptionLits.find(new_alits[k]) == AssumptionLits.end()) - throw "foo!"; - AssumptionLits.erase(new_alits[k]); - } - big_stack_entry &bsb = big_stack.back(); - bsb.alit_stack_sizes.swap(alit_stack_sizes); - bsb.alit_stack.swap(alit_stack); - bsb.new_alits.swap(new_alits); - bsb.weight_added.swap(weight_added); - big_stack.pop_back(); - slvr().pop(1); - continue; - } + if(alit_stack_sizes.empty()){ + if(big_stack.empty()) + throw "stack underflow"; + for(unsigned k = 0; k < new_alits.size(); k++){ + if(AssumptionLits.find(new_alits[k]) == AssumptionLits.end()) + throw "foo!"; + AssumptionLits.erase(new_alits[k]); + } + big_stack_entry &bsb = big_stack.back(); + bsb.alit_stack_sizes.swap(alit_stack_sizes); + bsb.alit_stack.swap(alit_stack); + bsb.new_alits.swap(new_alits); + bsb.weight_added.swap(weight_added); + big_stack.pop_back(); + slvr().pop(1); + continue; + } #endif alit_stack.resize(alit_stack_sizes.back()); alit_stack_sizes.pop_back(); @@ -1057,18 +1036,18 @@ namespace Duality { void RPFP_caching::slvr_push(){ #ifdef LIMIT_STACK_WEIGHT - if(weight_added.val > LIMIT_STACK_WEIGHT){ - big_stack.resize(big_stack.size()+1); - big_stack_entry &bsb = big_stack.back(); - bsb.alit_stack_sizes.swap(alit_stack_sizes); - bsb.alit_stack.swap(alit_stack); - bsb.new_alits.swap(new_alits); - bsb.weight_added.swap(weight_added); - slvr().push(); - for(unsigned i = 0; i < bsb.alit_stack.size(); i++) - slvr().add(bsb.alit_stack[i]); - return; - } + if(weight_added.val > LIMIT_STACK_WEIGHT){ + big_stack.resize(big_stack.size()+1); + big_stack_entry &bsb = big_stack.back(); + bsb.alit_stack_sizes.swap(alit_stack_sizes); + bsb.alit_stack.swap(alit_stack); + bsb.new_alits.swap(new_alits); + bsb.weight_added.swap(weight_added); + slvr().push(); + for(unsigned i = 0; i < bsb.alit_stack.size(); i++) + slvr().add(bsb.alit_stack[i]); + return; + } #endif alit_stack_sizes.push_back(alit_stack.size()); } @@ -1082,16 +1061,16 @@ namespace Duality { if(n && assumptions) std::copy(assumptions,assumptions+n,std::inserter(alit_stack,alit_stack.end())); check_result res; - if(core_size && core){ - std::vector full_core(alit_stack.size()), core1(n); - std::copy(assumptions,assumptions+n,core1.begin()); - res = slvr().check(alit_stack.size(), &alit_stack[0], core_size, &full_core[0]); - full_core.resize(*core_size); - if(res == unsat){ - FilterCore(core1,full_core); - *core_size = core1.size(); - std::copy(core1.begin(),core1.end(),core); - } + if (core_size && core) { + std::vector full_core(alit_stack.size()), core1(n); + std::copy(assumptions, assumptions + n, core1.begin()); + res = slvr().check(alit_stack.size(), &alit_stack[0], core_size, &full_core[0]); + full_core.resize(*core_size); + if (res == unsat) { + FilterCore(core1, full_core); + *core_size = core1.size(); + std::copy(core1.begin(), core1.end(), core); + } } else res = slvr().check(alit_stack.size(), &alit_stack[0]); @@ -1100,20 +1079,20 @@ namespace Duality { } lbool RPFP::ls_interpolate_tree(TermTree *assumptions, - TermTree *&interpolants, - model &_model, - TermTree *goals, - bool weak){ - return ls->interpolate_tree(assumptions, interpolants, _model, goals, weak); + TermTree *&interpolants, + model &_model, + TermTree *goals, + bool weak) { + return ls->interpolate_tree(assumptions, interpolants, _model, goals, weak); } lbool RPFP_caching::ls_interpolate_tree(TermTree *assumptions, - TermTree *&interpolants, - model &_model, - TermTree *goals, - bool weak){ - GetTermTreeAssertionLiterals(assumptions); - return ls->interpolate_tree(assumptions, interpolants, _model, goals, weak); + TermTree *&interpolants, + model &_model, + TermTree *goals, + bool weak) { + GetTermTreeAssertionLiterals(assumptions); + return ls->interpolate_tree(assumptions, interpolants, _model, goals, weak); } void RPFP_caching::GetTermTreeAssertionLiteralsRec(TermTree *assumptions){ @@ -1132,34 +1111,34 @@ namespace Duality { return; } - void RPFP_caching::GetTermTreeAssertionLiterals(TermTree *assumptions){ - // optimize binary case - if(assumptions->getChildren().size() == 1 - && assumptions->getChildren()[0]->getChildren().size() == 0){ - hash_map map; - TermTree *child = assumptions->getChildren()[0]; - std::vector dummy; - GetAssumptionLits(child->getTerm(),dummy,&map); - std::vector &ts = child->getTerms(); - for(unsigned i = 0; i < ts.size(); i++) - GetAssumptionLits(ts[i],dummy,&map); - std::vector assumps; - slvr().get_proof().get_assumptions(assumps); - if(!proof_core){ // save the proof core for later use - proof_core = new hash_set; - for(unsigned i = 0; i < assumps.size(); i++) - proof_core->insert(assumps[i]); + void RPFP_caching::GetTermTreeAssertionLiterals(TermTree *assumptions) { + // optimize binary case + if (assumptions->getChildren().size() == 1 + && assumptions->getChildren()[0]->getChildren().size() == 0) { + hash_map map; + TermTree *child = assumptions->getChildren()[0]; + std::vector dummy; + GetAssumptionLits(child->getTerm(), dummy, &map); + std::vector &ts = child->getTerms(); + for (unsigned i = 0; i < ts.size(); i++) + GetAssumptionLits(ts[i], dummy, &map); + std::vector assumps; + slvr().get_proof().get_assumptions(assumps); + if (!proof_core) { // save the proof core for later use + proof_core = new hash_set < ast > ; + for (unsigned i = 0; i < assumps.size(); i++) + proof_core->insert(assumps[i]); + } + std::vector *cnsts[2] = { &child->getTerms(), &assumptions->getTerms() }; + for (unsigned i = 0; i < assumps.size(); i++) { + expr &ass = assumps[i]; + expr alit = (ass.is_app() && ass.decl().get_decl_kind() == Implies) ? ass.arg(0) : ass; + bool isA = map.find(alit) != map.end(); + cnsts[isA ? 0 : 1]->push_back(ass); + } } - std::vector *cnsts[2] = {&child->getTerms(),&assumptions->getTerms()}; - for(unsigned i = 0; i < assumps.size(); i++){ - expr &ass = assumps[i]; - expr alit = (ass.is_app() && ass.decl().get_decl_kind() == Implies) ? ass.arg(0) : ass; - bool isA = map.find(alit) != map.end(); - cnsts[isA ? 0 : 1]->push_back(ass); - } - } - else - GetTermTreeAssertionLiteralsRec(assumptions); + else + GetTermTreeAssertionLiteralsRec(assumptions); } void RPFP::AddToProofCore(hash_set &core){ @@ -1177,27 +1156,27 @@ namespace Duality { } - void RPFP_caching::GetAssumptionLits(const expr &fmla, std::vector &lits, hash_map *opt_map){ - std::vector conjs; - CollectConjuncts(fmla,conjs); - for(unsigned i = 0; i < conjs.size(); i++){ - const expr &conj = conjs[i]; - std::pair foo(conj,expr(ctx)); - std::pair::iterator, bool> bar = AssumptionLits.insert(foo); - Term &res = bar.first->second; - if(bar.second){ - func_decl pred = ctx.fresh_func_decl("@alit", ctx.bool_sort()); - res = pred(); + void RPFP_caching::GetAssumptionLits(const expr &fmla, std::vector &lits, hash_map *opt_map) { + std::vector conjs; + CollectConjuncts(fmla, conjs); + for (unsigned i = 0; i < conjs.size(); i++) { + const expr &conj = conjs[i]; + std::pair foo(conj, expr(ctx)); + std::pair::iterator, bool> bar = AssumptionLits.insert(foo); + Term &res = bar.first->second; + if (bar.second) { + func_decl pred = ctx.fresh_func_decl("@alit", ctx.bool_sort()); + res = pred(); #ifdef LIMIT_STACK_WEIGHT - new_alits.push_back(conj); + new_alits.push_back(conj); #endif - slvr().add(ctx.make(Implies,res,conj)); - // std::cout << res << ": " << conj << "\n"; + slvr().add(ctx.make(Implies, res, conj)); + // std::cout << res << ": " << conj << "\n"; + } + if (opt_map) + (*opt_map)[res] = conj; + lits.push_back(res); } - if(opt_map) - (*opt_map)[res] = conj; - lits.push_back(res); - } } void RPFP::ConstrainParent(Edge *parent, Node *child){ @@ -1215,39 +1194,37 @@ namespace Duality { void RPFP::AssertNode(Node *n) { - if (n->dual.null()) - { - n->dual = GetUpperBound(n); - stack.back().nodes.push_back(n); - slvr_add(n->dual); + if (n->dual.null()) { + n->dual = GetUpperBound(n); + stack.back().nodes.push_back(n); + slvr_add(n->dual); } } // caching version of above void RPFP_caching::AssertNodeCache(Node *n, std::vector lits){ - if (n->dual.null()) - { - n->dual = GetUpperBound(n); - stack.back().nodes.push_back(n); - GetAssumptionLits(n->dual,lits); + if (n->dual.null()) { + n->dual = GetUpperBound(n); + stack.back().nodes.push_back(n); + GetAssumptionLits(n->dual, lits); } } /** Clone another RPFP into this one, keeping a map */ - void RPFP_caching::Clone(RPFP *other){ + void RPFP_caching::Clone(RPFP *other) { #if 0 - for(unsigned i = 0; i < other->nodes.size(); i++) - NodeCloneMap[other->nodes[i]] = CloneNode(other->nodes[i]); + for(unsigned i = 0; i < other->nodes.size(); i++) + NodeCloneMap[other->nodes[i]] = CloneNode(other->nodes[i]); #endif - for(unsigned i = 0; i < other->edges.size(); i++){ - Edge *edge = other->edges[i]; - Node *parent = CloneNode(edge->Parent); - std::vector cs; - for(unsigned j = 0; j < edge->Children.size(); j++) - // cs.push_back(NodeCloneMap[edge->Children[j]]); - cs.push_back(CloneNode(edge->Children[j])); - EdgeCloneMap[edge] = CreateEdge(parent,edge->F,cs); - } + for (unsigned i = 0; i < other->edges.size(); i++) { + Edge *edge = other->edges[i]; + Node *parent = CloneNode(edge->Parent); + std::vector cs; + for (unsigned j = 0; j < edge->Children.size(); j++) + // cs.push_back(NodeCloneMap[edge->Children[j]]); + cs.push_back(CloneNode(edge->Children[j])); + EdgeCloneMap[edge] = CreateEdge(parent, edge->F, cs); + } } /** Get the clone of a node */ @@ -1373,11 +1350,10 @@ namespace Duality { timer_start("interpolate_tree"); lbool res = ls_interpolate_tree(tree, interpolant, dualModel,goals,true); timer_stop("interpolate_tree"); - if (res == l_false) - { - DecodeTree(root, interpolant->getChildren()[0], persist); - delete interpolant; - } + if (res == l_false) { + DecodeTree(root, interpolant->getChildren()[0], persist); + delete interpolant; + } delete tree; if(goals) @@ -1419,11 +1395,10 @@ namespace Duality { timer_start("interpolate_tree"); lbool res = ls_interpolate_tree(tree, interpolant, dualModel,0,true); timer_stop("interpolate_tree"); - if (res == l_false) - { - DecodeTree(node, interpolant->getChildren()[0], 0); - delete interpolant; - } + if (res == l_false) { + DecodeTree(node, interpolant->getChildren()[0], 0); + delete interpolant; + } delete tree; timer_stop("Solve"); @@ -1461,44 +1436,43 @@ namespace Duality { * */ - check_result RPFP::Check(Node *root, std::vector underapproxes, std::vector *underapprox_core ) - { - timer_start("Check"); - ClearProofCore(); - // if (dualModel != null) dualModel.Dispose(); - check_result res; - if(!underapproxes.size()) - res = slvr_check(); - else { - std::vector us(underapproxes.size()); - for(unsigned i = 0; i < underapproxes.size(); i++) - us[i] = UnderapproxFlag(underapproxes[i]); - slvr_check(); // TODO: no idea why I need to do this - if(underapprox_core){ - std::vector unsat_core(us.size()); - unsigned core_size = 0; - res = slvr_check(us.size(),&us[0],&core_size,&unsat_core[0]); - underapprox_core->resize(core_size); - for(unsigned i = 0; i < core_size; i++) - (*underapprox_core)[i] = UnderapproxFlagRev(unsat_core[i]); - } - else { - res = slvr_check(us.size(),&us[0]); - bool dump = false; - if(dump){ - std::vector cnsts; - // cnsts.push_back(axioms[0]); - cnsts.push_back(root->dual); - cnsts.push_back(root->Outgoing->dual); - ls->write_interpolation_problem("temp.smt",cnsts,std::vector()); - } - } - // check_result temp = slvr_check(); - } - dualModel = slvr().get_model(); - timer_stop("Check"); - return res; - } + check_result RPFP::Check(Node *root, std::vector underapproxes, std::vector *underapprox_core) { + timer_start("Check"); + ClearProofCore(); + // if (dualModel != null) dualModel.Dispose(); + check_result res; + if (!underapproxes.size()) + res = slvr_check(); + else { + std::vector us(underapproxes.size()); + for (unsigned i = 0; i < underapproxes.size(); i++) + us[i] = UnderapproxFlag(underapproxes[i]); + slvr_check(); // TODO: no idea why I need to do this + if (underapprox_core) { + std::vector unsat_core(us.size()); + unsigned core_size = 0; + res = slvr_check(us.size(), &us[0], &core_size, &unsat_core[0]); + underapprox_core->resize(core_size); + for (unsigned i = 0; i < core_size; i++) + (*underapprox_core)[i] = UnderapproxFlagRev(unsat_core[i]); + } + else { + res = slvr_check(us.size(), &us[0]); + bool dump = false; + if (dump) { + std::vector cnsts; + // cnsts.push_back(axioms[0]); + cnsts.push_back(root->dual); + cnsts.push_back(root->Outgoing->dual); + ls->write_interpolation_problem("temp.smt", cnsts, std::vector()); + } + } + // check_result temp = slvr_check(); + } + dualModel = slvr().get_model(); + timer_stop("Check"); + return res; + } check_result RPFP::CheckUpdateModel(Node *root, std::vector assumps){ // check_result temp1 = slvr_check(); // no idea why I need to do this @@ -1545,54 +1519,54 @@ namespace Duality { } void RPFP::EvalArrayTerm(const RPFP::Term &t, ArrayValue &res){ - if(t.is_app()){ - decl_kind k = t.decl().get_decl_kind(); - if(k == AsArray){ - func_decl fd = t.decl().get_func_decl_parameter(0); - func_interp r = dualModel.get_func_interp(fd); - int num = r.num_entries(); - res.defined = true; - for(int i = 0; i < num; i++){ - expr arg = r.get_arg(i,0); - expr value = r.get_value(i); - res.entries[arg] = value; - } - res.def_val = r.else_value(); - return; + if (t.is_app()) { + decl_kind k = t.decl().get_decl_kind(); + if (k == AsArray) { + func_decl fd = t.decl().get_func_decl_parameter(0); + func_interp r = dualModel.get_func_interp(fd); + int num = r.num_entries(); + res.defined = true; + for (int i = 0; i < num; i++) { + expr arg = r.get_arg(i, 0); + expr value = r.get_value(i); + res.entries[arg] = value; + } + res.def_val = r.else_value(); + return; + } + else if (k == Store) { + EvalArrayTerm(t.arg(0), res); + if (!res.defined)return; + expr addr = t.arg(1); + expr val = t.arg(2); + if (addr.is_numeral() && val.is_numeral()) { + if (eq(val, res.def_val)) + res.entries.erase(addr); + else + res.entries[addr] = val; + } + else + res.defined = false; + return; + } } - else if(k == Store){ - EvalArrayTerm(t.arg(0),res); - if(!res.defined)return; - expr addr = t.arg(1); - expr val = t.arg(2); - if(addr.is_numeral() && val.is_numeral()){ - if(eq(val,res.def_val)) - res.entries.erase(addr); - else - res.entries[addr] = val; - } - else - res.defined = false; - return; - } - } res.defined = false; } int eae_count = 0; - RPFP::Term RPFP::EvalArrayEquality(const RPFP::Term &f){ - ArrayValue lhs,rhs; - eae_count++; - EvalArrayTerm(f.arg(0),lhs); - EvalArrayTerm(f.arg(1),rhs); - if(lhs.defined && rhs.defined){ - if(eq(lhs.def_val,rhs.def_val)) - if(lhs.entries == rhs.entries) - return ctx.bool_val(true); - return ctx.bool_val(false); - } - return f; + RPFP::Term RPFP::EvalArrayEquality(const RPFP::Term &f) { + ArrayValue lhs, rhs; + eae_count++; + EvalArrayTerm(f.arg(0), lhs); + EvalArrayTerm(f.arg(1), rhs); + if (lhs.defined && rhs.defined) { + if (eq(lhs.def_val, rhs.def_val)) + if (lhs.entries == rhs.entries) + return ctx.bool_val(true); + return ctx.bool_val(false); + } + return f; } /** Compute truth values of all boolean subterms in current model. @@ -1600,75 +1574,75 @@ namespace Duality { ands and, or, not. Returns result in memo. */ - int RPFP::SubtermTruth(hash_map &memo, const Term &f){ - if(memo.find(f) != memo.end()){ - return memo[f]; - } - int res; - if(f.is_app()){ - int nargs = f.num_args(); - decl_kind k = f.decl().get_decl_kind(); - if(k == Implies){ - res = SubtermTruth(memo,!f.arg(0) || f.arg(1)); - goto done; + int RPFP::SubtermTruth(hash_map &memo, const Term &f) { + if (memo.find(f) != memo.end()) { + return memo[f]; } - if(k == And) { - res = 1; - for(int i = 0; i < nargs; i++){ - int ar = SubtermTruth(memo,f.arg(i)); - if(ar == 0){ - res = 0; - goto done; - } - if(ar == 2)res = 2; - } - goto done; - } - else if(k == Or) { - res = 0; - for(int i = 0; i < nargs; i++){ - int ar = SubtermTruth(memo,f.arg(i)); - if(ar == 1){ - res = 1; - goto done; - } - if(ar == 2)res = 2; - } - goto done; - } - else if(k == Not) { - int ar = SubtermTruth(memo,f.arg(0)); - res = (ar == 0) ? 1 : ((ar == 1) ? 0 : 2); - goto done; + int res; + if (f.is_app()) { + int nargs = f.num_args(); + decl_kind k = f.decl().get_decl_kind(); + if (k == Implies) { + res = SubtermTruth(memo, !f.arg(0) || f.arg(1)); + goto done; + } + if (k == And) { + res = 1; + for (int i = 0; i < nargs; i++) { + int ar = SubtermTruth(memo, f.arg(i)); + if (ar == 0) { + res = 0; + goto done; + } + if (ar == 2)res = 2; + } + goto done; + } + else if (k == Or) { + res = 0; + for (int i = 0; i < nargs; i++) { + int ar = SubtermTruth(memo, f.arg(i)); + if (ar == 1) { + res = 1; + goto done; + } + if (ar == 2)res = 2; + } + goto done; + } + else if (k == Not) { + int ar = SubtermTruth(memo, f.arg(0)); + res = (ar == 0) ? 1 : ((ar == 1) ? 0 : 2); + goto done; + } } + { + bool pos; std::vector names; + if (f.is_label(pos, names)) { + res = SubtermTruth(memo, f.arg(0)); + goto done; + } } { - bool pos; std::vector names; - if(f.is_label(pos,names)){ - res = SubtermTruth(memo,f.arg(0)); - goto done; - } + expr bv = dualModel.eval(f); + if (bv.is_app() && bv.decl().get_decl_kind() == Equal && + bv.arg(0).is_array()) { + bv = EvalArrayEquality(bv); + } + // Hack!!!! array equalities can occur negatively! + if (bv.is_app() && bv.decl().get_decl_kind() == Not && + bv.arg(0).decl().get_decl_kind() == Equal && + bv.arg(0).arg(0).is_array()) { + bv = dualModel.eval(!EvalArrayEquality(bv.arg(0))); + } + if (eq(bv, ctx.bool_val(true))) + res = 1; + else if (eq(bv, ctx.bool_val(false))) + res = 0; + else + res = 2; } - { - expr bv = dualModel.eval(f); - if(bv.is_app() && bv.decl().get_decl_kind() == Equal && - bv.arg(0).is_array()){ - bv = EvalArrayEquality(bv); - } - // Hack!!!! array equalities can occur negatively! - if(bv.is_app() && bv.decl().get_decl_kind() == Not && - bv.arg(0).decl().get_decl_kind() == Equal && - bv.arg(0).arg(0).is_array()){ - bv = dualModel.eval(!EvalArrayEquality(bv.arg(0))); - } - if(eq(bv,ctx.bool_val(true))) - res = 1; - else if(eq(bv,ctx.bool_val(false))) - res = 0; - else - res = 2; - } - done: +done: memo[f] = res; return res; } @@ -1685,137 +1659,137 @@ namespace Duality { #if 0 int RPFP::GetLabelsRec(hash_map *memo, const Term &f, std::vector &labels, bool labpos){ - if(memo[labpos].find(f) != memo[labpos].end()){ - return memo[labpos][f]; - } - int res; - if(f.is_app()){ - int nargs = f.num_args(); - decl_kind k = f.decl().get_decl_kind(); - if(k == Implies){ - res = GetLabelsRec(memo,f.arg(1) || !f.arg(0), labels, labpos); - goto done; + if(memo[labpos].find(f) != memo[labpos].end()){ + return memo[labpos][f]; } - if(k == And) { - res = 1; - for(int i = 0; i < nargs; i++){ - int ar = GetLabelsRec(memo,f.arg(i), labels, labpos); - if(ar == 0){ - res = 0; - goto done; - } - if(ar == 2)res = 2; - } - goto done; - } - else if(k == Or) { - res = 0; - for(int i = 0; i < nargs; i++){ - int ar = GetLabelsRec(memo,f.arg(i), labels, labpos); - if(ar == 1){ - res = 1; - goto done; - } - if(ar == 2)res = 2; - } - goto done; - } - else if(k == Not) { - int ar = GetLabelsRec(memo,f.arg(0), labels, !labpos); - res = (ar == 0) ? 1 : ((ar == 1) ? 0 : 2); - goto done; + int res; + if(f.is_app()){ + int nargs = f.num_args(); + decl_kind k = f.decl().get_decl_kind(); + if(k == Implies){ + res = GetLabelsRec(memo,f.arg(1) || !f.arg(0), labels, labpos); + goto done; + } + if(k == And) { + res = 1; + for(int i = 0; i < nargs; i++){ + int ar = GetLabelsRec(memo,f.arg(i), labels, labpos); + if(ar == 0){ + res = 0; + goto done; + } + if(ar == 2)res = 2; + } + goto done; + } + else if(k == Or) { + res = 0; + for(int i = 0; i < nargs; i++){ + int ar = GetLabelsRec(memo,f.arg(i), labels, labpos); + if(ar == 1){ + res = 1; + goto done; + } + if(ar == 2)res = 2; + } + goto done; + } + else if(k == Not) { + int ar = GetLabelsRec(memo,f.arg(0), labels, !labpos); + res = (ar == 0) ? 1 : ((ar == 1) ? 0 : 2); + goto done; + } } + { + bool pos; std::vector names; + if(f.is_label(pos,names)){ + res = GetLabelsRec(memo,f.arg(0), labels, labpos); + if(pos == labpos && res == (pos ? 1 : 0)) + for(unsigned i = 0; i < names.size(); i++) + labels.push_back(names[i]); + goto done; + } } { - bool pos; std::vector names; - if(f.is_label(pos,names)){ - res = GetLabelsRec(memo,f.arg(0), labels, labpos); - if(pos == labpos && res == (pos ? 1 : 0)) - for(unsigned i = 0; i < names.size(); i++) - labels.push_back(names[i]); - goto done; - } + expr bv = dualModel.eval(f); + if(bv.is_app() && bv.decl().get_decl_kind() == Equal && + bv.arg(0).is_array()){ + bv = EvalArrayEquality(bv); + } + // Hack!!!! array equalities can occur negatively! + if(bv.is_app() && bv.decl().get_decl_kind() == Not && + bv.arg(0).decl().get_decl_kind() == Equal && + bv.arg(0).arg(0).is_array()){ + bv = dualModel.eval(!EvalArrayEquality(bv.arg(0))); + } + if(eq(bv,ctx.bool_val(true))) + res = 1; + else if(eq(bv,ctx.bool_val(false))) + res = 0; + else + res = 2; } - { - expr bv = dualModel.eval(f); - if(bv.is_app() && bv.decl().get_decl_kind() == Equal && - bv.arg(0).is_array()){ - bv = EvalArrayEquality(bv); - } - // Hack!!!! array equalities can occur negatively! - if(bv.is_app() && bv.decl().get_decl_kind() == Not && - bv.arg(0).decl().get_decl_kind() == Equal && - bv.arg(0).arg(0).is_array()){ - bv = dualModel.eval(!EvalArrayEquality(bv.arg(0))); - } - if(eq(bv,ctx.bool_val(true))) - res = 1; - else if(eq(bv,ctx.bool_val(false))) - res = 0; - else - res = 2; - } - done: +done: memo[labpos][f] = res; return res; } #endif - void RPFP::GetLabelsRec(hash_map &memo, const Term &f, std::vector &labels, - hash_set *done, bool truth){ - if(done[truth].find(f) != done[truth].end()) - return; /* already processed */ - if(f.is_app()){ - int nargs = f.num_args(); - decl_kind k = f.decl().get_decl_kind(); - if(k == Implies){ - GetLabelsRec(memo,f.arg(1) || !f.arg(0) ,labels,done,truth); - goto done; + void RPFP::GetLabelsRec(hash_map &memo, const Term &f, std::vector &labels, + hash_set *done, bool truth) { + if (done[truth].find(f) != done[truth].end()) + return; /* already processed */ + if (f.is_app()) { + int nargs = f.num_args(); + decl_kind k = f.decl().get_decl_kind(); + if (k == Implies) { + GetLabelsRec(memo, f.arg(1) || !f.arg(0), labels, done, truth); + goto done; + } + if (k == Iff) { + int b = SubtermTruth(memo, f.arg(0)); + if (b == 2) + throw "disaster in GetLabelsRec"; + GetLabelsRec(memo, f.arg(1), labels, done, truth ? b : !b); + goto done; + } + if (truth ? k == And : k == Or) { + for (int i = 0; i < nargs; i++) + GetLabelsRec(memo, f.arg(i), labels, done, truth); + goto done; + } + if (truth ? k == Or : k == And) { + for (int i = 0; i < nargs; i++) { + Term a = f.arg(i); + timer_start("SubtermTruth"); + int b = SubtermTruth(memo, a); + timer_stop("SubtermTruth"); + if (truth ? (b == 1) : (b == 0)) { + GetLabelsRec(memo, a, labels, done, truth); + goto done; + } + } + /* Unreachable! */ + // throw "error in RPFP::GetLabelsRec"; + goto done; + } + else if (k == Not) { + GetLabelsRec(memo, f.arg(0), labels, done, !truth); + goto done; + } + else { + bool pos; std::vector names; + if (f.is_label(pos, names)) { + GetLabelsRec(memo, f.arg(0), labels, done, truth); + if (pos == truth) + for (unsigned i = 0; i < names.size(); i++) + labels.push_back(names[i]); + goto done; + } + } } - if(k == Iff){ - int b = SubtermTruth(memo,f.arg(0)); - if(b == 2) - throw "disaster in GetLabelsRec"; - GetLabelsRec(memo,f.arg(1),labels,done,truth ? b : !b); - goto done; - } - if(truth ? k == And : k == Or) { - for(int i = 0; i < nargs; i++) - GetLabelsRec(memo,f.arg(i),labels,done,truth); - goto done; - } - if(truth ? k == Or : k == And) { - for(int i = 0; i < nargs; i++){ - Term a = f.arg(i); - timer_start("SubtermTruth"); - int b = SubtermTruth(memo,a); - timer_stop("SubtermTruth"); - if(truth ? (b == 1) : (b == 0)){ - GetLabelsRec(memo,a,labels,done,truth); - goto done; - } - } - /* Unreachable! */ - // throw "error in RPFP::GetLabelsRec"; - goto done; - } - else if(k == Not) { - GetLabelsRec(memo,f.arg(0),labels,done,!truth); - goto done; - } - else { - bool pos; std::vector names; - if(f.is_label(pos,names)){ - GetLabelsRec(memo,f.arg(0), labels, done, truth); - if(pos == truth) - for(unsigned i = 0; i < names.size(); i++) - labels.push_back(names[i]); - goto done; - } - } - } done: - done[truth].insert(f); + done[truth].insert(f); } void RPFP::GetLabels(Edge *e, std::vector &labels){ @@ -1833,185 +1807,184 @@ namespace Duality { int ir_count = 0; - void RPFP::ImplicantRed(hash_map &memo, const Term &f, std::vector &lits, - hash_set *done, bool truth, hash_set &dont_cares){ - if(done[truth].find(f) != done[truth].end()) - return; /* already processed */ + void RPFP::ImplicantRed(hash_map &memo, const Term &f, std::vector &lits, + hash_set *done, bool truth, hash_set &dont_cares) { + if (done[truth].find(f) != done[truth].end()) + return; /* already processed */ #if 0 - int this_count = ir_count++; - if(this_count == 50092) - std::cout << "foo!\n"; + int this_count = ir_count++; + if(this_count == 50092) + std::cout << "foo!\n"; #endif - if(f.is_app()){ - int nargs = f.num_args(); - decl_kind k = f.decl().get_decl_kind(); - if(k == Implies){ - ImplicantRed(memo,f.arg(1) || !f.arg(0) ,lits,done,truth,dont_cares); - goto done; - } - if(k == Iff){ - int b = SubtermTruth(memo,f.arg(0)); - if(b == 2) - throw "disaster in ImplicantRed"; - ImplicantRed(memo,f.arg(1),lits,done,truth ? b : !b,dont_cares); - goto done; - } - if(truth ? k == And : k == Or) { - for(int i = 0; i < nargs; i++) - ImplicantRed(memo,f.arg(i),lits,done,truth,dont_cares); - goto done; - } - if(truth ? k == Or : k == And) { - for(int i = 0; i < nargs; i++){ - Term a = f.arg(i); + if (f.is_app()) { + int nargs = f.num_args(); + decl_kind k = f.decl().get_decl_kind(); + if (k == Implies) { + ImplicantRed(memo, f.arg(1) || !f.arg(0), lits, done, truth, dont_cares); + goto done; + } + if (k == Iff) { + int b = SubtermTruth(memo, f.arg(0)); + if (b == 2) + throw "disaster in ImplicantRed"; + ImplicantRed(memo, f.arg(1), lits, done, truth ? b : !b, dont_cares); + goto done; + } + if (truth ? k == And : k == Or) { + for (int i = 0; i < nargs; i++) + ImplicantRed(memo, f.arg(i), lits, done, truth, dont_cares); + goto done; + } + if (truth ? k == Or : k == And) { + for (int i = 0; i < nargs; i++) { + Term a = f.arg(i); #if 0 - if(i == nargs - 1){ // last chance! - ImplicantRed(memo,a,lits,done,truth,dont_cares); - goto done; - } + if(i == nargs - 1){ // last chance! + ImplicantRed(memo,a,lits,done,truth,dont_cares); + goto done; + } #endif - timer_start("SubtermTruth"); + timer_start("SubtermTruth"); #ifdef Z3OPS - bool b = stt->eval(a); + bool b = stt->eval(a); #else - int b = SubtermTruth(memo,a); + int b = SubtermTruth(memo, a); #endif - timer_stop("SubtermTruth"); - if(truth ? (b == 1) : (b == 0)){ - ImplicantRed(memo,a,lits,done,truth,dont_cares); - goto done; - } - } - /* Unreachable! */ - // TODO: need to indicate this failure to caller - // std::cerr << "error in RPFP::ImplicantRed"; - goto done; + timer_stop("SubtermTruth"); + if (truth ? (b == 1) : (b == 0)) { + ImplicantRed(memo, a, lits, done, truth, dont_cares); + goto done; + } + } + /* Unreachable! */ + // TODO: need to indicate this failure to caller + // std::cerr << "error in RPFP::ImplicantRed"; + goto done; + } + else if (k == Not) { + ImplicantRed(memo, f.arg(0), lits, done, !truth, dont_cares); + goto done; + } } - else if(k == Not) { - ImplicantRed(memo,f.arg(0),lits,done,!truth,dont_cares); - goto done; - } - } { - if(dont_cares.find(f) == dont_cares.end()){ - expr rf = ResolveIte(memo,f,lits,done,dont_cares); - expr bv = truth ? rf : !rf; - lits.push_back(bv); - } + if (dont_cares.find(f) == dont_cares.end()) { + expr rf = ResolveIte(memo, f, lits, done, dont_cares); + expr bv = truth ? rf : !rf; + lits.push_back(bv); + } } - done: +done: done[truth].insert(f); } - void RPFP::ImplicantFullRed(hash_map &memo, const Term &f, std::vector &lits, - hash_set &done, hash_set &dont_cares, bool extensional){ - if(done.find(f) != done.end()) - return; /* already processed */ - if(f.is_app()){ - int nargs = f.num_args(); - decl_kind k = f.decl().get_decl_kind(); - if(k == Implies || k == Iff || k == And || k == Or || k == Not){ - for(int i = 0; i < nargs; i++) - ImplicantFullRed(memo,f.arg(i),lits,done,dont_cares, extensional); - goto done; + void RPFP::ImplicantFullRed(hash_map &memo, const Term &f, std::vector &lits, + hash_set &done, hash_set &dont_cares, bool extensional) { + if (done.find(f) != done.end()) + return; /* already processed */ + if (f.is_app()) { + int nargs = f.num_args(); + decl_kind k = f.decl().get_decl_kind(); + if (k == Implies || k == Iff || k == And || k == Or || k == Not) { + for (int i = 0; i < nargs; i++) + ImplicantFullRed(memo, f.arg(i), lits, done, dont_cares, extensional); + goto done; + } } - } { - if(dont_cares.find(f) == dont_cares.end()){ - int b = SubtermTruth(memo,f); - if(b != 0 && b != 1) goto done; - if(f.is_app() && f.decl().get_decl_kind() == Equal && f.arg(0).is_array()){ - if(b == 1 && !extensional){ - expr x = dualModel.eval(f.arg(0)); expr y = dualModel.eval(f.arg(1)); - if(!eq(x,y)) - b = 0; - } - if(b == 0) - goto done; - } - expr bv = (b==1) ? f : !f; - lits.push_back(bv); - } + if (dont_cares.find(f) == dont_cares.end()) { + int b = SubtermTruth(memo, f); + if (b != 0 && b != 1) goto done; + if (f.is_app() && f.decl().get_decl_kind() == Equal && f.arg(0).is_array()) { + if (b == 1 && !extensional) { + expr x = dualModel.eval(f.arg(0)); expr y = dualModel.eval(f.arg(1)); + if (!eq(x, y)) + b = 0; + } + if (b == 0) + goto done; + } + expr bv = (b == 1) ? f : !f; + lits.push_back(bv); + } } - done: +done: done.insert(f); } - RPFP::Term RPFP::ResolveIte(hash_map &memo, const Term &t, std::vector &lits, - hash_set *done, hash_set &dont_cares){ - if(resolve_ite_memo.find(t) != resolve_ite_memo.end()) - return resolve_ite_memo[t]; - Term res; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - if(f.get_decl_kind() == Ite){ - timer_start("SubtermTruth"); + RPFP::Term RPFP::ResolveIte(hash_map &memo, const Term &t, std::vector &lits, + hash_set *done, hash_set &dont_cares) { + if (resolve_ite_memo.find(t) != resolve_ite_memo.end()) + return resolve_ite_memo[t]; + Term res; + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + if (f.get_decl_kind() == Ite) { + timer_start("SubtermTruth"); #ifdef Z3OPS - bool sel = stt->eval(t.arg(0)); + bool sel = stt->eval(t.arg(0)); #else - int xval = SubtermTruth(memo,t.arg(0)); - bool sel; - if(xval == 0)sel = false; - else if(xval == 1)sel = true; - else - throw "unresolved ite in model"; + int xval = SubtermTruth(memo, t.arg(0)); + bool sel; + if (xval == 0)sel = false; + else if (xval == 1)sel = true; + else + throw "unresolved ite in model"; #endif - timer_stop("SubtermTruth"); - ImplicantRed(memo,t.arg(0),lits,done,sel,dont_cares); - res = ResolveIte(memo,t.arg(sel?1:2),lits,done,dont_cares); - } - else { - for(int i = 0; i < nargs; i++) - args.push_back(ResolveIte(memo,t.arg(i),lits,done,dont_cares)); - res = f(args.size(),&args[0]); - } + timer_stop("SubtermTruth"); + ImplicantRed(memo, t.arg(0), lits, done, sel, dont_cares); + res = ResolveIte(memo, t.arg(sel ? 1 : 2), lits, done, dont_cares); + } + else { + for (int i = 0; i < nargs; i++) + args.push_back(ResolveIte(memo, t.arg(i), lits, done, dont_cares)); + res = f(args.size(), &args[0]); + } } - else res = t; - resolve_ite_memo[t] = res; - return res; + else res = t; + resolve_ite_memo[t] = res; + return res; } - RPFP::Term RPFP::ElimIteRec(hash_map &memo, const Term &t, std::vector &cnsts){ - std::pair foo(t,expr(ctx)); - std::pair::iterator, bool> bar = memo.insert(foo); - Term &res = bar.first->second; - if(bar.second){ - if(t.is_app()){ - int nargs = t.num_args(); - std::vector args; - if(t.decl().get_decl_kind() == Equal){ - expr lhs = t.arg(0); - expr rhs = t.arg(1); - if(rhs.decl().get_decl_kind() == Ite){ - expr rhs_args[3]; - lhs = ElimIteRec(memo,lhs,cnsts); - for(int i = 0; i < 3; i++) - rhs_args[i] = ElimIteRec(memo,rhs.arg(i),cnsts); - res = (rhs_args[0] && (lhs == rhs_args[1])) || ((!rhs_args[0]) && (lhs == rhs_args[2])); - goto done; - } - } - if(t.decl().get_decl_kind() == Ite){ - func_decl sym = ctx.fresh_func_decl("@ite", t.get_sort()); - res = sym(); - cnsts.push_back(ElimIteRec(memo,ctx.make(Equal,res,t),cnsts)); - } - else { - for(int i = 0; i < nargs; i++) - args.push_back(ElimIteRec(memo,t.arg(i),cnsts)); - res = t.decl()(args.size(),&args[0]); - } + RPFP::Term RPFP::ElimIteRec(hash_map &memo, const Term &t, std::vector &cnsts) { + std::pair foo(t, expr(ctx)); + std::pair::iterator, bool> bar = memo.insert(foo); + Term &res = bar.first->second; + if (bar.second) { + if (t.is_app()) { + int nargs = t.num_args(); + std::vector args; + if (t.decl().get_decl_kind() == Equal) { + expr lhs = t.arg(0); + expr rhs = t.arg(1); + if (rhs.decl().get_decl_kind() == Ite) { + expr rhs_args[3]; + lhs = ElimIteRec(memo, lhs, cnsts); + for (int i = 0; i < 3; i++) + rhs_args[i] = ElimIteRec(memo, rhs.arg(i), cnsts); + res = (rhs_args[0] && (lhs == rhs_args[1])) || ((!rhs_args[0]) && (lhs == rhs_args[2])); + goto done; + } + } + if (t.decl().get_decl_kind() == Ite) { + func_decl sym = ctx.fresh_func_decl("@ite", t.get_sort()); + res = sym(); + cnsts.push_back(ElimIteRec(memo, ctx.make(Equal, res, t), cnsts)); + } + else { + for (int i = 0; i < nargs; i++) + args.push_back(ElimIteRec(memo, t.arg(i), cnsts)); + res = t.decl()(args.size(), &args[0]); + } + } + else if (t.is_quantifier()) + res = clone_quantifier(t, ElimIteRec(memo, t.body(), cnsts)); + else + res = t; } - else if(t.is_quantifier()) - res = clone_quantifier(t,ElimIteRec(memo,t.body(),cnsts)); - else - res = t; - } done: - return res; + return res; } RPFP::Term RPFP::ElimIte(const Term &t){ @@ -2084,169 +2057,166 @@ namespace Duality { hash_map cand_map; params simp_params; - VariableProjector(Z3User &_user, std::vector &keep_vec) : - Z3User(_user), simp_params() - { - num_vars = 0; - for(unsigned i = 0; i < keep_vec.size(); i++){ - keep.insert(keep_vec[i]); - var_ord[keep_vec[i]] = num_vars++; - } + VariableProjector(Z3User &_user, std::vector &keep_vec) : + Z3User(_user), simp_params() { + num_vars = 0; + for (unsigned i = 0; i < keep_vec.size(); i++) { + keep.insert(keep_vec[i]); + var_ord[keep_vec[i]] = num_vars++; + } } - - int VarNum(const Term &v){ - if(var_ord.find(v) == var_ord.end()) - var_ord[v] = num_vars++; - return var_ord[v]; + int VarNum(const Term &v) { + if (var_ord.find(v) == var_ord.end()) + var_ord[v] = num_vars++; + return var_ord[v]; } bool IsVar(const Term &t){ return t.is_app() && t.num_args() == 0 && t.decl().get_decl_kind() == Uninterpreted; } - bool IsPropLit(const Term &t, Term &a){ - if(IsVar(t)){ - a = t; - return true; - } - else if(t.is_app() && t.decl().get_decl_kind() == Not) - return IsPropLit(t.arg(0),a); - return false; + bool IsPropLit(const Term &t, Term &a) { + if (IsVar(t)) { + a = t; + return true; + } + else if (t.is_app() && t.decl().get_decl_kind() == Not) + return IsPropLit(t.arg(0), a); + return false; } - void CountOtherVarsRec(hash_map &memo, - const Term &t, - int id, - int &count){ - std::pair foo(t,0); - std::pair::iterator, bool> bar = memo.insert(foo); - // int &res = bar.first->second; - if(!bar.second) return; - if (t.is_app()) - { - func_decl f = t.decl(); - std::vector args; - int nargs = t.num_args(); - if (nargs == 0 && f.get_decl_kind() == Uninterpreted){ - if(cand_map.find(t) != cand_map.end()){ - count++; - sup_map[t].push_back(id); - } - } - for(int i = 0; i < nargs; i++) - CountOtherVarsRec(memo, t.arg(i), id, count); - } - else if (t.is_quantifier()) - CountOtherVarsRec(memo, t.body(), id, count); - } + void CountOtherVarsRec(hash_map &memo, + const Term &t, + int id, + int &count) { + std::pair foo(t, 0); + std::pair::iterator, bool> bar = memo.insert(foo); + // int &res = bar.first->second; + if (!bar.second) return; + if (t.is_app()) { + func_decl f = t.decl(); + std::vector args; + int nargs = t.num_args(); + if (nargs == 0 && f.get_decl_kind() == Uninterpreted) { + if (cand_map.find(t) != cand_map.end()) { + count++; + sup_map[t].push_back(id); + } + } + for (int i = 0; i < nargs; i++) + CountOtherVarsRec(memo, t.arg(i), id, count); + } + else if (t.is_quantifier()) + CountOtherVarsRec(memo, t.body(), id, count); + } - void NewElimCand(const Term &lhs, const Term &rhs){ - if(debug_gauss){ - std::cout << "mapping " << lhs << " to " << rhs << std::endl; - } - elim_cand cand; - cand.var = lhs; - cand.sup = 0; - cand.val = rhs; - elim_cands.push_back(cand); - cand_map[lhs] = elim_cands.size()-1; + void NewElimCand(const Term &lhs, const Term &rhs) { + if (debug_gauss) { + std::cout << "mapping " << lhs << " to " << rhs << std::endl; + } + elim_cand cand; + cand.var = lhs; + cand.sup = 0; + cand.val = rhs; + elim_cands.push_back(cand); + cand_map[lhs] = elim_cands.size() - 1; } - void MakeElimCand(const Term &lhs, const Term &rhs){ - if(eq(lhs,rhs)) - return; - if(!IsVar(lhs)){ - if(IsVar(rhs)){ - MakeElimCand(rhs,lhs); - return; - } - else{ - std::cout << "would have mapped a non-var\n"; - return; - } - } - if(IsVar(rhs) && VarNum(rhs) > VarNum(lhs)){ - MakeElimCand(rhs,lhs); - return; - } - if(keep.find(lhs) != keep.end()) - return; - if(cand_map.find(lhs) == cand_map.end()) - NewElimCand(lhs,rhs); - else { - int cand_idx = cand_map[lhs]; - if(IsVar(rhs) && cand_map.find(rhs) == cand_map.end() - && keep.find(rhs) == keep.end()) - NewElimCand(rhs,elim_cands[cand_idx].val); - elim_cands[cand_idx].val = rhs; - } + void MakeElimCand(const Term &lhs, const Term &rhs) { + if (eq(lhs, rhs)) + return; + if (!IsVar(lhs)) { + if (IsVar(rhs)) { + MakeElimCand(rhs, lhs); + return; + } + else { + std::cout << "would have mapped a non-var\n"; + return; + } + } + if (IsVar(rhs) && VarNum(rhs) > VarNum(lhs)) { + MakeElimCand(rhs, lhs); + return; + } + if (keep.find(lhs) != keep.end()) + return; + if (cand_map.find(lhs) == cand_map.end()) + NewElimCand(lhs, rhs); + else { + int cand_idx = cand_map[lhs]; + if (IsVar(rhs) && cand_map.find(rhs) == cand_map.end() + && keep.find(rhs) == keep.end()) + NewElimCand(rhs, elim_cands[cand_idx].val); + elim_cands[cand_idx].val = rhs; + } } - Term FindRep(const Term &t){ - if(cand_map.find(t) == cand_map.end()) - return t; - Term &res = elim_cands[cand_map[t]].val; - if(IsVar(res)){ - assert(VarNum(res) < VarNum(t)); - res = FindRep(res); - return res; - } - return t; + Term FindRep(const Term &t) { + if (cand_map.find(t) == cand_map.end()) + return t; + Term &res = elim_cands[cand_map[t]].val; + if (IsVar(res)) { + assert(VarNum(res) < VarNum(t)); + res = FindRep(res); + return res; + } + return t; } void GaussElimCheap(const std::vector &lits_in, - std::vector &lits_out){ - for(unsigned i = 0; i < lits_in.size(); i++){ - Term lit = lits_in[i]; - if(lit.is_app()){ - decl_kind k = lit.decl().get_decl_kind(); - if(k == Equal || k == Iff) - MakeElimCand(FindRep(lit.arg(0)),FindRep(lit.arg(1))); - } - } - - for(unsigned i = 0; i < elim_cands.size(); i++){ - elim_cand &cand = elim_cands[i]; - hash_map memo; - CountOtherVarsRec(memo,cand.val,i,cand.sup); - if(cand.sup == 0) - ready_cands.push_back(i); - } - - while(!ready_cands.empty()){ - elim_cand &cand = elim_cands[ready_cands.back()]; - ready_cands.pop_back(); - Term rep = FindRep(cand.var); - if(!eq(rep,cand.var)) - if(cand_map.find(rep) != cand_map.end()){ - int rep_pos = cand_map[rep]; - cand.val = elim_cands[rep_pos].val; - } - Term val = SubstRec(elim_map,cand.val); - if(debug_gauss){ - std::cout << "subbing " << cand.var << " --> " << val << std::endl; - } - elim_map[cand.var] = val; - std::vector &sup = sup_map[cand.var]; - for(unsigned i = 0; i < sup.size(); i++){ - int c = sup[i]; - if((--elim_cands[c].sup) == 0) - ready_cands.push_back(c); - } - } - - for(unsigned i = 0; i < lits_in.size(); i++){ - Term lit = lits_in[i]; - lit = SubstRec(elim_map,lit); - lit = lit.simplify(); - if(eq(lit,ctx.bool_val(true))) - continue; - Term a; - if(IsPropLit(lit,a)) - if(keep.find(lit) == keep.end()) - continue; - lits_out.push_back(lit); - } + std::vector &lits_out) { + for (unsigned i = 0; i < lits_in.size(); i++) { + Term lit = lits_in[i]; + if (lit.is_app()) { + decl_kind k = lit.decl().get_decl_kind(); + if (k == Equal || k == Iff) + MakeElimCand(FindRep(lit.arg(0)), FindRep(lit.arg(1))); + } + } + + for (unsigned i = 0; i < elim_cands.size(); i++) { + elim_cand &cand = elim_cands[i]; + hash_map memo; + CountOtherVarsRec(memo, cand.val, i, cand.sup); + if (cand.sup == 0) + ready_cands.push_back(i); + } + + while (!ready_cands.empty()) { + elim_cand &cand = elim_cands[ready_cands.back()]; + ready_cands.pop_back(); + Term rep = FindRep(cand.var); + if (!eq(rep, cand.var)) + if (cand_map.find(rep) != cand_map.end()) { + int rep_pos = cand_map[rep]; + cand.val = elim_cands[rep_pos].val; + } + Term val = SubstRec(elim_map, cand.val); + if (debug_gauss) { + std::cout << "subbing " << cand.var << " --> " << val << std::endl; + } + elim_map[cand.var] = val; + std::vector &sup = sup_map[cand.var]; + for (unsigned i = 0; i < sup.size(); i++) { + int c = sup[i]; + if ((--elim_cands[c].sup) == 0) + ready_cands.push_back(c); + } + } + + for (unsigned i = 0; i < lits_in.size(); i++) { + Term lit = lits_in[i]; + lit = SubstRec(elim_map, lit); + lit = lit.simplify(); + if (eq(lit, ctx.bool_val(true))) + continue; + Term a; + if (IsPropLit(lit, a)) + if (keep.find(lit) == keep.end()) + continue; + lits_out.push_back(lit); + } } // maps variables to constrains in which the occur pos, neg @@ -2255,88 +2225,88 @@ namespace Duality { std::vector la_pos_vars; bool fixing; - void IndexLAcoeff(const Term &coeff1, const Term &coeff2, Term t, int id){ - Term coeff = coeff1 * coeff2; - coeff = coeff.simplify(); - Term is_pos = (coeff >= ctx.int_val(0)); - is_pos = is_pos.simplify(); - if(eq(is_pos,ctx.bool_val(true))) - IndexLA(true,coeff,t, id); - else - IndexLA(false,coeff,t, id); + void IndexLAcoeff(const Term &coeff1, const Term &coeff2, Term t, int id) { + Term coeff = coeff1 * coeff2; + coeff = coeff.simplify(); + Term is_pos = (coeff >= ctx.int_val(0)); + is_pos = is_pos.simplify(); + if (eq(is_pos, ctx.bool_val(true))) + IndexLA(true, coeff, t, id); + else + IndexLA(false, coeff, t, id); } - void IndexLAremove(const Term &t){ - if(IsVar(t)){ - la_index[0][t] = -1; // means ineligible to be eliminated - la_index[1][t] = -1; // (more that one occurrence, or occurs not in linear comb) - } - else if(t.is_app()){ - int nargs = t.num_args(); - for(int i = 0; i < nargs; i++) - IndexLAremove(t.arg(i)); - } - // TODO: quantifiers? + void IndexLAremove(const Term &t) { + if (IsVar(t)) { + la_index[0][t] = -1; // means ineligible to be eliminated + la_index[1][t] = -1; // (more that one occurrence, or occurs not in linear comb) + } + else if (t.is_app()) { + int nargs = t.num_args(); + for (int i = 0; i < nargs; i++) + IndexLAremove(t.arg(i)); + } + // TODO: quantifiers? } - void IndexLA(bool pos, const Term &coeff, const Term &t, int id){ - if(t.is_numeral()) - return; - if(t.is_app()){ - int nargs = t.num_args(); - switch(t.decl().get_decl_kind()){ - case Plus: - for(int i = 0; i < nargs; i++) - IndexLA(pos,coeff,t.arg(i), id); - break; - case Sub: - IndexLA(pos,coeff,t.arg(0), id); - IndexLA(!pos,coeff,t.arg(1), id); - break; - case Times: - if(t.arg(0).is_numeral()) - IndexLAcoeff(coeff,t.arg(0),t.arg(1), id); - else if(t.arg(1).is_numeral()) - IndexLAcoeff(coeff,t.arg(1),t.arg(0), id); - break; - default: - if(IsVar(t) && (fixing || la_index[pos].find(t) == la_index[pos].end())){ - la_index[pos][t] = id; - la_coeffs[pos][t] = coeff; - if(pos && !fixing) - la_pos_vars.push_back(t); // this means we only add a var once - } - else - IndexLAremove(t); - } - } + void IndexLA(bool pos, const Term &coeff, const Term &t, int id) { + if (t.is_numeral()) + return; + if (t.is_app()) { + int nargs = t.num_args(); + switch (t.decl().get_decl_kind()) { + case Plus: + for (int i = 0; i < nargs; i++) + IndexLA(pos, coeff, t.arg(i), id); + break; + case Sub: + IndexLA(pos, coeff, t.arg(0), id); + IndexLA(!pos, coeff, t.arg(1), id); + break; + case Times: + if (t.arg(0).is_numeral()) + IndexLAcoeff(coeff, t.arg(0), t.arg(1), id); + else if (t.arg(1).is_numeral()) + IndexLAcoeff(coeff, t.arg(1), t.arg(0), id); + break; + default: + if (IsVar(t) && (fixing || la_index[pos].find(t) == la_index[pos].end())) { + la_index[pos][t] = id; + la_coeffs[pos][t] = coeff; + if (pos && !fixing) + la_pos_vars.push_back(t); // this means we only add a var once + } + else + IndexLAremove(t); + } + } } void IndexLAstart(bool pos, const Term &t, int id){ IndexLA(pos,(pos ? ctx.int_val(1) : ctx.int_val(-1)), t, id); } - void IndexLApred(bool pos, const Term &p, int id){ - if(p.is_app()){ - switch(p.decl().get_decl_kind()){ - case Not: - IndexLApred(!pos, p.arg(0),id); - break; - case Leq: - case Lt: - IndexLAstart(!pos, p.arg(0), id); - IndexLAstart(pos, p.arg(1), id); - break; - case Geq: - case Gt: - IndexLAstart(pos,p.arg(0), id); - IndexLAstart(!pos,p.arg(1), id); - break; - default: - IndexLAremove(p); - } - } + void IndexLApred(bool pos, const Term &p, int id) { + if (p.is_app()) { + switch (p.decl().get_decl_kind()) { + case Not: + IndexLApred(!pos, p.arg(0), id); + break; + case Leq: + case Lt: + IndexLAstart(!pos, p.arg(0), id); + IndexLAstart(pos, p.arg(1), id); + break; + case Geq: + case Gt: + IndexLAstart(pos, p.arg(0), id); + IndexLAstart(!pos, p.arg(1), id); + break; + default: + IndexLAremove(p); + } + } } void IndexLAfix(const Term &p, int id){ @@ -2345,51 +2315,51 @@ namespace Duality { fixing = false; } - bool IsCanonIneq(const Term &lit, Term &term, Term &bound){ - // std::cout << Z3_simplify_get_help(ctx) << std::endl; - bool pos = lit.decl().get_decl_kind() != Not; - Term atom = pos ? lit : lit.arg(0); - if(atom.decl().get_decl_kind() == Leq){ - if(pos){ - bound = atom.arg(0); - term = atom.arg(1).simplify(simp_params); + bool IsCanonIneq(const Term &lit, Term &term, Term &bound) { + // std::cout << Z3_simplify_get_help(ctx) << std::endl; + bool pos = lit.decl().get_decl_kind() != Not; + Term atom = pos ? lit : lit.arg(0); + if (atom.decl().get_decl_kind() == Leq) { + if (pos) { + bound = atom.arg(0); + term = atom.arg(1).simplify(simp_params); #if Z3_MAJOR_VERSION < 4 - term = SortSum(term); + term = SortSum(term); #endif - } - else { - bound = (atom.arg(1) + ctx.int_val(1)); - term = atom.arg(0); - // std::cout << "simplifying bound: " << bound << std::endl; - bound = bound.simplify(); - term = term.simplify(simp_params); + } + else { + bound = (atom.arg(1) + ctx.int_val(1)); + term = atom.arg(0); + // std::cout << "simplifying bound: " << bound << std::endl; + bound = bound.simplify(); + term = term.simplify(simp_params); #if Z3_MAJOR_VERSION < 4 - term = SortSum(term); + term = SortSum(term); #endif - } - return true; - } - else if(atom.decl().get_decl_kind() == Geq){ - if(pos){ - bound = atom.arg(1); // integer axiom - term = atom.arg(0).simplify(simp_params); + } + return true; + } + else if (atom.decl().get_decl_kind() == Geq) { + if (pos) { + bound = atom.arg(1); // integer axiom + term = atom.arg(0).simplify(simp_params); #if Z3_MAJOR_VERSION < 4 - term = SortSum(term); + term = SortSum(term); #endif - return true; - } - else{ - bound = -(atom.arg(1) - ctx.int_val(1)); // integer axiom - term = -atom.arg(0); - bound = bound.simplify(); - term = term.simplify(simp_params); + return true; + } + else { + bound = -(atom.arg(1) - ctx.int_val(1)); // integer axiom + term = -atom.arg(0); + bound = bound.simplify(); + term = term.simplify(simp_params); #if Z3_MAJOR_VERSION < 4 - term = SortSum(term); + term = SortSum(term); #endif - } - return true; - } - return false; + } + return true; + } + return false; } Term CanonIneqTerm(const Term &p){ @@ -2400,64 +2370,64 @@ namespace Duality { return term - bound; } - void ElimRedundantBounds(std::vector &lits){ - hash_map best_bound; - for(unsigned i = 0; i < lits.size(); i++){ - lits[i] = lits[i].simplify(simp_params); - Term term,bound; - if(IsCanonIneq(lits[i],term,bound)){ - if(best_bound.find(term) == best_bound.end()) - best_bound[term] = i; - else { - int best = best_bound[term]; - Term bterm,bbound; - IsCanonIneq(lits[best],bterm,bbound); - Term comp = bound > bbound; - comp = comp.simplify(); - if(eq(comp,ctx.bool_val(true))){ - lits[best] = ctx.bool_val(true); - best_bound[term] = i; - } - else { - lits[i] = ctx.bool_val(true); - } - } - } - } + void ElimRedundantBounds(std::vector &lits) { + hash_map best_bound; + for (unsigned i = 0; i < lits.size(); i++) { + lits[i] = lits[i].simplify(simp_params); + Term term, bound; + if (IsCanonIneq(lits[i], term, bound)) { + if (best_bound.find(term) == best_bound.end()) + best_bound[term] = i; + else { + int best = best_bound[term]; + Term bterm, bbound; + IsCanonIneq(lits[best], bterm, bbound); + Term comp = bound > bbound; + comp = comp.simplify(); + if (eq(comp, ctx.bool_val(true))) { + lits[best] = ctx.bool_val(true); + best_bound[term] = i; + } + else { + lits[i] = ctx.bool_val(true); + } + } + } + } } void FourierMotzkinCheap(const std::vector &lits_in, - std::vector &lits_out){ - simp_params.set(":som",true); - simp_params.set(":sort-sums",true); - fixing = false; lits_out = lits_in; - ElimRedundantBounds(lits_out); - for(unsigned i = 0; i < lits_out.size(); i++) - IndexLApred(true,lits_out[i],i); + std::vector &lits_out) { + simp_params.set(":som", true); + simp_params.set(":sort-sums", true); + fixing = false; lits_out = lits_in; + ElimRedundantBounds(lits_out); + for (unsigned i = 0; i < lits_out.size(); i++) + IndexLApred(true, lits_out[i], i); - for(unsigned i = 0; i < la_pos_vars.size(); i++){ - Term var = la_pos_vars[i]; - if(la_index[false].find(var) != la_index[false].end()){ - int pos_idx = la_index[true][var]; - int neg_idx = la_index[false][var]; - if(pos_idx >= 0 && neg_idx >= 0){ - if(keep.find(var) != keep.end()){ - std::cout << "would have eliminated keep var\n"; - continue; - } - Term tpos = CanonIneqTerm(lits_out[pos_idx]); - Term tneg = CanonIneqTerm(lits_out[neg_idx]); - Term pos_coeff = la_coeffs[true][var]; - Term neg_coeff = -la_coeffs[false][var]; - Term comb = neg_coeff * tpos + pos_coeff * tneg; - Term ineq = ctx.int_val(0) <= comb; - ineq = ineq.simplify(); - lits_out[pos_idx] = ineq; - lits_out[neg_idx] = ctx.bool_val(true); - IndexLAfix(ineq,pos_idx); - } - } - } + for (unsigned i = 0; i < la_pos_vars.size(); i++) { + Term var = la_pos_vars[i]; + if (la_index[false].find(var) != la_index[false].end()) { + int pos_idx = la_index[true][var]; + int neg_idx = la_index[false][var]; + if (pos_idx >= 0 && neg_idx >= 0) { + if (keep.find(var) != keep.end()) { + std::cout << "would have eliminated keep var\n"; + continue; + } + Term tpos = CanonIneqTerm(lits_out[pos_idx]); + Term tneg = CanonIneqTerm(lits_out[neg_idx]); + Term pos_coeff = la_coeffs[true][var]; + Term neg_coeff = -la_coeffs[false][var]; + Term comb = neg_coeff * tpos + pos_coeff * tneg; + Term ineq = ctx.int_val(0) <= comb; + ineq = ineq.simplify(); + lits_out[pos_idx] = ineq; + lits_out[neg_idx] = ctx.bool_val(true); + IndexLAfix(ineq, pos_idx); + } + } + } } Term ProjectFormula(const Term &f){ @@ -2473,42 +2443,42 @@ namespace Duality { } }; - void Z3User::CollectConjuncts(const Term &f, std::vector &lits, bool pos){ - if(f.is_app() && f.decl().get_decl_kind() == Not) - CollectConjuncts(f.arg(0), lits, !pos); - else if(pos && f.is_app() && f.decl().get_decl_kind() == And){ - int num_args = f.num_args(); - for(int i = 0; i < num_args; i++) - CollectConjuncts(f.arg(i),lits,true); - } - else if(!pos && f.is_app() && f.decl().get_decl_kind() == Or){ - int num_args = f.num_args(); - for(int i = 0; i < num_args; i++) - CollectConjuncts(f.arg(i),lits,false); - } - else if(pos){ - if(!eq(f,ctx.bool_val(true))) - lits.push_back(f); - } - else { - if(!eq(f,ctx.bool_val(false))) - lits.push_back(!f); - } + void Z3User::CollectConjuncts(const Term &f, std::vector &lits, bool pos) { + if (f.is_app() && f.decl().get_decl_kind() == Not) + CollectConjuncts(f.arg(0), lits, !pos); + else if (pos && f.is_app() && f.decl().get_decl_kind() == And) { + int num_args = f.num_args(); + for (int i = 0; i < num_args; i++) + CollectConjuncts(f.arg(i), lits, true); + } + else if (!pos && f.is_app() && f.decl().get_decl_kind() == Or) { + int num_args = f.num_args(); + for (int i = 0; i < num_args; i++) + CollectConjuncts(f.arg(i), lits, false); + } + else if (pos) { + if (!eq(f, ctx.bool_val(true))) + lits.push_back(f); + } + else { + if (!eq(f, ctx.bool_val(false))) + lits.push_back(!f); + } } - void Z3User::CollectJuncts(const Term &f, std::vector &lits, decl_kind op, bool negate){ - if(f.is_app() && f.decl().get_decl_kind() == Not) - CollectJuncts(f.arg(0), lits, (op == And) ? Or : And, !negate); - else if(f.is_app() && f.decl().get_decl_kind() == op){ - int num_args = f.num_args(); - for(int i = 0; i < num_args; i++) - CollectJuncts(f.arg(i),lits,op,negate); - } - else { - expr junct = negate ? Negate(f) : f; - lits.push_back(junct); - } - } + void Z3User::CollectJuncts(const Term &f, std::vector &lits, decl_kind op, bool negate) { + if (f.is_app() && f.decl().get_decl_kind() == Not) + CollectJuncts(f.arg(0), lits, (op == And) ? Or : And, !negate); + else if (f.is_app() && f.decl().get_decl_kind() == op) { + int num_args = f.num_args(); + for (int i = 0; i < num_args; i++) + CollectJuncts(f.arg(i), lits, op, negate); + } + else { + expr junct = negate ? Negate(f) : f; + lits.push_back(junct); + } + }| struct TermLt { bool operator()(const expr &x, const expr &y){ @@ -2591,7 +2561,7 @@ namespace Duality { hash_map memo; int res = SubtermTruth(memo, eu); if(res != 1) - throw "inconsistent projection"; + throw "inconsistent projection"; } #endif @@ -2622,16 +2592,16 @@ namespace Duality { if(memo[under].find(f) != memo[under].end()) return; memo[under].insert(f); - if(f.is_app()){ - if(!under && !f.has_quantifiers()) - return; - decl_kind k = f.decl().get_decl_kind(); - if(k == And || k == Or || k == Implies || k == Iff){ - int num_args = f.num_args(); - for(int i = 0; i < num_args; i++) - GetGroundLitsUnderQuants(memo,f.arg(i),res,under); - return; - } + if (f.is_app()) { + if (!under && !f.has_quantifiers()) + return; + decl_kind k = f.decl().get_decl_kind(); + if (k == And || k == Or || k == Implies || k == Iff) { + int num_args = f.num_args(); + for (int i = 0; i < num_args; i++) + GetGroundLitsUnderQuants(memo, f.arg(i), res, under); + return; + } } else if (f.is_quantifier()){ #if 0 @@ -2712,28 +2682,28 @@ namespace Duality { return g; } - RPFP::Term RPFP::ModelValueAsConstraint(const Term &t){ - if(t.is_array()){ - ArrayValue arr; - Term e = dualModel.eval(t); - EvalArrayTerm(e, arr); - if(arr.defined){ - std::vector cs; - for(std::map::iterator it = arr.entries.begin(), en = arr.entries.end(); it != en; ++it){ - expr foo = select(t,expr(ctx,it->first)) == expr(ctx,it->second); - cs.push_back(foo); - } - return conjoin(cs); + RPFP::Term RPFP::ModelValueAsConstraint(const Term &t) { + if (t.is_array()) { + ArrayValue arr; + Term e = dualModel.eval(t); + EvalArrayTerm(e, arr); + if (arr.defined) { + std::vector cs; + for (std::map::iterator it = arr.entries.begin(), en = arr.entries.end(); it != en; ++it) { + expr foo = select(t, expr(ctx, it->first)) == expr(ctx, it->second); + cs.push_back(foo); + } + return conjoin(cs); + } } - } - else { - expr r = dualModel.get_const_interp(t.decl()); - if(!r.null()){ - expr res = t == expr(ctx,r); - return res; + else { + expr r = dualModel.get_const_interp(t.decl()); + if (!r.null()) { + expr res = t == expr(ctx, r); + return res; + } } - } - return ctx.bool_val(true); + return ctx.bool_val(true); } void RPFP::EvalNodeAsConstraint(Node *p, Transformer &res) diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 2548d1180..2129a1810 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -187,10 +187,10 @@ namespace datalog { if (m_trail.get_num_scopes() == 0) { throw default_exception("there are no backtracking points to pop to"); } - if(m_engine.get()){ - if(get_engine() != DUALITY_ENGINE) - throw default_exception("operation is not supported by engine"); - } + if(m_engine.get()){ + if(get_engine() != DUALITY_ENGINE) + throw default_exception("operation is not supported by engine"); + } m_trail.pop_scope(1); } @@ -478,7 +478,7 @@ namespace datalog { void context::add_rule(expr* rl, symbol const& name, unsigned bound) { m_rule_fmls.push_back(rl); m_rule_names.push_back(name); - m_rule_bounds.push_back(bound); + m_rule_bounds.push_back(bound); } void context::flush_add_rules() { @@ -706,7 +706,7 @@ namespace datalog { check_existential_tail(r); check_positive_predicates(r); break; - case DUALITY_ENGINE: + case DUALITY_ENGINE: check_existential_tail(r); check_positive_predicates(r); break; diff --git a/src/muz/duality/duality_dl_interface.cpp b/src/muz/duality/duality_dl_interface.cpp index 7666b39cf..0ab9762b0 100755 --- a/src/muz/duality/duality_dl_interface.cpp +++ b/src/muz/duality/duality_dl_interface.cpp @@ -77,12 +77,12 @@ namespace Duality { old_rs = 0; } ~duality_data(){ - if(old_rs) - dealloc(old_rs); - if(rpfp) - dealloc(rpfp); - if(ls) - dealloc(ls); + if(old_rs) + dealloc(old_rs); + if(rpfp) + dealloc(rpfp); + if(ls) + (ls); } }; @@ -171,16 +171,16 @@ lbool dl_interface::query(::expr * query) { query_ref = m_ctx.get_manager().mk_false(); else { func_decl_ref query_pred(m_ctx.get_manager()); - query_pred = m_ctx.get_rules().get_output_predicate(); - ptr_vector sorts; - unsigned nargs = query_pred.get()->get_arity(); - expr_ref_vector vars(m_ctx.get_manager()); - for(unsigned i = 0; i < nargs; i++){ - ::sort *s = query_pred.get()->get_domain(i); - vars.push_back(m_ctx.get_manager().mk_var(nargs-1-i,s)); - } - query_ref = m_ctx.get_manager().mk_app(query_pred.get(),nargs,vars.c_ptr()); - query = query_ref.get(); + query_pred = m_ctx.get_rules().get_output_predicate(); + ptr_vector sorts; + unsigned nargs = query_pred.get()->get_arity(); + expr_ref_vector vars(m_ctx.get_manager()); + for(unsigned i = 0; i < nargs; i++){ + ::sort *s = query_pred.get()->get_domain(i); + vars.push_back(m_ctx.get_manager().mk_var(nargs-1-i,s)); + } + query_ref = m_ctx.get_manager().mk_app(query_pred.get(),nargs,vars.c_ptr()); + query = query_ref.get(); } unsigned nrules = rs.get_num_rules(); for(unsigned i = 0; i < nrules; i++){ @@ -250,16 +250,16 @@ lbool dl_interface::query(::expr * query) { while(true){ if(cl.is_app()){ - decl_kind k = cl.decl().get_decl_kind(); - if(k == Implies) - cl = cl.arg(1); - else { - heads.insert(cl.decl()); - break; - } + decl_kind k = cl.decl().get_decl_kind(); + if(k == Implies) + cl = cl.arg(1); + else { + heads.insert(cl.decl()); + break; + } } else if(cl.is_quantifier()) - cl = cl.body(); + cl = cl.body(); else break; } } @@ -268,18 +268,18 @@ lbool dl_interface::query(::expr * query) { ::ast *fa = pinned[i]; if(is_func_decl(fa)){ ::func_decl *fd = to_func_decl(fa); - if(m_ctx.is_predicate(fd)) { - func_decl f(_d->ctx,fd); - if(!heads.contains(fd)){ - int arity = f.arity(); - std::vector args; - for(int j = 0; j < arity; j++) - args.push_back(_d->ctx.fresh_func_decl("X",f.domain(j))()); - expr c = implies(_d->ctx.bool_val(false),f(args)); - c = _d->ctx.make_quant(Forall,args,c); - clauses.push_back(c); - bounds.push_back(UINT_MAX); - } + if (m_ctx.is_predicate(fd)) { + func_decl f(_d->ctx, fd); + if (!heads.contains(fd)) { + int arity = f.arity(); + std::vector args; + for (int j = 0; j < arity; j++) + args.push_back(_d->ctx.fresh_func_decl("X", f.domain(j))()); + expr c = implies(_d->ctx.bool_val(false), f(args)); + c = _d->ctx.make_quant(Forall, args, c); + clauses.push_back(c); + bounds.push_back(UINT_MAX); + } } } } @@ -483,17 +483,17 @@ void dl_interface::display_certificate_non_const(std::ostream& out) { model orig_model = _d->cex.get_tree()->dualModel; for(unsigned i = 0; i < orig_model.num_consts(); i++){ func_decl cnst = orig_model.get_const_decl(i); - if(locals.find(cnst) == locals.end()){ - expr thing = orig_model.get_const_interp(cnst); - mod.register_decl(to_func_decl(cnst.raw()),to_expr(thing.raw())); + if (locals.find(cnst) == locals.end()) { + expr thing = orig_model.get_const_interp(cnst); + mod.register_decl(to_func_decl(cnst.raw()), to_expr(thing.raw())); } } for(unsigned i = 0; i < orig_model.num_funcs(); i++){ func_decl cnst = orig_model.get_func_decl(i); - if(locals.find(cnst) == locals.end()){ - func_interp thing = orig_model.get_func_interp(cnst); - ::func_interp *thing_raw = thing; - mod.register_decl(to_func_decl(cnst.raw()),thing_raw->copy()); + if (locals.find(cnst) == locals.end()) { + func_interp thing = orig_model.get_func_interp(cnst); + ::func_interp *thing_raw = thing; + mod.register_decl(to_func_decl(cnst.raw()), thing_raw->copy()); } } model_v2_pp(out,mod); diff --git a/src/muz/transforms/dl_transforms.cpp b/src/muz/transforms/dl_transforms.cpp index 9a4667f2c..08404b6e5 100644 --- a/src/muz/transforms/dl_transforms.cpp +++ b/src/muz/transforms/dl_transforms.cpp @@ -72,7 +72,7 @@ namespace datalog { transf.register_plugin(alloc(datalog::mk_bit_blast, ctx, 35000)); if (!ctx.get_params().quantify_arrays()) - transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 36000)); + transf.register_plugin(alloc(datalog::mk_array_blast, ctx, 36000)); transf.register_plugin(alloc(datalog::mk_karr_invariants, ctx, 36010)); if (ctx.get_params().magic()) { transf.register_plugin(alloc(datalog::mk_magic_symbolic, ctx, 36020)); diff --git a/src/tactic/aig/aig.cpp b/src/tactic/aig/aig.cpp index 9fdce96e9..991c4714b 100644 --- a/src/tactic/aig/aig.cpp +++ b/src/tactic/aig/aig.cpp @@ -27,7 +27,7 @@ Notes: struct aig; class aig_lit { - friend class aig_ref; + friend class aig_ref; aig * m_ref; public: aig_lit(aig * n = 0):m_ref(n) {} @@ -1508,10 +1508,10 @@ public: template aig_lit mk_aig(S const & s) { aig_lit r; - r = m_true; - inc_ref(r); + r = m_true; + inc_ref(r); try { - expr2aig proc(*this); + expr2aig proc(*this); unsigned sz = s.size(); for (unsigned i = 0; i < sz; i++) { SASSERT(ref_count(r) >= 1); @@ -1528,9 +1528,9 @@ public: } SASSERT(ref_count(r) >= 1); } - catch (aig_exception ex) { - dec_ref(r); - throw ex; + catch (aig_exception ex) { + dec_ref(r); + throw ex; } dec_ref_result(r); return r; From 71912830f13f991261220a427fcf06382bb62bfd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 8 Jan 2015 17:54:44 +0000 Subject: [PATCH 138/507] Formatting, mostly tabs Signed-off-by: Christoph M. Wintersteiger --- src/ast/ast.cpp | 2 +- src/ast/ast_smt_pp.cpp | 2 +- src/ast/bv_decl_plugin.cpp | 14 ++++++------- src/ast/datatype_decl_plugin.cpp | 8 ++++---- src/ast/simplifier/distribute_forall.cpp | 2 +- src/cmd_context/basic_cmds.cpp | 2 +- src/muz/base/dl_boogie_proof.cpp | 2 +- src/muz/base/dl_context.cpp | 26 ++++++++++++------------ src/muz/fp/dl_cmds.cpp | 12 +++++------ src/muz/transforms/dl_mk_bit_blast.cpp | 2 +- src/tactic/aig/aig.cpp | 2 +- 11 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 5679c951b..b134d38cb 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -2848,7 +2848,7 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro SASSERT(is_or(f1)); app * cls = to_app(f1); unsigned cls_sz = cls->get_num_args(); - CTRACE("cunit_bug", !(num_proofs == cls_sz || (num_proofs == cls_sz + 1 && is_false(new_fact))), + CTRACE("cunit_bug", !(num_proofs == cls_sz || (num_proofs == cls_sz + 1 && is_false(new_fact))), for (unsigned i = 0; i < num_proofs; i++) tout << mk_pp(get_fact(proofs[i]), *this) << "\n"; tout << "===>\n"; tout << mk_pp(new_fact, *this) << "\n";); diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 59e5c04b9..b28b640bb 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -1003,7 +1003,7 @@ public: visit_sort(d->get_domain(i), true); } m_out << ")"; - } + } }; diff --git a/src/ast/bv_decl_plugin.cpp b/src/ast/bv_decl_plugin.cpp index f1c61619a..b056ded36 100644 --- a/src/ast/bv_decl_plugin.cpp +++ b/src/ast/bv_decl_plugin.cpp @@ -136,7 +136,7 @@ void bv_decl_plugin::finalize() { for (; it != end; ++it) { ptr_vector & ds = *it; DEC_REF(ds); - } + } DEC_REF(m_mkbv); } @@ -157,13 +157,13 @@ void bv_decl_plugin::mk_bv_sort(unsigned bv_size) { } inline sort * bv_decl_plugin::get_bv_sort(unsigned bv_size) { - if (bv_size < (1 << 12)) { - mk_bv_sort(bv_size); + if (bv_size < (1 << 12)) { + mk_bv_sort(bv_size); return m_bv_sorts[bv_size]; - } - parameter p(bv_size); - sort_size sz(sort_size::mk_very_big()); - return m_manager->mk_sort(symbol("bv"), sort_info(m_family_id, BV_SORT, sz, 1, &p)); + } + parameter p(bv_size); + sort_size sz(sort_size::mk_very_big()); + return m_manager->mk_sort(symbol("bv"), sort_info(m_family_id, BV_SORT, sz, 1, &p)); } sort * bv_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) { diff --git a/src/ast/datatype_decl_plugin.cpp b/src/ast/datatype_decl_plugin.cpp index ee3271b9b..00f026f55 100644 --- a/src/ast/datatype_decl_plugin.cpp +++ b/src/ast/datatype_decl_plugin.cpp @@ -919,9 +919,9 @@ void datatype_util::display_datatype(sort *s0, std::ostream& strm) { todo.push_back(s0); mark.mark(s0, true); while (!todo.empty()) { - sort* s = todo.back(); + sort* s = todo.back(); todo.pop_back(); - strm << s->get_name() << " =\n"; + strm << s->get_name() << " =\n"; ptr_vector const * cnstrs = get_datatype_constructors(s); for (unsigned i = 0; i < cnstrs->size(); ++i) { @@ -931,14 +931,14 @@ void datatype_util::display_datatype(sort *s0, std::ostream& strm) { ptr_vector const * accs = get_constructor_accessors(cns); for (unsigned j = 0; j < accs->size(); ++j) { func_decl* acc = (*accs)[j]; - sort* s1 = acc->get_range(); + sort* s1 = acc->get_range(); strm << "(" << acc->get_name() << ": " << s1->get_name() << ") "; if (is_datatype(s1) && are_siblings(s1, s0) && !mark.is_marked(s1)) { mark.mark(s1, true); todo.push_back(s1); } } - strm << "\n"; + strm << "\n"; } } diff --git a/src/ast/simplifier/distribute_forall.cpp b/src/ast/simplifier/distribute_forall.cpp index 5e2958579..bd2af5675 100644 --- a/src/ast/simplifier/distribute_forall.cpp +++ b/src/ast/simplifier/distribute_forall.cpp @@ -148,7 +148,7 @@ void distribute_forall::operator()(expr * f, expr_ref & result) { while (!m_todo.empty()) { expr * e = m_todo.back(); - if (visit_children(e)) { + if (visit_children(e)) { m_todo.pop_back(); reduce1(e); } diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index a80c5bc6c..94bd4f5e1 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -255,7 +255,7 @@ protected: s == m_print_success || s == m_print_warning || s == m_expand_definitions || s == m_interactive_mode || s == m_produce_proofs || s == m_produce_unsat_cores || s == m_produce_models || s == m_produce_assignments || s == m_produce_interpolants || - s == m_regular_output_channel || s == m_diagnostic_output_channel || + s == m_regular_output_channel || s == m_diagnostic_output_channel || s == m_random_seed || s == m_verbosity || s == m_global_decls; } diff --git a/src/muz/base/dl_boogie_proof.cpp b/src/muz/base/dl_boogie_proof.cpp index d11e4a932..42d21dfb9 100644 --- a/src/muz/base/dl_boogie_proof.cpp +++ b/src/muz/base/dl_boogie_proof.cpp @@ -142,7 +142,7 @@ namespace datalog { steps.push_back(step()); obj_map index; index.insert(m_proof, 0); - + for (unsigned j = 0; j < rules.size(); ++j) { proof* p = rules[j]; proof_ref_vector premises(m); diff --git a/src/muz/base/dl_context.cpp b/src/muz/base/dl_context.cpp index 2129a1810..7c9c5813b 100644 --- a/src/muz/base/dl_context.cpp +++ b/src/muz/base/dl_context.cpp @@ -963,12 +963,12 @@ namespace datalog { // TODO: what? if(get_engine() != DUALITY_ENGINE) { new_query(); - rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end(); - rule_ref r(m_rule_manager); - for (; it != end; ++it) { + rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end(); + rule_ref r(m_rule_manager); + for (; it != end; ++it) { r = *it; check_rule(r); - } + } } #endif m_mc = mk_skip_model_converter(); @@ -985,10 +985,10 @@ namespace datalog { flush_add_rules(); break; case DUALITY_ENGINE: - // this lets us use duality with SAS 2013 abstraction - if(quantify_arrays()) - flush_add_rules(); - break; + // this lets us use duality with SAS 2013 abstraction + if(quantify_arrays()) + flush_add_rules(); + break; default: UNREACHABLE(); } @@ -1109,11 +1109,11 @@ namespace datalog { void context::get_raw_rule_formulas(expr_ref_vector& rules, svector& names, vector &bounds){ for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { - expr_ref r = bind_variables(m_rule_fmls[i].get(), true); - rules.push_back(r.get()); - // rules.push_back(m_rule_fmls[i].get()); - names.push_back(m_rule_names[i]); - bounds.push_back(m_rule_bounds[i]); + expr_ref r = bind_variables(m_rule_fmls[i].get(), true); + rules.push_back(r.get()); + // rules.push_back(m_rule_fmls[i].get()); + names.push_back(m_rule_names[i]); + bounds.push_back(m_rule_bounds[i]); } } diff --git a/src/muz/fp/dl_cmds.cpp b/src/muz/fp/dl_cmds.cpp index e2e3680cc..a0af94953 100644 --- a/src/muz/fp/dl_cmds.cpp +++ b/src/muz/fp/dl_cmds.cpp @@ -110,7 +110,7 @@ struct dl_context { m_trail.push(push_back_vector >(m_collected_cmds->m_names)); } else { - m_context->add_rule(rule, name, bound); + m_context->add_rule(rule, name, bound); } } @@ -260,11 +260,11 @@ public: print_certificate(ctx); break; case l_undef: - if(dlctx.get_status() == datalog::BOUNDED){ - ctx.regular_stream() << "bounded\n"; - print_certificate(ctx); - break; - } + if(dlctx.get_status() == datalog::BOUNDED){ + ctx.regular_stream() << "bounded\n"; + print_certificate(ctx); + break; + } ctx.regular_stream() << "unknown\n"; switch(dlctx.get_status()) { case datalog::INPUT_ERROR: diff --git a/src/muz/transforms/dl_mk_bit_blast.cpp b/src/muz/transforms/dl_mk_bit_blast.cpp index fd1dbb205..9b451811c 100644 --- a/src/muz/transforms/dl_mk_bit_blast.cpp +++ b/src/muz/transforms/dl_mk_bit_blast.cpp @@ -219,7 +219,7 @@ namespace datalog { class mk_bit_blast::impl { - context & m_context; + context & m_context; ast_manager & m; params_ref m_params; mk_interp_tail_simplifier m_simplifier; diff --git a/src/tactic/aig/aig.cpp b/src/tactic/aig/aig.cpp index 991c4714b..e3101ad67 100644 --- a/src/tactic/aig/aig.cpp +++ b/src/tactic/aig/aig.cpp @@ -1531,7 +1531,7 @@ public: catch (aig_exception ex) { dec_ref(r); throw ex; - } + } dec_ref_result(r); return r; } From 46e236487be2fa172a021afce577f133e09acd06 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 9 Jan 2015 11:53:18 +0000 Subject: [PATCH 139/507] Eliminated FPRMNum classes Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 86 +++++++++++++++++----------------- src/api/dotnet/Expr.cs | 24 +++++----- src/api/dotnet/FPRMExpr.cs | 50 ++++++++++++++++++++ src/api/dotnet/FPRMNum.cs | 96 -------------------------------------- src/api/java/Context.java | 40 ++++++++-------- src/api/java/Expr.java | 2 - 6 files changed, 125 insertions(+), 173 deletions(-) delete mode 100644 src/api/dotnet/FPRMNum.cs diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 9eb544f8a..89a89b959 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3456,91 +3456,91 @@ namespace Microsoft.Z3 /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. /// - public FPRMNum MkFPRoundNearestTiesToEven() + public FPRMExpr MkFPRoundNearestTiesToEven() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_even(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_round_nearest_ties_to_even(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. /// - public FPRMNum MkFPRNE() + public FPRMExpr MkFPRNE() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_rne(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_rne(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. /// - public FPRMNum MkFPRoundNearestTiesToAway() + public FPRMExpr MkFPRoundNearestTiesToAway() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. /// - public FPRMNum MkFPRNA() + public FPRMExpr MkFPRNA() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_rna(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_rna(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. /// - public FPRMNum MkFPRoundTowardPositive() + public FPRMExpr MkFPRoundTowardPositive() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_positive(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_round_toward_positive(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. /// - public FPRMNum MkFPRTP() + public FPRMExpr MkFPRTP() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_rtp(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_rtp(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. /// - public FPRMNum MkFPRoundTowardNegative() + public FPRMExpr MkFPRoundTowardNegative() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_negative(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_round_toward_negative(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. /// - public FPRMNum MkFPRTN() + public FPRMExpr MkFPRTN() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_rtn(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_rtn(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. /// - public FPRMNum MkFPRoundTowardZero() + public FPRMExpr MkFPRoundTowardZero() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_zero(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_round_toward_zero(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. /// - public FPRMNum MkFPRTZ() + public FPRMExpr MkFPRTZ() { - Contract.Ensures(Contract.Result() != null); - return new FPRMNum(this, Native.Z3_mk_fpa_rtz(nCtx)); + Contract.Ensures(Contract.Result() != null); + return new FPRMExpr(this, Native.Z3_mk_fpa_rtz(nCtx)); } #endregion #endregion @@ -3637,7 +3637,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFPNaN(FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_nan(nCtx, s.NativeObject)); } @@ -3648,7 +3648,7 @@ namespace Microsoft.Z3 /// indicates whether the result should be negative. public FPNum MkFPInf(FPSort s, bool negative) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_inf(nCtx, s.NativeObject, negative ? 1 : 0)); } @@ -3659,7 +3659,7 @@ namespace Microsoft.Z3 /// indicates whether the result should be negative. public FPNum MkFPZero(FPSort s, bool negative) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_zero(nCtx, s.NativeObject, negative ? 1 : 0)); } @@ -3670,7 +3670,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFPNumeral(float v, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_numeral_float(nCtx, v, s.NativeObject)); } @@ -3681,7 +3681,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFPNumeral(double v, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_numeral_double(nCtx, v, s.NativeObject)); } @@ -3692,7 +3692,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFPNumeral(int v, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_numeral_int(nCtx, v, s.NativeObject)); } @@ -3705,7 +3705,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFPNumeral(bool sgn, uint sig, int exp, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_numeral_uint_int(nCtx, sgn ? 1 : 0, sig, exp, s.NativeObject)); } @@ -3718,7 +3718,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFPNumeral(bool sgn, UInt64 sig, Int64 exp, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return new FPNum(this, Native.Z3_mk_fpa_numeral_uint64_int64(nCtx, sgn ? 1 : 0, sig, exp, s.NativeObject)); } @@ -3729,7 +3729,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFP(float v, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return MkFPNumeral(v, s); } @@ -3740,7 +3740,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFP(double v, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return MkFPNumeral(v, s); } @@ -3751,7 +3751,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFP(int v, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return MkFPNumeral(v, s); } @@ -3764,7 +3764,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFP(bool sgn, uint sig, int exp, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return MkFPNumeral(sgn, sig, exp, s); } @@ -3777,7 +3777,7 @@ namespace Microsoft.Z3 /// FloatingPoint sort. public FPNum MkFP(bool sgn, UInt64 sig, Int64 exp, FPSort s) { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result() != null); return MkFPNumeral(sgn, sig, exp, s); } diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index 97e57b920..eb1d1c02d 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1475,57 +1475,57 @@ namespace Microsoft.Z3 /// /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven /// - public bool IsFPRMNumRoundNearestTiesToEven{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + public bool IsFPRMRoundNearestTiesToEven{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } /// /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway /// - public bool IsFPRMNumRoundNearestTiesToAway{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + public bool IsFPRMRoundNearestTiesToAway{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } /// /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative /// - public bool IsFPRMNumRoundTowardNegative{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + public bool IsFPRMRoundTowardNegative{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } /// /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive /// - public bool IsFPRMNumRoundTowardPositive{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + public bool IsFPRMRoundTowardPositive{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } /// /// Indicates whether the term is the floating-point rounding numeral roundTowardZero /// - public bool IsFPRMNumRoundTowardZero{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + public bool IsFPRMRoundTowardZero{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } /// /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven /// - public bool IsFPRMNumRNE{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + public bool IsFPRMExprRNE{ get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } /// /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway /// - public bool IsFPRMNumRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + public bool IsFPRMExprRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } /// /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative /// - public bool IsFPRMNumRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + public bool IsFPRMExprRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } /// /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive /// - public bool IsFPRMNumRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + public bool IsFPRMExprRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } /// /// Indicates whether the term is the floating-point rounding numeral roundTowardZero /// - public bool IsFPRMNumRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + public bool IsFPRMExprRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } /// /// Indicates whether the term is a floating-point rounding mode numeral /// - public bool IsFPRMNum { + public bool IsFPRMExpr { get { return IsApp && (FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY|| @@ -1809,7 +1809,7 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); - case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMNum(ctx, obj); + case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj); } } diff --git a/src/api/dotnet/FPRMExpr.cs b/src/api/dotnet/FPRMExpr.cs index 896c3e6b9..47ea3e670 100644 --- a/src/api/dotnet/FPRMExpr.cs +++ b/src/api/dotnet/FPRMExpr.cs @@ -30,6 +30,56 @@ namespace Microsoft.Z3 /// public class FPRMExpr : Expr { + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool isRoundNearestTiesToEven { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool isRNE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool isRoundNearestTiesToAway { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool isRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool isRoundTowardPositive { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool isRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool isRoundTowardNegative { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool isRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool isRoundTowardZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool isRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + #region Internal /// Constructor for FPRMExpr internal FPRMExpr(Context ctx, IntPtr obj) diff --git a/src/api/dotnet/FPRMNum.cs b/src/api/dotnet/FPRMNum.cs deleted file mode 100644 index 628480d96..000000000 --- a/src/api/dotnet/FPRMNum.cs +++ /dev/null @@ -1,96 +0,0 @@ -/*++ -Copyright (c) 2013 Microsoft Corporation - -Module Name: - - FPRMNum.cs - -Abstract: - - Z3 Managed API: Floating Point Rounding Mode Numerals - -Author: - - Christoph Wintersteiger (cwinter) 2013-06-10 - -Notes: - ---*/ -using System; -using System.Diagnostics.Contracts; - -namespace Microsoft.Z3 -{ - /// - /// FloatingPoint RoundingMode Numerals - /// - [ContractVerification(true)] - public class FPRMNum : FPRMExpr - { - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven - /// - public bool isRoundNearestTiesToEven { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven - /// - public bool isRNE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway - /// - public bool isRoundNearestTiesToAway { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway - /// - public bool isRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive - /// - public bool isRoundTowardPositive { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive - /// - public bool isRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative - /// - public bool isRoundTowardNegative { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative - /// - public bool isRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardZero - /// - public bool isRoundTowardZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardZero - /// - public bool isRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } - - #region Internal - internal FPRMNum(Context ctx, IntPtr obj) - : base(ctx, obj) - { - Contract.Requires(ctx != null); - } - #endregion - - /// - /// Returns a string representation of the numeral. - /// - public override string ToString() - { - return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); - } - } -} diff --git a/src/api/java/Context.java b/src/api/java/Context.java index cfbd7c2c8..29be4aae8 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -2865,90 +2865,90 @@ public class Context extends IDisposable * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. * @throws Z3Exception on error **/ - public FPRMNum mkFPRoundNearestTiesToEven() throws Z3Exception + public FPRMExpr mkFPRoundNearestTiesToEven() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRoundNearestTiesToEven(nCtx())); + return new FPRMExpr(this, Native.mkFpaRoundNearestTiesToEven(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRNE() throws Z3Exception + public FPRMExpr mkFPRNE() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRne(nCtx())); + return new FPRMExpr(this, Native.mkFpaRne(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRoundNearestTiesToAway() throws Z3Exception + public FPRMExpr mkFPRoundNearestTiesToAway() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRoundNearestTiesToAway(nCtx())); + return new FPRMExpr(this, Native.mkFpaRoundNearestTiesToAway(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRNA() throws Z3Exception + public FPRMExpr mkFPRNA() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRna(nCtx())); + return new FPRMExpr(this, Native.mkFpaRna(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRoundTowardPositive() throws Z3Exception + public FPRMExpr mkFPRoundTowardPositive() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRoundTowardPositive(nCtx())); + return new FPRMExpr(this, Native.mkFpaRoundTowardPositive(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRTP() throws Z3Exception + public FPRMExpr mkFPRTP() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRtp(nCtx())); + return new FPRMExpr(this, Native.mkFpaRtp(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRoundTowardNegative() throws Z3Exception + public FPRMExpr mkFPRoundTowardNegative() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRoundTowardNegative(nCtx())); + return new FPRMExpr(this, Native.mkFpaRoundTowardNegative(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRTN() throws Z3Exception + public FPRMExpr mkFPRTN() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRtn(nCtx())); + return new FPRMExpr(this, Native.mkFpaRtn(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRoundTowardZero() throws Z3Exception + public FPRMExpr mkFPRoundTowardZero() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRoundTowardZero(nCtx())); + return new FPRMExpr(this, Native.mkFpaRoundTowardZero(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. * @throws Z3Exception **/ - public FPRMNum mkFPRTZ() throws Z3Exception + public FPRMExpr mkFPRTZ() throws Z3Exception { - return new FPRMNum(this, Native.mkFpaRtz(nCtx())); + return new FPRMExpr(this, Native.mkFpaRtz(nCtx())); } /** FloatingPoint Sorts **/ diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 886c69f08..49f49a295 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -2140,8 +2140,6 @@ public class Expr extends AST return new BitVecNum(ctx, obj); case Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); - case Z3_ROUNDING_MODE_SORT: - return new FPRMNum(ctx, obj); default: ; } } From 3391c9c44c40057eba47d92cc7deceb782de35d8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 9 Jan 2015 11:53:24 +0000 Subject: [PATCH 140/507] typo fix Signed-off-by: Christoph M. Wintersteiger --- src/duality/duality_rpfp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/duality/duality_rpfp.cpp b/src/duality/duality_rpfp.cpp index 6ef6d623a..764fc72ad 100755 --- a/src/duality/duality_rpfp.cpp +++ b/src/duality/duality_rpfp.cpp @@ -2478,7 +2478,7 @@ done: expr junct = negate ? Negate(f) : f; lits.push_back(junct); } - }| + } struct TermLt { bool operator()(const expr &x, const expr &y){ From ee0ec7fe3a05e569bcc3906d7721af08d621db46 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 10 Jan 2015 17:28:07 +0000 Subject: [PATCH 141/507] FPA API: numerals, .NET and Java Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 89 +++++++++++++++++++++++++++++- src/api/api_numeral.cpp | 83 +++++++++++++++++----------- src/api/dotnet/Context.cs | 36 ++++++------ src/api/dotnet/Expr.cs | 9 ++- src/api/dotnet/FPNum.cs | 57 +++++++++++++++++++ src/api/dotnet/FPRMExpr.cs | 50 ----------------- src/api/dotnet/FPRMNum.cs | 100 +++++++++++++++++++++++++++++++++ src/api/java/Context.java | 40 +++++++------- src/api/java/Expr.java | 110 ++++++++++++++++++++----------------- src/api/java/FPExpr.java | 41 ++++++++++++++ src/api/java/FPNum.java | 86 +++++++++++++++++++++++++++++ src/api/java/FPRMExpr.java | 29 ++++++++++ src/api/java/FPRMNum.java | 90 ++++++++++++++++++++++++++++++ src/api/java/FPRMSort.java | 35 ++++++++++++ src/api/java/FPSort.java | 49 +++++++++++++++++ src/api/z3_fpa.h | 41 ++++++++++++++ 16 files changed, 770 insertions(+), 175 deletions(-) create mode 100644 src/api/dotnet/FPRMNum.cs create mode 100644 src/api/java/FPExpr.java create mode 100644 src/api/java/FPNum.java create mode 100644 src/api/java/FPRMExpr.java create mode 100644 src/api/java/FPRMNum.java create mode 100644 src/api/java/FPRMSort.java create mode 100644 src/api/java/FPSort.java diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 94dfaaa68..219f9b166 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -200,7 +200,8 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_ninf(to_sort(s)) : ctx->fpa_util().mk_pinf(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_ninf(to_sort(s)) : + ctx->fpa_util().mk_pinf(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -210,7 +211,8 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_nzero(to_sort(s)) : ctx->fpa_util().mk_pzero(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_nzero(to_sort(s)) : + ctx->fpa_util().mk_pzero(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -231,7 +233,10 @@ extern "C" { RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpa_util().fm()); - ctx->fpa_util().fm().set(tmp, ctx->fpa_util().get_ebits(to_sort(ty)), ctx->fpa_util().get_sbits(to_sort(ty)), v); + ctx->fpa_util().fm().set(tmp, + ctx->fpa_util().get_ebits(to_sort(ty)), + ctx->fpa_util().get_sbits(to_sort(ty)), + v); Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); @@ -667,6 +672,84 @@ extern "C" { Z3_CATCH_RETURN(0); } + Z3_bool Z3_API Z3_fpa_get_numeral_sign(Z3_context c, Z3_ast t, int * sgn) { + Z3_TRY; + LOG_Z3_fpa_get_numeral_sign(c, t, sgn); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); + scoped_mpf val(mpfm); + bool r = plugin->is_numeral(to_expr(t), val); + *sgn = (mpfm.is_nan(val)) ? 0 : mpfm.sgn(val); + return r; + Z3_CATCH_RETURN(0); + } + + Z3_string Z3_API Z3_fpa_get_numeral_significand_string(__in Z3_context c, __in Z3_ast t) { + Z3_TRY; + LOG_Z3_fpa_get_numeral_significand_string(c, t); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); + scoped_mpf val(mpfm); + if (!plugin->is_numeral(to_expr(t), val)) { + SET_ERROR_CODE(Z3_INVALID_ARG); + return ""; + } + unsigned sbits = val.get().get_sbits(); + scoped_mpq q(mpqm); + mpqm.set(q, mpfm.sig(val)); + mpqm.div(q, mpfm.m_powers2(sbits - 1), q); + std::stringstream ss; + mpqm.display_decimal(ss, q, sbits); + return mk_c(c)->mk_external_string(ss.str()); + Z3_CATCH_RETURN(""); + + } + + Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(__in Z3_context c, __in Z3_ast t) { + Z3_TRY; + LOG_Z3_fpa_get_numeral_exponent_string(c, t); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); + scoped_mpf val(mpfm); + bool r = plugin->is_numeral(to_expr(t), val); + if (!r) { + SET_ERROR_CODE(Z3_INVALID_ARG); + return ""; + } + const mpf_exp_t exp = mpfm.exp(val); + std::stringstream ss; + ss << exp; + return mk_c(c)->mk_external_string(ss.str()); + Z3_CATCH_RETURN(""); + } + + Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(__in Z3_context c, __in Z3_ast t, __out __int64 * n) { + Z3_TRY; + LOG_Z3_fpa_get_numeral_exponent_string(c, t); + RESET_ERROR_CODE(); + ast_manager & m = mk_c(c)->m(); + mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); + scoped_mpf val(mpfm); + bool r = plugin->is_numeral(to_expr(t), val); + if (!r) { + SET_ERROR_CODE(Z3_INVALID_ARG); + return 0; + } + *n = mpfm.exp(val); + return 1; + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_fpa_to_ieee_bv(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_to_ieee_bv(c, t); diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 0745a8709..d5a25dfc2 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -50,7 +50,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_numeral(Z3_context c, const char* n, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_numeral(c, n, ty); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); if (!check_numeral_sort(c, ty)) { RETURN_Z3(0); } @@ -64,20 +64,19 @@ extern "C" { char const* m = n; while (*m) { if (!(('0' <= *m && *m <= '9') || - ('/' == *m) || ('-' == *m) || - (' ' == *m) || ('\n' == *m) || - ('.' == *m) || ('e' == *m) || - ('E' == *m) || - (('p' == *m) && is_float) || - (('P' == *m)) && is_float)) { + ('/' == *m) || ('-' == *m) || + (' ' == *m) || ('\n' == *m) || + ('.' == *m) || ('e' == *m) || + ('E' == *m) || + (('p' == *m) && is_float) || + (('P' == *m)) && is_float)) { SET_ERROR_CODE(Z3_PARSER_ERROR); return 0; } ++m; } - ast * a = 0; - if (_ty->get_family_id() == mk_c(c)->get_fpa_fid()) - { + ast * a = 0; + if (_ty->get_family_id() == mk_c(c)->get_fpa_fid()) { // avoid expanding floats into huge rationals. fpa_util & fu = mk_c(c)->fpa_util(); scoped_mpf t(fu.fm()); @@ -90,23 +89,11 @@ extern "C" { RETURN_Z3(of_ast(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_int(Z3_context c, int value, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_int(c, value, ty); - RESET_ERROR_CODE(); - if (!check_numeral_sort(c, ty)) { - RETURN_Z3(0); - } - ast * a = mk_c(c)->mk_numeral_core(rational(value), to_sort(ty)); - RETURN_Z3(of_ast(a)); - Z3_CATCH_RETURN(0); - } - - Z3_ast Z3_API Z3_mk_unsigned_int(Z3_context c, unsigned value, Z3_sort ty) { - Z3_TRY; - LOG_Z3_mk_unsigned_int(c, value, ty); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); if (!check_numeral_sort(c, ty)) { RETURN_Z3(0); } @@ -114,11 +101,23 @@ extern "C" { RETURN_Z3(of_ast(a)); Z3_CATCH_RETURN(0); } - + + Z3_ast Z3_API Z3_mk_unsigned_int(Z3_context c, unsigned value, Z3_sort ty) { + Z3_TRY; + LOG_Z3_mk_unsigned_int(c, value, ty); + RESET_ERROR_CODE(); + if (!check_numeral_sort(c, ty)) { + RETURN_Z3(0); + } + ast * a = mk_c(c)->mk_numeral_core(rational(value), to_sort(ty)); + RETURN_Z3(of_ast(a)); + Z3_CATCH_RETURN(0); + } + Z3_ast Z3_API Z3_mk_int64(Z3_context c, long long value, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_int64(c, value, ty); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); if (!check_numeral_sort(c, ty)) { RETURN_Z3(0); } @@ -127,11 +126,11 @@ extern "C" { RETURN_Z3(of_ast(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_unsigned_int64(Z3_context c, unsigned long long value, Z3_sort ty) { Z3_TRY; LOG_Z3_mk_unsigned_int64(c, value, ty); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); if (!check_numeral_sort(c, ty)) { RETURN_Z3(0); } @@ -146,10 +145,11 @@ extern "C" { LOG_Z3_is_numeral_ast(c, a); RESET_ERROR_CODE(); expr* e = to_expr(a); - return + return mk_c(c)->autil().is_numeral(e) || mk_c(c)->bvutil().is_numeral(e) || - mk_c(c)->fpa_util().is_numeral(e); + mk_c(c)->fpa_util().is_numeral(e) || + mk_c(c)->fpa_util().is_rm_numeral(e); Z3_CATCH_RETURN(Z3_FALSE); } @@ -193,7 +193,28 @@ extern "C" { // floats are separated from all others to avoid huge rationals. fpa_util & fu = mk_c(c)->fpa_util(); scoped_mpf tmp(fu.fm()); - if (mk_c(c)->fpa_util().is_numeral(to_expr(a), tmp)) { + mpf_rounding_mode rm; + if (mk_c(c)->fpa_util().is_rm_numeral(to_expr(a), rm)) { + switch (rm) { + case OP_FPA_RM_NEAREST_TIES_TO_EVEN: + return mk_c(c)->mk_external_string("roundNearestTiesToEven"); + break; + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: + return mk_c(c)->mk_external_string("roundNearestTiesToAway"); + break; + case OP_FPA_RM_TOWARD_POSITIVE: + return mk_c(c)->mk_external_string("roundTowardPositive"); + break; + case OP_FPA_RM_TOWARD_NEGATIVE: + return mk_c(c)->mk_external_string("roundTowardNegative"); + break; + case OP_FPA_RM_TOWARD_ZERO: + default: + return mk_c(c)->mk_external_string("roundTowardZero"); + break; + } + } + else if (mk_c(c)->fpa_util().is_numeral(to_expr(a), tmp)) { return mk_c(c)->mk_external_string(fu.fm().to_string(tmp)); } else { diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 89a89b959..70777a6e8 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3465,82 +3465,82 @@ namespace Microsoft.Z3 /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. /// - public FPRMExpr MkFPRNE() + public FPRMNum MkFPRNE() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_rne(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_rne(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. /// - public FPRMExpr MkFPRoundNearestTiesToAway() + public FPRMNum MkFPRoundNearestTiesToAway() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_round_nearest_ties_to_away(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. /// - public FPRMExpr MkFPRNA() + public FPRMNum MkFPRNA() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_rna(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_rna(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. /// - public FPRMExpr MkFPRoundTowardPositive() + public FPRMNum MkFPRoundTowardPositive() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_round_toward_positive(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_positive(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. /// - public FPRMExpr MkFPRTP() + public FPRMNum MkFPRTP() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_rtp(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_rtp(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. /// - public FPRMExpr MkFPRoundTowardNegative() + public FPRMNum MkFPRoundTowardNegative() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_round_toward_negative(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_negative(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. /// - public FPRMExpr MkFPRTN() + public FPRMNum MkFPRTN() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_rtn(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_rtn(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. /// - public FPRMExpr MkFPRoundTowardZero() + public FPRMNum MkFPRoundTowardZero() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_round_toward_zero(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_round_toward_zero(nCtx)); } /// /// Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. /// - public FPRMExpr MkFPRTZ() + public FPRMNum MkFPRTZ() { Contract.Ensures(Contract.Result() != null); - return new FPRMExpr(this, Native.Z3_mk_fpa_rtz(nCtx)); + return new FPRMNum(this, Native.Z3_mk_fpa_rtz(nCtx)); } #endregion #endregion diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index eb1d1c02d..e3ff27da1 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1470,7 +1470,12 @@ namespace Microsoft.Z3 /// /// Indicates whether the term is a floating-point numeral /// - public bool IsFPNumeral { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_NUM; } } + public bool IsFPNumeral { get { return IsFP && IsNumeral; } } + + /// + /// Indicates whether the term is a floating-point rounding mode numeral + /// + public bool IsFPRMNumeral { get { return IsFPRM && IsNumeral; } } /// /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven @@ -1809,7 +1814,7 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); case Z3_sort_kind.Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); - case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMExpr(ctx, obj); + case Z3_sort_kind.Z3_ROUNDING_MODE_SORT: return new FPRMNum(ctx, obj); } } diff --git a/src/api/dotnet/FPNum.cs b/src/api/dotnet/FPNum.cs index 14c089198..e85687ccf 100644 --- a/src/api/dotnet/FPNum.cs +++ b/src/api/dotnet/FPNum.cs @@ -27,6 +27,63 @@ namespace Microsoft.Z3 [ContractVerification(true)] public class FPNum : FPExpr { + /// + /// Retrieves the sign of a floating-point literal + /// + /// + /// Remarks: returns true if the numeral is negative + /// + public bool Sign + { + get + { + int res = 0; + if (Native.Z3_fpa_get_numeral_sign(Context.nCtx, NativeObject, ref res) == 0) + throw new Z3Exception("Sign is not a Boolean value"); + return res != 0; + } + } + + /// + /// The significand value of a floating-point numeral as a string + /// + /// + /// The significand s is always 0 < s < 2.0; the resulting string is long + /// enough to represent the real significand precisely. + /// + public string Significand + { + get + { + return Native.Z3_fpa_get_numeral_significand_string(Context.nCtx, NativeObject); + } + } + + /// + /// Return the exponent value of a floating-point numeral as a string + /// + public string Exponent + { + get + { + return Native.Z3_fpa_get_numeral_exponent_string(Context.nCtx, NativeObject); + } + } + + /// + /// Return the exponent value of a floating-point numeral as a signed 64-bit integer + /// + public Int64 ExponentInt64 + { + get + { + Int64 result = 0; + if (Native.Z3_fpa_get_numeral_exponent_int64(Context.nCtx, NativeObject, ref result) == 0) + throw new Z3Exception("Exponent is not a 64 bit integer"); + return result; + } + } + #region Internal internal FPNum(Context ctx, IntPtr obj) : base(ctx, obj) diff --git a/src/api/dotnet/FPRMExpr.cs b/src/api/dotnet/FPRMExpr.cs index 47ea3e670..896c3e6b9 100644 --- a/src/api/dotnet/FPRMExpr.cs +++ b/src/api/dotnet/FPRMExpr.cs @@ -30,56 +30,6 @@ namespace Microsoft.Z3 /// public class FPRMExpr : Expr { - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven - /// - public bool isRoundNearestTiesToEven { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven - /// - public bool isRNE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway - /// - public bool isRoundNearestTiesToAway { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway - /// - public bool isRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive - /// - public bool isRoundTowardPositive { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive - /// - public bool isRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative - /// - public bool isRoundTowardNegative { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative - /// - public bool isRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardZero - /// - public bool isRoundTowardZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } - - /// - /// Indicates whether the term is the floating-point rounding numeral roundTowardZero - /// - public bool isRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } - #region Internal /// Constructor for FPRMExpr internal FPRMExpr(Context ctx, IntPtr obj) diff --git a/src/api/dotnet/FPRMNum.cs b/src/api/dotnet/FPRMNum.cs new file mode 100644 index 000000000..81cff167e --- /dev/null +++ b/src/api/dotnet/FPRMNum.cs @@ -0,0 +1,100 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMExpr.cs + +Abstract: + + Z3 Managed API: Floating Point Rounding Mode Numerals + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Diagnostics.Contracts; + +namespace Microsoft.Z3 +{ + /// + /// Floating-point rounding mode numerals + /// + public class FPRMNum : FPRMExpr + { + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool isRoundNearestTiesToEven { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + /// + public bool isRNE { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool isRoundNearestTiesToAway { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + /// + public bool isRNA { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool isRoundTowardPositive { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardPositive + /// + public bool isRTP { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool isRoundTowardNegative { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardNegative + /// + public bool isRTN { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool isRoundTowardZero { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + + /// + /// Indicates whether the term is the floating-point rounding numeral roundTowardZero + /// + public bool isRTZ { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } } + + /// + /// Returns a string representation of the numeral. + /// + public override string ToString() + { + return Native.Z3_get_numeral_string(Context.nCtx, NativeObject); + } + + #region Internal + /// Constructor for FPRMNum + internal FPRMNum(Context ctx, IntPtr obj) + : base(ctx, obj) + { + Contract.Requires(ctx != null); + } + #endregion + } +} diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 29be4aae8..cfbd7c2c8 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -2865,90 +2865,90 @@ public class Context extends IDisposable * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. * @throws Z3Exception on error **/ - public FPRMExpr mkFPRoundNearestTiesToEven() throws Z3Exception + public FPRMNum mkFPRoundNearestTiesToEven() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRoundNearestTiesToEven(nCtx())); + return new FPRMNum(this, Native.mkFpaRoundNearestTiesToEven(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRNE() throws Z3Exception + public FPRMNum mkFPRNE() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRne(nCtx())); + return new FPRMNum(this, Native.mkFpaRne(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRoundNearestTiesToAway() throws Z3Exception + public FPRMNum mkFPRoundNearestTiesToAway() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRoundNearestTiesToAway(nCtx())); + return new FPRMNum(this, Native.mkFpaRoundNearestTiesToAway(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRNA() throws Z3Exception + public FPRMNum mkFPRNA() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRna(nCtx())); + return new FPRMNum(this, Native.mkFpaRna(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRoundTowardPositive() throws Z3Exception + public FPRMNum mkFPRoundTowardPositive() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRoundTowardPositive(nCtx())); + return new FPRMNum(this, Native.mkFpaRoundTowardPositive(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRTP() throws Z3Exception + public FPRMNum mkFPRTP() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRtp(nCtx())); + return new FPRMNum(this, Native.mkFpaRtp(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRoundTowardNegative() throws Z3Exception + public FPRMNum mkFPRoundTowardNegative() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRoundTowardNegative(nCtx())); + return new FPRMNum(this, Native.mkFpaRoundTowardNegative(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRTN() throws Z3Exception + public FPRMNum mkFPRTN() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRtn(nCtx())); + return new FPRMNum(this, Native.mkFpaRtn(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRoundTowardZero() throws Z3Exception + public FPRMNum mkFPRoundTowardZero() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRoundTowardZero(nCtx())); + return new FPRMNum(this, Native.mkFpaRoundTowardZero(nCtx())); } /** * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. * @throws Z3Exception **/ - public FPRMExpr mkFPRTZ() throws Z3Exception + public FPRMNum mkFPRTZ() throws Z3Exception { - return new FPRMExpr(this, Native.mkFpaRtz(nCtx())); + return new FPRMNum(this, Native.mkFpaRtz(nCtx())); } /** FloatingPoint Sorts **/ diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index 49f49a295..57f53ec6b 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -1714,98 +1714,105 @@ public class Expr extends AST * Indicates whether the terms is of floating-point sort. * @throws Z3Exception */ - public boolean IsFP() throws Z3Exception { return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_FLOATING_POINT_SORT; } + public boolean isFP() throws Z3Exception { return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_FLOATING_POINT_SORT; } /** * Indicates whether the terms is of floating-point rounding mode sort. * @return * @throws Z3Exception */ - public boolean IsFPRM() throws Z3Exception { return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_ROUNDING_MODE_SORT; } + public boolean isFPRM() throws Z3Exception { return Z3_sort_kind.fromInt(Native.getSortKind(getContext().nCtx(), Native.getSort(getContext().nCtx(), getNativeObject()))) == Z3_sort_kind.Z3_ROUNDING_MODE_SORT; } /** * Indicates whether the term is a floating-point numeral * @return * @throws Z3Exception */ - public boolean IsFPNumeral() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NUM; } + public boolean isFPNumeral() throws Z3Exception { return isFP() && isNumeral(); } + + /** + * Indicates whether the term is a floating-point rounding mode numeral + * @return + * @throws Z3Exception + */ + public boolean isFPRMNumeral() throws Z3Exception { return isFPRM() && isNumeral(); } /** * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven * @return * @throws Z3Exception */ - public boolean IsFPRMNumRoundNearestTiesToEven() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } + public boolean isFPRMNumRoundNearestTiesToEven() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } /** * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway * @return * @throws Z3Exception */ - public boolean IsFPRMNumRoundNearestTiesToAway() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } + public boolean isFPRMNumRoundNearestTiesToAway() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } /** * Indicates whether the term is the floating-point rounding numeral roundTowardNegative * @return * @throws Z3Exception */ - public boolean IsFPRMNumRoundTowardNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } + public boolean isFPRMNumRoundTowardNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } /** * Indicates whether the term is the floating-point rounding numeral roundTowardPositive * @return * @throws Z3Exception */ - public boolean IsFPRMNumRoundTowardPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } + public boolean isFPRMNumRoundTowardPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } /** * Indicates whether the term is the floating-point rounding numeral roundTowardZero * @return * @throws Z3Exception */ - public boolean IsFPRMNumRoundTowardZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } + public boolean isFPRMNumRoundTowardZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } /** * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven * @return * @throws Z3Exception */ - public boolean IsFPRMNumRNE() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } + public boolean isFPRMNumRNE() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } /** * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway * @return * @throws Z3Exception */ - public boolean IsFPRMNumRNA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } + public boolean isFPRMNumRNA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } /** * Indicates whether the term is the floating-point rounding numeral roundTowardNegative * @return * @throws Z3Exception */ - public boolean IsFPRMNumRTN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } + public boolean isFPRMNumRTN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } /** * Indicates whether the term is the floating-point rounding numeral roundTowardPositive * @return * @throws Z3Exception */ - public boolean IsFPRMNumRTP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } + public boolean isFPRMNumRTP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } /** * Indicates whether the term is the floating-point rounding numeral roundTowardZero * @return * @throws Z3Exception */ - public boolean IsFPRMNumRTZ() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } + public boolean isFPRMNumRTZ() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } /** * Indicates whether the term is a floating-point rounding mode numeral * @return * @throws Z3Exception */ - public boolean IsFPRMNum() throws Z3Exception { + public boolean isFPRMNum() throws Z3Exception { return isApp() && (getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY || getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN || @@ -1819,42 +1826,42 @@ public class Expr extends AST * @return * @throws Z3Exception */ - public boolean IsFPPlusInfinity() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_PLUS_INF; } + public boolean isFPPlusInfinity() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_PLUS_INF; } /** * Indicates whether the term is a floating-point -oo * @return * @throws Z3Exception */ - public boolean IsFPMinusInfinity() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MINUS_INF; } + public boolean isFPMinusInfinity() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MINUS_INF; } /** * Indicates whether the term is a floating-point NaN * @return * @throws Z3Exception */ - public boolean IsFPNaN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NAN; } + public boolean isFPNaN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NAN; } /** * Indicates whether the term is a floating-point +zero * @return * @throws Z3Exception */ - public boolean IsFPPlusZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_PLUS_ZERO; } + public boolean isFPPlusZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_PLUS_ZERO; } /** * Indicates whether the term is a floating-point -zero * @return * @throws Z3Exception */ - public boolean IsFPMinusZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MINUS_ZERO; } + public boolean isFPMinusZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MINUS_ZERO; } /** * Indicates whether the term is a floating-point addition term * @return * @throws Z3Exception */ - public boolean IsFPAdd() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ADD; } + public boolean isFPAdd() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ADD; } /** @@ -1862,211 +1869,210 @@ public class Expr extends AST * @return * @throws Z3Exception */ - public boolean IsFPSub() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_SUB; } + public boolean isFPSub() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_SUB; } /** * Indicates whether the term is a floating-point negation term * @return * @throws Z3Exception */ - public boolean IsFPNeg() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NEG; } + public boolean isFPNeg() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_NEG; } /** * Indicates whether the term is a floating-point multiplication term * @return * @throws Z3Exception */ - public boolean IsFPMul() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MUL; } + public boolean isFPMul() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MUL; } /** * Indicates whether the term is a floating-point divison term * @return * @throws Z3Exception */ - public boolean IsFPDiv() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_DIV; } + public boolean isFPDiv() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_DIV; } /** * Indicates whether the term is a floating-point remainder term * @return * @throws Z3Exception */ - public boolean IsFPRem() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_REM; } + public boolean isFPRem() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_REM; } /** * Indicates whether the term is a floating-point term absolute value term * @return * @throws Z3Exception */ - public boolean IsFPAbs() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ABS; } + public boolean isFPAbs() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ABS; } /** * Indicates whether the term is a floating-point minimum term * @return * @throws Z3Exception */ - public boolean IsFPMin() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MIN; } + public boolean isFPMin() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MIN; } /** * Indicates whether the term is a floating-point maximum term * @return * @throws Z3Exception */ - public boolean IsFPMax() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MAX; } + public boolean isFPMax() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_MAX; } /** * Indicates whether the term is a floating-point fused multiply-add term * @return * @throws Z3Exception */ - public boolean IsFPFMA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_FMA; } + public boolean isFPFMA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_FMA; } /** * Indicates whether the term is a floating-point square root term * @return * @throws Z3Exception */ - public boolean IsFPSqrt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_SQRT; } + public boolean isFPSqrt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_SQRT; } /** * Indicates whether the term is a floating-point roundToIntegral term * @return * @throws Z3Exception */ - public boolean IsFPRoundToIntegral() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ROUND_TO_INTEGRAL; } + public boolean isFPRoundToIntegral() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_ROUND_TO_INTEGRAL; } /** * Indicates whether the term is a floating-point equality term * @return * @throws Z3Exception */ - public boolean IsFPEq() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_EQ; } + public boolean isFPEq() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_EQ; } /** * Indicates whether the term is a floating-point less-than term * @return * @throws Z3Exception */ - public boolean IsFPLt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_LT; } + public boolean isFPLt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_LT; } /** * Indicates whether the term is a floating-point greater-than term * @return * @throws Z3Exception */ - public boolean IsFPGt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_GT; } + public boolean isFPGt() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_GT; } /** * Indicates whether the term is a floating-point less-than or equal term * @return * @throws Z3Exception */ - public boolean IsFPLe() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_LE; } + public boolean isFPLe() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_LE; } /** * Indicates whether the term is a floating-point greater-than or erqual term * @return * @throws Z3Exception */ - public boolean IsFPGe() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_GE; } + public boolean isFPGe() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_GE; } /** * Indicates whether the term is a floating-point isNaN predicate term * @return * @throws Z3Exception */ - public boolean IsFPisNaN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NAN; } + public boolean isFPisNaN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NAN; } /** * Indicates whether the term is a floating-point isInf predicate term * @return * @throws Z3Exception */ - public boolean IsFPisInf() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_INF; } + public boolean isFPisInf() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_INF; } /** * Indicates whether the term is a floating-point isZero predicate term * @return * @throws Z3Exception */ - public boolean IsFPisZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_ZERO; } + public boolean isFPisZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_ZERO; } /** * Indicates whether the term is a floating-point isNormal term * @return * @throws Z3Exception */ - public boolean IsFPisNormal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NORMAL; } + public boolean isFPisNormal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NORMAL; } /** * Indicates whether the term is a floating-point isSubnormal predicate term * @return * @throws Z3Exception */ - public boolean IsFPisSubnormal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_SUBNORMAL; } + public boolean isFPisSubnormal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_SUBNORMAL; } /** * Indicates whether the term is a floating-point isNegative predicate term * @return * @throws Z3Exception */ - public boolean IsFPisNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NEGATIVE; } + public boolean isFPisNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_NEGATIVE; } /** * Indicates whether the term is a floating-point isPositive predicate term * @return * @throws Z3Exception */ - public boolean IsFPisPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_POSITIVE; } + public boolean isFPisPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_IS_POSITIVE; } /** * Indicates whether the term is a floating-point constructor term * @return * @throws Z3Exception */ - public boolean IsFPFP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_FP; } + public boolean isFPFP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_FP; } /** * Indicates whether the term is a floating-point conversion term * @return * @throws Z3Exception */ - public boolean IsFPToFp() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_FP; } + public boolean isFPToFp() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_FP; } /** * Indicates whether the term is a floating-point conversion from unsigned bit-vector term * @return * @throws Z3Exception */ - public boolean IsFPToFpUnsigned() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_FP_UNSIGNED; } + public boolean isFPToFpUnsigned() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_FP_UNSIGNED; } /** * Indicates whether the term is a floating-point conversion to unsigned bit-vector term * @return * @throws Z3Exception */ - public boolean IsFPToUBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_UBV; } + public boolean isFPToUBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_UBV; } /** * Indicates whether the term is a floating-point conversion to signed bit-vector term * @return * @throws Z3Exception */ - public boolean IsFPToSBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_SBV; } + public boolean isFPToSBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_SBV; } /** * Indicates whether the term is a floating-point conversion to real term * @return * @throws Z3Exception */ - public boolean IsFPToReal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_REAL; } - + public boolean isFPToReal() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_REAL; } /** * Indicates whether the term is a floating-point conversion to IEEE-754 bit-vector term1 * @return * @throws Z3Exception */ - public boolean IsFPToIEEEBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_IEEE_BV; } + public boolean isFPToIEEEBV() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_TO_IEEE_BV; } /** @@ -2140,6 +2146,8 @@ public class Expr extends AST return new BitVecNum(ctx, obj); case Z3_FLOATING_POINT_SORT: return new FPNum(ctx, obj); + case Z3_ROUNDING_MODE_SORT: + return new FPRMNum(ctx, obj); default: ; } } diff --git a/src/api/java/FPExpr.java b/src/api/java/FPExpr.java new file mode 100644 index 000000000..e5193a042 --- /dev/null +++ b/src/api/java/FPExpr.java @@ -0,0 +1,41 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPExpr.java + +Abstract: + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +package com.microsoft.z3; + +/** + * FloatingPoint Expressions + */ +public class FPExpr extends Expr +{ + /** + * The number of exponent bits. + * @throws Z3Exception + */ + public int getEBits() throws Z3Exception { return ((FPSort)getSort()).getEBits(); } + + /** + * The number of significand bits. + * @throws Z3Exception + */ + public int getSBits() throws Z3Exception { return ((FPSort)getSort()).getSBits(); } + + public FPExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + +} diff --git a/src/api/java/FPNum.java b/src/api/java/FPNum.java new file mode 100644 index 000000000..f2c9b7f98 --- /dev/null +++ b/src/api/java/FPNum.java @@ -0,0 +1,86 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPNum.java + +Abstract: + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +package com.microsoft.z3; + +/** + * FloatingPoint Numerals + */ +public class FPNum extends FPExpr +{ + /** + * Retrieves the sign of a floating-point literal + * Remarks: returns true if the numeral is negative + * @throws Z3Exception + */ + public boolean getSign() throws Z3Exception { + Native.IntPtr res = new Native.IntPtr(); + if (Native.fpaGetNumeralSign(getContext().nCtx(), getNativeObject(), res) ^ true) + throw new Z3Exception("Sign is not a Boolean value"); + return res.value != 0; + + + } + + /** + * The significand value of a floating-point numeral as a string + * Remarks: The significand s is always 0 < s < 2.0; the resulting string is long + * enough to represent the real significand precisely. + * @throws Z3Exception + **/ + public String getSignificand() throws Z3Exception { + return Native.fpaGetNumeralSignificandString(getContext().nCtx(), getNativeObject()); + } + + /** + * Return the exponent value of a floating-point numeral as a string + * @throws Z3Exception + */ + public String getExponent() throws Z3Exception { + return Native.fpaGetNumeralExponentString(getContext().nCtx(), getNativeObject()); + } + + /** + * Return the exponent value of a floating-point numeral as a signed 64-bit integer + * @throws Z3Exception + */ + public long getExponentInt64() throws Z3Exception { + Native.LongPtr res = new Native.LongPtr(); + if (Native.fpaGetNumeralExponentInt64(getContext().nCtx(), getNativeObject(), res) ^ true) + throw new Z3Exception("Exponent is not a 64 bit integer"); + return res.value; + } + + public FPNum(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + /** + * Returns a string representation of the numeral. + */ + public String toString() + { + try + { + return Native.getNumeralString(getContext().nCtx(), getNativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + +} diff --git a/src/api/java/FPRMExpr.java b/src/api/java/FPRMExpr.java new file mode 100644 index 000000000..482c3b899 --- /dev/null +++ b/src/api/java/FPRMExpr.java @@ -0,0 +1,29 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMExpr.java + +Abstract: + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +package com.microsoft.z3; + +/** + * FloatingPoint RoundingMode Expressions + */ +public class FPRMExpr extends Expr +{ + public FPRMExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + +} diff --git a/src/api/java/FPRMNum.java b/src/api/java/FPRMNum.java new file mode 100644 index 000000000..04e7727e2 --- /dev/null +++ b/src/api/java/FPRMNum.java @@ -0,0 +1,90 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMNum.java + +Abstract: + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.Z3_decl_kind; + +/** + * FloatingPoint RoundingMode Numerals + */ +public class FPRMNum extends FPRMExpr { + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + * @throws Z3Exception + * **/ + public boolean isRoundNearestTiesToEven() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToEven + * @throws Z3Exception + */ + public boolean isRNE() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + * @throws Z3Exception + */ + public boolean isRoundNearestTiesToAway() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundNearestTiesToAway + * @throws Z3Exception + */ + public boolean isRNA() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardPositive + * @throws Z3Exception + */ + public boolean isRoundTowardPositive() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardPositive + * @throws Z3Exception + */ + public boolean isRTP() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_POSITIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardNegative + * @throws Z3Exception + */ + public boolean isRoundTowardNegative() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardNegative + * @throws Z3Exception + */ + public boolean isRTN() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_NEGATIVE; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardZero + * @throws Z3Exception + */ + public boolean isRoundTowardZero() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } + + /** + * Indicates whether the term is the floating-point rounding numeral roundTowardZero + * @throws Z3Exception + */ + public boolean isRTZ() throws Z3Exception { return isApp() && getFuncDecl().getDeclKind() == Z3_decl_kind.Z3_OP_FPA_RM_TOWARD_ZERO; } + + public FPRMNum(Context ctx, long obj) throws Z3Exception { + super(ctx, obj); + } + +} diff --git a/src/api/java/FPRMSort.java b/src/api/java/FPRMSort.java new file mode 100644 index 000000000..ff6422ef6 --- /dev/null +++ b/src/api/java/FPRMSort.java @@ -0,0 +1,35 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPRMExpr.java + +Abstract: + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +package com.microsoft.z3; + +/** + * The FloatingPoint RoundingMode sort + **/ +public class FPRMSort extends Sort +{ + + public FPRMSort(Context ctx) throws Z3Exception + { + super(ctx, Native.mkFpaRoundingModeSort(ctx.nCtx())); + } + + public FPRMSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + +} \ No newline at end of file diff --git a/src/api/java/FPSort.java b/src/api/java/FPSort.java new file mode 100644 index 000000000..284979524 --- /dev/null +++ b/src/api/java/FPSort.java @@ -0,0 +1,49 @@ +/*++ +Copyright (c) 2013 Microsoft Corporation + +Module Name: + + FPSort.java + +Abstract: + +Author: + + Christoph Wintersteiger (cwinter) 2013-06-10 + +Notes: + +--*/ +package com.microsoft.z3; + +/** + * A FloatingPoint sort + **/ +public class FPSort extends Sort +{ + + public FPSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + public FPSort(Context ctx, int ebits, int sbits) throws Z3Exception + { + super(ctx, Native.mkFpaSort(ctx.nCtx(), ebits, sbits)); + } + + /** + * The number of exponent bits. + */ + public int getEBits() throws Z3Exception { + return Native.fpaGetEbits(getContext().nCtx(), getNativeObject()); + } + + /** + * The number of significand bits. + */ + public int getSBits() throws Z3Exception { + return Native.fpaGetEbits(getContext().nCtx(), getNativeObject()); + } + +} diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 043d43e2f..7457ed9a3 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -834,6 +834,47 @@ extern "C" { */ unsigned Z3_API Z3_fpa_get_sbits(__in Z3_context c, __in Z3_sort s); + /** + \brief Retrieves the sign of a floating-point literal + + Remarks: sets \c sgn to 0 if the literal is NaN or positive and to 1 otherwise. + + \param t a floating-point numeral. + + def_API('Z3_fpa_get_numeral_sign', BOOL, (_in(CONTEXT), _in(AST), _out(INT))) + */ + Z3_bool Z3_API Z3_fpa_get_numeral_sign(__in Z3_context c, __in Z3_ast t, __out int * sgn); + + /** + \brief Return the significand value of a floating-point numeral as a string + + Remarks: The significand s is always 0 < s < 2.0; the resulting string is long + enough to represent the real significand precisely. + + \param t a floating-point numeral. + + def_API('Z3_fpa_get_numeral_significand_string', STRING, (_in(CONTEXT), _in(AST))) + */ + Z3_string Z3_API Z3_fpa_get_numeral_significand_string(__in Z3_context c, __in Z3_ast t); + + /** + \brief Return the exponent value of a floating-point numeral as a string + + \param t a floating-point numeral. + + def_API('Z3_fpa_get_numeral_exponent_string', STRING, (_in(CONTEXT), _in(AST))) + */ + Z3_string Z3_API Z3_fpa_get_numeral_exponent_string(__in Z3_context c, __in Z3_ast t); + + /** + \brief Return the exponent value of a floating-point numeral as a signed 64-bit integer + + \param t a floating-point numeral. + + def_API('Z3_fpa_get_numeral_exponent_int64', BOOL, (_in(CONTEXT), _in(AST), _out(INT64))) + */ + Z3_bool Z3_API Z3_fpa_get_numeral_exponent_int64(__in Z3_context c, __in Z3_ast t, __out __int64 * n); + /** \brief Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. From 4bd8e0f4979c7cebad17207d268ba2e15f27de28 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 11 Jan 2015 18:28:07 +0000 Subject: [PATCH 142/507] FPA API cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 12 ++++++------ src/api/java/Context.java | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 70777a6e8..1a36a35dc 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3758,11 +3758,11 @@ namespace Microsoft.Z3 /// /// Create a numeral of FloatingPoint sort from a sign bit and two integers. /// - /// the sign. - /// the significand. + /// the sign. /// the exponent. + /// the significand. /// FloatingPoint sort. - public FPNum MkFP(bool sgn, uint sig, int exp, FPSort s) + public FPNum MkFP(bool sgn, int exp, uint sig, FPSort s) { Contract.Ensures(Contract.Result() != null); return MkFPNumeral(sgn, sig, exp, s); @@ -3771,11 +3771,11 @@ namespace Microsoft.Z3 /// /// Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. /// - /// the sign. - /// the significand. + /// the sign. /// the exponent. + /// the significand. /// FloatingPoint sort. - public FPNum MkFP(bool sgn, UInt64 sig, Int64 exp, FPSort s) + public FPNum MkFP(bool sgn, Int64 exp, UInt64 sig, FPSort s) { Contract.Ensures(Contract.Result() != null); return MkFPNumeral(sgn, sig, exp, s); diff --git a/src/api/java/Context.java b/src/api/java/Context.java index cfbd7c2c8..2b4c47d76 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3170,7 +3170,7 @@ public class Context extends IDisposable * @param s FloatingPoint sort. * @throws Z3Exception **/ - public FPNum mkFP(boolean sgn, int sig, int exp, FPSort s) throws Z3Exception + public FPNum mkFP(boolean sgn, int exp, int sig, FPSort s) throws Z3Exception { return mkFPNumeral(sgn, sig, exp, s); } @@ -3183,7 +3183,7 @@ public class Context extends IDisposable * @param s FloatingPoint sort. * @throws Z3Exception **/ - public FPNum mkFP(boolean sgn, long sig, long exp, FPSort s) throws Z3Exception + public FPNum mkFP(boolean sgn, long exp, long sig, FPSort s) throws Z3Exception { return mkFPNumeral(sgn, sig, exp, s); } From e0bc704106e15595856ec81419fb299dcb51aa87 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 11 Jan 2015 18:29:12 +0000 Subject: [PATCH 143/507] FPA API bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 26 +++++++++++++++++++------- src/api/z3_fpa.h | 6 +++--- src/ast/fpa_decl_plugin.cpp | 16 +++++++++++++++- src/util/mpf.h | 17 +++++++++++++++++ 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 219f9b166..67ffe12d9 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -217,7 +217,7 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_fp(Z3_context c, Z3_ast sgn, Z3_ast sig, Z3_ast exp) { + Z3_ast Z3_API Z3_mk_fpa_fp(Z3_context c, Z3_ast sgn, Z3_ast exp, Z3_ast sig) { Z3_TRY; LOG_Z3_mk_fpa_fp(c, sgn, sig, exp); RESET_ERROR_CODE(); @@ -680,7 +680,11 @@ extern "C" { mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); - bool r = plugin->is_numeral(to_expr(t), val); + bool r = plugin->is_numeral(to_expr(t), val); + if (!r || mpfm.is_nan(val)) { + SET_ERROR_CODE(Z3_INVALID_ARG); + return 0; + } *sgn = (mpfm.is_nan(val)) ? 0 : mpfm.sgn(val); return r; Z3_CATCH_RETURN(0); @@ -694,14 +698,18 @@ extern "C" { mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); - scoped_mpf val(mpfm); - if (!plugin->is_numeral(to_expr(t), val)) { + scoped_mpf val(mpfm); + if (!plugin->is_numeral(to_expr(t), val)) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } + else if (!mpfm.is_regular(val)) { + SET_ERROR_CODE(Z3_INVALID_ARG) + return ""; + } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); - mpqm.set(q, mpfm.sig(val)); + mpqm.set(q, mpfm.sig_normalized(val)); mpqm.div(q, mpfm.m_powers2(sbits - 1), q); std::stringstream ss; mpqm.display_decimal(ss, q, sbits); @@ -724,7 +732,11 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } - const mpf_exp_t exp = mpfm.exp(val); + else if (!mpfm.is_normal(val) && !mpfm.is_denormal(val)) { + SET_ERROR_CODE(Z3_INVALID_ARG) + return ""; + } + mpf_exp_t exp = mpfm.exp_normalized(val); std::stringstream ss; ss << exp; return mk_c(c)->mk_external_string(ss.str()); @@ -740,7 +752,7 @@ extern "C" { unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); - bool r = plugin->is_numeral(to_expr(t), val); + bool r = plugin->is_numeral(to_expr(t), val); if (!r) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 7457ed9a3..75002e1a5 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -273,13 +273,13 @@ extern "C" { of the arguments. \params c logical context. - \params sgn sign - \params sig significand + \params sgn sign \params exp exponent + \params sig significand def_API('Z3_mk_fpa_fp', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(AST))) */ - Z3_ast Z3_API Z3_mk_fpa_fp(__in Z3_context c, __in Z3_ast sgn, __in Z3_ast sig, __in Z3_ast exp); + Z3_ast Z3_API Z3_mk_fpa_fp(__in Z3_context c, __in Z3_ast sgn, __in Z3_ast exp, __in Z3_ast sig); /** \brief Create a numeral of FloatingPoint sort from a float. diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index a8e805066..9900812dd 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -76,7 +76,21 @@ func_decl * fpa_decl_plugin::mk_numeral_decl(mpf const & v) { } app * fpa_decl_plugin::mk_numeral(mpf const & v) { - return m_manager->mk_const(mk_numeral_decl(v)); + sort * s = mk_float_sort(v.get_ebits(), v.get_sbits()); + func_decl * d; + if (m_fm.is_nan(v)) + d = m_manager->mk_const_decl(symbol("NaN"), s, func_decl_info(m_family_id, OP_FPA_NAN)); + else if (m_fm.is_pinf(v)) + d = m_manager->mk_const_decl(symbol("+oo"), s, func_decl_info(m_family_id, OP_FPA_PLUS_INF)); + else if (m_fm.is_ninf(v)) + d = m_manager->mk_const_decl(symbol("-oo"), s, func_decl_info(m_family_id, OP_FPA_MINUS_INF)); + else if (m_fm.is_pzero(v)) + d = m_manager->mk_const_decl(symbol("+zero"), s, func_decl_info(m_family_id, OP_FPA_PLUS_ZERO)); + else if (m_fm.is_nzero(v)) + d = m_manager->mk_const_decl(symbol("-zero"), s, func_decl_info(m_family_id, OP_FPA_MINUS_ZERO)); + else + d = mk_numeral_decl(v); + return m_manager->mk_const(d); } bool fpa_decl_plugin::is_numeral(expr * n, mpf & val) { diff --git a/src/util/mpf.h b/src/util/mpf.h index b919e0371..599e8e743 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -146,7 +146,24 @@ public: bool sgn(mpf const & x) const { return x.sign; } const mpz & sig(mpf const & x) const { return x.significand; } + mpz sig_normalized(mpf const & x) { + mpf t; + set(t, x); + unpack(t, true); + mpz r; + mpz_manager().set(r, t.significand); + del(t); + return r; + } const mpf_exp_t & exp(mpf const & x) const { return x.exponent; } + mpf_exp_t exp_normalized(mpf const & x) { + mpf t; + set(t, x); + unpack(t, true); + mpf_exp_t r = t.exponent; + del(t); + return r; + } bool is_nan(mpf const & x); bool is_inf(mpf const & x); From 6c971b130132c8774d5e92b2a331a5a702485382 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 11 Jan 2015 18:29:40 +0000 Subject: [PATCH 144/507] Beginnings of a Python API for FPA Signed-off-by: Christoph M. Wintersteiger --- src/api/python/z3.py | 912 ++++++++++++++++++++++++++++++++++++ src/api/python/z3printer.py | 207 +++++++- 2 files changed, 1114 insertions(+), 5 deletions(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index bb0212820..a2f0191cf 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -555,6 +555,10 @@ def _to_sort_ref(s, ctx): return ArraySortRef(s, ctx) elif k == Z3_DATATYPE_SORT: return DatatypeSortRef(s, ctx) + elif k == Z3_FLOATING_POINT_SORT: + return FPSortRef(s, ctx) + elif k == Z3_ROUNDING_MODE_SORT: + return FPRMSortRef(s, ctx) return SortRef(s, ctx) def _sort(ctx, a): @@ -899,6 +903,17 @@ def _to_expr_ref(a, ctx): return ArrayRef(a, ctx) if sk == Z3_DATATYPE_SORT: return DatatypeRef(a, ctx) + if sk == Z3_FLOATING_POINT_SORT: + if k == Z3_APP_AST: + e = ExprRef(a, ctx) + if e.decl().kind() == Z3_OP_FPA_NUM: + return FPNumRef(a, ctx) + else: + return FPRef(a, ctx) + else: + return FPRef(a, ctx) + if sk == Z3_ROUNDING_MODE_SORT: + return FPRMRef(a, ctx) return ExprRef(a, ctx) def _coerce_expr_merge(s, a): @@ -7429,3 +7444,900 @@ def sequence_interpolant(v,p=None,ctx=None): f = And(Interpolant(f),v[i]) return tree_interpolant(f,p,ctx) +######################################### +# +# Floating-Point Arithmetic +# +######################################### + + +# Global default rounding mode +_dflt_rounding_mode = Z3_OP_FPA_RM_TOWARD_ZERO +_dflt_fpsort_ebits = 11 +_dflt_fpsort_sbits = 53 + +def get_default_rounding_mode(ctx=None): + """Retrieves the global default rounding mode.""" + global _dflt_rounding_mode + if _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO: + return RTZ(ctx) + elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE: + return RTN(ctx) + elif _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE: + return RTP(ctx) + elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN: + return RNE(ctx) + elif _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY: + return RNA(ctx) + +def set_default_rounding_mode(rm, ctx=None): + global _dflt_rounding_mode + if is_fprm_value(rm): + _dflt_rounding_mode = rm.decl().kind() + else: + _z3_assert(_dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_ZERO or + _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_NEGATIVE or + _dflt_rounding_mode == Z3_OP_FPA_RM_TOWARD_POSITIVE or + _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN or + _dflt_rounding_mode == Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY, + "illegal rounding mode") + _dflt_rounding_mode = rm + +def get_default_fp_sort(ctx=None): + return FPSort(_dflt_fpsort_ebits, _dflt_fpsort_sbits, ctx) + +def set_default_fp_sort(ebits, sbits, ctx=None): + global _dflt_fpsort_ebits + global _dflt_fpsort_sbits + _dflt_fpsort_ebits = ebits + _dflt_fpsort_sbits = sbits + +def _dflt_rm(ctx=None): + return get_default_rounding_mode(ctx) + +def _dflt_fps(ctx=None): + return get_default_fp_sort(ctx) + +### FP Sorts + +class FPSortRef(SortRef): + """Floating-point sort.""" + + def ebits(self): + """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`. + >>> b = FPSort(8, 24) + >>> b.ebits() + 8 + """ + return int(Z3_fpa_get_ebits(self.ctx_ref(), self.ast)) + + def sbits(self): + """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`. + >>> b = FloatingPointSort(8, 24) + >>> b.sbits() + 24 + """ + return int(Z3_fpa_get_sbits(self.ctx_ref(), self.ast)) + + def cast(self, val): + """Try to cast `val` as a Floating-point expression + + >>> b = FPSort(8, 24) + >>> b.cast(1.0) + 1.0 + >>> b.cast(1.0).sexpr() + '1.0' + """ + if is_expr(val): + if __debug__: + _z3_assert(self.ctx == val.ctx, "Context mismatch") + return val + else: + return FPVal(val, None, self, self.ctx) + + +def Float16(ctx=None): + """Floating-point 16-bit (half) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_16(ctx.ref()), ctx) + +def FloatHalf(ctx=None): + """Floating-point 16-bit (half) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_half(ctx.ref()), ctx) + +def Float32(ctx=None): + """Floating-point 32-bit (single) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_32(ctx.ref()), ctx) + +def FloatSingle(ctx=None): + """Floating-point 32-bit (single) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_single(ctx.ref()), ctx) + +def Float64(ctx=None): + """Floating-point 64-bit (double) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_64(ctx.ref()), ctx) + +def FloatSingle(ctx=None): + """Floating-point 64-bit (double) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_double(ctx.ref()), ctx) + +def Float128(ctx=None): + """Floating-point 128-bit (quadruple) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_128(ctx.ref()), ctx) + +def FloatSingle(ctx=None): + """Floating-point 128-bit (quadruple) sort.""" + ctx = _get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort_quadruple(ctx.ref()), ctx) + +class FPRMSortRef(SortRef): + """"Floating-point rounding mode sort.""" + + +def is_fp_sort(s): + """Return True if `s` is a Z3 floating-point sort. + + >>> is_fp_sort(FloatingPointSort(8, 24)) + True + >>> is_fp_sort(IntSort()) + False + """ + return isinstance(s, FPSortRef) + +def is_fprm_sort(s): + """Return True if `s` is a Z3 floating-point rounding mode sort. + + >>> is_fprm_sort(FPSort(8, 24)) + False + >>> is_fprm_sort() + False + """ + return isinstance(s, FPSortRef) + +### FP Expressions + +class FPRef(ExprRef): + """Floating-point expressions.""" + + def sort(self): + """Return the sort of the floating-point expression `self`. + + >>> x = FP('1.0', FPSort(8, 24)) + >>> x.sort() + (_ FloatingPoint 8 24) + >>> x.sort() == FloatingPointSort(8, 24) + True + """ + return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx) + + def ebits(self): + """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`. + >>> b = FloatingPointSort(8, 24) + >>> b.ebits() + 8 + """ + return self.sort().ebits(); + + def sbits(self): + """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`. + >>> b = FloatingPointSort(8, 24) + >>> b.sbits() + 24 + """ + return self.sort().sbits(); + + def as_string(self): + """Return a Z3 floating point expression as a Python string.""" + return Z3_ast_to_string(self.ctx_ref(), self.as_ast()) + + def __le__(self, other): + return fpLEQ(self, other) + + def __lt__(self, other): + return fpLEQ(self, other) + + def __ge__(self, other): + return fpGEQ(self, other) + + def __gt__(self, other): + return fpGT(self, other) + + def __ne__(self, other): + return fpNEQ(self, other) + + + def __add__(self, other): + """Create the Z3 expression `self + other`. + + >>> x = FP('x', 8, 24) + >>> y = FP('y', 8, 24) + >>> x + y + x + y + >>> (x + y).sort() + FloatingPoint(8 24) + """ + a, b = z3._coerce_exprs(self, other) + return fpAdd(_dflt_rm(), self, other) + + def __radd__(self, other): + """Create the Z3 expression `other + self`. + + >>> x = FP('x', FPSort(8, 24)) + >>> 10 + x + 10 + x + """ + a, b = _coerce_exprs(self, other) + return fpAdd(_dflt_rm(), other, self) + + def __sub__(self, other): + """Create the Z3 expression `self - other`. + + >>> x = FP('x', 8, 24) + >>> y = FP('y', 8, 24) + >>> x - y + x - y + >>> (x - y).sort() + FloatingPoint(8 24) + """ + a, b = z3._coerce_exprs(self, other) + return fpSub(_dflt_rm(), self, other) + + def __rsub__(self, other): + """Create the Z3 expression `other - self`. + + >>> x = FP('x', FPSort(8, 24)) + >>> 10 - x + 10 - x + """ + a, b = _coerce_exprs(self, other) + return fpSub(_dflt_rm(), other, self) + + def __mul__(self, other): + """Create the Z3 expression `self * other`. + + >>> x = FP('x', 8, 24) + >>> y = FP('y', 8, 24) + >>> x * y + x * y + >>> (x * y).sort() + FloatingPoint(8 24) + """ + a, b = z3._coerce_exprs(self, other) + return fpMul(_dflt_rm(), self, other) + + def __rmul_(self, other): + """Create the Z3 expression `other * self`. + + >>> x = FP('x', FPSort(8, 24)) + >>> 10 * x + 10 * x + """ + a, b = _coerce_exprs(self, other) + return fpMul(_dflt_rm(), other, self) + + def __pos__(self): + """Create the Z3 expression `+self`.""" + return self + + def __neg__(self): + """Create the Z3 expression `-self`.""" + return FPRef(fpNeg(self)) + + def __truediv__(self, other): + """Create the Z3 expression division `self / other`.""" + return self.__div__(other) + + def __rtruediv__(self, other): + """Create the Z3 expression division `other / self`.""" + return self.__rdiv__(other) + + def __mod__(self, other): + """Create the Z3 expression mod `self % other`.""" + return fpRem(self, other) + + def __rmod__(self, other): + """Create the Z3 expression mod `other % self`.""" + return fpRem(other, self) + +class FPRMRef(ExprRef): + """Floating-point rounding mode expressions""" + + def as_string(self): + """Return a Z3 floating point expression as a Python string.""" + return Z3_ast_to_string(self.ctx_ref(), self.as_ast()) + + +def RoundNearestTiesToEven (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx) + +def RNE (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx) + +def RoundNearestTiesToAway (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx) + +def RNA (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx) + +def RoundTowardPositive (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx) + +def RTP (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx) + +def RoundTowardNegative (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx) + +def RTN (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx) + +def RoundTowardZero (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx) + +def RTZ (ctx=None): + ctx = _get_ctx(ctx) + return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx) + +def is_fprm(a): + """Return `True` if `a` is a Z3 floating-point rounding mode expression. + + >>> rm = ? + """ + return isinstance(a, FPRMRef) + +def is_fprm_value(a): + """Return `True` if `a` is a Z3 floating-point rounding mode numeral value.""" + return is_fprm(a) and _is_numeral(a.ctx, a.ast) + +### FP Numerals + +class FPNumRef(FPRef): + def isNaN(self): + return self.decl().kind() == Z3_OP_FPA_NAN + + def isInf(self): + return self.decl().kind() == Z3_OP_FPA_PLUS_INF or self.decl().kind() == Z3_OP_FPA_MINUS_INF + + def isZero(self): + return self.decl().kind() == Z3_OP_FPA_PLUS_ZERO or self.decl().kind() == Z3_OP_FPA_MINUS_ZERO + + def isNegative(self): + return (self.num_args() == 0 and (Z3_OP_FPA_MINUS_INF or Z3_OP_FPA_MINUS_ZERO)) or (self.num_args() == 3 and self.arg(0) == BitVecVal(1)) + +def _to_fpnum(num, ctx=None): + if isinstance(num, FPNum): + return num + else: + return FPNum(num, ctx) + +def is_fp(a): + """Return `True` if `a` is a Z3 floating-point expression. + + >>> b = FP('b', FPSort(8, 24)) + >>> is_fp(b) + True + >>> is_fp(b + 1.0) + True + >>> is_fp(Int('x')) + False + """ + return isinstance(a, FPRef) + +def is_fp_value(a): + """Return `True` if `a` is a Z3 floating-point numeral value. + + >>> b = FP('b', FPSort(8, 24)) + >>> is_fp_value(b) + False + >>> b = FPVal(1.0, FPSort(8, 24)) + >>> b + 1.0p0 + >>> is_fp_value(b) + True + """ + return is_fp(a) and _is_numeral(a.ctx, a.ast) + +def FPSort(ebits, sbits, ctx=None): + """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used. + + >>> Single = FPSort(8, 24) + >>> Double = FPSort(11, 53) + >>> Single + (_ FloatingPoint 8 24) + >>> x = Const('x', Single) + >>> eq(x, FP('x', 8, 24)) + True + """ + ctx = z3._get_ctx(ctx) + return FPSortRef(Z3_mk_fpa_sort(ctx.ref(), ebits, sbits), ctx) + +def _to_float_str(val): + if isinstance(val, float): + return str(val) + elif isinstance(val, bool): + if val: + return "1.0" + else: + return "0.0" + elif _is_int(val): + return str(val) + elif isinstance(val, str): + return val + if __debug__: + _z3_assert(False, "Python value cannot be used as a double") + +def fpNaN(s): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + return FPNumRef(Z3_mk_fpa_nan(s.ctx_ref(), s.ast), s.ctx) + +def fpPlusInfinity(s): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, False), s.ctx) + +def fpMinusInfinity(s): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, True), s.ctx) + +def fpInfinity(s, negative): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + _z3_assert(isinstance(negative, bool), "expected Boolean flag") + return FPNumRef(Z3_mk_fpa_inf(s.ctx_ref(), s.ast, negative), s.ctx) + +def fpPlusZero(s): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, False), s.ctx) + +def fpMinusZero(s): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, True), s.ctx) + +def fpZero(s, negative): + _z3_assert(isinstance(s, FPSortRef), "sort mismatch") + _z3_assert(isinstance(negative, bool), "expected Boolean flag") + return FPNumRef(Z3_mk_fpa_zero(s.ctx_ref(), s.ast, negative), s.ctx) + +def FPVal(sig, exp=None, fps=None, ctx=None): + """Return a floating-point value of value `val` and sort `fps`. If `ctx=None`, then the global context is used. + + >>> v = FPVal(1.0, FPSort(8, 24))) + >>> v + 1.0 + >>> print("0x%.8x" % v.as_long()) + 0x0000000a + """ + ctx = _get_ctx(ctx) + if is_fp_sort(exp): + fps = exp + exp = None + elif fps == None: + fps = _dflt_fps(ctx) + _z3_assert(is_fp_sort(fps), "sort mismatch") + if exp == None: + exp = 0 + val = _to_float_str(sig) + val = val + 'p' + val = val + _to_int_str(exp) + return FPNumRef(Z3_mk_numeral(ctx.ref(), val, fps.ast), ctx) + +def FP(name, fpsort, ctx=None): + """Return a floating-point constant named `name`. + `fpsort` is the floating-point sort. + If `ctx=None`, then the global context is used. + + >>> x = FP('x', FPSort(8, 24)) + >>> is_fp(x) + True + >>> x.ebits() + 8 + >>> x.sort() + (_ FloatingPoint 8 24) + >>> word = FPSort(8, 24) + >>> x2 = FP('x', word) + >>> eq(x, x2) + True + """ + ctx = fpsort.ctx + return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx) + +def FPs(names, fpsort, ctx=None): + """Return an array of floating-point constants. + + >>> x, y, z = BitVecs('x y z', 16) + >>> x.size() + 16 + >>> x.sort() + BitVec(16) + >>> Sum(x, y, z) + 0 + x + y + z + >>> Product(x, y, z) + 1*x*y*z + >>> simplify(Product(x, y, z)) + x*y*z + """ + ctx = z3._get_ctx(ctx) + if isinstance(names, str): + names = names.split(" ") + return [FP(name, fpsort, ctx) for name in names] + +def fpAbs(a): + """Create a Z3 floating-point absolute value expression. + + >>> s = FPSort(8, 24) + >>> rm = FPRM.RNE + >>> x = FPVal(1.0, s) + >>> fpAbs(x) + 1.0 + >>> x = FPVal(-1.0, s) + >>> fpAbs(x) + 1.0 + >>> fpAbs(x).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fp(a), "First argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_abs(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpNeg(a): + """Create a Z3 floating-point addition expression. + + >>> s = FPSort(8, 24) + >>> rm = FPRM.RNE + >>> x = FP('x', s) + >>> y = FP('y', s) + fp.add(rm, x, y) + >>> fp.add(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fp(a), "First argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_neg(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpAdd(rm, a, b): + """Create a Z3 floating-point addition expression. + + >>> s = FPSort(8, 24) + >>> rm = FPRM.RNE + >>> x = FP('x', s) + >>> y = FP('y', s) + fp.add(rm, x, y) + >>> fp.add(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_add(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) + +def fpSub(rm, a, b): + """Create a Z3 floating-point subtraction expression. + + >>> s = FPSort(8, 24) + >>> rm = FPRM.RNE + >>> x = FP('x', s) + >>> y = FP('y', s) + fp.add(rm, x, y) + >>> fp.add(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_sub(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) + +def fpMul(rm, a, b): + """Create a Z3 floating-point multiplication expression. + + >>> s = FPSort(8, 24) + >>> rm = FPRM.RNE + >>> x = FP('x', s) + >>> y = FP('y', s) + fp.add(rm, x, y) + >>> fp.add(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_mul(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) + +def fpDiv(rm, a, b): + """Create a Z3 floating-point divison expression. + + >>> s = FPSort(8, 24) + >>> rm = FPRM.RNE + >>> x = FP('x', s) + >>> y = FP('y', s) + fpAdd(rm, x, y) + >>> fp.add(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_mul(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) + +def fpRem(a, b): + """Create a Z3 floating-point remainder expression. + + >>> s = FPSort(8, 24) + >>> rm = RNE() + >>> x = FP('x', s) + >>> y = FP('y', s) + fpRem(x, y) + >>> fpRem(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fp(a) and is_fp(b), "Both arguments must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_rem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpMin(a, b): + """Create a Z3 floating-point minimium expression. + + >>> s = FPSort(8, 24) + >>> rm = RNE() + >>> x = FP('x', s) + >>> y = FP('y', s) + fpMin(x, y) + >>> fpMin(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fp(a) and is_fp(b), "Both arguments must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_min(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpMax(a, b): + """Create a Z3 floating-point maximum expression. + + >>> s = FPSort(8, 24) + >>> rm = RNE() + >>> x = FP('x', s) + >>> y = FP('y', s) + fpMin(x, y) + >>> fpMin(rm, x, y).sort() + FloatingPoint(8, 24) + """ + if __debug__: + _z3_assert(is_fp(a) and is_fp(b), "Both arguments must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_max(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpFMA(rm, a, b, c): + """Create a Z3 floating-point fused multiply-add expression. + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a) and is_fp(b) and is_fp(c), "Second, third, and fourth argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_fma(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), rm.ctx) + +def fpSqrt(rm, a): + """Create a Z3 floating-point square root expression. + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a), "Second argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_sqrt(rm.ctx_ref(), rm.as_ast(), a.as_ast()), rm.ctx) + +def fpRoundToIntegral(rm, a): + """Create a Z3 floating-point roundToIntegral expression. + """ + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(a), "Second argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_round_to_integral(rm.ctx_ref(), rm.as_ast(), a.as_ast()), rm.ctx) + +def fpIsNaN(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_nan(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpIsInfinite(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_infinite(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpIsZero(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_zero(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpIsNormal(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_normal(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpIsSubnormal(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_subnormal(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpIsNegative(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_negative(a.ctx_ref(), a.as_ast()), a.ctx) + +def fpIsPositive(a): + """Create a Z3 floating-point isNaN expression. + """ + if __debug__: + _z3_assert(is_fp(a), "Argument must be Z3 floating-point expressions") + return FPRef(Z3_mk_fpa_is_positive(a.ctx_ref(), a.as_ast()), a.ctx) + +def _check_fp_args(a, b): + if __debug__: + _z3_assert(is_fp(a) or is_fp(b), "At least one of the arguments must be a Z3 floating-point expression") + +def fpLT(a, b): + """Create the Z3 floating-point expression `other <= self`. + + >>> x, y = FPs('x y', FPSort(8, 24)) + >>> fpLT(x, y) + x <= y + >>> (x <= y).sexpr() + '?' + >>> fpLT(x, y).sexpr() + '?' + """ + _check_fp_args(a, b) + a, b = _coerce_exprs(a, b) + return BoolRef(Z3_mk_fpa_lt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpLEQ(a, b): + """Create the Z3 floating-point expression `other <= self`. + + >>> x, y = FPs('x y', FPSort(8, 24)) + >>> fpLEQ(x, y) + x <= y + >>> (x <= y).sexpr() + '?' + >>> fpLEQ(x, y).sexpr() + '?' + """ + _check_fp_args(a, b) + a, b = _coerce_exprs(a, b) + return BoolRef(Z3_mk_fpa_leq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpGT(a, b): + """Create the Z3 floating-point expression `other <= self`. + + >>> x, y = FPs('x y', FPSort(8, 24)) + >>> fpGT(x, y) + x <= y + >>> (x <= y).sexpr() + '?' + >>> fpGT(x, y).sexpr() + '?' + """ + _check_fp_args(a, b) + a, b = _coerce_exprs(a, b) + return BoolRef(Z3_mk_fpa_gt(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + + +def fpGEQ(a, b): + """Create the Z3 floating-point expression `other <= self`. + + >>> x, y = FPs('x y', FPSort(8, 24)) + >>> fp_geq(x, y) + x <= y + >>> (x <= y).sexpr() + '?' + >>> fp_geq(x, y).sexpr() + '?' + """ + _check_fp_args(a, b) + a, b = _coerce_exprs(a, b) + return BoolRef(Z3_mk_fpa_geq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpEQ(a, b): + """Create the Z3 floating-point expression `other <= self`. + + >>> x, y = FPs('x y', FPSort(8, 24)) + >>> fpEQ(x, y) + x <= y + >>> (x <= y).sexpr() + '?' + >>> fpEQ(x, y).sexpr() + '?' + """ + _check_fp_args(a, b) + a, b = _coerce_exprs(a, b) + return BoolRef(Z3_mk_fpa_eq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) + +def fpNEQ(a, b): + """Create the Z3 floating-point expression `other <= self`. + + >>> x, y = FPs('x y', FPSort(8, 24)) + >>> fpNEQ(x, y) + x <= y + >>> (x <= y).sexpr() + '?' + >>> fpNEQ(x, y).sexpr() + '?' + """ + _check_fp_args(a, b) + a, b = _coerce_exprs(a, b) + return Not(BoolRef(Z3_mk_fpa_eq(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx), a.ctx) + + + +def fpFP(sgn, exp, sig): + """Create the Z3 floating-point value `fpFP(sgn, sig, exp)` from the three bit-vectorssgn, sig, and exp.""" + _z3_assert(is_bv(sgn) and is_bv(exp) and is_bv(sig), "sort mismatch") + _z3_assert(sgn.sort().size() == 1, "sort mismatch") + return FPRef(Z3_mk_fpa_fp(sgn.ctx_ref(), sgn.ast, exp.ast, sig.ast), sgn.ctx) + + +def fpToFP(a1, a2=None, a3=None): + """Create a Z3 floating-point conversion expression from other terms.""" + if is_bv(a1) and is_fp_sort(a2): + return FPRef(Z3_mk_fpa_to_fp_bv(a1.ctx_ref(), a1.ast, a2.ast), a1.ctx) + elif is_fprm(a1) and is_fp(a2) and is_fp_sort(a3): + return FPRef(Z3_mk_fpa_to_fp_float(a1.ctx_ref(), a1.ast, a2.ast, a3.ast), a1.ctx) + elif is_fprm(a1) and is_real(a2) and is_fp_sort(a3): + return FPRef(Z3_mk_fpa_to_fp_real(a1.ctx_ref(), a1.ast, a2.ast, a3.ast), a1.ctx) + elif is_fprm(a1) and is_bv(a2) and is_fp_sort(a3): + return FPRef(Z3_mk_fpa_to_fp_signed(a1.ctx_ref(), a1.ast, a2.ast, a3.ast), a1.ctx) + else: + raise Z3Exception("Unsupported combination of arguments for conversion to floating-point term.") + +def fpToFPUnsigned(rm, x, s): + """Create a Z3 floating-point conversion expression, from unsigned bit-vector to floating-point expression.""" + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_bv(x), "Second argument must be a Z3 bit-vector expression") + _z3_assert(is_fp_sort(s), "Third argument must be Z3 floating-point sort") + return FPRef(Z3_mk_fpa_to_fp_unsigned(rm.ctx_ref(), rm.ast, x.ast, s.ast), rm.ctx) + +def fpToSBV(rm, x, s): + """Create a Z3 floating-point conversion expression, from floating-point expression to signed bit-vector.""" + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression") + _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort") + return FPRef(Z3_mk_fpa_to_sbv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx) + +def fpToUBV(rm, x, s): + """Create a Z3 floating-point conversion expression, from floating-point expression to unsigned bit-vector.""" + if __debug__: + _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") + _z3_assert(is_fp(x), "Second argument must be a Z3 floating-point expression") + _z3_assert(is_bv_sort(s), "Third argument must be Z3 bit-vector sort") + return FPRef(Z3_mk_fpa_to_ubv(rm.ctx_ref(), rm.ast, x.ast, s.size()), rm.ctx) + +def fpToReal(x): + """Create a Z3 floating-point conversion expression, from floating-point expression to real.""" + if __debug__: + _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression") + return FPRef(Z3_mk_fpa_to_real(x.ctx_ref(), x.ast), x.ctx) + +def fpToIEEEBV(x): + """Create a Z3 floating-point conversion expression, from floating-point expression to IEEE bit-vector.""" + if __debug__: + _z3_assert(is_fp(x), "First argument must be a Z3 floating-point expression") + return FPRef(Z3_mk_fpa_to_ieee_bv(x.ctx_ref(), x.ast), x.ctx) \ No newline at end of file diff --git a/src/api/python/z3printer.py b/src/api/python/z3printer.py index d1d85d30e..a74a67fa8 100644 --- a/src/api/python/z3printer.py +++ b/src/api/python/z3printer.py @@ -8,6 +8,7 @@ import sys, io, z3 from z3consts import * from z3core import * +from ctypes import * ############################## # @@ -30,7 +31,7 @@ _z3_op_to_str = { Z3_OP_BASHR : '>>', Z3_OP_BSHL : '<<', Z3_OP_BLSHR : 'LShR', Z3_OP_CONCAT : 'Concat', Z3_OP_EXTRACT : 'Extract', Z3_OP_BV2INT : 'BV2Int', Z3_OP_ARRAY_MAP : 'Map', Z3_OP_SELECT : 'Select', Z3_OP_STORE : 'Store', - Z3_OP_CONST_ARRAY : 'K' + Z3_OP_CONST_ARRAY : 'K' } # List of infix operators @@ -45,17 +46,65 @@ _z3_unary = [ Z3_OP_UMINUS, Z3_OP_BNOT, Z3_OP_BNEG ] # Precedence _z3_precedence = { Z3_OP_POWER : 0, - Z3_OP_UMINUS : 1, Z3_OP_BNEG : 1, Z3_OP_BNOT : 1, + Z3_OP_UMINUS : 1, Z3_OP_BNEG : 1, Z3_OP_BNOT : 1, Z3_OP_MUL : 2, Z3_OP_DIV : 2, Z3_OP_IDIV : 2, Z3_OP_MOD : 2, Z3_OP_BMUL : 2, Z3_OP_BSDIV : 2, Z3_OP_BSMOD : 2, - Z3_OP_ADD : 3, Z3_OP_SUB : 3, Z3_OP_BADD : 3, Z3_OP_BSUB : 3, + Z3_OP_ADD : 3, Z3_OP_SUB : 3, Z3_OP_BADD : 3, Z3_OP_BSUB : 3, Z3_OP_BASHR : 4, Z3_OP_BSHL : 4, Z3_OP_BAND : 5, Z3_OP_BXOR : 6, Z3_OP_BOR : 7, Z3_OP_LE : 8, Z3_OP_LT : 8, Z3_OP_GE : 8, Z3_OP_GT : 8, Z3_OP_EQ : 8, Z3_OP_SLEQ : 8, Z3_OP_SLT : 8, Z3_OP_SGEQ : 8, Z3_OP_SGT : 8, - Z3_OP_IFF : 8 + Z3_OP_IFF : 8, + + Z3_OP_FPA_NEG : 1, + Z3_OP_FPA_MUL : 2, Z3_OP_FPA_DIV : 2, Z3_OP_FPA_REM : 2, Z3_OP_FPA_FMA : 2, + Z3_OP_FPA_ADD: 3, Z3_OP_FPA_SUB : 3, + Z3_OP_FPA_LE : 8, Z3_OP_FPA_LT : 8, Z3_OP_FPA_GE : 8, Z3_OP_FPA_GT : 8, Z3_OP_FPA_EQ : 8 } +# FPA operators +_z3_op_to_fpa_normal_str = { + Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN : 'RNE()', Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY : 'RNA()', + Z3_OP_FPA_RM_TOWARD_POSITIVE : 'RTP()', Z3_OP_FPA_RM_TOWARD_NEGATIVE : 'RTN()', + Z3_OP_FPA_RM_TOWARD_ZERO : 'RTZ()', + Z3_OP_FPA_PLUS_INF : '+oo', Z3_OP_FPA_MINUS_INF : '-oo', + Z3_OP_FPA_NAN : 'NaN', Z3_OP_FPA_PLUS_ZERO : 'PZero', Z3_OP_FPA_MINUS_ZERO : 'NZero', + Z3_OP_FPA_ADD : 'fpAdd', Z3_OP_FPA_SUB : 'fpSub', Z3_OP_FPA_NEG : 'fpNeg', Z3_OP_FPA_MUL : 'fpMul', + Z3_OP_FPA_DIV : 'fpDiv', Z3_OP_FPA_REM : 'fpRem', Z3_OP_FPA_ABS : 'fpAbs', + Z3_OP_FPA_NEG : 'fpNeg', Z3_OP_FPA_MIN : 'fpMin', Z3_OP_FPA_MAX : 'fpMax', + Z3_OP_FPA_FMA : 'fpFMA', Z3_OP_FPA_SQRT : 'fpSqrt', Z3_OP_FPA_ROUND_TO_INTEGRAL : 'fpRoundToIntegral', + + Z3_OP_FPA_EQ : 'fpEQ', Z3_OP_FPA_LT : 'fpLT', Z3_OP_FPA_GT : 'fpGT', Z3_OP_FPA_LE : 'fpLEQ', + Z3_OP_FPA_GE : 'fpGEQ', + + Z3_OP_FPA_IS_NAN : 'fpIsNaN', Z3_OP_FPA_IS_INF : 'fpIsInf', Z3_OP_FPA_IS_ZERO : 'fpIsZero', + Z3_OP_FPA_IS_NORMAL : 'fpIsNormal', Z3_OP_FPA_IS_SUBNORMAL : 'fpIsSubnormal', + Z3_OP_FPA_IS_NEGATIVE : 'fpIsNegative', Z3_OP_FPA_IS_POSITIVE : 'fpIsPositive', + + Z3_OP_FPA_FP : 'fpFP', Z3_OP_FPA_TO_FP : 'fpToFP', Z3_OP_FPA_TO_FP_UNSIGNED: 'fpToFPUnsigned', + Z3_OP_FPA_TO_UBV : 'fpToUBV', Z3_OP_FPA_TO_SBV : 'fpToSBV', Z3_OP_FPA_TO_REAL: 'fpToReal', + Z3_OP_FPA_TO_IEEE_BV : 'fpToIEEEBV' + } + +_z3_op_to_fpa_pretty_str = { + Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN : 'RNE()', Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY : 'RNA()', + Z3_OP_FPA_RM_TOWARD_POSITIVE : 'RTP()', Z3_OP_FPA_RM_TOWARD_NEGATIVE : 'RTN()', + Z3_OP_FPA_RM_TOWARD_ZERO : 'RTZ()', + Z3_OP_FPA_PLUS_INF : '+oo', Z3_OP_FPA_MINUS_INF : '-oo', + Z3_OP_FPA_NAN : 'NaN', Z3_OP_FPA_PLUS_ZERO : '+0.0', Z3_OP_FPA_MINUS_ZERO : '-0.0', + + Z3_OP_FPA_ADD : '+', Z3_OP_FPA_SUB : '-', Z3_OP_FPA_NEG : '-', Z3_OP_FPA_MUL : '*', + Z3_OP_FPA_DIV : '/', Z3_OP_FPA_REM : '%', + Z3_OP_FPA_NEG: '-', + + Z3_OP_FPA_EQ : 'fpEQ', Z3_OP_FPA_LT : '<', Z3_OP_FPA_GT : '>', Z3_OP_FPA_LE : '<=', Z3_OP_FPA_GE : '>=' +} + +_z3_fpa_infix = [ + Z3_OP_FPA_ADD, Z3_OP_FPA_SUB, Z3_OP_FPA_MUL, Z3_OP_FPA_DIV, Z3_OP_FPA_REM, + Z3_OP_FPA_LT, Z3_OP_FPA_GT, Z3_OP_FPA_LE, Z3_OP_FPA_GE +] + def _is_assoc(k): return k == Z3_OP_BOR or k == Z3_OP_BXOR or k == Z3_OP_BAND or k == Z3_OP_ADD or k == Z3_OP_BADD or k == Z3_OP_MUL or k == Z3_OP_BMUL @@ -134,10 +183,14 @@ _infix_map = {} _unary_map = {} _infix_compact_map = {} +for (_k,_v) in _z3_op_to_fpa_normal_str.items(): + _z3_op_to_str[_k] = _v + for _k in _z3_infix: _infix_map[_k] = True for _k in _z3_unary: _unary_map[_k] = True + for _k in _z3_infix_compact: _infix_compact_map[_k] = True @@ -463,6 +516,7 @@ class Formatter: self.precision = 10 self.ellipses = to_format(_ellipses) self.max_visited = 10000 + self.fpa_pretty = False def pp_ellipses(self): return self.ellipses @@ -499,6 +553,8 @@ class Formatter: return seq1('Array', (self.pp_sort(s.domain()), self.pp_sort(s.range()))) elif isinstance(s, z3.BitVecSortRef): return seq1('BitVec', (to_format(s.size()), )) + elif isinstance(s, z3.FPSortRef): + return seq1('FPSort', (to_format(s.ebits()), to_format(s.sbits()))) else: return to_format(s.name()) @@ -520,6 +576,118 @@ class Formatter: def pp_bv(self, a): return to_format(a.as_string()) + def pp_fprm_value(self, a): + z3._z3_assert(z3.is_fprm_value(a), 'expected FPRMNumRef') + if self.fpa_pretty and _z3_op_to_fpa_pretty_str.has_key(a.decl().kind()): + return to_format(_z3_op_to_fpa_pretty_str.get(a.decl().kind())) + else: + return to_format(a.as_string()) + + def pp_fp_value(self, a): + z3._z3_assert(isinstance(a, z3.FPNumRef), 'type mismatch') + if not self.fpa_pretty: + if (a.isNaN()): + return to_format('NaN') + elif (a.isInf()): + if (a.isNegative()): + return to_format('-oo') + else: + return to_format('+oo') + elif (a.isZero()): + if (a.isNegative()): + return to_format('-zero') + else: + return to_format('+zero') + else: + z3._z3_assert(z3.is_fp_value(a), 'expecting FP num ast') + r = [] + sgn = c_long(0) + sgnb = Z3_fpa_get_numeral_sign(a.ctx_ref(), a.ast, byref(sgn)) + sig = Z3_fpa_get_numeral_significand_string(a.ctx_ref(), a.ast) + exp = Z3_fpa_get_numeral_exponent_string(a.ctx_ref(), a.ast) + r.append(to_format('FPVal(')) + if not sgnb and sgn: + r.append(to_format('-')) + r.append(to_format(sig)) + r.append(to_format('*(2**')) + r.append(to_format(exp)) + r.append(to_format(', ')) + r.append(to_format(a.sort())) + r.append(to_format('))')) + return compose(r) + else: + if (a.isNaN()): + return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_NAN]) + elif (a.isInf()): + if (a.isNegative()): + return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_FPA_MINUS_INF]) + else: + return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_FPA_PLUS_INF]) + elif (a.isZero()): + if (a.isNegative()): + return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_FPA_MINUS_ZERO]) + else: + return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_FPA_PLUS_ZERO]) + else: + z3._z3_assert(z3.is_fp_value(a), 'expecting FP num ast') + r = [] + sgn = c_long(0) + sgnb = Z3_fpa_get_numeral_sign(a.ctx_ref(), a.ast, byref(sgn)) + sig = Z3_fpa_get_numeral_significand_string(a.ctx_ref(), a.ast) + exp = Z3_fpa_get_numeral_exponent_string(a.ctx_ref(), a.ast) + if not sgnb and sgn != 0: + r.append(to_format('-')) + r.append(to_format(sig)) + if (exp != '0'): + r.append(to_format('*(2**')) + r.append(to_format(exp)) + r.append(to_format(')')) + return compose(r) + + + def pp_fp(self, a, d, xs): + z3._z3_assert(isinstance(a, z3.FPRef), "type mismatch") + k = a.decl().kind() + op = '?' + if self.fpa_pretty: + op = _z3_op_to_fpa_pretty_str.get(k, None) + if (op == None): + op = _z3_op_to_str.get(k, None) + + n = a.num_args() + + if self.fpa_pretty and self.is_infix(k) and n >= 3: + rm = a.arg(0) + if z3.is_fprm_value(rm) and z3._dflt_rm(a.ctx).eq(rm): + arg1 = to_format(self.pp_expr(a.arg(1), d+1, xs)) + arg2 = to_format(self.pp_expr(a.arg(2), d+1, xs)) + r = [] + r.append(arg1) + r.append(to_format(' ')) + r.append(to_format(op)) + r.append(to_format(' ')) + r.append(arg2) + return compose(r) + + if _z3_op_to_fpa_normal_str.has_key(k): + op = _z3_op_to_fpa_normal_str.get(k, None) + + r = [] + r.append(to_format(op)) + if not z3.is_const(a): + r.append(to_format('(')) + first = True + for c in a.children(): + if first: + first = False + else: + r.append(to_format(', ')) + r.append(self.pp_expr(c, d+1, xs)) + r.append(to_format(')')) + return compose(r) + else: + return to_format(a.as_string()) + def pp_prefix(self, a, d, xs): r = [] sz = 0 @@ -678,9 +846,15 @@ class Formatter: elif z3.is_rational_value(a): return self.pp_rational(a) elif z3.is_algebraic_value(a): - return self.pp_algebraic(a) + return self.pp_algebraic(a) elif z3.is_bv_value(a): return self.pp_bv(a) + elif z3.is_fprm_value(a): + return self.pp_fprm_value(a) + elif z3.is_fp_value(a): + return self.pp_fp_value(a) + elif z3.is_fp(a): + return self.pp_fp(a, d, xs) elif z3.is_const(a): return self.pp_const(a) else: @@ -939,6 +1113,12 @@ def set_pp_option(k, v): else: set_html_mode(False) return True + if k == 'fpa_pretty': + if v: + set_fpa_pretty(True) + else: + set_fpa_pretty(False) + return True val = getattr(_PP, k, None) if val != None: z3._z3_assert(type(v) == type(val), "Invalid pretty print option value") @@ -965,6 +1145,23 @@ def set_html_mode(flag=True): else: _Formatter = Formatter() +def set_fpa_pretty(flag=True): + global _Formatter + global _z3_op_to_str + _Formatter.fpa_pretty = flag + if flag: + for (_k,_v) in _z3_op_to_fpa_pretty_str.items(): + _z3_op_to_str[_k] = _v + for _k in _z3_fpa_infix: + _infix_map[_k] = True + else: + for (_k,_v) in _z3_op_to_fpa_normal_str.items(): + _z3_op_to_str[_k] = _v + for _k in _z3_fpa_infix: + _infix_map[_k] = False + + + def in_html_mode(): return isinstance(_Formatter, HTMLFormatter) From d4ecc3c1be6f3fe4ecd1e018581795cbcdd98573 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 12 Jan 2015 15:59:20 +0000 Subject: [PATCH 145/507] Disabled BV-SLS as default tactic in anticipation for integration with the unstable branch. Signed-off-by: Christoph M. Wintersteiger --- src/tactic/portfolio/default_tactic.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 53da9a159..5a5cbcf94 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -32,8 +32,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), - // cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), From 66abc1c65eae3cec95d362ae849e689ce6d2113a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 12 Jan 2015 17:03:27 +0000 Subject: [PATCH 146/507] Removed unnecessary file Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Properties/AssemblyInfo.cs | 38 ----------------------- 1 file changed, 38 deletions(-) delete mode 100644 src/api/dotnet/Properties/AssemblyInfo.cs diff --git a/src/api/dotnet/Properties/AssemblyInfo.cs b/src/api/dotnet/Properties/AssemblyInfo.cs deleted file mode 100644 index ee0e3f354..000000000 --- a/src/api/dotnet/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security.Permissions; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Z3 .NET Interface")] -[assembly: AssemblyDescription(".NET Interface to the Z3 Theorem Prover")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft Corporation")] -[assembly: AssemblyProduct("Z3")] -[assembly: AssemblyCopyright("Copyright © Microsoft Corporation 2006")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4853ed71-2078-40f4-8117-bc46646bce0e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("4.2.0.0")] -[assembly: AssemblyVersion("4.3.2.0")] -[assembly: AssemblyFileVersion("4.3.2.0")] From 40014d019ca8e656a3bc1e6c2966b716e597cc99 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 11 Feb 2014 17:44:59 +0000 Subject: [PATCH 147/507] sls tactic default --- src/tactic/portfolio/smt_strategic_solver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index ae79446e3..52b0a3c90 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -37,11 +37,13 @@ Notes: #include"horn_tactic.h" #include"smt_solver.h" +#include"sls_tactic.h" + tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") - return mk_qfbv_tactic(m, p); + return mk_qfbv_sls_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); else if (logic=="QF_LIA") From b002697e038554d0986fc974ed81bf2da0a62727 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 18 Feb 2014 14:01:47 +0000 Subject: [PATCH 148/507] some extensions/modifications. versions added. --- src/tactic/portfolio/default_tactic.cpp | 3 +- src/tactic/sls/sls_evaluator.h | 4 +- src/tactic/sls/sls_tactic.cpp | 146 ++++++++++++-- src/tactic/sls/sls_tracker.h | 249 +++++++++++++++++++++--- versions/z3-crsat-0.01.txt | 12 ++ versions/z3-gsat-0.01.txt | 10 + versions/z3-gsat-res-0.01.txt | 10 + versions/z3-wsat-0.01.txt | 12 ++ versions/z3-wsat-0.01b.txt | 12 ++ versions/z3-wsat-0.01c.txt | 12 ++ versions/z3-wsat-0.01d.txt | 11 ++ versions/z3-wsat-0.01e.txt | 11 ++ versions/z3-wsat-0.02.txt | 13 ++ versions/z3-wsat-res-0.01.txt | 13 ++ 14 files changed, 470 insertions(+), 48 deletions(-) create mode 100644 versions/z3-crsat-0.01.txt create mode 100644 versions/z3-gsat-0.01.txt create mode 100644 versions/z3-gsat-res-0.01.txt create mode 100644 versions/z3-wsat-0.01.txt create mode 100644 versions/z3-wsat-0.01b.txt create mode 100644 versions/z3-wsat-0.01c.txt create mode 100644 versions/z3-wsat-0.01d.txt create mode 100644 versions/z3-wsat-0.01e.txt create mode 100644 versions/z3-wsat-0.02.txt create mode 100644 versions/z3-wsat-res-0.01.txt diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 9ecc16ecf..b28b7bec0 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -28,10 +28,11 @@ Notes: #include"probe_arith.h" #include"quant_tactics.h" #include"qffpa_tactic.h" +#include"sls_tactic.h" tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 77ff50454..61305386e 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -584,8 +584,8 @@ public: run_update(cur_depth); } - void randomize_local(goal_ref const & g) { - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g); + void randomize_local(goal_ref const & g, unsigned int flip) { + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); // Randomize _all_ candidates: diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 6783d9621..c194af267 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -35,6 +35,17 @@ Notes: #include"sls_tactic.h" #include"nnf_tactic.h" +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 30 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 +#define _VNS_ 0 +#define _WEIGHT_DIST_ 3 +#define _WEIGHT_DIST_FACTOR_ 0.1 + #include"sls_params.hpp" #include"sls_evaluator.h" #include"sls_tracker.h" @@ -257,7 +268,7 @@ class sls_tactic : public tactic { // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g); + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; @@ -303,6 +314,82 @@ class sls_tactic : public tactic { m_mpz_manager.del(new_value); } + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -372,22 +459,29 @@ class sls_tactic : public tactic { unsigned plateau_cnt = 0; - while (plateau_cnt < m_plateau_limit) { - + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif do { checkpoint(); old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); - +#endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; for (unsigned i = 0; i < g->size(); i++) { @@ -400,9 +494,11 @@ class sls_tactic : public tactic { for (unsigned i = 0; i < g->size(); i++) tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << m_tracker.get_score(g->form(i)) << std::endl; ); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } else { + // Andreas: Why does randomizing not count as a move? (Now it does.) m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -441,6 +537,7 @@ class sls_tactic : public tactic { if (score >= 1.0) { // score could theoretically be imprecise. + // Andreas: Can it only be imprecise in one direction? bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -451,19 +548,30 @@ class sls_tactic : public tactic { } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ } while (score > old_score && res == l_undef); - - if (score != old_score) + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); plateau_cnt = 0; - else { + } else { + m_stats.m_moves++; plateau_cnt++; - if (plateau_cnt < m_plateau_limit) { + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); - m_evaluator.randomize_local(g); + m_evaluator.randomize_local(g, m_stats.m_moves); //mk_random_move(g); score = top_score(g); - } + //} } } @@ -484,7 +592,8 @@ class sls_tactic : public tactic { do { checkpoint(); - if ((m_stats.m_restarts % 100) == 0) + // Andreas: I think restarts are too impotant to ignore 99% of them are happening... + //if ((m_stats.m_restarts % 100) == 0) report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); res = search(g); @@ -492,9 +601,12 @@ class sls_tactic : public tactic { if (res == l_undef) m_tracker.randomize(); } - while (res != l_true && m_stats.m_restarts++ < m_max_restarts); + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - if (res == l_true) { + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -628,7 +740,13 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), +#if _CNF_ + // Andreas: We will probably never use this. CNF sucks. + mk_cnf_tactic(m, p)); +#else + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); +#endif } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 7fbafec60..1061bd90e 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -28,8 +28,8 @@ class sls_tracker { random_gen m_rng; unsigned m_random_bits; unsigned m_random_bits_cnt; - mpz m_zero, m_one, m_two; - + mpz m_zero, m_one, m_two; + struct value_score { value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0) { }; ~value_score() { if (m) m->del(value); } @@ -249,12 +249,46 @@ public: } } - void initialize(goal_ref const & g) { + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } + + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; + m_constants_occ.insert_if_not_there(e, t); + find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); + expr_fast_mark1 visited; + quick_for_each_expr(ffd_proc, visited, e); + } + + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); + // Andreas: Maybe not fully correct. +#if _FOCUS_ == 2 + initialize_recursive(proc, visited, e); +#endif for_each_expr(proc, visited, e); } @@ -262,6 +296,10 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); + // Andreas: Maybe not fully correct. +#if _FOCUS_ == 2 + initialize_recursive(e); +#endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -382,8 +420,6 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); } -#define _SCORE_AND_MIN - double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); @@ -400,30 +436,41 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - #ifdef _SCORE_AND_MIN - double min = 1.0; + // Andreas: Seems to have no effect. Probably it does not even occur. +#if _SCORE_AND_AVG_ + double sum = 0.0; + for (unsigned i = 0; i < a->get_num_args(); i++) + sum += get_score(args[i]); + res = sum / (double) a->get_num_args(); +#else + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; } res = min; - #else - double sum = 0.0; - for (unsigned i = 0; i < a->get_num_args(); i++) - sum += get_score(args[i]); - res = sum / (double) a->get_num_args(); - #endif +#endif } else if (m_manager.is_or(n)) { SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - double max = 0.0; + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. +#if _SCORE_OR_MUL_ + double inv = 1.0; + for (unsigned i = 0; i < a->get_num_args(); i++) { + double cur = get_score(args[i]); + inv *= (1.0 - get_score(args[i])); + } + res = 1.0 - inv; +#else + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur > max) max = cur; } res = max; +#endif } else if (m_manager.is_ite(n)) { SASSERT(!negated); @@ -468,7 +515,7 @@ public: } m_mpz_manager.machine_div(diff, m_two, diff); } - res = 1.0 - (hamming_distance / (double) bv_sz); + res = 1.0 - (hamming_distance / (double) bv_sz); #else rational r(diff); r /= m_powers(bv_sz); @@ -503,7 +550,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -564,7 +611,7 @@ public: TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -598,6 +645,20 @@ public: SASSERT(res >= 0.0 && res <= 1.0); +#if _WEIGHT_DIST_ + app * a = to_app(n); + family_id afid = a->get_family_id(); + if (afid == m_bv_util.get_family_id()) +#endif +#if _WEIGHT_DIST_ == 1 + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#elif _WEIGHT_DIST_ == 2 + res *= res; +#elif _WEIGHT_DIST_ == 3 + if (res < 1.0) res = 0.0; +#endif + + TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } @@ -647,7 +708,111 @@ public: NOT_IMPLEMENTED_YET(); } - ptr_vector & get_unsat_constants(goal_ref const & g) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + for (unsigned i = 0; i < sz; i++) { + expr * q = g->form(i); + if (m_mpz_manager.eq(get_value(q), m_one)) + continue; + ptr_vector const & this_decls = m_constants_occ.find(q); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + } + return m_temp_constants; + } + + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } + + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); + // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. + if (!q) + return m_temp_constants; + + ptr_vector const & this_decls = m_constants_occ.find(q); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); + if (!q) + return m_temp_constants; + + return go_deeper(q); + } + + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { @@ -655,19 +820,41 @@ public: } else { m_temp_constants.reset(); - for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); - if (m_mpz_manager.eq(get_value(q), m_one)) - continue; - ptr_vector const & this_decls = m_constants_occ.find(q); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } +#if _FOCUS_ == 1 +#if _BFS_ == 3 + unsigned int pos = 0; + double max = get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - return m_temp_constants; +#elif _BFS_ == 2 + unsigned int pos = 0; + double min = get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + } +#elif _BFS_ == 1 + unsigned int pos = flip % m_constants.size(); +#else + unsigned int pos = get_random_uint(16) % m_constants.size(); +#endif + return get_unsat_constants_walksat(g, sz, pos); +#elif _FOCUS_ == 2 +#if _BFS_ + unsigned int pos = flip % m_constants.size(); +#else + unsigned int pos = get_random_uint(16) % m_constants.size(); +#endif + return get_unsat_constants_crsat(g, sz, pos); +#else + return get_unsat_constants_gsat(g, sz); +#endif } } }; diff --git a/versions/z3-crsat-0.01.txt b/versions/z3-crsat-0.01.txt new file mode 100644 index 000000000..49e1a1525 --- /dev/null +++ b/versions/z3-crsat-0.01.txt @@ -0,0 +1,12 @@ +More focused (_FOCUS_ == 2) WalkSAT version. +Variables are chosen among candidates in only one unsatisfied bit-vector term. +Flip rate slightly slower; probably due to larger hash-table and recursive formula structure. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 3 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-gsat-0.01.txt b/versions/z3-gsat-0.01.txt new file mode 100644 index 000000000..eb806a67f --- /dev/null +++ b/versions/z3-gsat-0.01.txt @@ -0,0 +1,10 @@ +Basic GSAT version. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 0 +#define _FOCUS_ 0 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-gsat-res-0.01.txt b/versions/z3-gsat-res-0.01.txt new file mode 100644 index 000000000..6a211f2bc --- /dev/null +++ b/versions/z3-gsat-res-0.01.txt @@ -0,0 +1,10 @@ +Basic GSAT version corresponding to Christoph's original code. +Restarts after 100 plateaus. + +#define _CNF_ 0 +#define _BFS_ 0 +#define _FOCUS_ 0 +#define _RESTARTS_ 1 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt new file mode 100644 index 000000000..141193f76 --- /dev/null +++ b/versions/z3-wsat-0.01.txt @@ -0,0 +1,12 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Flip rate increased by roughly 10%-300%. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt new file mode 100644 index 000000000..2c0c0e7ad --- /dev/null +++ b/versions/z3-wsat-0.01b.txt @@ -0,0 +1,12 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Chooses a random top level assertion instead of using a BFS approach (_BFS_ == 0). +No restarts. + +#define _CNF_ 0 +#define _BFS_ 0 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01c.txt b/versions/z3-wsat-0.01c.txt new file mode 100644 index 000000000..223560e08 --- /dev/null +++ b/versions/z3-wsat-0.01c.txt @@ -0,0 +1,12 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +AND is scored by average; OR is scored by inverse multiplication. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 1 +#define _SCORE_OR_MUL_ 1 \ No newline at end of file diff --git a/versions/z3-wsat-0.01d.txt b/versions/z3-wsat-0.01d.txt new file mode 100644 index 000000000..072191370 --- /dev/null +++ b/versions/z3-wsat-0.01d.txt @@ -0,0 +1,11 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion with MINIMAL top_score. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 2 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01e.txt b/versions/z3-wsat-0.01e.txt new file mode 100644 index 000000000..b018c5e0d --- /dev/null +++ b/versions/z3-wsat-0.01e.txt @@ -0,0 +1,11 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion with MAXIMAL top_score. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 3 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.02.txt b/versions/z3-wsat-0.02.txt new file mode 100644 index 000000000..34dcb157c --- /dev/null +++ b/versions/z3-wsat-0.02.txt @@ -0,0 +1,13 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Score function reduced to 0/1. +No restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 +#define _WEIGHTED_DIST_ 1 \ No newline at end of file diff --git a/versions/z3-wsat-res-0.01.txt b/versions/z3-wsat-res-0.01.txt new file mode 100644 index 000000000..575180a59 --- /dev/null +++ b/versions/z3-wsat-res-0.01.txt @@ -0,0 +1,13 @@ +Basic WalkSAT version. +Variables are chosen among candidates in only ONE top level assertion. +Flip rate increased by roughly 10%-300% compared to GSAT. +Restarts after 100 plateaus. +Fps slightly decreased due to restarts. + +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 1 +#define _TIMELIMIT_ 300 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 \ No newline at end of file From e310ab5cd793d16e8a37e1a76023b5c477e2fb2e Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Sun, 9 Mar 2014 15:42:51 +0000 Subject: [PATCH 149/507] plenty of new stuff --- src/sat/tactic/sat_tactic.cpp | 4 +- src/tactic/portfolio/default_tactic.cpp | 1 + src/tactic/portfolio/smt_strategic_solver.cpp | 1 + src/tactic/sls/sls_evaluator.h | 323 ++++++++- src/tactic/sls/sls_tactic.cpp | 661 ++++++++++++++++-- src/tactic/sls/sls_tracker.h | 345 ++++++++- versions/z3-wsat-0.01.txt | 4 +- versions/z3-wsat-0.01b.txt | 4 +- 8 files changed, 1235 insertions(+), 108 deletions(-) diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index d48994861..717bf7007 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -66,7 +66,9 @@ class sat_tactic : public tactic { CASSERT("sat_solver", m_solver.check_invariant()); IF_VERBOSE(TACTIC_VERBOSITY_LVL, m_solver.display_status(verbose_stream());); TRACE("sat_dimacs", m_solver.display_dimacs(tout);); - + //m_solver.display_dimacs(std::cerr); + //exit(0); + lbool r = m_solver.check(); if (r == l_false) { g->assert_expr(m.mk_false(), 0, 0); diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index b28b7bec0..53da9a159 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -33,6 +33,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), + // cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index 52b0a3c90..f63b4fd8c 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -43,6 +43,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") + // return mk_qfbv_tactic(m, p); return mk_qfbv_sls_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 61305386e..eec9524a9 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -34,6 +34,9 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; +#if _EARLY_PRUNE_ + vector > m_traversal_stack_bool; +#endif public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -519,11 +522,15 @@ public: } } - void run_update(unsigned cur_depth) { + void run_serious_update(unsigned cur_depth) { // precondition: m_traversal_stack contains the entry point(s) expr_fast_mark1 visited; mpz new_value; +#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ + double new_score; +#endif + SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -533,8 +540,92 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - m_tracker.set_score(cur, m_tracker.score(cur)); +#if _REAL_RS_ || _REAL_PBFS_ + if (!m_tracker.has_uplinks(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } +#endif + +#if _EARLY_PRUNE_ + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); +#else +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif +#endif + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack[next_d].push_back(next); + visited.mark(next); + } + } + } + } + + cur_depth_exprs.reset(); + cur_depth--; + } + + m_mpz_manager.del(new_value); + } + + void run_update(unsigned cur_depth) { + // precondition: m_traversal_stack contains the entry point(s) + expr_fast_mark1 visited; + mpz new_value; + +#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ + double new_score; +#endif + + SASSERT(cur_depth < m_traversal_stack.size()); + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + (*this)(to_app(cur), new_value); + m_tracker.set_value(cur, new_value); +#if _EARLY_PRUNE_ + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); +#else +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -569,8 +660,11 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } - +#if _REAL_RS_ || _REAL_PBFS_ + run_serious_update(max_depth); +#else run_update(max_depth); +#endif } void update(func_decl * fd, const mpz & new_value) { @@ -584,6 +678,196 @@ public: run_update(cur_depth); } + void serious_update(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + m_traversal_stack[cur_depth].push_back(ep); + + run_serious_update(cur_depth); + } + +#if _EARLY_PRUNE_ + unsigned run_update_bool_prune(unsigned cur_depth) { + expr_fast_mark1 visited; + + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); + + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + prune_score = m_tracker.get_score_prune(cur); + m_tracker.set_score(cur, new_score); + + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; + + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + else + { + } + } + + cur_depth_exprs.reset(); + cur_depth--; + + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; + +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } + + return pot_benefits; + } + + void run_update_prune(unsigned max_depth) { + // precondition: m_traversal_stack contains the entry point(s) + expr_fast_mark1 visited; + mpz new_value; + + unsigned cur_depth = max_depth; + SASSERT(cur_depth < m_traversal_stack.size()); + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + (*this)(to_app(cur), new_value); + m_tracker.set_value(cur, new_value); + // should always have uplinks ... + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); + visited.mark(next); + } + } + } + } + + cur_depth_exprs.reset(); + cur_depth--; + } + + m_mpz_manager.del(new_value); + } + + unsigned update_prune(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + + if (m_traversal_stack_bool.size() <= cur_depth) + m_traversal_stack_bool.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); + } +#endif + + void randomize_local(expr * e, unsigned int flip) { + ptr_vector & unsat_constants = m_tracker.get_constants(e); + + // Randomize _one_ candidate: + unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); + func_decl * fd = unsat_constants[r]; +#if _PERC_CHANGE_ + sort * srt = fd->get_range(); + mpz temp; + + if (m_manager.is_bool(srt)) + m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); + + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } +#else + mpz temp = m_tracker.get_random(fd->get_range()); +#endif + update(fd, temp); + m_mpz_manager.del(temp); + } + void randomize_local(goal_ref const & g, unsigned int flip) { ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); @@ -603,8 +887,37 @@ public: // Randomize _one_ candidate: unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); func_decl * fd = unsat_constants[r]; - mpz temp = m_tracker.get_random(fd->get_range()); - update(fd, temp); +#if _PERC_CHANGE_ + sort * srt = fd->get_range(); + mpz temp; + + if (m_manager.is_bool(srt)) + m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); + + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } +#else + mpz temp = m_tracker.get_random(fd->get_range()); +#endif + +#if _REAL_RS_ || _REAL_PBFS_ + serious_update(fd, temp); +#else + update(fd, temp); +#endif m_mpz_manager.del(temp); TRACE("sls", /*tout << "Randomization candidates: "; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index c194af267..a08588a51 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -35,16 +35,102 @@ Notes: #include"sls_tactic.h" #include"nnf_tactic.h" -#define _CNF_ 0 -#define _BFS_ 1 +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom #define _FOCUS_ 1 + +// do we use restarts? +// 0 = no, otherwise the value defines the maximum number of moves #define _RESTARTS_ 0 -#define _TIMELIMIT_ 30 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? #define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? #define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained #define _VNS_ 0 -#define _WEIGHT_DIST_ 3 -#define _WEIGHT_DIST_FACTOR_ 0.1 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 0 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.25 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 0 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 0.01 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +#define _PROBABILISTIC_UCT_ 0 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 1 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 1 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 1 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 1 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) + InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) + InvalidConfiguration; +#endif + #include"sls_params.hpp" #include"sls_evaluator.h" @@ -57,12 +143,17 @@ class sls_tactic : public tactic { stopwatch m_stopwatch; unsigned m_full_evals; unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + stats() : m_restarts(0), m_full_evals(0), m_incr_evals(0), m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -92,7 +183,9 @@ class sls_tactic : public tactic { unsigned m_max_restarts; unsigned m_plateau_limit; - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : m_manager(m), @@ -174,13 +267,20 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - top_sum += m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + return top_sum / (double) sz; #endif } @@ -191,22 +291,54 @@ class sls_tactic : public tactic { return top_score(g); } - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else return top_score(g); +#endif } + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; + } +#endif + + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { - + #ifdef Z3DEBUG mpz old_value; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else double r = incremental_score(g, fd, temp); - +#endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl; ); @@ -214,6 +346,22 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); #endif +// if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // same as what_if, but only applied to the score of a specific atom, not the total score + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -224,7 +372,35 @@ class sls_tactic : public tactic { return false; } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + + } + + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + } + + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); + } + + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -261,59 +437,73 @@ class sls_tactic : public tactic { void mk_random_move(goal_ref const & g) { unsigned rnd_mv = 0; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + if (m_stats.m_moves > 10000) + rnd_mv = 0; ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; - unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(fd->get_range()); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + mpz new_value; - m_evaluator.update(fd, new_value); + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; - m_mpz_manager.del(new_value); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } + + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -359,6 +549,7 @@ class sls_tactic : public tactic { SASSERT(check == score); } + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else @@ -390,9 +581,13 @@ class sls_tactic : public tactic { return new_score; } + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif unsigned bv_sz; double new_score = score; @@ -403,8 +598,12 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // first try to flip every bit - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { - // What would happen if we flipped bit #i ? +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -414,7 +613,8 @@ class sls_tactic : public tactic { } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -426,16 +626,99 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } - +#endif // try inverting mk_inv(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif } // reset to what it was before double check = incremental_score(g, fd, old_value); - SASSERT(check == score); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; + } + + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -443,7 +726,150 @@ class sls_tactic : public tactic { return new_score; } - lbool search(goal_ref const & g) { + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + + m_old_values.reset(); + + return 0; + } + + // what_if version needed in the context of 2nd intensification try, combining local and global score + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // find_best_move version needed in the context of 2nd intensification try + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) + { + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; + } + + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; + } + + // main search loop + lbool search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -463,16 +889,48 @@ class sls_tactic : public tactic { #if _RESTARTS_ while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { + if (m_stats.m_moves == 5590) checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif old_score = score; new_const = (unsigned)-1; ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -525,9 +983,17 @@ class sls_tactic : public tactic { case MV_INC: m_stats.m_incs++; break; case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - score = incremental_score(g, fd, new_value); +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif TRACE("sls", tout << "Score distribution:"; for (unsigned i = 0; i < g->size(); i++) @@ -535,9 +1001,10 @@ class sls_tactic : public tactic { tout << " TOP: " << score << std::endl; ); } - if (score >= 1.0) { + if (score >= 0.99999) { +// if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: Can it only be imprecise in one direction? + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -568,10 +1035,26 @@ class sls_tactic : public tactic { // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else m_evaluator.randomize_local(g, m_stats.m_moves); - //mk_random_move(g); +#endif + //mk_random_move(g); score = top_score(g); - //} + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } } } @@ -587,6 +1070,37 @@ class sls_tactic : public tactic { return; } + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif m_tracker.initialize(g); lbool res = l_undef; @@ -740,13 +1254,8 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), -#if _CNF_ - // Andreas: We will probably never use this. CNF sucks. - mk_cnf_tactic(m, p)); -#else // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); -#endif } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 1061bd90e..b26912e5c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -28,21 +28,32 @@ class sls_tracker { random_gen m_rng; unsigned m_random_bits; unsigned m_random_bits_cnt; - mpz m_zero, m_one, m_two; + mpz m_zero, m_one, m_two; struct value_score { - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0) { }; +#if _EARLY_PRUNE_ + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; +#else + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; +#endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; +#if _EARLY_PRUNE_ + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; +#endif unsigned distance; // max distance from any root + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; + touched = other.touched; return *this; } }; @@ -60,6 +71,20 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; +#if _UCT_ + unsigned m_touched; +#endif +#if _REAL_RS_ || _REAL_PBFS_ + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; +#endif +#if _CACHE_TOP_SCORE_ + double m_top_sum; +#endif +#if _WEIGHT_DIST_ == 4 + double m_weight_dist_factor; +#endif public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -79,6 +104,26 @@ public: m_mpz_manager.del(m_two); } +#if _WEIGHT_DIST_ == 4 + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } +#endif + +#if _CACHE_TOP_SCORE_ + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } + + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } + + inline double get_top_sum() { + return m_top_sum; + } +#endif + inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); m_mpz_manager.set(m_scores.find(n).value, r); @@ -123,6 +168,28 @@ public: return get_score(ep); } +#if _EARLY_PRUNE_ + inline void set_score_prune(expr * n, double score) { + SASSERT(m_scores.contains(n)); + m_scores.find(n).score_prune = score; + } + + inline double & get_score_prune(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).score_prune; + } + + inline unsigned has_pos_occ(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).has_pos_occ; + } + + inline unsigned has_neg_occ(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).has_neg_occ; + } +#endif + inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).distance; @@ -297,7 +364,7 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 +#if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); #endif ptr_vector t; @@ -310,8 +377,57 @@ public: calculate_expr_distances(g); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); + +#if _REAL_RS_ || _REAL_PBFS_ + m_list_false = new expr*[sz]; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + break_assertion(g->form(i)); +#endif + +#if _EARLY_PRUNE_ + for (unsigned i = 0; i < sz; i++) + setup_occs(g->form(i)); +#endif + +#if _UCT_ + m_touched = 1; +#endif } +#if _REAL_RS_ || _REAL_PBFS_ + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } +// printf("Going in %d\n", m_where_false.size()); + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } + + void break_assertion(expr * e) + { + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } +#endif + void show_model(std::ostream & out) { unsigned sz = get_num_constants(); for (unsigned i = 0; i < sz; i++) { @@ -420,10 +536,45 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); } +#if _EARLY_PRUNE_ + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } + else + NOT_IMPLEMENTED_YET(); + } +#endif + double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -488,7 +639,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -648,6 +799,7 @@ public: #if _WEIGHT_DIST_ app * a = to_app(n); family_id afid = a->get_family_id(); + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 @@ -656,13 +808,14 @@ public: res *= res; #elif _WEIGHT_DIST_ == 3 if (res < 1.0) res = 0.0; +#elif _WEIGHT_DIST_ == 4 + if (res < 1.0) res *= m_weight_dist_factor; #endif - TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -708,6 +861,44 @@ public: NOT_IMPLEMENTED_YET(); } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } + + ptr_vector & get_constants(expr * e) { + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz = this_decls.size(); + for (unsigned i = 0; i < sz; i++) { + func_decl * fd = this_decls[i]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); @@ -743,7 +934,6 @@ public: // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { @@ -754,6 +944,19 @@ public: return m_temp_constants; } + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz = this_decls.size(); + for (unsigned j = 0; j < sz; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + ptr_vector & go_deeper(expr * e) { if (m_manager.is_bool(e)) { if (m_manager.is_and(e)) { @@ -812,44 +1015,138 @@ public: return go_deeper(q); } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 -#if _BFS_ == 3 - unsigned int pos = 0; - double max = get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { +#if _UCT_ + unsigned pos = -1; + value_score vscore; +#if _PROBABILISTIC_UCT_ + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + } +#endif + if (pos == static_cast(-1)) + return m_temp_constants; + +#if _UCT_ == 1 + m_scores.find(g->form(pos)).touched++; + m_touched++; +#elif _UCT_ == 2 + m_scores.find(g->form(pos)).touched = flip; +#endif + expr * e = g->form(pos); + +#elif _BFS_ == 3 + unsigned int pos = -1; + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); double q = get_score(e); if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = 0; - double min = get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { + unsigned int pos = -1; + double min = 2.0; + for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); double q = get_score(e); if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - unsigned int pos = flip % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); +#elif _UNIFORM_RANDOM_ + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); +#elif _REAL_RS_ + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[get_random_uint(16) % sz]; +#elif _REAL_PBFS_ + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - unsigned int pos = get_random_uint(16) % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(g, sz, pos); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - unsigned int pos = flip % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - unsigned int pos = get_random_uint(16) % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif return get_unsat_constants_crsat(g, sz, pos); #else diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt index 141193f76..fec38518d 100644 --- a/versions/z3-wsat-0.01.txt +++ b/versions/z3-wsat-0.01.txt @@ -9,4 +9,6 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file +#define _SCORE_OR_MUL_ 0 + +BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt index 2c0c0e7ad..8bcf2ffeb 100644 --- a/versions/z3-wsat-0.01b.txt +++ b/versions/z3-wsat-0.01b.txt @@ -9,4 +9,6 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file +#define _SCORE_OR_MUL_ 0 + +BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file From e33e637ad8b08528593f685f29f0dfec2015ce42 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 09:40:01 +0000 Subject: [PATCH 150/507] removed tabs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_evaluator.h | 268 ++++++------- src/tactic/sls/sls_tactic.cpp | 572 ++++++++++++++-------------- src/tactic/sls/sls_tracker.h | 672 ++++++++++++++++----------------- 3 files changed, 756 insertions(+), 756 deletions(-) diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index eec9524a9..cdb08038f 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -528,7 +528,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -542,33 +542,33 @@ public: m_tracker.set_value(cur, new_value); #if _REAL_RS_ || _REAL_PBFS_ - if (!m_tracker.has_uplinks(cur)) - { - if (m_mpz_manager.eq(new_value,m_one)) - m_tracker.make_assertion(cur); - else - m_tracker.break_assertion(cur); - } + if (!m_tracker.has_uplinks(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } #endif #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -596,7 +596,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -609,23 +609,23 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -661,7 +661,7 @@ public: if (cur_depth > max_depth) max_depth = cur_depth; } #if _REAL_RS_ || _REAL_PBFS_ - run_serious_update(max_depth); + run_serious_update(max_depth); #else run_update(max_depth); #endif @@ -693,27 +693,27 @@ public: unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { expr * cur = cur_depth_exprs[i]; - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - prune_score = m_tracker.get_score_prune(cur); + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); - if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -722,54 +722,54 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); + m_traversal_stack_bool[next_d].push_back(next); visited.mark(next); } } } - else - { - } - } + else + { + } + } - cur_depth_exprs.reset(); + cur_depth_exprs.reset(); cur_depth--; - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } - return pot_benefits; + return pot_benefits; } void run_update_prune(unsigned max_depth) { @@ -777,7 +777,7 @@ public: expr_fast_mark1 visited; mpz new_value; - unsigned cur_depth = max_depth; + unsigned cur_depth = max_depth; SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -787,7 +787,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // should always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -795,10 +795,10 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - if (m_manager.is_bool(next)) - m_traversal_stack_bool[max_depth].push_back(next); - else - m_traversal_stack[next_d].push_back(next); + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); visited.mark(next); } } @@ -817,23 +817,23 @@ public: expr * ep = m_tracker.get_entry_point(fd); unsigned cur_depth = m_tracker.get_distance(ep); - if (m_traversal_stack_bool.size() <= cur_depth) + if (m_traversal_stack_bool.size() <= cur_depth) m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune(cur_depth); + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); } #endif - void randomize_local(expr * e, unsigned int flip) { + void randomize_local(expr * e, unsigned int flip) { ptr_vector & unsat_constants = m_tracker.get_constants(e); // Randomize _one_ candidate: @@ -841,30 +841,30 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif - update(fd, temp); + update(fd, temp); m_mpz_manager.del(temp); } @@ -889,34 +889,34 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif #if _REAL_RS_ || _REAL_PBFS_ - serious_update(fd, temp); + serious_update(fd, temp); #else - update(fd, temp); + update(fd, temp); #endif m_mpz_manager.del(temp); diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index a08588a51..553acc35a 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -125,10 +125,10 @@ Notes: #if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) - InvalidConfiguration; + InvalidConfiguration; #endif #if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; + InvalidConfiguration; #endif @@ -150,10 +150,10 @@ class sls_tactic : public tactic { m_full_evals(0), m_incr_evals(0), m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -183,8 +183,8 @@ class sls_tactic : public tactic { unsigned m_max_restarts; unsigned m_plateau_limit; - ptr_vector m_old_values; - + ptr_vector m_old_values; + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : @@ -267,18 +267,18 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); #if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); + m_tracker.set_top_sum(top_sum); #endif return top_sum / (double) sz; @@ -292,20 +292,20 @@ class sls_tactic : public tactic { } double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif } double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif @@ -314,18 +314,18 @@ class sls_tactic : public tactic { #if _EARLY_PRUNE_ double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) + if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(g); + return top_score(g); #endif - else - return 0.0; + else + return 0.0; } #endif - // checks whether the score outcome of a given move is better than the previous score + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { @@ -357,11 +357,11 @@ class sls_tactic : public tactic { return false; } - // same as what_if, but only applied to the score of a specific atom, not the total score + // same as what_if, but only applied to the score of a specific atom, not the total score bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -378,29 +378,29 @@ class sls_tactic : public tactic { m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); - } + } - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { mpz temp, mask, mask2; m_mpz_manager.mul(old_value, m_two, temp); m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); } void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { m_mpz_manager.div(old_value, m_two, result); } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -437,73 +437,73 @@ class sls_tactic : public tactic { void mk_random_move(goal_ref const & g) { unsigned rnd_mv = 0; - if (m_stats.m_moves > 10000) - rnd_mv = 0; + if (m_stats.m_moves > 10000) + rnd_mv = 0; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; + mpz new_value; - sort * srt = fd->get_range(); + sort * srt = fd->get_range(); if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { #if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + mt = MV_FLIP; #endif - unsigned bit = 0; + unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } - // will use VNS to ignore some possible moves and increase the flips per second + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -514,7 +514,7 @@ class sls_tactic : public tactic { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -536,12 +536,12 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } } // reset to what it was before @@ -549,12 +549,12 @@ class sls_tactic : public tactic { SASSERT(check == score); } - // we can either check the condition once in the beginning or check it repeatedly after every bit + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) #endif for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { func_decl * fd = to_evaluate[i]; @@ -563,30 +563,30 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } // reset to what it was before double check = incremental_score(g, fd, old_value); SASSERT(check == score); } - m_mpz_manager.del(old_value); + m_mpz_manager.del(old_value); m_mpz_manager.del(temp); return new_score; } - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; + mpz temp2; #endif unsigned bv_sz; double new_score = score; @@ -599,11 +599,11 @@ class sls_tactic : public tactic { // first try to flip every bit #if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { #else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { #endif - // What would happen if we flipped bit #i ? + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -614,7 +614,7 @@ class sls_tactic : public tactic { if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { #if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -660,7 +660,7 @@ class sls_tactic : public tactic { // reset to what it was before double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching + // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -669,17 +669,17 @@ class sls_tactic : public tactic { #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif - return new_score; + return new_score; } - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -718,7 +718,7 @@ class sls_tactic : public tactic { } // reset to what it was before - m_evaluator.update(fd, old_value); + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -726,37 +726,37 @@ class sls_tactic : public tactic { return new_score; } - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); #if _BFS_ - unsigned pos = m_stats.m_moves % sz; + unsigned pos = m_stats.m_moves % sz; #else - unsigned pos = m_tracker.get_random_uint(16) % sz; + unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); } else { m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -767,35 +767,35 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); } - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - m_old_values.reset(); + m_old_values.reset(); - return 0; - } + return 0; + } - // what_if version needed in the context of 2nd intensification try, combining local and global score + // what_if version needed in the context of 2nd intensification try, combining local and global score bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, double & best_score, mpz & best_value, unsigned i) { double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); + double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - if (new_score >= best_score) { + if (new_score >= best_score) { best_score = new_score; m_mpz_manager.set(best_value, temp); return true; @@ -804,17 +804,17 @@ class sls_tactic : public tactic { return false; } - // find_best_move version needed in the context of 2nd intensification try + // find_best_move version needed in the context of 2nd intensification try double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; + { + mpz old_value, temp; double best_score = 0; sort * srt = fd->get_range(); unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); what_if(g, e, fd, temp, best_score, best_value, i); } @@ -822,54 +822,54 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); m_mpz_manager.del(temp); - return best_score; + return best_score; } - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); #if _BFS_ - unsigned new_const = m_stats.m_moves % sz; + unsigned new_const = m_stats.m_moves % sz; #else - unsigned new_const = m_tracker.get_random_uint(16) % sz; + unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { new_score = find_best_move_local(g, q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - return 0; - } + return 0; + } - // main search loop - lbool search(goal_ref const & g) { + // main search loop + lbool search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -885,52 +885,52 @@ class sls_tactic : public tactic { unsigned plateau_cnt = 0; - // Andreas: Why do we only allow so few plateaus? + // Andreas: Why do we only allow so few plateaus? #if _RESTARTS_ - while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { - if (m_stats.m_moves == 5590) + if (m_stats.m_moves == 5590) checkpoint(); #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif #if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { #if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #elif _TYPE_RSTEP_ == 2 - mk_random_move(g); + mk_random_move(g); #endif score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } #endif old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -952,11 +952,11 @@ class sls_tactic : public tactic { for (unsigned i = 0; i < g->size(); i++) tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? + // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } else { - // Andreas: Why does randomizing not count as a move? (Now it does.) + // Andreas: Why does randomizing not count as a move? (Now it does.) m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -984,15 +984,15 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(g, fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; @@ -1004,7 +1004,7 @@ class sls_tactic : public tactic { if (score >= 0.99999) { // if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -1015,43 +1015,43 @@ class sls_tactic : public tactic { } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ } while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); + report_tactic_progress("This should not happen I guess.", plateau_cnt); plateau_cnt = 0; - } else { - m_stats.m_moves++; + } else { + m_stats.m_moves++; plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); #if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); + handle_plateau(g, score); + //handle_plateau(g); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #endif - //mk_random_move(g); + //mk_random_move(g); score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } @@ -1070,43 +1070,43 @@ class sls_tactic : public tactic { return; } - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif m_tracker.initialize(g); lbool res = l_undef; do { checkpoint(); - // Andreas: I think restarts are too impotant to ignore 99% of them are happening... + // Andreas: I think restarts are too impotant to ignore 99% of them are happening... //if ((m_stats.m_restarts % 100) == 0) report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); @@ -1115,12 +1115,12 @@ class sls_tactic : public tactic { if (res == l_undef) m_tracker.randomize(); } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); + report_tactic_progress("Number of flips:", m_stats.m_moves); if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -1254,7 +1254,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index b26912e5c..006bbb888 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -29,31 +29,31 @@ class sls_tracker { unsigned m_random_bits; unsigned m_random_bits_cnt; mpz m_zero, m_one, m_two; - + struct value_score { #if _EARLY_PRUNE_ - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; #else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; #endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; #if _EARLY_PRUNE_ - double score_prune; - unsigned has_pos_occ; - unsigned has_neg_occ; + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; #endif unsigned distance; // max distance from any root - unsigned touched; + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; - touched = other.touched; + touched = other.touched; return *this; } }; @@ -72,18 +72,18 @@ private: ptr_vector m_temp_constants; occ_type m_constants_occ; #if _UCT_ - unsigned m_touched; + unsigned m_touched; #endif #if _REAL_RS_ || _REAL_PBFS_ - ptr_vector m_unsat_expr; - obj_map m_where_false; - expr** m_list_false; + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; #endif #if _CACHE_TOP_SCORE_ - double m_top_sum; + double m_top_sum; #endif #if _WEIGHT_DIST_ == 4 - double m_weight_dist_factor; + double m_weight_dist_factor; #endif public: @@ -105,23 +105,23 @@ public: } #if _WEIGHT_DIST_ == 4 - inline void set_weight_dist_factor(double val) { - m_weight_dist_factor = val; - } + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } #endif #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { - m_top_sum += add - sub; - } + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } - inline void set_top_sum(double new_score) { - m_top_sum = new_score; - } + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } - inline double get_top_sum() { - return m_top_sum; - } + inline double get_top_sum() { + return m_top_sum; + } #endif inline void set_value(expr * n, const mpz & r) { @@ -174,20 +174,20 @@ public: m_scores.find(n).score_prune = score; } - inline double & get_score_prune(expr * n) { + inline double & get_score_prune(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).score_prune; } - inline unsigned has_pos_occ(expr * n) { + inline unsigned has_pos_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_pos_occ; - } + } - inline unsigned has_neg_occ(expr * n) { + inline unsigned has_neg_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; - } + } #endif inline unsigned get_distance(expr * n) { @@ -316,45 +316,45 @@ public: } } - void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(proc, visited, q); - } - } - for_each_expr(proc, visited, e); - } + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } - void initialize_recursive(expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(q); - } - } - ptr_vector t; + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + } - void initialize(goal_ref const & g) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 - initialize_recursive(proc, visited, e); + initialize_recursive(proc, visited, e); #endif for_each_expr(proc, visited, e); } @@ -363,9 +363,9 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ - initialize_recursive(e); + initialize_recursive(e); #endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); @@ -379,53 +379,53 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); #if _REAL_RS_ || _REAL_PBFS_ - m_list_false = new expr*[sz]; + m_list_false = new expr*[sz]; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - break_assertion(g->form(i)); + if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + break_assertion(g->form(i)); #endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = 1; + m_touched = 1; #endif } #if _REAL_RS_ || _REAL_PBFS_ - void make_assertion(expr * e) - { - if (m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) - { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - } -// printf("Going in %d\n", m_where_false.size()); - } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); - } + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } +// printf("Going in %d\n", m_where_false.size()); + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } - void break_assertion(expr * e) - { - if (!m_where_false.contains(e)) - { - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); - } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); - } + void break_assertion(expr * e) + { + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } #endif void show_model(std::ostream & out) { @@ -537,35 +537,35 @@ public: } #if _EARLY_PRUNE_ - void setup_occs(expr * n, bool negated = false) { - if (m_manager.is_bool(n)) - { - if (m_manager.is_and(n) || m_manager.is_or(n)) - { - SASSERT(!negated); - app * a = to_app(n); - expr * const * args = a->get_args(); - for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); - } - else if (m_manager.is_not(n)) - { - SASSERT(!negated); - app * a = to_app(n); - SASSERT(a->get_num_args() == 1); - expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); - setup_occs(child, true); - } - else - { - if (negated) - m_scores.find(n).has_neg_occ = 1; - else - m_scores.find(n).has_pos_occ = 1; - } - } + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } else NOT_IMPLEMENTED_YET(); } @@ -574,7 +574,7 @@ public: double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -587,14 +587,14 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. + // Andreas: Seems to have no effect. Probably it does not even occur. #if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) sum += get_score(args[i]); res = sum / (double) a->get_num_args(); #else - double min = 1.0; + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; @@ -606,16 +606,16 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. #if _SCORE_OR_MUL_ - double inv = 1.0; + double inv = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); inv *= (1.0 - get_score(args[i])); } res = 1.0 - inv; #else - double max = 0.0; + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur > max) max = cur; @@ -639,7 +639,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -701,7 +701,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -762,7 +762,7 @@ public: TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -797,25 +797,25 @@ public: SASSERT(res >= 0.0 && res <= 1.0); #if _WEIGHT_DIST_ - app * a = to_app(n); - family_id afid = a->get_family_id(); + app * a = to_app(n); + family_id afid = a->get_family_id(); - if (afid == m_bv_util.get_family_id()) + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; #elif _WEIGHT_DIST_ == 2 - res *= res; + res *= res; #elif _WEIGHT_DIST_ == 3 - if (res < 1.0) res = 0.0; + if (res < 1.0) res = 0.0; #elif _WEIGHT_DIST_ == 4 - if (res < 1.0) res *= m_weight_dist_factor; + if (res < 1.0) res *= m_weight_dist_factor; #endif TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -861,34 +861,34 @@ public: NOT_IMPLEMENTED_YET(); } - expr * get_unsat_expression(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - } - } - return e; - } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } - ptr_vector & get_constants(expr * e) { + ptr_vector & get_constants(expr * e) { ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned i = 0; i < sz; i++) { @@ -897,9 +897,9 @@ public: m_temp_constants.push_back(fd); } return m_temp_constants; - } + } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) @@ -913,244 +913,244 @@ public: } } return m_temp_constants; - } + } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { - for (unsigned i = pos; i < sz; i++) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; + return q; } - return 0; - } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. - if (!q) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); + if (!q) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned j = 0; j < sz; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & go_deeper(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - } - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); if (!q) - return m_temp_constants; + return m_temp_constants; - return go_deeper(q); - } + return go_deeper(q); + } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) - return m_temp_constants; - else - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 #if _UCT_ - unsigned pos = -1; - value_score vscore; + unsigned pos = -1; + value_score vscore; #if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - for (unsigned i = start_index; i < sz; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } #else - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - vscore = m_scores.find(e); + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); #elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } #endif - if (pos == static_cast(-1)) - return m_temp_constants; + if (pos == static_cast(-1)) + return m_temp_constants; #if _UCT_ == 1 - m_scores.find(g->form(pos)).touched++; - m_touched++; + m_scores.find(g->form(pos)).touched++; + m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(g->form(pos)).touched = flip; #endif - expr * e = g->form(pos); + expr * e = g->form(pos); #elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; + unsigned int pos = -1; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; + unsigned int pos = -1; + double min = 2.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); #elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[get_random_uint(16) % sz]; + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[get_random_uint(16) % sz]; #elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[flip % sz]; + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(e); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif - return get_unsat_constants_crsat(g, sz, pos); + return get_unsat_constants_crsat(g, sz, pos); #else - return get_unsat_constants_gsat(g, sz); + return get_unsat_constants_gsat(g, sz); #endif } } From aa6f8a4b8a1cb68933b420f053b487971dfb2d28 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Wed, 19 Mar 2014 11:49:44 +0000 Subject: [PATCH 151/507] Current version for relocating. --- src/tactic/sls/sls_evaluator.h | 92 +++++----- src/tactic/sls/sls_tactic.cpp | 295 +++++++++++++++++++++++++++--- src/tactic/sls/sls_tracker.h | 315 ++++++++++++++++++++++++++++++--- 3 files changed, 600 insertions(+), 102 deletions(-) diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index cdb08038f..696d7664a 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -78,7 +78,11 @@ public: case OP_AND: { m_mpz_manager.set(result, m_one); for (unsigned i = 0; i < n_args; i++) +#if _DIRTY_UP_ + if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) && !m_tracker.is_top_expr(args[i])) { +#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { +#endif m_mpz_manager.set(result, m_zero); break; } @@ -86,7 +90,11 @@ public: } case OP_OR: { for (unsigned i = 0; i < n_args; i++) +#if _DIRTY_UP_ + if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) || m_tracker.is_top_expr(args[i])) { +#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { +#endif m_mpz_manager.set(result, m_one); break; } @@ -94,9 +102,16 @@ public: } case OP_NOT: { SASSERT(n_args == 1); +#if _DIRTY_UP_ + if (m_tracker.is_top_expr(args[0])) + m_mpz_manager.set(result, m_zero); + else + m_mpz_manager.set(result, (m_mpz_manager.is_zero(m_tracker.get_value(args[0]))) ? m_one : m_zero); +#else const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); - m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); + m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); +#endif break; } case OP_EQ: { @@ -542,7 +557,8 @@ public: m_tracker.set_value(cur, new_value); #if _REAL_RS_ || _REAL_PBFS_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) { if (m_mpz_manager.eq(new_value,m_one)) m_tracker.make_assertion(cur); @@ -554,7 +570,8 @@ public: #if _EARLY_PRUNE_ new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); @@ -562,13 +579,14 @@ public: #else #if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -611,7 +629,8 @@ public: #if _EARLY_PRUNE_ new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); @@ -619,13 +638,14 @@ public: #else #if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -695,7 +715,7 @@ public: double prune_score, new_score; unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); + SASSERT(cur_depth < m_traversal_stack_bool.size()); ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; @@ -704,7 +724,8 @@ public: new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif prune_score = m_tracker.get_score_prune(cur); @@ -745,7 +766,8 @@ public: #if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else @@ -833,44 +855,7 @@ public: } #endif - void randomize_local(expr * e, unsigned int flip) { - ptr_vector & unsat_constants = m_tracker.get_constants(e); - - // Randomize _one_ candidate: - unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); - func_decl * fd = unsat_constants[r]; -#if _PERC_CHANGE_ - sort * srt = fd->get_range(); - mpz temp; - - if (m_manager.is_bool(srt)) - m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); - - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } -#else - mpz temp = m_tracker.get_random(fd->get_range()); -#endif - update(fd, temp); - m_mpz_manager.del(temp); - } - - void randomize_local(goal_ref const & g, unsigned int flip) { - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); - + void randomize_local(ptr_vector & unsat_constants) { // Randomize _all_ candidates: //// bool did_something = false; @@ -927,6 +912,15 @@ public: tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + + } + + void randomize_local(expr * e) { + randomize_local(m_tracker.get_constants(e)); + } + + void randomize_local(goal_ref const & g, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(g, flip)); } }; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 553acc35a..ada0ec359 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -34,6 +34,8 @@ Notes: #include"propagate_values_tactic.h" #include"sls_tactic.h" #include"nnf_tactic.h" +#include"luby.h" +#include "ctx_simplify_tactic.h" // which unsatisfied assertion is selected? only works with _FOCUS_ > 0 // 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score @@ -43,9 +45,23 @@ Notes: // 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom #define _FOCUS_ 1 +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 0 + // do we use restarts? -// 0 = no, otherwise the value defines the maximum number of moves -#define _RESTARTS_ 0 +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 3.0 // timelimit #define _TIMELIMIT_ 3600 @@ -66,38 +82,58 @@ Notes: // 2 = yes, by squaring it // 3 = yes, by setting it to zero // 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 0 +#define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 #define _WEIGHT_DIST_FACTOR_ 0.25 +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + // do we use intensification steps in local minima? if so, how many? #define _INTENSIFICATION_ 0 #define _INTENSIFICATION_TRIES_ 0 +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + // do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 0 +#define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 0.01 +#define _UCT_CONSTANT_ 10.0 // is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score #define _PROBABILISTIC_UCT_ 0 +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 1 + // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 // shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 1 +#define _USE_MUL2DIV2_ 0 // shall we try multiplication by 3? -#define _USE_MUL3_ 1 +#define _USE_MUL3_ 0 // shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 1 +#define _USE_UNARY_MINUS_ 0 // is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 1 +#define _UNIFORM_RANDOM_ 0 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 @@ -124,13 +160,21 @@ Notes: #define _CACHE_TOP_SCORE_ 1 -#if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) InvalidConfiguration; #endif #if (_PROBABILISTIC_UCT_ && !_UCT_) InvalidConfiguration; #endif - +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) + InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) + InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) + InvalidConfiguration; +#endif #include"sls_params.hpp" #include"sls_evaluator.h" @@ -180,6 +224,7 @@ class sls_tactic : public tactic { sls_tracker m_tracker; sls_evaluator m_evaluator; + unsigned m_restart_limit; unsigned m_max_restarts; unsigned m_plateau_limit; @@ -208,6 +253,41 @@ class sls_tactic : public tactic { m_mpz_manager.del(m_two); } + double get_restart_armin(unsigned cnt_restarts) + { + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow(_RESTART_CONST_ARMIN_, inner_id + 1); + } + + inline unsigned check_restart(unsigned curr_value) + { + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; + } + ast_manager & m() const { return m_manager; } void set_cancel(bool f) { m_cancel = f; } @@ -435,12 +515,10 @@ class sls_tactic : public tactic { NOT_IMPLEMENTED_YET(); } - void mk_random_move(goal_ref const & g) { + void mk_random_move(ptr_vector & unsat_constants) + { unsigned rnd_mv = 0; - if (m_stats.m_moves > 10000) - rnd_mv = 0; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; @@ -503,6 +581,10 @@ class sls_tactic : public tactic { m_mpz_manager.del(new_value); } + void mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); + } + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { @@ -857,7 +939,7 @@ class sls_tactic : public tactic { m_stats.m_flips++; global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); + local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -875,6 +957,130 @@ class sls_tactic : public tactic { unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + // main search loop + lbool search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; score = rescore(g); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; @@ -887,12 +1093,12 @@ class sls_tactic : public tactic { // Andreas: Why do we only allow so few plateaus? #if _RESTARTS_ - while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { - if (m_stats.m_moves == 5590) checkpoint(); #if _WEIGHT_DIST_ == 4 @@ -1072,7 +1278,11 @@ class sls_tactic : public tactic { verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; @@ -1081,9 +1291,14 @@ class sls_tactic : public tactic { verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; verbose_stream() << "_UCT_ " << _UCT_ << std::endl; verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; @@ -1099,21 +1314,30 @@ class sls_tactic : public tactic { verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); #endif m_tracker.initialize(g); lbool res = l_undef; + m_restart_limit = _RESTART_LIMIT_; + do { checkpoint(); - // Andreas: I think restarts are too impotant to ignore 99% of them are happening... - //if ((m_stats.m_restarts % 100) == 0) - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); res = search(g); if (res == l_undef) - m_tracker.randomize(); + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); @@ -1121,6 +1345,13 @@ class sls_tactic : public tactic { if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -1183,12 +1414,17 @@ public: } virtual void cleanup() { - imp * d = alloc(imp, m, m_params, m_stats); + imp * d = m_imp; #pragma omp critical (tactic_cancel) { - std::swap(d, m_imp); + d = m_imp; } dealloc(d); + d = alloc(imp, m, m_params, m_stats); + #pragma omp critical (tactic_cancel) + { + m_imp = d; + } } virtual void collect_statistics(statistics & st) const { @@ -1246,6 +1482,9 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // conservative gaussian elimination. gaussian_p.set_uint("gaussian_max_occs", 2); + params_ref ctx_p; + ctx_p.set_uint("max_depth", 32); + ctx_p.set_uint("max_steps", 5000000); return and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), using_params(mk_solve_eqs_tactic(m), gaussian_p), @@ -1254,6 +1493,10 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), + // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? + //mk_ctx_simplify_tactic(m, ctx_p), + // Andreas: This one at least eliminates top level duplicates ... + mk_simplify_tactic(m), // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 006bbb888..0aca1f59c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -65,6 +65,7 @@ private: typedef obj_map scores_type; typedef obj_map > uplinks_type; typedef obj_map > occ_type; + obj_hashtable m_top_expr; scores_type m_scores; uplinks_type m_uplinks; entry_point_type m_entry_points; @@ -75,15 +76,15 @@ private: unsigned m_touched; #endif #if _REAL_RS_ || _REAL_PBFS_ - ptr_vector m_unsat_expr; - obj_map m_where_false; - expr** m_list_false; + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; #endif #if _CACHE_TOP_SCORE_ - double m_top_sum; + double m_top_sum; #endif -#if _WEIGHT_DIST_ == 4 - double m_weight_dist_factor; +#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ + double m_weight_dist_factor; #endif public: @@ -104,7 +105,7 @@ public: m_mpz_manager.del(m_two); } -#if _WEIGHT_DIST_ == 4 +#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ inline void set_weight_dist_factor(double val) { m_weight_dist_factor = val; } @@ -182,12 +183,12 @@ public: inline unsigned has_pos_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_pos_occ; - } + } inline unsigned has_neg_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; - } + } #endif inline unsigned get_distance(expr * n) { @@ -213,11 +214,62 @@ public: return m_uplinks.contains(n); } + inline bool is_top_expr(expr * n) { + return m_top_expr.contains(n); + } + inline ptr_vector & get_uplinks(expr * n) { SASSERT(m_uplinks.contains(n)); return m_uplinks.find(n); } +#if _REAL_RS_ || _REAL_PBFS_ + void debug_real(goal_ref const & g, unsigned flip) + { + unsigned count = 0; + for (unsigned i = 0; i < g->size(); i++) + { + expr * e = g->form(i); + if (m_mpz_manager.eq(get_value(e),m_one) && m_where_false.contains(e)) + { + printf("iteration %d: ", flip); + printf("form %d is sat but in unsat list at position %d of %d\n", i, m_where_false.find(e), m_where_false.size()); + exit(4); + } + + if (m_mpz_manager.eq(get_value(e),m_zero) && !m_where_false.contains(e)) + { + printf("iteration %d: ", flip); + printf("form %d is unsat but not in unsat list\n", i); + exit(4); + } + + if (m_mpz_manager.eq(get_value(e),m_zero) && m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + expr * q = m_list_false[pos]; + if (q != e) + { + printf("iteration %d: ", flip); + printf("form %d is supposed to be at pos %d in unsat list but something else was there\n", i, pos); + exit(4); + } + } + + if (m_mpz_manager.eq(get_value(e),m_zero)) + count++; + } + + // should be true now that duplicate assertions are removed + if (count != m_where_false.size()) + { + printf("iteration %d: ", flip); + printf("%d are unsat but list is of size %d\n", count, m_where_false.size()); + exit(4); + } + } +#endif + void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -327,7 +379,7 @@ public: } } for_each_expr(proc, visited, e); - } + } void initialize_recursive(expr * e) { if (m_manager.is_and(e) || m_manager.is_or(e)) { @@ -344,7 +396,7 @@ public: find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + } void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); @@ -352,6 +404,10 @@ public: unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); + if (!m_top_expr.contains(e)) + m_top_expr.insert(e); + else + printf("this is already in ...\n"); // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 initialize_recursive(proc, visited, e); @@ -380,18 +436,20 @@ public: #if _REAL_RS_ || _REAL_PBFS_ m_list_false = new expr*[sz]; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - break_assertion(g->form(i)); + //for (unsigned i = 0; i < sz; i++) + //{ + // if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + // break_assertion(g->form(i)); + //} #endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; #endif } @@ -407,8 +465,12 @@ public: expr * q = m_list_false[m_where_false.size()]; m_list_false[pos] = q; m_where_false.find(q) = pos; + //printf("Moving %d from %d to %d\n", q, m_where_false.size(), pos); } -// printf("Going in %d\n", m_where_false.size()); + //else + //printf("Erasing %d from %d to %d\n", e, pos); +// m_list_false[m_where_false.size()] = 0; +// printf("Going in %d\n", m_where_false.size()); } //if (m_unsat_expr.contains(e)) //m_unsat_expr.erase(e); @@ -416,12 +478,14 @@ public: void break_assertion(expr * e) { + //printf("I'm broken... that's still fine.\n"); if (!m_where_false.contains(e)) { + //printf("This however is not so cool...\n"); unsigned pos = m_where_false.size(); m_list_false[pos] = e; m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); + // printf("Going in %d\n", m_where_false.size()); } //if (!m_unsat_expr.contains(e)) //m_unsat_expr.push_back(e); @@ -522,7 +586,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize() { + void randomize(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -534,6 +598,28 @@ public: } TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); + +#if _UCT_RESET_ + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; +#endif + } + + void reset(goal_ref const & g) { + TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); + + for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { + mpz temp = m_zero; + set_value(it->m_value, temp); + m_mpz_manager.del(temp); + } + +#if _UCT_RESET_ + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; +#endif } #if _EARLY_PRUNE_ @@ -591,12 +677,20 @@ public: #if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) +#if _DIRTY_UP_ + sum += is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else sum += get_score(args[i]); +#endif res = sum / (double) a->get_num_args(); #else double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif if (cur < min) min = cur; } res = min; @@ -610,14 +704,22 @@ public: #if _SCORE_OR_MUL_ double inv = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif inv *= (1.0 - get_score(args[i])); } res = 1.0 - inv; #else double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif if (cur > max) max = cur; } res = max; @@ -772,7 +874,11 @@ public: expr * child = a->get_arg(0); if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. NOT_IMPLEMENTED_YET(); +#if _DIRTY_UP_ + res = is_top_expr(child) ? 0.0 : score_bool(child, true); +#else res = score_bool(child, true); +#endif } else if (m_manager.is_distinct(n)) { app * a = to_app(n); @@ -803,7 +909,11 @@ public: if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 +#if _WEIGHT_TOGGLE_ + if (res < 1.0) res *= m_weight_dist_factor; +#else if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#endif #elif _WEIGHT_DIST_ == 2 res *= res; #elif _WEIGHT_DIST_ == 3 @@ -900,6 +1010,10 @@ public: } ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + if (sz == 1) + return get_constants(); + m_temp_constants.reset(); + for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) @@ -945,7 +1059,7 @@ public: } ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e) + if (!e || m_temp_constants.size()) return m_temp_constants; ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); @@ -1033,32 +1147,43 @@ public: #if _PROBABILISTIC_UCT_ double sum_score = 0.0; unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) { expr * e = g->form(i); vscore = m_scores.find(e); - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { sum_score += q; if (rand() <= (q * RAND_MAX / sum_score) + 1) pos = i; - } + } } for (unsigned i = 0; i < start_index; i++) { expr * e = g->form(i); vscore = m_scores.find(e); - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { sum_score += q; if (rand() <= (q * RAND_MAX / sum_score) + 1) pos = i; - } + } } #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); +// for (unsigned i = 0; i < m_where_false.size(); i++) { +// expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); @@ -1078,6 +1203,7 @@ public: m_scores.find(g->form(pos)).touched = flip; #endif expr * e = g->form(pos); +// expr * e = m_list_false[pos]; #elif _BFS_ == 3 unsigned int pos = -1; @@ -1109,7 +1235,7 @@ public: #elif _UNIFORM_RANDOM_ unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return m_temp_constants; expr * e = g->form(pos); @@ -1120,8 +1246,7 @@ public: sz = m_where_false.size(); if (sz == 0) return m_temp_constants; - else - expr * e = m_list_false[get_random_uint(16) % sz]; + expr * e = m_list_false[get_random_uint(16) % sz]; #elif _REAL_PBFS_ //unsigned pos = m_false_list[flip % m_cnt_false]; //expr * e = get_unsat_assertion(g, sz, pos); @@ -1154,6 +1279,142 @@ public: #endif } } + + + expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); + + if (sz == 1) + return g->form(0); + + m_temp_constants.reset(); +#if _FOCUS_ == 1 +#if _UCT_ + unsigned pos = -1; + value_score vscore; +#if _PROBABILISTIC_UCT_ + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score + _UCT_EPS_; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score + _UCT_EPS_; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); +// for (unsigned i = 0; i < m_where_false.size(); i++) { +// expr * e = m_list_false[i]; + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + } +#endif + if (pos == static_cast(-1)) + return 0; + +#if _UCT_ == 1 + m_scores.find(g->form(pos)).touched++; + m_touched++; +#elif _UCT_ == 2 + m_scores.find(g->form(pos)).touched = flip; +#endif +// return m_list_false[pos]; + return g->form(pos); + +#elif _BFS_ == 3 + unsigned int pos = -1; + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _BFS_ == 2 + unsigned int pos = -1; + double min = 2.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + } + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _BFS_ == 1 + unsigned int pos = flip % sz; + return get_unsat_assertion(g, sz, pos); +#elif _UNIFORM_RANDOM_ + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _REAL_RS_ + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return 0; + return m_list_false[get_random_uint(16) % sz]; +#elif _REAL_PBFS_ + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return0; + else + return m_list_false[flip % sz]; +#else + unsigned int pos = get_random_uint(16) % sz; + return get_unsat_assertion(g, sz, pos); +#endif + return g->form(pos); +#elif _FOCUS_ == 2 +#if _BFS_ + unsigned int pos = flip % sz; +#else + unsigned int pos = get_random_uint(16) % sz; +#endif + return get_unsat_constants_crsat(g, sz, pos); +#endif + } }; #endif \ No newline at end of file From b1eeb9adf409da3188f0380a0b7280e5d6a428eb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 17:04:38 +0000 Subject: [PATCH 152/507] SLS refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 158 +++ src/tactic/sls/sls_engine.cpp | 1160 +++++++++++++++++ src/tactic/sls/sls_engine.h | 159 +++ src/tactic/sls/sls_evaluator.h | 3 + src/tactic/sls/sls_tactic.cpp | 1397 +-------------------- src/tactic/sls/sls_tracker.h | 10 +- 6 files changed, 1520 insertions(+), 1367 deletions(-) create mode 100644 src/tactic/sls/sls_compilation_settings.h create mode 100644 src/tactic/sls/sls_engine.cpp create mode 100644 src/tactic/sls/sls_engine.h diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h new file mode 100644 index 000000000..aea4787b0 --- /dev/null +++ b/src/tactic/sls/sls_compilation_settings.h @@ -0,0 +1,158 @@ +/*++ +Copyright (c) 2014 Microsoft Corporation + +Module Name: + + sls_compilation_constants.h + +Abstract: + + Stochastic Local Search (SLS) compilation constants + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + + This file should go away completely once we have evaluated all options. + +--*/ +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom +#define _FOCUS_ 1 + +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 0 + +// do we use restarts? +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 3.0 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? +#define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? +#define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained +#define _VNS_ 0 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 1 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.25 + +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 1 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 10.0 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score +#define _PROBABILISTIC_UCT_ 0 + +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 1 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 0 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 0 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 0 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 0 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) +InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) +InvalidConfiguration; +#endif +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) +InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) +InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) +InvalidConfiguration; +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp new file mode 100644 index 000000000..92471aad8 --- /dev/null +++ b/src/tactic/sls/sls_engine.cpp @@ -0,0 +1,1160 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + sls_engine.cpp + +Abstract: + + A Stochastic Local Search (SLS) engine + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + +--*/ +#include + +#include"map.h" +#include"ast_smt2_pp.h" +#include"ast_pp.h" +#include"var_subst.h" +#include"model_pp.h" +#include"tactic.h" +#include"cooperate.h" +#include"luby.h" + +#include"sls_compilation_settings.h" +#include"sls_params.hpp" +#include"sls_engine.h" + + +sls_engine::sls_engine(ast_manager & m, params_ref const & p) : + m_manager(m), + m_powers(m_mpz_manager), + m_zero(m_mpz_manager.mk_z(0)), + m_one(m_mpz_manager.mk_z(1)), + m_two(m_mpz_manager.mk_z(2)), + m_cancel(false), + m_bv_util(m), + m_tracker(m, m_bv_util, m_mpz_manager, m_powers), + m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) +{ + updt_params(p); +} + +sls_engine::~sls_engine() { + m_mpz_manager.del(m_zero); + m_mpz_manager.del(m_one); + m_mpz_manager.del(m_two); +} + +double sls_engine::get_restart_armin(unsigned cnt_restarts) +{ + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); +} + +void sls_engine::updt_params(params_ref const & _p) { + sls_params p(_p); + m_produce_models = _p.get_bool("model", false); + m_max_restarts = p.restarts(); + m_tracker.set_random_seed(p.random_seed()); + m_plateau_limit = p.plateau_limit(); +} + +void sls_engine::checkpoint() { + if (m_cancel) + throw tactic_exception(TACTIC_CANCELED_MSG); + cooperate("sls"); +} + +bool sls_engine::full_eval(goal_ref const & g, model & mdl) { + bool res = true; + + unsigned sz = g->size(); + for (unsigned i = 0; i < sz && res; i++) { + checkpoint(); + expr_ref o(m_manager); + + if (!mdl.eval(g->form(i), o, true)) + exit(ERR_INTERNAL_FATAL); + + res = m_manager.is_true(o.get()); + } + + TRACE("sls", tout << "Evaluation: " << res << std::endl;); + + return res; +} + +double sls_engine::top_score(goal_ref const & g) { +#if 0 + double min = m_tracker.get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + double q = m_tracker.get_score(g->form(i)); + if (q < min) min = q; + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " MIN: " << min << std::endl;); + return min; +#else + double top_sum = 0.0; + unsigned sz = g->size(); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); + } + + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " AVG: " << top_sum / (double)sz << std::endl;); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + + return top_sum / (double)sz; +#endif +} + +double sls_engine::rescore(goal_ref const & g) { + m_evaluator.update_all(); + m_stats.m_full_evals++; + return top_score(g); +} + +double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif +} + +double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif +} + +double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { +#if _EARLY_PRUNE_ + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; +#else + NOT_IMPLEMENTED_YET(); +#endif +} + +// checks whether the score outcome of a given move is better than the previous score +bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + +#ifdef Z3DEBUG + mpz old_value; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); +#endif + +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else + double r = incremental_score(g, fd, temp); +#endif +#ifdef Z3DEBUG + TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << + " --> " << r << std::endl;); + + m_mpz_manager.del(old_value); +#endif + + // if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +// same as what_if, but only applied to the score of a specific atom, not the total score +bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); + if (r >= best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +void sls_engine::mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + +} + +// Andreas: do we really need all those temporary mpzs? +void sls_engine::mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); +} + +void sls_engine::mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); +} + +void sls_engine::mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + unsigned shift; + m_mpz_manager.add(old_value, m_one, incremented); + if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) + m_mpz_manager.set(incremented, m_zero); +} + +void sls_engine::mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { + if (m_mpz_manager.is_zero(old_value)) { + m_mpz_manager.set(decremented, m_powers(bv_sz)); + m_mpz_manager.dec(decremented); + } + else + m_mpz_manager.sub(old_value, m_one, decremented); +} + +void sls_engine::mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { + m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); +} + +void sls_engine::mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { + m_mpz_manager.set(flipped, m_zero); + + if (m_bv_util.is_bv_sort(s)) { + mpz mask; + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(old_value, mask, flipped); + m_mpz_manager.del(mask); + } + else if (m_manager.is_bool(s)) + m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); + else + NOT_IMPLEMENTED_YET(); +} + +void sls_engine::mk_random_move(ptr_vector & unsat_constants) +{ + unsigned rnd_mv = 0; + unsigned ucc = unsat_constants.size(); + unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; + func_decl * fd = unsat_constants[rc]; + + mpz new_value; + + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type)rnd_mv; + + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; + + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout);); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); +} + +void sls_engine::mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); +} + +// will use VNS to ignore some possible moves and increase the flips per second +double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + // we can either check the condition once in the beginning or check it repeatedly after every bit +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif + unsigned bv_sz; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } +#endif + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; +} + +// same as find_best_move but only considers the score of the current expression instead of the overall score +double sls_engine::find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + +// first try of intensification ... does not seem to be efficient +bool sls_engine::handle_plateau(goal_ref const & g) +{ + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back(&m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } + else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], *m_old_values[i]); + + m_old_values.reset(); + + return 0; +} + +// what_if version needed in the context of 2nd intensification try, combining local and global score +bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +// find_best_move version needed in the context of 2nd intensification try +double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) +{ + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; +} + +// second try to use intensification ... also not very effective +bool sls_engine::handle_plateau(goal_ref const & g, double old_score) +{ + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; +} + +// main search loop +lbool sls_engine::search(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + +bailout: + m_mpz_manager.del(new_value); + + return res; +} + +// main search loop +lbool sls_engine::search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + + score = rescore(g); + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + + unsigned plateau_cnt = 0; + + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { +#endif + do { + checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif + old_score = score; + new_const = (unsigned)-1; + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } + TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; + for (unsigned i = 0; i < to_evaluate.size(); i++) + tout << to_evaluate[i]->get_name() << std::endl;); + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + if (new_const == static_cast(-1)) { + TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + }); + + TRACE("sls_max", m_tracker.show_model(tout); + tout << "Scores: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl;); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? + score = old_score; + } + else { + // Andreas: Why does randomizing not count as a move? (Now it does.) + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; + switch (move) { + case MV_FLIP: + tout << "Flip"; + if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; + break; + case MV_INC: + tout << "+1"; + break; + case MV_DEC: + tout << "-1"; + break; + case MV_INV: + tout << "NEG"; + break; + }; + tout << ") ; new score = " << std::setprecision(32) << score << std::endl;); + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + + TRACE("sls", tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + } + + if (score >= 0.99999) { + // if (score >= 1.0) { + // score could theoretically be imprecise. + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ + } while (score > old_score && res == l_undef); + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); + plateau_cnt = 0; + } + else { + m_stats.m_moves++; + plateau_cnt++; + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { + TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else + m_evaluator.randomize_local(g, m_stats.m_moves); +#endif + //mk_random_move(g); + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } + } + +bailout: + m_mpz_manager.del(new_value); + + return res; +} + +void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { + if (g->inconsistent()) { + mc = 0; + return; + } + + m_produce_models = g->models_enabled(); + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout);); + } + g->reset(); + } + else + mc = 0; +} + +unsigned sls_engine::check_restart(unsigned curr_value) +{ + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; +} \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h new file mode 100644 index 000000000..878354c6d --- /dev/null +++ b/src/tactic/sls/sls_engine.h @@ -0,0 +1,159 @@ +/*++ +Copyright (c) 2014 Microsoft Corporation + +Module Name: + + sls_engine.h + +Abstract: + + A Stochastic Local Search (SLS) engine + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + +--*/ +#ifndef _SLS_ENGINE_H_ +#define _SLS_ENGINE_H_ + +#include"stopwatch.h" +#include"lbool.h" +#include"model_converter.h" + +#include"sls_compilation_settings.h" +#include"sls_tracker.h" +#include"sls_evaluator.h" + +class sls_engine { +public: + class stats { + public: + unsigned m_restarts; + stopwatch m_stopwatch; + unsigned m_full_evals; + unsigned m_incr_evals; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + + stats() : + m_restarts(0), + m_full_evals(0), + m_incr_evals(0), + m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), + m_flips(0), + m_incs(0), + m_decs(0), + m_invs(0) { + m_stopwatch.reset(); + m_stopwatch.start(); + } + void reset() { + m_full_evals = m_flips = m_incr_evals = 0; + m_stopwatch.reset(); + m_stopwatch.start(); + } + }; + +protected: + ast_manager & m_manager; + stats m_stats; + unsynch_mpz_manager m_mpz_manager; + powers m_powers; + mpz m_zero, m_one, m_two; + bool m_produce_models; + volatile bool m_cancel; + bv_util m_bv_util; + sls_tracker m_tracker; + sls_evaluator m_evaluator; + + unsigned m_restart_limit; + unsigned m_max_restarts; + unsigned m_plateau_limit; + + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; + +public: + sls_engine(ast_manager & m, params_ref const & p); + ~sls_engine(); + + ast_manager & m() const { return m_manager; } + + void set_cancel(bool f) { m_cancel = f; } + void cancel() { set_cancel(true); } + void reset_cancel() { set_cancel(false); } + + void updt_params(params_ref const & _p); + + stats const & get_stats(void) { return m_stats; } + void reset_statistics(void) { m_stats.reset(); } + + bool full_eval(goal_ref const & g, model & mdl); + + + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result); + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); + void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); + void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + + + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); + + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); + + + lbool search(goal_ref const & g); + + void operator()(goal_ref const & g, model_converter_ref & mc); + +protected: + void checkpoint(); + lbool search_old(goal_ref const & g); + double get_restart_armin(unsigned cnt_restarts); + + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + + double top_score(goal_ref const & g); + double rescore(goal_ref const & g); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); +#endif + + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + void mk_random_move(ptr_vector & unsat_constants); + void mk_random_move(goal_ref const & g); + + bool handle_plateau(goal_ref const & g); + bool handle_plateau(goal_ref const & g, double old_score); + + inline unsigned check_restart(unsigned curr_value); +}; + +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 696d7664a..9daf93c32 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -20,6 +20,9 @@ Notes: #ifndef _SLS_EVALUATOR_H_ #define _SLS_EVALUATOR_H_ +#include"model_evaluator.h" + +#include"sls_compilation_settings.h" #include"sls_powers.h" #include"sls_tracker.h" diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index ada0ec359..0f157d3a6 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,1364 +16,31 @@ Author: Notes: --*/ -#include -#include"map.h" #include"nnf.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"model_pp.h" -#include"model_evaluator.h" #include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"stopwatch.h" #include"propagate_values_tactic.h" -#include"sls_tactic.h" +#include"ctx_simplify_tactic.h" +#include"elim_uncnstr_tactic.h" #include"nnf_tactic.h" -#include"luby.h" -#include "ctx_simplify_tactic.h" - -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 0 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick clause when randomizing in a plateau or use the current one? -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 - -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 - -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? -#define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 - -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) - InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) - InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) - InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) - InvalidConfiguration; -#endif +#include"stopwatch.h" +#include"sls_tactic.h" #include"sls_params.hpp" -#include"sls_evaluator.h" -#include"sls_tracker.h" +#include"sls_engine.h" -class sls_tactic : public tactic { - class stats { - public: - unsigned m_restarts; - stopwatch m_stopwatch; - unsigned m_full_evals; - unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; - - stats() : - m_restarts(0), - m_full_evals(0), - m_incr_evals(0), - m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), - m_flips(0), - m_incs(0), - m_decs(0), - m_invs(0) { - m_stopwatch.reset(); - m_stopwatch.start(); - } - void reset() { - m_full_evals = m_flips = m_incr_evals = 0; - m_stopwatch.reset(); - m_stopwatch.start(); - } - }; - - struct imp { - ast_manager & m_manager; - stats & m_stats; - unsynch_mpz_manager m_mpz_manager; - powers m_powers; - mpz m_zero, m_one, m_two; - bool m_produce_models; - volatile bool m_cancel; - bv_util m_bv_util; - sls_tracker m_tracker; - sls_evaluator m_evaluator; - - unsigned m_restart_limit; - unsigned m_max_restarts; - unsigned m_plateau_limit; - - ptr_vector m_old_values; - - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; - - imp(ast_manager & m, params_ref const & p, stats & s) : - m_manager(m), - m_stats(s), - m_powers(m_mpz_manager), - m_zero(m_mpz_manager.mk_z(0)), - m_one(m_mpz_manager.mk_z(1)), - m_two(m_mpz_manager.mk_z(2)), - m_cancel(false), - m_bv_util(m), - m_tracker(m, m_bv_util, m_mpz_manager, m_powers), - m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) - { - updt_params(p); - } - - ~imp() { - m_mpz_manager.del(m_zero); - m_mpz_manager.del(m_one); - m_mpz_manager.del(m_two); - } - - double get_restart_armin(unsigned cnt_restarts) - { - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow(_RESTART_CONST_ARMIN_, inner_id + 1); - } - - inline unsigned check_restart(unsigned curr_value) - { - if (curr_value > m_restart_limit) - { -#if _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); -#elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 1 - if (m_stats.m_restarts & 1) - m_restart_limit += _RESTART_LIMIT_; - else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; -#else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif - return 0; - } - return 1; - } - - ast_manager & m() const { return m_manager; } - - void set_cancel(bool f) { m_cancel = f; } - void cancel() { set_cancel(true); } - void reset_cancel() { set_cancel(false); } - - static void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); - } - - void updt_params(params_ref const & _p) { - sls_params p(_p); - m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); - m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); - } - - void checkpoint() { - if (m_cancel) - throw tactic_exception(TACTIC_CANCELED_MSG); - cooperate("sls"); - } - - bool full_eval(goal_ref const & g, model & mdl) { - bool res = true; - - unsigned sz = g->size(); - for (unsigned i = 0; i < sz && res; i++) { - checkpoint(); - expr_ref o(m_manager); - - if (!mdl.eval(g->form(i), o, true)) - exit(ERR_INTERNAL_FATAL); - - res = m_manager.is_true(o.get()); - } - - TRACE("sls", tout << "Evaluation: " << res << std::endl;); - - return res; - } - - double top_score(goal_ref const & g) { - #if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl; ); - return min; - #else - double top_sum = 0.0; - unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - top_sum += m_tracker.get_score(e); - } - - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " AVG: " << top_sum / (double) sz << std::endl; ); - -#if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); -#endif - - return top_sum / (double) sz; - #endif - } - - double rescore(goal_ref const & g) { - m_evaluator.update_all(); - m_stats.m_full_evals++; - return top_score(g); - } - - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; - } -#endif - - // checks whether the score outcome of a given move is better than the previous score - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - #ifdef Z3DEBUG - mpz old_value; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - #endif - -#if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); -#else - double r = incremental_score(g, fd, temp); -#endif - #ifdef Z3DEBUG - TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << - " --> " << r << std::endl; ); - - m_mpz_manager.del(old_value); - #endif - -// if (r >= best_score) { - if (r > best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // same as what_if, but only applied to the score of a specific atom, not the total score - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.add(old_value, add_value, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - - } - - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - } - - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); - } - - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { - unsigned shift; - m_mpz_manager.add(old_value, m_one, incremented); - if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) - m_mpz_manager.set(incremented, m_zero); - } - - void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { - if (m_mpz_manager.is_zero(old_value)) { - m_mpz_manager.set(decremented, m_powers(bv_sz)); - m_mpz_manager.dec(decremented); - } - else - m_mpz_manager.sub(old_value, m_one, decremented); - } - - void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { - m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); - } - - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { - m_mpz_manager.set(flipped, m_zero); - - if (m_bv_util.is_bv_sort(s)) { - mpz mask; - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(old_value, mask, flipped); - m_mpz_manager.del(mask); - } - else if (m_manager.is_bool(s)) - m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); - else - NOT_IMPLEMENTED_YET(); - } - - void mk_random_move(ptr_vector & unsat_constants) - { - unsigned rnd_mv = 0; - - unsigned ucc = unsat_constants.size(); - unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; - func_decl * fd = unsat_constants[rc]; - - mpz new_value; - - sort * srt = fd->get_range(); - if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { -#if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; -#else - mt = MV_FLIP; -#endif - unsigned bit = 0; - - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } - - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } - - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } - - void mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); - } - - // will use VNS to ignore some possible moves and increase the flips per second - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif - unsigned bv_sz; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { -#else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { -#endif - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } -#endif - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - return new_score; - } - - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - - m_old_values.reset(); - - return 0; - } - - // what_if version needed in the context of 2nd intensification try, combining local and global score - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // find_best_move version needed in the context of 2nd intensification try - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; - } - - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; - } - - // main search loop - lbool search(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - unsigned plateau_cnt = 0; - - score = rescore(g); - unsigned sz = g->size(); -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - checkpoint(); - m_stats.m_moves++; - -#if _REAL_RS_ || _REAL_PBFS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } - continue; -#endif - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - old_score = score; - new_const = (unsigned)-1; - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - - if (new_const == static_cast(-1)) { - score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); - else -#endif -#if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); -#else - m_evaluator.randomize_local(to_evaluate); -#endif -#endif - -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } else { - func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - // main search loop - lbool search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0 ; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl; ); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - } - - if (score >= 0.99999) { -// if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } - while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - void operator()(goal_ref const & g, model_converter_ref & mc) { - if (g->inconsistent()) { - mc = 0; - return; - } - - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout); ); - } - g->reset(); - } - else - mc = 0; - } - }; - +class sls_tactic : public tactic { ast_manager & m; params_ref m_params; - imp * m_imp; - stats m_stats; + sls_engine * m_engine; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_imp = alloc(imp, m, p, m_stats); + m_engine = alloc(sls_engine, m, p); } virtual tactic * translate(ast_manager & m) { @@ -1381,16 +48,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_imp); + dealloc(m_engine); } virtual void updt_params(params_ref const & p) { m_params = p; - m_imp->updt_params(p); + m_engine->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - imp::collect_param_descrs(r); + sls_params::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -1398,14 +65,13 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); - m_imp->m_produce_models = g->models_enabled(); + SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_imp->operator()(g, mc); + m_engine->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -1414,40 +80,41 @@ public: } virtual void cleanup() { - imp * d = m_imp; + sls_engine * d = m_engine; #pragma omp critical (tactic_cancel) { - d = m_imp; + d = m_engine; } dealloc(d); - d = alloc(imp, m, m_params, m_stats); + d = alloc(sls_engine, m, m_params); #pragma omp critical (tactic_cancel) { - m_imp = d; + m_engine = d; } } virtual void collect_statistics(statistics & st) const { - double seconds = m_stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", m_stats.m_restarts); - st.update("sls full evals", m_stats.m_full_evals); - st.update("sls incr evals", m_stats.m_incr_evals); - st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); - st.update("sls FLIP moves", m_stats.m_flips); - st.update("sls INC moves", m_stats.m_incs); - st.update("sls DEC moves", m_stats.m_decs); - st.update("sls INV moves", m_stats.m_invs); - st.update("sls moves", m_stats.m_moves); - st.update("sls moves/sec", m_stats.m_moves / seconds); + sls_engine::stats const & stats = m_engine->get_stats(); + double seconds = stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", stats.m_restarts); + st.update("sls full evals", stats.m_full_evals); + st.update("sls incr evals", stats.m_incr_evals); + st.update("sls incr evals/sec", stats.m_incr_evals / seconds); + st.update("sls FLIP moves", stats.m_flips); + st.update("sls INC moves", stats.m_incs); + st.update("sls DEC moves", stats.m_decs); + st.update("sls INV moves", stats.m_invs); + st.update("sls moves", stats.m_moves); + st.update("sls moves/sec", stats.m_moves / seconds); } virtual void reset_statistics() { - m_stats.reset(); + m_engine->reset_statistics(); } virtual void set_cancel(bool f) { - if (m_imp) - m_imp->set_cancel(f); + if (m_engine) + m_engine->set_cancel(f); } }; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 0aca1f59c..3675265ee 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,12 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include"goal.h" +#include"model.h" + +#include"sls_compilation_settings.h" +#include"sls_powers.h" + class sls_tracker { ast_manager & m_manager; unsynch_mpz_manager & m_mpz_manager; @@ -1186,7 +1192,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif @@ -1334,7 +1340,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif From a6227d5446d206a2d264f2305a08953288a4eae7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 17:26:05 +0000 Subject: [PATCH 153/507] SLS refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index aea4787b0..8e52596e0 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -18,6 +18,10 @@ Notes: This file should go away completely once we have evaluated all options. --*/ + +#ifndef _SLS_COMPILATION_SETTINGS_H_ +#define _SLS_COMPILATION_SETTINGS_H_ + // which unsatisfied assertion is selected? only works with _FOCUS_ > 0 // 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score #define _BFS_ 0 @@ -155,4 +159,6 @@ InvalidConfiguration; #endif #if (_PERC_STICKY_ && !_FOCUS_) InvalidConfiguration; +#endif + #endif \ No newline at end of file From 1e55b3bfb5035e1fa8b44014cab58a036a727216 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Thu, 20 Mar 2014 15:58:53 +0000 Subject: [PATCH 154/507] uct forget and minisat restarts added --- src/tactic/sls/sls_tactic.cpp | 1417 ++++++++++++++++++++++++++++++++- src/tactic/sls/sls_tracker.h | 22 +- 2 files changed, 1402 insertions(+), 37 deletions(-) diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 0f157d3a6..b2b7035e0 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,31 +16,1378 @@ Author: Notes: --*/ +#include +#include"map.h" #include"nnf.h" +#include"cooperate.h" +#include"ast_smt2_pp.h" +#include"ast_pp.h" +#include"var_subst.h" +#include"model_pp.h" +#include"model_evaluator.h" #include"solve_eqs_tactic.h" +#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"ctx_simplify_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"nnf_tactic.h" #include"stopwatch.h" - +#include"propagate_values_tactic.h" #include"sls_tactic.h" -#include"sls_params.hpp" -#include"sls_engine.h" +#include"nnf_tactic.h" +#include"luby.h" +#include "ctx_simplify_tactic.h" -class sls_tactic : public tactic { +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom +#define _FOCUS_ 1 + +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 1 + +// do we use restarts? +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 4.0 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? +#define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? +#define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained +#define _VNS_ 0 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 1 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.5 + +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 1 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 20.0 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score +#define _PROBABILISTIC_UCT_ 0 + +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// do we gradually reduce the touched values of _UCT_? +#define _UCT_FORGET_ 0 +#define _UCT_FORGET_FACTOR_ 0.5 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 0 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 0 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 0 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 0 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 0 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) + InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) + InvalidConfiguration; +#endif +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) + InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) + InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) + InvalidConfiguration; +#endif + +#include"sls_params.hpp" +#include"sls_evaluator.h" +#include"sls_tracker.h" + +class sls_tactic : public tactic { + class stats { + public: + unsigned m_restarts; + stopwatch m_stopwatch; + unsigned m_full_evals; + unsigned m_incr_evals; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + + stats() : + m_restarts(0), + m_full_evals(0), + m_incr_evals(0), + m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), + m_flips(0), + m_incs(0), + m_decs(0), + m_invs(0) { + m_stopwatch.reset(); + m_stopwatch.start(); + } + void reset() { + m_full_evals = m_flips = m_incr_evals = 0; + m_stopwatch.reset(); + m_stopwatch.start(); + } + }; + + struct imp { + ast_manager & m_manager; + stats & m_stats; + unsynch_mpz_manager m_mpz_manager; + powers m_powers; + mpz m_zero, m_one, m_two; + bool m_produce_models; + volatile bool m_cancel; + bv_util m_bv_util; + sls_tracker m_tracker; + sls_evaluator m_evaluator; + + unsigned m_restart_limit; + unsigned m_max_restarts; + unsigned m_plateau_limit; + + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; + + imp(ast_manager & m, params_ref const & p, stats & s) : + m_manager(m), + m_stats(s), + m_powers(m_mpz_manager), + m_zero(m_mpz_manager.mk_z(0)), + m_one(m_mpz_manager.mk_z(1)), + m_two(m_mpz_manager.mk_z(2)), + m_cancel(false), + m_bv_util(m), + m_tracker(m, m_bv_util, m_mpz_manager, m_powers), + m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) + { + updt_params(p); + } + + ~imp() { + m_mpz_manager.del(m_zero); + m_mpz_manager.del(m_one); + m_mpz_manager.del(m_two); + } + + double get_restart_armin(unsigned cnt_restarts) + { + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow(_RESTART_CONST_ARMIN_, inner_id + 1); + } + + inline unsigned check_restart(unsigned curr_value) + { + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 5 + m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); +#elif _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; + } + + ast_manager & m() const { return m_manager; } + + void set_cancel(bool f) { m_cancel = f; } + void cancel() { set_cancel(true); } + void reset_cancel() { set_cancel(false); } + + static void collect_param_descrs(param_descrs & r) { + sls_params::collect_param_descrs(r); + } + + void updt_params(params_ref const & _p) { + sls_params p(_p); + m_produce_models = _p.get_bool("model", false); + m_max_restarts = p.restarts(); + m_tracker.set_random_seed(p.random_seed()); + m_plateau_limit = p.plateau_limit(); + } + + void checkpoint() { + if (m_cancel) + throw tactic_exception(TACTIC_CANCELED_MSG); + cooperate("sls"); + } + + bool full_eval(goal_ref const & g, model & mdl) { + bool res = true; + + unsigned sz = g->size(); + for (unsigned i = 0; i < sz && res; i++) { + checkpoint(); + expr_ref o(m_manager); + + if (!mdl.eval(g->form(i), o, true)) + exit(ERR_INTERNAL_FATAL); + + res = m_manager.is_true(o.get()); + } + + TRACE("sls", tout << "Evaluation: " << res << std::endl;); + + return res; + } + + double top_score(goal_ref const & g) { + #if 0 + double min = m_tracker.get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + double q = m_tracker.get_score(g->form(i)); + if (q < min) min = q; + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " MIN: " << min << std::endl; ); + return min; + #else + double top_sum = 0.0; + unsigned sz = g->size(); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); + } + + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " AVG: " << top_sum / (double) sz << std::endl; ); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + + return top_sum / (double) sz; + #endif + } + + double rescore(goal_ref const & g) { + m_evaluator.update_all(); + m_stats.m_full_evals++; + return top_score(g); + } + + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; + } +#endif + + // checks whether the score outcome of a given move is better than the previous score + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + + #ifdef Z3DEBUG + mpz old_value; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + #endif + +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else + double r = incremental_score(g, fd, temp); +#endif + #ifdef Z3DEBUG + TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << + " --> " << r << std::endl; ); + + m_mpz_manager.del(old_value); + #endif + +// if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // same as what_if, but only applied to the score of a specific atom, not the total score + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); + if (r >= best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + + } + + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + } + + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); + } + + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + unsigned shift; + m_mpz_manager.add(old_value, m_one, incremented); + if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) + m_mpz_manager.set(incremented, m_zero); + } + + void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { + if (m_mpz_manager.is_zero(old_value)) { + m_mpz_manager.set(decremented, m_powers(bv_sz)); + m_mpz_manager.dec(decremented); + } + else + m_mpz_manager.sub(old_value, m_one, decremented); + } + + void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { + m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); + } + + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { + m_mpz_manager.set(flipped, m_zero); + + if (m_bv_util.is_bv_sort(s)) { + mpz mask; + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(old_value, mask, flipped); + m_mpz_manager.del(mask); + } + else if (m_manager.is_bool(s)) + m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); + else + NOT_IMPLEMENTED_YET(); + } + + void mk_random_move(ptr_vector & unsat_constants) + { + unsigned rnd_mv = 0; + unsigned ucc = unsat_constants.size(); + unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; + func_decl * fd = unsat_constants[rc]; + + mpz new_value; + + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; + + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; + + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } + + void mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); + } + + // will use VNS to ignore some possible moves and increase the flips per second + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + // we can either check the condition once in the beginning or check it repeatedly after every bit +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif + unsigned bv_sz; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } +#endif + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; + } + + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + + m_old_values.reset(); + + return 0; + } + + // what_if version needed in the context of 2nd intensification try, combining local and global score + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // find_best_move version needed in the context of 2nd intensification try + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) + { + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; + } + + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; + } + + // main search loop + lbool search(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _UCT_FORGET_ + if (m_stats.m_moves % _UCT_FORGET_ == 0) + m_tracker.uct_forget(g); +#endif + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + // main search loop + lbool search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + + score = rescore(g); + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl; ); + + unsigned plateau_cnt = 0; + + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { +#endif + do { + checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif + old_score = score; + new_const = (unsigned)-1; + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } + TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; + for (unsigned i = 0 ; i < to_evaluate.size(); i++) + tout << to_evaluate[i]->get_name() << std::endl; ); + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + if (new_const == static_cast(-1)) { + TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + }); + + TRACE("sls_max", m_tracker.show_model(tout); + tout << "Scores: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl; ); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? + score = old_score; + } + else { + // Andreas: Why does randomizing not count as a move? (Now it does.) + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; + switch (move) { + case MV_FLIP: + tout << "Flip"; + if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; + break; + case MV_INC: + tout << "+1"; + break; + case MV_DEC: + tout << "-1"; + break; + case MV_INV: + tout << "NEG"; + break; + }; + tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + + TRACE("sls", tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl; ); + } + + if (score >= 0.99999) { +// if (score >= 1.0) { + // score could theoretically be imprecise. + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ + } + while (score > old_score && res == l_undef); + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); + plateau_cnt = 0; + } else { + m_stats.m_moves++; + plateau_cnt++; + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { + TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else + m_evaluator.randomize_local(g, m_stats.m_moves); +#endif + //mk_random_move(g); + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + void operator()(goal_ref const & g, model_converter_ref & mc) { + if (g->inconsistent()) { + mc = 0; + return; + } + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_DIRTY_UP_ " << _DIRTY_UP_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_RESTART_CONST_ARMIN_ " << std::fixed << std::setprecision(2) << _RESTART_CONST_ARMIN_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; + verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout); ); + } + g->reset(); + } + else + mc = 0; + } + }; + ast_manager & m; params_ref m_params; - sls_engine * m_engine; + imp * m_imp; + stats m_stats; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_engine = alloc(sls_engine, m, p); + m_imp = alloc(imp, m, p, m_stats); } virtual tactic * translate(ast_manager & m) { @@ -48,16 +1395,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_engine); + dealloc(m_imp); } virtual void updt_params(params_ref const & p) { m_params = p; - m_engine->updt_params(p); + m_imp->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); + imp::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -65,13 +1412,14 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); + SASSERT(g->is_well_sorted()); + m_imp->m_produce_models = g->models_enabled(); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_engine->operator()(g, mc); + m_imp->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -80,41 +1428,40 @@ public: } virtual void cleanup() { - sls_engine * d = m_engine; + imp * d = m_imp; #pragma omp critical (tactic_cancel) { - d = m_engine; + d = m_imp; } dealloc(d); - d = alloc(sls_engine, m, m_params); + d = alloc(imp, m, m_params, m_stats); #pragma omp critical (tactic_cancel) { - m_engine = d; + m_imp = d; } } virtual void collect_statistics(statistics & st) const { - sls_engine::stats const & stats = m_engine->get_stats(); - double seconds = stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", stats.m_restarts); - st.update("sls full evals", stats.m_full_evals); - st.update("sls incr evals", stats.m_incr_evals); - st.update("sls incr evals/sec", stats.m_incr_evals / seconds); - st.update("sls FLIP moves", stats.m_flips); - st.update("sls INC moves", stats.m_incs); - st.update("sls DEC moves", stats.m_decs); - st.update("sls INV moves", stats.m_invs); - st.update("sls moves", stats.m_moves); - st.update("sls moves/sec", stats.m_moves / seconds); + double seconds = m_stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", m_stats.m_restarts); + st.update("sls full evals", m_stats.m_full_evals); + st.update("sls incr evals", m_stats.m_incr_evals); + st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); + st.update("sls FLIP moves", m_stats.m_flips); + st.update("sls INC moves", m_stats.m_incs); + st.update("sls DEC moves", m_stats.m_decs); + st.update("sls INV moves", m_stats.m_invs); + st.update("sls moves", m_stats.m_moves); + st.update("sls moves/sec", m_stats.m_moves / seconds); } virtual void reset_statistics() { - m_engine->reset_statistics(); + m_stats.reset(); } virtual void set_cancel(bool f) { - if (m_engine) - m_engine->set_cancel(f); + if (m_imp) + m_imp->set_cancel(f); } }; @@ -163,7 +1510,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? //mk_ctx_simplify_tactic(m, ctx_p), // Andreas: This one at least eliminates top level duplicates ... - mk_simplify_tactic(m), + //mk_simplify_tactic(m), // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 3675265ee..1c33d42a7 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -276,6 +276,20 @@ public: } #endif + void uct_forget(goal_ref const & g) { + expr * e; + unsigned touched_old, touched_new; + + for (unsigned i = 0; i < g->size(); i++) + { + e = g->form(i); + touched_old = m_scores.find(e).touched; + touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); + m_scores.find(e).touched = touched_new; + m_touched += touched_new - touched_old; + } + } + void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -1195,6 +1209,8 @@ public: double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#elif _UCT_ == 3 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } @@ -1202,7 +1218,7 @@ public: if (pos == static_cast(-1)) return m_temp_constants; -#if _UCT_ == 1 +#if _UCT_ == 1 || _UCT_ == 3 m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 @@ -1343,6 +1359,8 @@ public: double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#elif _UCT_ == 3 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } @@ -1350,7 +1368,7 @@ public: if (pos == static_cast(-1)) return 0; -#if _UCT_ == 1 +#if _UCT_ == 1 || _UCT_ == 3 m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 From dfd2566e256d52cc3179137f3ee4f942d732d643 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 26 Mar 2014 17:26:06 +0000 Subject: [PATCH 155/507] removed dependency of bvsls on goal_refs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 219 +++++++++++++++++++-------------- src/tactic/sls/sls_engine.h | 58 ++++----- src/tactic/sls/sls_evaluator.h | 4 +- src/tactic/sls/sls_tracker.h | 84 ++++++------- 4 files changed, 195 insertions(+), 170 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 92471aad8..9fa2cc263 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -74,15 +74,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(goal_ref const & g, model & mdl) { +bool sls_engine::full_eval(model & mdl) { bool res = true; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(g->form(i), o, true)) + if (!mdl.eval(m_assertions[i], o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,7 +93,7 @@ bool sls_engine::full_eval(goal_ref const & g, model & mdl) { return res; } -double sls_engine::top_score(goal_ref const & g) { +double sls_engine::top_score() { #if 0 double min = m_tracker.get_score(g->form(0)); unsigned sz = g->size(); @@ -108,15 +108,15 @@ double sls_engine::top_score(goal_ref const & g) { return min; #else double top_sum = 0.0; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = m_assertions[i]; top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); + tout << " " << m_tracker.get_score(m_assertions[i]); tout << " AVG: " << top_sum / (double)sz << std::endl;); #if _CACHE_TOP_SCORE_ @@ -127,40 +127,40 @@ double sls_engine::top_score(goal_ref const & g) { #endif } -double sls_engine::rescore(goal_ref const & g) { +double sls_engine::rescore() { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(g); + return top_score(); } -double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif } -double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif } -double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { #if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif else return 0.0; @@ -170,8 +170,13 @@ double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, c } // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if( + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -179,9 +184,9 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); + double r = incremental_score_prune(fd, temp); #else - double r = incremental_score(g, fd, temp); + double r = incremental_score(fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -202,8 +207,15 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd } // same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if_local( + expr * e, + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) +{ m_evaluator.update(fd, temp); double r = m_tracker.get_score(e); if (r >= best_score) { @@ -344,13 +356,19 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); +void sls_engine::mk_random_move() { + mk_random_move(m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves)); } // will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move_vns( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; unsigned bv_sz, max_bv_sz = 0; double new_score = score; @@ -366,31 +384,31 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; // try to flip lsb mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = 0; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); SASSERT(check == score); } @@ -412,13 +430,13 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector { mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); SASSERT(check == score); } m_mpz_manager.del(old_value); @@ -427,8 +445,14 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector } // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ mpz temp2; @@ -451,7 +475,7 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } @@ -462,19 +486,19 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; #if _USE_UNARY_MINUS_ @@ -504,7 +528,7 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -572,15 +596,15 @@ double sls_engine::find_best_move_local(expr * e, ptr_vector & to_eva } // first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau(goal_ref const & g) +bool sls_engine::handle_plateau() { - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); #if _BFS_ unsigned pos = m_stats.m_moves % sz; #else unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + expr * e = m_tracker.get_unsat_assertion(sz, pos); if (!e) return 0; @@ -634,10 +658,15 @@ bool sls_engine::handle_plateau(goal_ref const & g) } // what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); +bool sls_engine::what_if( + expr * e, + func_decl * fd, + const mpz & temp, + double & best_score, + mpz & best_value, + unsigned i) +{ + double global_score = incremental_score(fd, temp); double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; @@ -651,7 +680,7 @@ bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz } // find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) +double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i) { mpz old_value, temp; double best_score = 0; @@ -662,7 +691,7 @@ double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); + what_if(e, fd, temp, best_score, best_value, i); } m_mpz_manager.del(old_value); @@ -672,15 +701,15 @@ double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl } // second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(goal_ref const & g, double old_score) +bool sls_engine::handle_plateau(double old_score) { - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); #if _BFS_ unsigned new_const = m_stats.m_moves % sz; #else unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + expr * e = m_tracker.get_unsat_assertion(m_assertions, sz, new_const); if (!e) return 0; @@ -697,12 +726,12 @@ bool sls_engine::handle_plateau(goal_ref const & g, double old_score) for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) { - new_score = find_best_move_local(g, q, fd, new_value, i); + new_score = find_best_move_local(q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); + global_score = incremental_score(fd, new_value); local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -715,7 +744,7 @@ bool sls_engine::handle_plateau(goal_ref const & g, double old_score) } // main search loop -lbool sls_engine::search(goal_ref const & g) { +lbool sls_engine::search() { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -723,8 +752,8 @@ lbool sls_engine::search(goal_ref const & g) { move_type move; unsigned plateau_cnt = 0; - score = rescore(g); - unsigned sz = g->size(); + score = rescore(); + unsigned sz = m_assertions.size(); #if _PERC_STICKY_ expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif @@ -750,7 +779,7 @@ lbool sls_engine::search(goal_ref const & g) { if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + expr * e = m_tracker.get_unsat_assertion(m_assertions, m_stats.m_moves); #endif if (!e) { @@ -793,7 +822,7 @@ lbool sls_engine::search(goal_ref const & g) { #if _VNS_ score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { @@ -811,14 +840,14 @@ lbool sls_engine::search(goal_ref const & g) { else #endif #if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(m_assertions, m_stats.m_moves); #else m_evaluator.randomize_local(to_evaluate); #endif #endif #if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); + score = m_tracker.get_top_sum() / m_assertions.size(); #else score = top_score(g); #endif @@ -828,7 +857,7 @@ lbool sls_engine::search(goal_ref const & g) { #if _REAL_RS_ || _REAL_PBFS_ score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(fd, new_value); #endif } } @@ -840,18 +869,18 @@ bailout: } // main search loop -lbool sls_engine::search_old(goal_ref const & g) { +lbool sls_engine::search_old() { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - score = rescore(g); + score = rescore(); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); tout << " TOP: " << score << std::endl;); unsigned plateau_cnt = 0; @@ -897,7 +926,7 @@ lbool sls_engine::search_old(goal_ref const & g) { old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves); if (!to_evaluate.size()) { res = l_true; @@ -908,22 +937,22 @@ lbool sls_engine::search_old(goal_ref const & g) { tout << to_evaluate[i]->get_name() << std::endl;); #if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move_vns(to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + for (unsigned i = 0; i < m_assertions.size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + tout << mk_ismt2_pp(m_assertions[i], m_manager) << std::endl; }); TRACE("sls_max", m_tracker.show_model(tout); tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl;); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << mk_ismt2_pp(m_assertions[i], m_manager) << " ---> " << + m_tracker.get_score(m_assertions[i]) << std::endl;); // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } @@ -962,14 +991,14 @@ lbool sls_engine::search_old(goal_ref const & g) { } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); tout << " TOP: " << score << std::endl;); } @@ -978,8 +1007,8 @@ lbool sls_engine::search_old(goal_ref const & g) { // score could theoretically be imprecise. // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + for (unsigned i = 0; i < m_assertions.size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) all_true = false; if (all_true) { res = l_true; // sat @@ -1010,17 +1039,17 @@ lbool sls_engine::search_old(goal_ref const & g) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); #if _INTENSIFICATION_ handle_plateau(g, score); - //handle_plateau(g); + //handle_plateau(); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(m_assertions, m_stats.m_moves); #endif - //mk_random_move(g); - score = top_score(g); + //mk_random_move(); + score = top_score(); if (score >= 1.0) { bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + for (unsigned i = 0; i < m_assertions.size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) all_true = false; if (all_true) { res = l_true; // sat @@ -1046,6 +1075,10 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); + for (unsigned i = 0; i < g->size(); i++) + assert_expr(g->form(i)); + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; @@ -1089,7 +1122,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { #if _WEIGHT_TOGGLE_ m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); #endif - m_tracker.initialize(g); + m_tracker.initialize(m_assertions); lbool res = l_undef; m_restart_limit = _RESTART_LIMIT_; @@ -1098,14 +1131,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { checkpoint(); report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); + res = search(); if (res == l_undef) { #if _RESTART_INIT_ - m_tracker.randomize(g); + m_tracker.randomize(); #else - m_tracker.reset(g); + m_tracker.reset(m_assertions); #endif } } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 878354c6d..8458817b6 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -71,6 +71,7 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; + ptr_vector m_assertions; unsigned m_restart_limit; unsigned m_max_restarts; @@ -92,11 +93,12 @@ public: void updt_params(params_ref const & _p); + void assert_expr(expr * e) { m_assertions.push_back(e); } + stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(goal_ref const & g, model & mdl); - + bool full_eval(model & mdl); void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); @@ -104,54 +106,44 @@ public: void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - - - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); - - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); - - - lbool search(goal_ref const & g); + lbool search(void); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); - lbool search_old(goal_ref const & g); + lbool search_old(void); double get_restart_armin(unsigned cnt_restarts); - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - + bool what_if(expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - double top_score(goal_ref const & g); - double rescore(goal_ref const & g); - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double top_score(); + double rescore(); + double serious_score(func_decl * fd, const mpz & new_value); + double incremental_score(func_decl * fd, const mpz & new_value); #if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score_prune(func_decl * fd, const mpz & new_value); #endif - - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - + double find_best_move(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i); + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_vns(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(goal_ref const & g); + void mk_random_move(); - bool handle_plateau(goal_ref const & g); - bool handle_plateau(goal_ref const & g, double old_score); + bool handle_plateau(void); + bool handle_plateau(double old_score); inline unsigned check_restart(unsigned curr_value); }; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 9daf93c32..7638ba5f4 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -922,8 +922,8 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(goal_ref const & g, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(g, flip)); + void randomize_local(ptr_vector const & as, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(as, flip)); } }; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 1c33d42a7..c49257692 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,7 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"goal.h" +#include"bv_decl_plugin.h" #include"model.h" #include"sls_compilation_settings.h" @@ -365,12 +365,12 @@ public: } }; - void calculate_expr_distances(goal_ref const & g) { + void calculate_expr_distances(ptr_vector const & as) { // precondition: m_scores is set up. - unsigned sz = g->size(); + unsigned sz = as.size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(g->form(i))); + stack.push_back(to_app(as[i])); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -418,12 +418,12 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(goal_ref const & g) { + void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = g->size(); + unsigned sz = as.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); else @@ -438,7 +438,7 @@ public: visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); @@ -450,7 +450,7 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(g); + calculate_expr_distances(as); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); @@ -465,11 +465,11 @@ public: #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(as[i]); #endif #if _UCT_ - m_touched = _UCT_INIT_ ? g->size() : 1; + m_touched = _UCT_INIT_ ? as.size() : 1; #endif } @@ -606,7 +606,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(goal_ref const & g) { + void randomize(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -620,13 +620,13 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; + m_touched = _UCT_INIT_ ? as.size() : 1; + for (unsigned i = 0; i < as.size(); i++) + m_scores.find(as[i]).touched = 1; #endif } - void reset(goal_ref const & g) { + void reset(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -636,9 +636,9 @@ public: } #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; + m_touched = _UCT_INIT_ ? as.size() : 1; + for (unsigned i = 0; i < as.size(); i++) + m_scores.find(as[i]).touched = 1; #endif } @@ -1029,13 +1029,13 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(ptr_vector const & as, unsigned sz) { if (sz == 1) return get_constants(); m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1049,22 +1049,22 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * get_unsat_assertion(ptr_vector const & as, unsigned sz, unsigned int pos) { for (unsigned i = pos; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.neq(get_value(q), m_one)) return q; } for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.neq(get_value(q), m_one)) return q; } return 0; } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(as, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; @@ -1141,19 +1141,19 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(as, sz, pos); if (!q) return m_temp_constants; return go_deeper(q); } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); + ptr_vector & get_unsat_constants(ptr_vector const & as, unsigned int flip) { + unsigned sz = as.size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + if (m_mpz_manager.eq(get_value(as[0]), m_one)) return m_temp_constants; else return get_constants(); @@ -1201,7 +1201,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1219,12 +1219,12 @@ public: return m_temp_constants; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; + m_scores.find(as[pos]).touched++; m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(as[pos]).touched = flip; #endif - expr * e = g->form(pos); + expr * e = as[pos]; // expr * e = m_list_false[pos]; #elif _BFS_ == 3 @@ -1303,11 +1303,11 @@ public: } - expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); + expr * get_unsat_assertion(ptr_vector const & as, unsigned int flip) { + unsigned sz = as.size(); if (sz == 1) - return g->form(0); + return as[0]; m_temp_constants.reset(); #if _FOCUS_ == 1 @@ -1351,7 +1351,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1369,13 +1369,13 @@ public: return 0; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; + m_scores.find(as[pos]).touched++; m_touched++; #elif _UCT_ == 2 m_scores.find(g->form(pos)).touched = flip; #endif // return m_list_false[pos]; - return g->form(pos); + return as[pos]; #elif _BFS_ == 3 unsigned int pos = -1; @@ -1429,7 +1429,7 @@ public: unsigned int pos = get_random_uint(16) % sz; return get_unsat_assertion(g, sz, pos); #endif - return g->form(pos); + return as[pos]; #elif _FOCUS_ == 2 #if _BFS_ unsigned int pos = flip % sz; From e9482a1447bcc552521fa5b9851b79f707629ec1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Mar 2014 13:34:21 +0000 Subject: [PATCH 156/507] disabled old code --- src/tactic/sls/sls_engine.cpp | 4 +++- src/tactic/sls/sls_engine.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 9fa2cc263..cc06e4f78 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -868,6 +868,7 @@ bailout: return res; } +#if 0 // Old code. // main search loop lbool sls_engine::search_old() { lbool res = l_undef; @@ -1060,6 +1061,7 @@ lbool sls_engine::search_old() { } } } +#endif bailout: m_mpz_manager.del(new_value); @@ -1190,4 +1192,4 @@ unsigned sls_engine::check_restart(unsigned curr_value) return 0; } return 1; -} \ No newline at end of file +} diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8458817b6..5d4c9a0fc 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -114,7 +114,6 @@ public: protected: void checkpoint(); - lbool search_old(void); double get_restart_armin(unsigned cnt_restarts); bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, @@ -148,4 +147,4 @@ protected: inline unsigned check_restart(unsigned curr_value); }; -#endif \ No newline at end of file +#endif From cf1a600fb981bfae72dd895e9fef9a9f79f3c5fb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Mar 2014 13:37:04 +0000 Subject: [PATCH 157/507] bugfix --- src/tactic/sls/sls_engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index cc06e4f78..10aaf6601 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1061,13 +1061,13 @@ lbool sls_engine::search_old() { } } } -#endif bailout: m_mpz_manager.del(new_value); return res; } +#endif void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { From beef8198a42b18ce5d5f86df0729c2c0b5628a48 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:27:06 +0000 Subject: [PATCH 158/507] removed dependency of bvsls on goal_refs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index c49257692..cf1ad9ea3 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -276,13 +276,13 @@ public: } #endif - void uct_forget(goal_ref const & g) { + void uct_forget(ptr_vector & as) { expr * e; unsigned touched_old, touched_new; - for (unsigned i = 0; i < g->size(); i++) + for (unsigned i = 0; i < as.size(); i++) { - e = g->form(i); + e = as[i]; touched_old = m_scores.find(e).touched; touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); m_scores.find(e).touched = touched_new; From ff7af2680de792f2ac1deacc84cb0687b9d48f14 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:28:40 +0000 Subject: [PATCH 159/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index cf1ad9ea3..fac080ee7 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include"for_each_expr.h" #include"bv_decl_plugin.h" #include"model.h" From 4e8c0c14188a0d1a315379cc0a42090f3c48f47c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:30:15 +0000 Subject: [PATCH 160/507] compilation fixes Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.h | 1 + src/tactic/sls/sls_tracker.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 5d4c9a0fc..96041d09e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,6 +22,7 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" +#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index fac080ee7..537492213 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -21,6 +21,7 @@ Notes: #define _SLS_TRACKER_H_ #include"for_each_expr.h" +#include"ast_smt2_pp.h" #include"bv_decl_plugin.h" #include"model.h" From c541694f403cd185f6ec09f8e5ab6c3fb149cdd4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 14:58:59 +0000 Subject: [PATCH 161/507] bvsls refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 21 ++++++++++++--------- src/tactic/sls/sls_engine.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 10aaf6601..e7ee2abbd 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1069,6 +1069,16 @@ bailout: } #endif +void sls_engine::init_tracker() { +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(m_assertions); +} + void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { mc = 0; @@ -1078,8 +1088,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); for (unsigned i = 0; i < g->size(); i++) - assert_expr(g->form(i)); - + assert_expr(g->form(i)); verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; @@ -1118,13 +1127,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(m_assertions); + init_tracker(); lbool res = l_undef; m_restart_limit = _RESTART_LIMIT_; diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 96041d09e..c56d6ec40 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -109,6 +109,8 @@ public: void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void init_tracker(void); + lbool search(void); void operator()(goal_ref const & g, model_converter_ref & mc); From 239849957a9f120994b453c1f4fa4ff5df3d7c10 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 15:26:52 +0000 Subject: [PATCH 162/507] bvsls refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 44 +++++++++++++++++++---------------- src/tactic/sls/sls_engine.h | 1 + 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index e7ee2abbd..2b359608a 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1125,8 +1125,31 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + lbool res = operator()(); + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout);); + } + g->reset(); + } + else + mc = 0; +} + +lbool sls_engine::operator()() { init_tracker(); lbool res = l_undef; @@ -1149,25 +1172,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout);); - } - g->reset(); - } - else - mc = 0; } unsigned sls_engine::check_restart(unsigned curr_value) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index c56d6ec40..c6e3af155 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -113,6 +113,7 @@ public: lbool search(void); + lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: From f88b034b8b04e27773a5e2c476fe52884a3cd56d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 15:28:02 +0000 Subject: [PATCH 163/507] bvsls bugfix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 2b359608a..dc4451bb5 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1172,6 +1172,8 @@ lbool sls_engine::operator()() { } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + return res; } unsigned sls_engine::check_restart(unsigned curr_value) From 42702c8d8a9be639f3962cacc61bd3103cbe77f4 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Sun, 20 Apr 2014 16:38:49 +0100 Subject: [PATCH 164/507] Current version before integration ... --- src/tactic/sls/sls_compilation_settings.h | 40 +- src/tactic/sls/sls_engine.cpp | 586 +++++++++++++++------- src/tactic/sls/sls_engine.h | 73 +-- src/tactic/sls/sls_evaluator.h | 152 +++++- src/tactic/sls/sls_tactic.cpp | 4 +- src/tactic/sls/sls_tracker.h | 472 ++++++++++++++--- src/tactic/smtlogics/qfbv_tactic.cpp | 28 ++ 7 files changed, 1068 insertions(+), 287 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 8e52596e0..d2b899dd8 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -36,17 +36,21 @@ Notes: // do we use dirty unit propagation to get rid of nested top level assertions? #define _DIRTY_UP_ 0 +// shall we use additive weighting scheme? +#define _PAWS_ 5 +#define _PAWS_INIT_ 40 + // do we use restarts? // 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 +#define _RESTARTS_ 1 // limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 +#define _RESTART_LIMIT_ 100 // 0 = initialize with all zero, 1 initialize with random value #define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat #define _RESTART_SCHEME_ 1 // base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 +#define _RESTART_CONST_ARMIN_ 2.0 // timelimit #define _TIMELIMIT_ 3600 @@ -61,6 +65,21 @@ Notes: // 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained #define _VNS_ 0 +// shall we check 2-bit flips in plateaus using Monte Carlo? +#define _VNS_MC_ 0 + +// how many 2-bit flips shall we try per bit? +#define _VNS_MC_TRIES_ 1 + +// shall we check another assertion if no improving step was found in the first one? +#define _VNS_REPICK_ 0 + +// what is the probability of doing so (percentage)? +#define _VNS_PERC_ 100 + +// do a decreasing move with percentage ... +#define _INSIST_PERC_ 0 + // do we reduce the score of unsatisfied literals? // 0 = no // 1 = yes, by multiplying it with some factor @@ -70,7 +89,7 @@ Notes: #define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 +#define _WEIGHT_DIST_FACTOR_ 0.5 // shall we toggle the weight after each restart? #define _WEIGHT_TOGGLE_ 0 @@ -82,14 +101,15 @@ Notes: // what is the percentage of random moves in plateaus (instead of full randomization)? #define _PERC_PLATEAU_MOVES_ 0 -// shall we repick clause when randomizing in a plateau or use the current one? +// shall we repick assertion when randomizing in a plateau or use the current one? +// 0 = use old one, 1 = repick according to usual scheme, 2 = repick randomly and force different one #define _REPICK_ 1 // do we use some UCT-like scheme for assertion-selection? overrides _BFS_ #define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 +#define _UCT_CONSTANT_ 20.0 // is uct clause selection probabilistic similar to variable selection in sparrow? // 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score @@ -103,7 +123,11 @@ Notes: // how shall we initialize the _UCT_ total touched counter? // 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 +#define _UCT_INIT_ 0 + +// do we gradually reduce the touched values of _UCT_? +#define _UCT_FORGET_ 0 +#define _UCT_FORGET_FACTOR_ 0.9 // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index dc4451bb5..342e649af 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -74,15 +74,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(model & mdl) { +bool sls_engine::full_eval(goal_ref const & g, model & mdl) { bool res = true; - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(m_assertions[i], o, true)) + if (!mdl.eval(g->form(i), o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,7 +93,7 @@ bool sls_engine::full_eval(model & mdl) { return res; } -double sls_engine::top_score() { +double sls_engine::top_score(goal_ref const & g) { #if 0 double min = m_tracker.get_score(g->form(0)); unsigned sz = g->size(); @@ -108,15 +108,15 @@ double sls_engine::top_score() { return min; #else double top_sum = 0.0; - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = m_assertions[i]; + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(m_assertions[i]); + tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double)sz << std::endl;); #if _CACHE_TOP_SCORE_ @@ -127,40 +127,40 @@ double sls_engine::top_score() { #endif } -double sls_engine::rescore() { +double sls_engine::rescore(goal_ref const & g) { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(); + return top_score(g); } -double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / m_assertions.size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(); + return top_score(g); #endif } -double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / m_assertions.size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(); + return top_score(g); #endif } -double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { #if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / m_assertions.size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(); + return top_score(g); #endif else return 0.0; @@ -169,14 +169,17 @@ double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value #endif } +double sls_engine::incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune_new(fd, new_value)) + return (m_tracker.get_top_sum() / g->size()); + else + return 0.0; +} + // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if( - func_decl * fd, - const unsigned & fd_inx, - const mpz & temp, - double & best_score, - unsigned & best_const, - mpz & best_value) { +bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -184,9 +187,9 @@ bool sls_engine::what_if( #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(fd, temp); + double r = incremental_score_prune(g, fd, temp); #else - double r = incremental_score(fd, temp); + double r = incremental_score(g, fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -195,8 +198,33 @@ bool sls_engine::what_if( m_mpz_manager.del(old_value); #endif - // if (r >= best_score) { + //if (r >= best_score) { if (r > best_score) { + m_tracker.reset_equal_scores(); + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + /*else if (r == best_score) { + if (m_tracker.get_random_uint(16) % m_tracker.inc_equal_scores() == 0) + { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + }*/ + + return false; +} + +bool sls_engine::what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + + double r = incremental_score_prune_new(g, fd, temp); + + if (r >= best_score) { best_score = r; best_const = fd_inx; m_mpz_manager.set(best_value, temp); @@ -207,15 +235,8 @@ bool sls_engine::what_if( } // same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local( - expr * e, - func_decl * fd, - const unsigned & fd_inx, - const mpz & temp, - double & best_score, - unsigned & best_const, - mpz & best_value) -{ +bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { m_evaluator.update(fd, temp); double r = m_tracker.get_score(e); if (r >= best_score) { @@ -356,19 +377,13 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move() { - mk_random_move(m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves)); +void sls_engine::mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); } // will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns( - ptr_vector & to_evaluate, - double score, - unsigned & best_const, - mpz & best_value, - unsigned & new_bit, - move_type & move) -{ +double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; unsigned bv_sz, max_bv_sz = 0; double new_score = score; @@ -384,31 +399,31 @@ double sls_engine::find_best_move_vns( if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; // try to flip lsb mk_flip(srt, old_value, 0, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { new_bit = 0; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(fd, old_value); + double check = incremental_score(g, fd, old_value); SASSERT(check == score); } @@ -430,13 +445,13 @@ double sls_engine::find_best_move_vns( { mk_flip(srt, old_value, j, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(fd, old_value); + double check = incremental_score(g, fd, old_value); SASSERT(check == score); } m_mpz_manager.del(old_value); @@ -444,23 +459,99 @@ double sls_engine::find_best_move_vns( return new_score; } +double sls_engine::find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + for (unsigned j = 1; j < max_bv_sz; j++) + { + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move( - ptr_vector & to_evaluate, - double score, - unsigned & best_const, - mpz & best_value, - unsigned & new_bit, - move_type & move) -{ +double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ mpz temp2; #endif unsigned bv_sz; +#if _INSIST_PERC_ + double new_score = m_tracker.get_random_uint(16) % 100 < _INSIST_PERC_ ? 0.0 : score; +#else double new_score = score; +#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + m_tracker.reset_equal_scores(); + +// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { +// for (unsigned i = m_tracker.get_random_uint(16) % to_evaluate.size(); i != to_evaluate.size(); i = to_evaluate.size()) { +// for (unsigned i = to_evaluate.size(); i-- > 0; ) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -470,15 +561,28 @@ double sls_engine::find_best_move( #if _SKIP_BITS_ for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { #else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz; j++) { +// for (unsigned j = bv_sz; j-- > 0; ) { #endif // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + //if (m_tracker.get_random_uint(1)) + //if ((move != MV_FLIP) || (new_bit > j)) + //{ + //if (what_if_new(g, fd, i, temp, new_score, best_const, best_value)) { + // new_bit = j; + // move = MV_FLIP; + //} + //} + //else + //{ + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } + //} } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -486,19 +590,22 @@ double sls_engine::find_best_move( if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; #if _USE_UNARY_MINUS_ @@ -528,7 +635,7 @@ double sls_engine::find_best_move( } // reset to what it was before - double check = incremental_score(fd, old_value); + double check = incremental_score(g, fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -538,6 +645,50 @@ double sls_engine::find_best_move( #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif + + if ((new_score == score) && 1)// (m_tracker.get_random_uint(1))) + best_const = -1; + + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value) { + mpz old_value, temp, temp2; + unsigned bv_sz; + double new_score = score; + +// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { +// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz; j++) { + mk_flip(srt, old_value, j, temp); + for (unsigned l = 0; l < _VNS_MC_TRIES_ && l < bv_sz / 2; l++) + { + unsigned k = m_tracker.get_random_uint(16) % bv_sz; + while (k == j) + k = m_tracker.get_random_uint(16) % bv_sz; + mk_flip(srt, temp, k, temp2); + what_if(g, fd, i, temp2, new_score, best_const, best_value); + } + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + m_mpz_manager.del(temp2); + return new_score; } @@ -596,15 +747,15 @@ double sls_engine::find_best_move_local(expr * e, ptr_vector & to_eva } // first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau() +bool sls_engine::handle_plateau(goal_ref const & g) { - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); #if _BFS_ unsigned pos = m_stats.m_moves % sz; #else unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(sz, pos); + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); if (!e) return 0; @@ -658,15 +809,10 @@ bool sls_engine::handle_plateau() } // what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if( - expr * e, - func_decl * fd, - const mpz & temp, - double & best_score, - mpz & best_value, - unsigned i) -{ - double global_score = incremental_score(fd, temp); +bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; @@ -680,7 +826,7 @@ bool sls_engine::what_if( } // find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i) +double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) { mpz old_value, temp; double best_score = 0; @@ -691,7 +837,7 @@ double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_val for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); - what_if(e, fd, temp, best_score, best_value, i); + what_if(g, e, fd, temp, best_score, best_value, i); } m_mpz_manager.del(old_value); @@ -701,15 +847,15 @@ double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_val } // second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(double old_score) +bool sls_engine::handle_plateau(goal_ref const & g, double old_score) { - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); #if _BFS_ unsigned new_const = m_stats.m_moves % sz; #else unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(m_assertions, sz, new_const); + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); if (!e) return 0; @@ -726,12 +872,12 @@ bool sls_engine::handle_plateau(double old_score) for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) { - new_score = find_best_move_local(q, fd, new_value, i); + new_score = find_best_move_local(g, q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(fd, new_value); + global_score = incremental_score(g, fd, new_value); local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -744,7 +890,7 @@ bool sls_engine::handle_plateau(double old_score) } // main search loop -lbool sls_engine::search() { +lbool sls_engine::search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -752,8 +898,15 @@ lbool sls_engine::search() { move_type move; unsigned plateau_cnt = 0; - score = rescore(); - unsigned sz = m_assertions.size(); + score = rescore(g); + unsigned sz = g->size(); + + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + #if _PERC_STICKY_ expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif @@ -767,9 +920,18 @@ lbool sls_engine::search() { #else while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #endif + //if (m_stats.m_stopwatch.get_current_seconds() > 10.0) + //{printf("Got %f fps and size is %d with avg bw %f\n", m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds(), m_tracker.get_formula_size(), m_tracker.get_avg_bw(g)); exit(0);} + checkpoint(); m_stats.m_moves++; +#if _UCT_FORGET_ + //if (m_stats.m_moves % sz == 0) + if (m_stats.m_moves % _UCT_FORGET_ == 0) + m_tracker.uct_forget(g); +#endif + #if _REAL_RS_ || _REAL_PBFS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif @@ -779,13 +941,14 @@ lbool sls_engine::search() { if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #else - expr * e = m_tracker.get_unsat_assertion(m_assertions, m_stats.m_moves); + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif if (!e) { res = l_true; goto bailout; } + //ptr_vector & to_evaluate = m_tracker.get_unsat_constants_only(e); ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); #else ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); @@ -818,13 +981,69 @@ lbool sls_engine::search() { #endif old_score = score; new_const = (unsigned)-1; + move = MV_FLIP; + new_bit = 0; #if _VNS_ score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); #endif +#if _VNS_MC_ > _VNS_REPICK_ +#if _VNS_MC_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); +#endif +#if _VNS_REPICK_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } +#endif +#endif + +#if _VNS_MC_ < _VNS_REPICK_ +#if _VNS_REPICK_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } +#endif +#if _VNS_MC_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); +#endif +#endif + +#if (_VNS_MC_ == _VNS_REPICK_) && _VNS_MC_ && _VNS_REPICK_ + if (new_const == static_cast(-1)) { + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); + else { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } + } +#endif + + if (new_const == static_cast(-1)) { score = old_score; plateau_cnt++; @@ -839,25 +1058,52 @@ lbool sls_engine::search() { mk_random_move(to_evaluate); else #endif -#if _REPICK_ - m_evaluator.randomize_local(m_assertions, m_stats.m_moves); +#if _REPICK_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _REPICK_ == 2 + { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + m_evaluator.randomize_local(q); + else + m_evaluator.randomize_local(e); + } #else - m_evaluator.randomize_local(to_evaluate); + m_evaluator.randomize_local_n(g, to_evaluate); + //m_evaluator.randomize_local(to_evaluate); #endif #endif #if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / m_assertions.size(); + score = m_tracker.get_top_sum() / g->size(); #else score = top_score(g); #endif + +#if _PAWS_ + for (unsigned i = 0; i < sz; i++) + { + expr * q = g->form(i); + if (m_tracker.get_random_uint(16) % 100 < _PAWS_) + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) + m_tracker.decrease_weight(q); + } + else + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) + m_tracker.increase_weight(q); + } + } +#endif + } else { func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ score = serious_score(g, fd, new_value); #else - score = incremental_score(fd, new_value); + score = incremental_score(g, fd, new_value); #endif } } @@ -868,20 +1114,19 @@ bailout: return res; } -#if 0 // Old code. // main search loop -lbool sls_engine::search_old() { +lbool sls_engine::search_old(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - score = rescore(); + score = rescore(g); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; tout << "Score distribution:"; - for (unsigned i = 0; i < m_assertions.size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); tout << " TOP: " << score << std::endl;); unsigned plateau_cnt = 0; @@ -927,7 +1172,7 @@ lbool sls_engine::search_old() { old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); if (!to_evaluate.size()) { res = l_true; @@ -938,22 +1183,22 @@ lbool sls_engine::search_old() { tout << to_evaluate[i]->get_name() << std::endl;); #if _VNS_ - score = find_best_move_vns(to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < m_assertions.size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) - tout << mk_ismt2_pp(m_assertions[i], m_manager) << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; }); TRACE("sls_max", m_tracker.show_model(tout); tout << "Scores: " << std::endl; - for (unsigned i = 0; i < m_assertions.size(); i++) - tout << mk_ismt2_pp(m_assertions[i], m_manager) << " ---> " << - m_tracker.get_score(m_assertions[i]) << std::endl;); + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl;); // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } @@ -991,15 +1236,15 @@ lbool sls_engine::search_old() { case MV_DIV2: m_stats.m_div2s++; break; } -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(fd, new_value); +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ + score = serious_score(g, fd, new_value); #else - score = incremental_score(fd, new_value); + score = incremental_score(g, fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < m_assertions.size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); tout << " TOP: " << score << std::endl;); } @@ -1008,8 +1253,8 @@ lbool sls_engine::search_old() { // score could theoretically be imprecise. // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; - for (unsigned i = 0; i < m_assertions.size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) all_true = false; if (all_true) { res = l_true; // sat @@ -1040,17 +1285,17 @@ lbool sls_engine::search_old() { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); #if _INTENSIFICATION_ handle_plateau(g, score); - //handle_plateau(); + //handle_plateau(g); #else - m_evaluator.randomize_local(m_assertions, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #endif - //mk_random_move(); - score = top_score(); + //mk_random_move(g); + score = top_score(g); if (score >= 1.0) { bool all_true = true; - for (unsigned i = 0; i < m_assertions.size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) all_true = false; if (all_true) { res = l_true; // sat @@ -1067,17 +1312,6 @@ bailout: return res; } -#endif - -void sls_engine::init_tracker() { -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(m_assertions); -} void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { @@ -1087,9 +1321,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); - for (unsigned i = 0; i < g->size(); i++) - assert_expr(g->form(i)); - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; @@ -1100,7 +1331,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_PAWS_ " << _PAWS_ << std::endl; + verbose_stream() << "_PAWS_INIT_ " << _PAWS_INIT_ << std::endl; verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_VNS_MC_ " << _VNS_MC_ << std::endl; + verbose_stream() << "_VNS_MC_TRIES_ " << _VNS_MC_TRIES_ << std::endl; + verbose_stream() << "_VNS_REPICK_ " << _VNS_REPICK_ << std::endl; + verbose_stream() << "_VNS_PERC_ " << _VNS_PERC_ << std::endl; + verbose_stream() << "_INSIST_PERC_ " << _INSIST_PERC_ << std::endl; verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; @@ -1111,6 +1349,8 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; + verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; @@ -1125,9 +1365,36 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - lbool res = operator()(); +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); @@ -1149,38 +1416,13 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { mc = 0; } -lbool sls_engine::operator()() { - init_tracker(); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(); -#else - m_tracker.reset(m_assertions); -#endif - } - } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - return res; -} - unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_limit) { -#if _RESTART_SCHEME_ == 4 +#if _RESTART_SCHEME_ == 5 + m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); +#elif _RESTART_SCHEME_ == 4 m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; @@ -1188,9 +1430,11 @@ unsigned sls_engine::check_restart(unsigned curr_value) m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) + //if (m_stats.m_restarts % 3 == 2) m_restart_limit += _RESTART_LIMIT_; else m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; + //m_restart_limit += (2 << (m_stats.m_restarts / 3)) * _RESTART_LIMIT_; #else m_restart_limit += _RESTART_LIMIT_; #endif @@ -1201,4 +1445,4 @@ unsigned sls_engine::check_restart(unsigned curr_value) return 0; } return 1; -} +} \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index c6e3af155..902c6b7a0 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,7 +22,6 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" -#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" @@ -72,7 +71,6 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; - ptr_vector m_assertions; unsigned m_restart_limit; unsigned m_max_restarts; @@ -94,12 +92,11 @@ public: void updt_params(params_ref const & _p); - void assert_expr(expr * e) { m_assertions.push_back(e); } - stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(model & mdl); + bool full_eval(goal_ref const & g, model & mdl); + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); @@ -107,48 +104,66 @@ public: void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - void init_tracker(void); + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - lbool search(void); + double find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + double find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value); + + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + + + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); + + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); + + + lbool search(goal_ref const & g); - lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); + lbool search_old(goal_ref const & g); double get_restart_armin(unsigned cnt_restarts); - bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - bool what_if(expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); + + bool what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + double incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value); + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - double top_score(); - double rescore(); - double serious_score(func_decl * fd, const mpz & new_value); - double incremental_score(func_decl * fd, const mpz & new_value); + double top_score(goal_ref const & g); + double rescore(goal_ref const & g); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); #if _EARLY_PRUNE_ - double incremental_score_prune(func_decl * fd, const mpz & new_value); + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); #endif - double find_best_move(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - double find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i); - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - double find_best_move_vns(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(); - bool handle_plateau(void); - bool handle_plateau(double old_score); + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + void mk_random_move(ptr_vector & unsat_constants); + void mk_random_move(goal_ref const & g); + + bool handle_plateau(goal_ref const & g); + bool handle_plateau(goal_ref const & g, double old_score); inline unsigned check_restart(unsigned curr_value); }; -#endif +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 7638ba5f4..78f2cb79a 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -575,7 +575,7 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); @@ -584,12 +584,13 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -634,7 +635,7 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); @@ -643,12 +644,12 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -683,7 +684,7 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ run_serious_update(max_depth); #else run_update(max_depth); @@ -729,14 +730,16 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + //if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) pot_benefits = 1; if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + //if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { @@ -771,7 +774,7 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); @@ -858,6 +861,104 @@ public: } #endif + unsigned run_update_bool_prune_new(unsigned cur_depth) { + expr_fast_mark1 visited; + + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); + + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + prune_score = m_tracker.get_score_prune(cur); + m_tracker.set_score(cur, new_score); + + if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; + + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + else + { + } + } + + cur_depth_exprs.reset(); + cur_depth--; + + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } + + return pot_benefits; + } + + unsigned update_prune_new(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + + if (m_traversal_stack_bool.size() <= cur_depth) + m_traversal_stack_bool.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune_new(cur_depth); + } + void randomize_local(ptr_vector & unsat_constants) { // Randomize _all_ candidates: @@ -901,7 +1002,7 @@ public: mpz temp = m_tracker.get_random(fd->get_range()); #endif -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ serious_update(fd, temp); #else update(fd, temp); @@ -922,9 +1023,36 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(ptr_vector const & as, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(as, flip)); + void randomize_local(goal_ref const & g, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(g, flip)); } + + void randomize_local_n(goal_ref const & g, ptr_vector & unsat_constants) { + unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); + func_decl * fd = unsat_constants[r]; + sort * srt = fd->get_range(); + unsigned bv_sz = m_manager.is_bool(srt) ? 1 : m_bv_util.get_bv_size(srt); + mpz max_val = m_tracker.get_random(srt); + update(fd, max_val); + double max_score = m_tracker.get_top_sum() / g->size(); + mpz temp_val; + double temp_score; + for (unsigned i = 1; i < 2; i++) + //for (unsigned i = 1; i < bv_sz; i++) + { + m_mpz_manager.set(temp_val, m_tracker.get_random(srt)); + update(fd, temp_val); + temp_score = m_tracker.get_top_sum() / g->size(); + if (temp_score > max_score) + { + m_mpz_manager.set(max_val, temp_val); + max_score = temp_score; + } + } + update(fd, max_val); + m_mpz_manager.del(temp_val); + m_mpz_manager.del(max_val); + } }; #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index b2b7035e0..0b6b01e7c 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -1509,14 +1509,14 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { mk_max_bv_sharing_tactic(m), // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? //mk_ctx_simplify_tactic(m, ctx_p), - // Andreas: This one at least eliminates top level duplicates ... + // Andreas: This one at least eliminates top level duplicates ... but has very bad effects on performance! //mk_simplify_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); +// tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 537492213..87c90f1f8 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,9 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"for_each_expr.h" -#include"ast_smt2_pp.h" -#include"bv_decl_plugin.h" +#include"goal.h" #include"model.h" #include"sls_compilation_settings.h" @@ -88,12 +86,17 @@ private: obj_map m_where_false; expr** m_list_false; #endif +#if _PAWS_ + obj_map m_weights; + //obj_map m_weights; +#endif #if _CACHE_TOP_SCORE_ double m_top_sum; #endif #if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ double m_weight_dist_factor; #endif + unsigned m_equal_scores; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -113,15 +116,52 @@ public: m_mpz_manager.del(m_two); } + unsigned get_formula_size() { + return m_scores.size(); + } + + double get_avg_bw(goal_ref const & g) { + double sum = 0.0; + unsigned count = 0; + + for (unsigned i = 0; i < g->size(); i++) + { + m_temp_constants.reset(); + ptr_vector const & this_decls = m_constants_occ.find(g->form(i)); + unsigned sz = this_decls.size(); + for (unsigned i = 0; i < sz; i++) { + func_decl * fd = this_decls[i]; + m_temp_constants.push_back(fd); + sort * srt = fd->get_range(); + sum += (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + count++; + } + } + + return sum / count; + } + #if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ inline void set_weight_dist_factor(double val) { m_weight_dist_factor = val; } #endif + void reset_equal_scores() { + m_equal_scores = 1; + } + + unsigned inc_equal_scores() { + return ++m_equal_scores; + } + #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { + inline void adapt_top_sum(expr * e, double add, double sub) { +#if _PAWS_ + m_top_sum += m_weights.find(e) * (add - sub); +#else m_top_sum += add - sub; +#endif } inline void set_top_sum(double new_score) { @@ -278,19 +318,21 @@ public: } #endif - void uct_forget(ptr_vector & as) { +#if _UCT_ + void uct_forget(goal_ref const & g) { expr * e; unsigned touched_old, touched_new; - for (unsigned i = 0; i < as.size(); i++) + for (unsigned i = 0; i < g->size(); i++) { - e = as[i]; + e = g->form(i); touched_old = m_scores.find(e).touched; touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); m_scores.find(e).touched = touched_new; m_touched += touched_new - touched_old; } } +#endif void initialize(app * n) { // Build score table @@ -367,12 +409,12 @@ public: } }; - void calculate_expr_distances(ptr_vector const & as) { + void calculate_expr_distances(goal_ref const & g) { // precondition: m_scores is set up. - unsigned sz = as.size(); + unsigned sz = g->size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(as[i])); + stack.push_back(to_app(g->form(i))); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -420,12 +462,12 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(ptr_vector const & as) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = as.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); if (!m_top_expr.contains(e)) m_top_expr.insert(e); else @@ -440,7 +482,7 @@ public: visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); @@ -452,7 +494,7 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(as); + calculate_expr_distances(g); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); @@ -465,16 +507,49 @@ public: //} #endif +#if _PAWS_ + for (unsigned i = 0; i < sz; i++) + { + expr * e = g->form(i); + if (!m_weights.contains(e)) + m_weights.insert(e, _PAWS_INIT_); + } +#endif + #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(as[i]); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = _UCT_INIT_ ? as.size() : 1; + m_touched = _UCT_INIT_ ? g->size() : 1; #endif } +#if _PAWS_ + void increase_weight(expr * e) + { + //printf("Increasing %d to", m_weights.find(e)); + m_weights.find(e)++; + //m_weights.find(e) *= 1.1; + //printf(" %d\n", m_weights.find(e)); + } + + void decrease_weight(expr * e) + { + unsigned old_weight = m_weights.find(e); + m_weights.find(e) = old_weight > _PAWS_INIT_ ? old_weight - 1 : _PAWS_INIT_; + //m_weights.find(e) = old_weight > 1.1 ? old_weight / 1.1 : 1; + //printf("Decreasing %d to %d\n", old_weight, m_weights.find(e)); + } + + unsigned get_weight(expr * e) + //double get_weight(expr * e) + { + return m_weights.find(e); + } +#endif + #if _REAL_RS_ || _REAL_PBFS_ void make_assertion(expr * e) { @@ -608,7 +683,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(ptr_vector const & as) { + void randomize(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -622,13 +697,13 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? as.size() : 1; - for (unsigned i = 0; i < as.size(); i++) - m_scores.find(as[i]).touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; #endif } - void reset(ptr_vector const & as) { + void reset(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -638,9 +713,9 @@ public: } #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? as.size() : 1; - for (unsigned i = 0; i < as.size(); i++) - m_scores.find(as[i]).touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; #endif } @@ -765,6 +840,7 @@ public: const mpz & v1 = get_value(arg1); if (negated) { + //res = (m_mpz_manager.eq(v0, v1)) ? 0.5 * (m_bv_util.get_bv_size(arg0) - 1.0) / m_bv_util.get_bv_size(arg0) : 1.0; res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << std::endl; ); @@ -811,40 +887,209 @@ public: SASSERT(a->get_num_args() == 2); const mpz & x = get_value(a->get_arg(0)); const mpz & y = get_value(a->get_arg(1)); - unsigned bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); if (negated) { if (m_mpz_manager.gt(x, y)) + { + /*mpz diff; + m_mpz_manager.sub(x, y, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +/* mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_gt = 0; + unsigned curr_gt = 0; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 1; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 0; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); + m_mpz_manager.del(x_copy); + m_mpz_manager.del(y_copy);*/ +#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= rational(m_powers(bv_sz)); + double dbl = 1.0 - n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + m_mpz_manager.del(diff); +#endif + } + } + else { + if (m_mpz_manager.le(x, y)) + { + /*mpz diff; + m_mpz_manager.sub(y, x, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); - } - } - else { - if (m_mpz_manager.le(x, y)) + res = 1.0 + 0.5 * dbl;*/ res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +/* mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_le = 1; + unsigned curr_le = 1; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_le = curr_le; + curr_le = 0; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_le = curr_le; + curr_le = 1; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2);*/ +#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); + double dbl = 1.0 - n.get_double(); res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - else if (m_bv_util.is_bv_sle(n)) { // x <= y +/* else if (m_bv_util.is_bv_sle(n)) { // x <= y + app * a = to_app(n); + SASSERT(a->get_num_args() == 2); + const mpz & x = get_value(a->get_arg(0)); + const mpz & y = get_value(a->get_arg(1)); + int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + + mpz x_unsigned; + mpz y_unsigned; + const mpz & p = m_powers(bv_sz); + const mpz & p_half = m_powers(bv_sz-1); + if (x >= p_half) { m_mpz_manager.sub(x, p, x_unsigned); } + if (y >= p_half) { m_mpz_manager.sub(y, p, y_unsigned); } + + if (negated) { + if (x_unsigned > y_unsigned) + res = 1.0; + else { + mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_gt = 0; + unsigned curr_gt = 0; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 1; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 0; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); + m_mpz_manager.del(x_copy); + m_mpz_manager.del(y_copy); + } + } + else { + if (x_unsigned <= y_unsigned) + res = 1.0; + else { + mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_le = 1; + unsigned curr_le = 1; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_le = curr_le; + curr_le = 0; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_le = curr_le; + curr_le = 1; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2); + } + } + TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << + m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); + + m_mpz_manager.del(x_unsigned); + m_mpz_manager.del(y_unsigned); + }*/ + else if (m_bv_util.is_bv_sle(n)) { // x <= y app * a = to_app(n); SASSERT(a->get_num_args() == 2); mpz x; m_mpz_manager.set(x, get_value(a->get_arg(0))); @@ -857,31 +1102,61 @@ public: if (negated) { if (x > y) - res = 1.0; + { + /*mpz diff; + m_mpz_manager.sub(x, y, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ + res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= p; - double dbl = n.get_double(); - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + double dbl = 1.0 - n.get_double(); + //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } else { if (x <= y) - res = 1.0; + { + /*mpz diff; + m_mpz_manager.sub(y, x, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ + res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); + SASSERT(!m_mpz_manager.is_neg(diff)); rational n(diff); n /= p; - double dbl = n.get_double(); + double dbl = 1.0 - n.get_double(); res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); @@ -1031,13 +1306,13 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(ptr_vector const & as, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { if (sz == 1) return get_constants(); m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1051,22 +1326,22 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { for (unsigned i = pos; i < sz; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) return q; } for (unsigned i = 0; i < pos; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) return q; } return 0; } - ptr_vector & get_unsat_constants_walksat(ptr_vector const & as, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(as, sz, pos); + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; @@ -1143,20 +1418,66 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_crsat(ptr_vector const & as, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(as, sz, pos); + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); if (!q) return m_temp_constants; return go_deeper(q); } - ptr_vector & get_unsat_constants(ptr_vector const & as, unsigned int flip) { - unsigned sz = as.size(); + void go_deeper_only(expr * e) { + //if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + //if (m_mpz_manager.neq(get_value(q), m_one)) go_deeper(q); + } + go_deeper(args[pos]); + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + go_deeper(q); + } + } + //} + else + { + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + } + } + + ptr_vector & get_unsat_constants_only(expr * e) { + if (e && !m_temp_constants.size()) + go_deeper_only(e); + + return m_temp_constants; + } + + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(as[0]), m_one)) + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + { + m_temp_constants.reset(); return m_temp_constants; + } else return get_constants(); } @@ -1169,11 +1490,12 @@ public: #if _PROBABILISTIC_UCT_ double sum_score = 0.0; unsigned start_index = get_random_uint(16) % sz; - + for (unsigned i = start_index; i < sz; i++) { expr * e = g->form(i); vscore = m_scores.find(e); + #if _PROBABILISTIC_UCT_ == 2 double q = vscore.score * vscore.score; #else @@ -1203,7 +1525,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1221,12 +1543,12 @@ public: return m_temp_constants; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(as[pos]).touched++; + m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 - m_scores.find(as[pos]).touched = flip; + m_scores.find(g->form(pos)).touched = flip; #endif - expr * e = as[pos]; + expr * e = g->form(pos); // expr * e = m_list_false[pos]; #elif _BFS_ == 3 @@ -1304,12 +1626,15 @@ public: } } + expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); - expr * get_unsat_assertion(ptr_vector const & as, unsigned int flip) { - unsigned sz = as.size(); - - if (sz == 1) - return as[0]; + if (sz == 1) { + if (m_mpz_manager.eq(get_value(g->form(0)), m_zero)) + return g->form(0); + else + return 0; + } m_temp_constants.reset(); #if _FOCUS_ == 1 @@ -1353,12 +1678,12 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #elif _UCT_ == 3 @@ -1371,13 +1696,13 @@ public: return 0; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(as[pos]).touched++; + m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 m_scores.find(g->form(pos)).touched = flip; #endif // return m_list_false[pos]; - return as[pos]; + return g->form(pos); #elif _BFS_ == 3 unsigned int pos = -1; @@ -1431,7 +1756,7 @@ public: unsigned int pos = get_random_uint(16) % sz; return get_unsat_assertion(g, sz, pos); #endif - return as[pos]; + return g->form(pos); #elif _FOCUS_ == 2 #if _BFS_ unsigned int pos = flip % sz; @@ -1441,6 +1766,23 @@ public: return get_unsat_constants_crsat(g, sz, pos); #endif } + + expr * get_new_unsat_assertion(goal_ref const & g, expr * e) { + unsigned sz = g->size(); + + if (sz == 1) + return 0; + + m_temp_constants.reset(); + + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (g->form(i) != e)) pos = i; + + if (pos == static_cast(-1)) + return 0; + return g->form(pos); + } }; #endif \ No newline at end of file diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index ac53ca0c8..a7870176d 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -28,6 +28,8 @@ Notes: #include"bv_size_reduction_tactic.h" #include"aig_tactic.h" #include"sat_tactic.h" +//#include"nnf_tactic.h" +//#include"sls_tactic.h" #define MEMLIMIT 300 @@ -93,6 +95,32 @@ tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) { mk_sat_tactic(m)); #endif + /* use full sls + tactic * st = using_params(and_then(preamble_st, + cond(mk_is_qfbv_probe(), + cond(mk_is_qfbv_eq_probe(), + and_then(mk_bv1_blaster_tactic(m), + using_params(mk_smt_tactic(), solver_p)), + and_then(mk_nnf_tactic(m, p), mk_sls_tactic(m))), + mk_smt_tactic())), + main_p);*/ + + /* use pure dpll + tactic * st = using_params(and_then(mk_simplify_tactic(m), + cond(mk_is_qfbv_probe(), + and_then(mk_bit_blaster_tactic(m), + when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)), + and_then(using_params(and_then(mk_simplify_tactic(m), + mk_solve_eqs_tactic(m)), + local_ctx_p), + if_no_proofs(cond(mk_produce_unsat_cores_probe(), + mk_aig_tactic(), + using_params(mk_aig_tactic(), + big_aig_p))))), + new_sat), + mk_smt_tactic())), + main_p);*/ + tactic * st = using_params(and_then(preamble_st, // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function // symbols. In this case, we should not use From 8a30a2caa9f6644866d855a247f621e47cee95e4 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 00:32:45 +0100 Subject: [PATCH 165/507] Almost cleaned up version. --- src/tactic/sls/sls_compilation_settings.h | 156 +-- src/tactic/sls/sls_engine.cpp | 1168 +++------------------ src/tactic/sls/sls_engine.h | 89 +- src/tactic/sls/sls_evaluator.h | 262 +---- src/tactic/sls/sls_tactic.cpp | 6 +- src/tactic/sls/sls_tracker.h | 904 ++-------------- 6 files changed, 315 insertions(+), 2270 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index d2b899dd8..9add78daa 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,167 +22,13 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 0 - -// shall we use additive weighting scheme? -#define _PAWS_ 5 -#define _PAWS_INIT_ 40 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 1 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 100 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 2.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// shall we check 2-bit flips in plateaus using Monte Carlo? -#define _VNS_MC_ 0 - -// how many 2-bit flips shall we try per bit? -#define _VNS_MC_TRIES_ 1 - -// shall we check another assertion if no improving step was found in the first one? -#define _VNS_REPICK_ 0 - -// what is the probability of doing so (percentage)? -#define _VNS_PERC_ 100 - -// do a decreasing move with percentage ... -#define _INSIST_PERC_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.5 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick assertion when randomizing in a plateau or use the current one? -// 0 = use old one, 1 = repick according to usual scheme, 2 = repick randomly and force different one -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 20.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 0 - -// do we gradually reduce the touched values of _UCT_? -#define _UCT_FORGET_ 0 -#define _UCT_FORGET_FACTOR_ 0.9 - // shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 +#define _USE_ADDSUB_ 0 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 // shall we use early pruning for incremental update? #define _EARLY_PRUNE_ 1 -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) -InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) -InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) -InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) -InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) -InvalidConfiguration; -#endif - #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 342e649af..c240a0c51 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -44,6 +44,7 @@ sls_engine::sls_engine(ast_manager & m, params_ref const & p) : m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) { updt_params(p); + m_tracker.updt_params(p); } sls_engine::~sls_engine() { @@ -52,20 +53,21 @@ sls_engine::~sls_engine() { m_mpz_manager.del(m_two); } -double sls_engine::get_restart_armin(unsigned cnt_restarts) -{ - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); -} - void sls_engine::updt_params(params_ref const & _p) { sls_params p(_p); m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); + m_max_restarts = p.max_restarts(); m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); + m_walksat = p.walksat(); + m_walksat_repick = p.walksat_repick(); + m_paws_sp = p.paws_sp(); + m_wp = p.wp(); + m_vns_mc = p.vns_mc(); + m_vns_repick = p.vns_repick(); + + m_restart_base = p.restart_base(); + m_restart_next = m_restart_base; + m_restart_init = p.restart_init(); } void sls_engine::checkpoint() { @@ -74,15 +76,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(goal_ref const & g, model & mdl) { +bool sls_engine::full_eval(model & mdl) { bool res = true; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(g->form(i), o, true)) + if (!mdl.eval(m_assertions[i], o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,93 +95,58 @@ bool sls_engine::full_eval(goal_ref const & g, model & mdl) { return res; } -double sls_engine::top_score(goal_ref const & g) { -#if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl;); - return min; -#else +double sls_engine::top_score() { double top_sum = 0.0; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = m_assertions[i]; top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); + tout << " " << m_tracker.get_score(m_assertions[i]); tout << " AVG: " << top_sum / (double)sz << std::endl;); -#if _CACHE_TOP_SCORE_ m_tracker.set_top_sum(top_sum); -#endif return top_sum / (double)sz; -#endif } -double sls_engine::rescore(goal_ref const & g) { +double sls_engine::rescore() { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(g); + return top_score(); } -double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif + return (m_tracker.get_top_sum() / m_assertions.size()); } -double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif + return (m_tracker.get_top_sum() / m_assertions.size()); } -double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { -#if _EARLY_PRUNE_ +double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; -#else - NOT_IMPLEMENTED_YET(); -#endif -} - -double sls_engine::incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune_new(fd, new_value)) - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); else return 0.0; } // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if( + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -187,9 +154,9 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); + double r = incremental_score_prune(fd, temp); #else - double r = incremental_score(g, fd, temp); + double r = incremental_score(fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -198,7 +165,7 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd m_mpz_manager.del(old_value); #endif - //if (r >= best_score) { + // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { m_tracker.reset_equal_scores(); best_score = r; @@ -206,45 +173,6 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd m_mpz_manager.set(best_value, temp); return true; } - /*else if (r == best_score) { - if (m_tracker.get_random_uint(16) % m_tracker.inc_equal_scores() == 0) - { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - }*/ - - return false; -} - -bool sls_engine::what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - double r = incremental_score_prune_new(g, fd, temp); - - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; -} - -// same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } return false; } @@ -261,22 +189,6 @@ void sls_engine::mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, } -// Andreas: do we really need all those temporary mpzs? -void sls_engine::mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); -} - -void sls_engine::mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); -} - void sls_engine::mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); @@ -334,7 +246,7 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + move_type mt = MV_FLIP; #endif unsigned bit = 0; @@ -373,216 +285,40 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout);); } - m_evaluator.update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); -} - -// will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; -} - -double sls_engine::find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - for (unsigned j = 1; j < max_bv_sz; j++) - { - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; -} - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif unsigned bv_sz; -#if _INSIST_PERC_ - double new_score = m_tracker.get_random_uint(16) % 100 < _INSIST_PERC_ ? 0.0 : score; -#else double new_score = score; -#endif m_tracker.reset_equal_scores(); -// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { for (unsigned i = 0; i < to_evaluate.size(); i++) { -// for (unsigned i = m_tracker.get_random_uint(16) % to_evaluate.size(); i != to_evaluate.size(); i = to_evaluate.size()) { -// for (unsigned i = to_evaluate.size(); i-- > 0; ) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { -#else -// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { for (unsigned j = 0; j < bv_sz; j++) { -// for (unsigned j = bv_sz; j-- > 0; ) { -#endif // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - //if (m_tracker.get_random_uint(1)) - //if ((move != MV_FLIP) || (new_bit > j)) - //{ - //if (what_if_new(g, fd, i, temp, new_score, best_const, best_value)) { - // new_bit = j; - // move = MV_FLIP; - //} - //} - //else - //{ - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } - //} } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -590,76 +326,41 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - //if (m_tracker.get_random_uint(1)) - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - //if (m_tracker.get_random_uint(1)) - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - //if (m_tracker.get_random_uint(1)) - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } m_mpz_manager.del(old_value); m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - - if ((new_score == score) && 1)// (m_tracker.get_random_uint(1))) - best_const = -1; return new_score; } // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, +double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value) { mpz old_value, temp, temp2; unsigned bv_sz; double new_score = score; -// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -667,22 +368,21 @@ double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & m_mpz_manager.set(old_value, m_tracker.get_value(fd)); if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { -// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { for (unsigned j = 0; j < bv_sz; j++) { mk_flip(srt, old_value, j, temp); - for (unsigned l = 0; l < _VNS_MC_TRIES_ && l < bv_sz / 2; l++) + for (unsigned l = 0; l < m_vns_mc && l < bv_sz / 2; l++) { unsigned k = m_tracker.get_random_uint(16) % bv_sz; while (k == j) k = m_tracker.get_random_uint(16) % bv_sz; mk_flip(srt, temp, k, temp2); - what_if(g, fd, i, temp2, new_score, best_const, best_value); + what_if(fd, i, temp2, new_score, best_const, best_value); } } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -692,618 +392,89 @@ double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & return new_score; } -// same as find_best_move but only considers the score of the current expression instead of the overall score -double sls_engine::find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; -} - -// first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau(goal_ref const & g) -{ - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back(&m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } - else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], *m_old_values[i]); - - m_old_values.reset(); - - return 0; -} - -// what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; -} - -// find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) -{ - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; -} - -// second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(goal_ref const & g, double old_score) -{ - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; -} - // main search loop -lbool sls_engine::search(goal_ref const & g) { +lbool sls_engine::search() { lbool res = l_undef; double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; + unsigned new_const = (unsigned)-1, new_bit; mpz new_value; move_type move; - unsigned plateau_cnt = 0; - score = rescore(g); - unsigned sz = g->size(); - - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl;); - -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - //if (m_stats.m_stopwatch.get_current_seconds() > 10.0) - //{printf("Got %f fps and size is %d with avg bw %f\n", m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds(), m_tracker.get_formula_size(), m_tracker.get_avg_bw(g)); exit(0);} + score = rescore(); + unsigned sz = m_assertions.size(); + while (check_restart(m_stats.m_moves)) { checkpoint(); m_stats.m_moves++; + if (m_stats.m_moves % m_restart_base == 0) + m_tracker.ucb_forget(m_assertions); -#if _UCT_FORGET_ - //if (m_stats.m_moves % sz == 0) - if (m_stats.m_moves % _UCT_FORGET_ == 0) - m_tracker.uct_forget(g); -#endif - -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - //ptr_vector & to_evaluate = m_tracker.get_unsat_constants_only(e); - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) { res = l_true; goto bailout; } -#endif -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + if (m_wp && m_tracker.get_random_uint(10) < m_wp) { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif + score = m_tracker.get_top_sum() / sz; + continue; } - continue; -#endif -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif old_score = score; new_const = (unsigned)-1; - move = MV_FLIP; - new_bit = 0; -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); -#if _VNS_MC_ > _VNS_REPICK_ -#if _VNS_MC_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); -#endif -#if _VNS_REPICK_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } + if (m_vns_mc && (new_const == static_cast(-1))) + score = find_best_move_mc(to_evaluate, score, new_const, new_value); + + /*if (m_vns_repick && (new_const == static_cast(-1))) + { + expr * q = m_tracker.get_new_unsat_assertion(m_assertions, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); } -#endif -#endif - -#if _VNS_MC_ < _VNS_REPICK_ -#if _VNS_REPICK_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } - } -#endif -#if _VNS_MC_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); -#endif -#endif - -#if (_VNS_MC_ == _VNS_REPICK_) && _VNS_MC_ && _VNS_REPICK_ - if (new_const == static_cast(-1)) { - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); - else { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } - } - } -#endif - + }*/ if (new_const == static_cast(-1)) { score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); + if (m_walksat && m_walksat_repick) + m_evaluator.randomize_local(m_assertions); else -#endif -#if _REPICK_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _REPICK_ == 2 - { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - m_evaluator.randomize_local(q); - else - m_evaluator.randomize_local(e); - } -#else - m_evaluator.randomize_local_n(g, to_evaluate); - //m_evaluator.randomize_local(to_evaluate); -#endif -#endif + m_evaluator.randomize_local(to_evaluate); -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif + score = m_tracker.get_top_sum() / m_assertions.size(); -#if _PAWS_ - for (unsigned i = 0; i < sz; i++) + if (m_paws_sp < 1024) { - expr * q = g->form(i); - if (m_tracker.get_random_uint(16) % 100 < _PAWS_) + for (unsigned i = 0; i < sz; i++) { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) - m_tracker.decrease_weight(q); - } - else - { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) - m_tracker.increase_weight(q); + expr * q = m_assertions[i]; + if (m_tracker.get_random_uint(10) < m_paws_sp) + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) + m_tracker.decrease_weight(q); + } + else + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) + m_tracker.increase_weight(q); + } } } -#endif - } else { func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - -bailout: - m_mpz_manager.del(new_value); - - return res; -} - -// main search loop -lbool sls_engine::search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl;); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true = false; - if (all_true) { - res = l_true; // sat - goto bailout; - } - else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl;); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl;); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl;); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl;); - } - - if (score >= 0.99999) { - // if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true = false; - if (all_true) { - res = l_true; // sat - goto bailout; - } - else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } - else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true = false; - if (all_true) { - res = l_true; // sat - goto bailout; - } - else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } + score = serious_score(fd, new_value); } } @@ -1321,80 +492,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_PAWS_ " << _PAWS_ << std::endl; - verbose_stream() << "_PAWS_INIT_ " << _PAWS_INIT_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_VNS_MC_ " << _VNS_MC_ << std::endl; - verbose_stream() << "_VNS_MC_TRIES_ " << _VNS_MC_TRIES_ << std::endl; - verbose_stream() << "_VNS_REPICK_ " << _VNS_REPICK_ << std::endl; - verbose_stream() << "_VNS_PERC_ " << _VNS_PERC_ << std::endl; - verbose_stream() << "_INSIST_PERC_ " << _INSIST_PERC_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; - verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + for (unsigned i = 0; i < g->size(); i++) + assert_expr(g->form(i)); + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + lbool res = operator()(); if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); @@ -1416,33 +521,66 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { mc = 0; } -unsigned sls_engine::check_restart(unsigned curr_value) +lbool sls_engine::operator()() { + m_tracker.initialize(m_assertions); + lbool res = l_undef; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(); + + if (res == l_undef) + { + if (m_restart_init) + m_tracker.randomize(m_assertions); + else + m_tracker.reset(m_assertions); + } + } while (res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + return res; +} + +/* Andreas: Needed for Armin's restart scheme if we don't want to use loops. +inline double sls_engine::get_restart_armin(unsigned cnt_restarts) { - if (curr_value > m_restart_limit) + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); +} +*/ + +inline unsigned sls_engine::check_restart(unsigned curr_value) +{ + if (curr_value > m_restart_next) { + /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save 1 parameter. + I leave the other versions as comments in case you want to try it again somewhen. #if _RESTART_SCHEME_ == 5 - m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); + m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); #elif _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); + m_restart_next += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? m_restart_base : (m_restart_base * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; + m_restart_next += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * m_restart_base; #elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; + m_restart_next += get_luby(m_stats.m_restarts + 1) * m_restart_base; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) - //if (m_stats.m_restarts % 3 == 2) - m_restart_limit += _RESTART_LIMIT_; + m_restart_next += m_restart_base; else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; - //m_restart_limit += (2 << (m_stats.m_restarts / 3)) * _RESTART_LIMIT_; + m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; #else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif + m_restart_limit += m_restart_base; +#endif */ + if (m_stats.m_restarts & 1) + m_restart_next += m_restart_base; + else + m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; return 0; } return 1; -} \ No newline at end of file +} diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 902c6b7a0..ff0e55f24 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,6 +22,7 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" +#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" @@ -35,17 +36,13 @@ public: stopwatch m_stopwatch; unsigned m_full_evals; unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs; stats() : m_restarts(0), m_full_evals(0), m_incr_evals(0), m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -71,14 +68,22 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; + ptr_vector m_assertions; - unsigned m_restart_limit; unsigned m_max_restarts; - unsigned m_plateau_limit; + unsigned m_walksat; + unsigned m_walksat_repick; + unsigned m_wp; + unsigned m_vns_mc; + unsigned m_vns_repick; + unsigned m_paws_sp; + unsigned m_restart_base; + unsigned m_restart_next; + unsigned m_restart_init; ptr_vector m_old_values; - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; public: sls_engine(ast_manager & m, params_ref const & p); @@ -92,78 +97,46 @@ public: void updt_params(params_ref const & _p); + void assert_expr(expr * e) { m_assertions.push_back(e); } + stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(goal_ref const & g, model & mdl); - + bool full_eval(model & mdl); void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result); void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value); - - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - - - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); - - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); - - - lbool search(goal_ref const & g); + lbool search(void); + lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); - lbool search_old(goal_ref const & g); - double get_restart_armin(unsigned cnt_restarts); - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - bool what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value); - double incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value); + double top_score(); + double rescore(); + double serious_score(func_decl * fd, const mpz & new_value); + double incremental_score(func_decl * fd, const mpz & new_value); - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value); + double incremental_score_prune(func_decl * fd, const mpz & new_value); + double find_best_move(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - double top_score(goal_ref const & g); - double rescore(goal_ref const & g); - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); -#endif - - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_mc(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value); void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(goal_ref const & g); - - bool handle_plateau(goal_ref const & g); - bool handle_plateau(goal_ref const & g, double old_score); + //inline double get_restart_armin(unsigned cnt_restarts); inline unsigned check_restart(unsigned curr_value); }; -#endif \ No newline at end of file +#endif diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 78f2cb79a..37bfa5a2d 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -81,11 +81,7 @@ public: case OP_AND: { m_mpz_manager.set(result, m_one); for (unsigned i = 0; i < n_args; i++) -#if _DIRTY_UP_ - if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) && !m_tracker.is_top_expr(args[i])) { -#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { -#endif m_mpz_manager.set(result, m_zero); break; } @@ -93,11 +89,7 @@ public: } case OP_OR: { for (unsigned i = 0; i < n_args; i++) -#if _DIRTY_UP_ - if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) || m_tracker.is_top_expr(args[i])) { -#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { -#endif m_mpz_manager.set(result, m_one); break; } @@ -105,16 +97,9 @@ public: } case OP_NOT: { SASSERT(n_args == 1); -#if _DIRTY_UP_ - if (m_tracker.is_top_expr(args[0])) - m_mpz_manager.set(result, m_zero); - else - m_mpz_manager.set(result, (m_mpz_manager.is_zero(m_tracker.get_value(args[0]))) ? m_one : m_zero); -#else const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); -#endif break; } case OP_EQ: { @@ -545,9 +530,7 @@ public: expr_fast_mark1 visited; mpz new_value; -#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ double new_score; -#endif SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { @@ -559,8 +542,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); -#if _REAL_RS_ || _REAL_PBFS_ - //if (!m_tracker.has_uplinks(cur)) +#if _REAL_RS_ if (m_tracker.is_top_expr(cur)) { if (m_mpz_manager.eq(new_value,m_one)) @@ -570,25 +552,12 @@ public: } #endif + new_score = m_tracker.score(cur); + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif - m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); -#else -#if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif #endif if (m_tracker.has_uplinks(cur)) { @@ -617,9 +586,7 @@ public: expr_fast_mark1 visited; mpz new_value; -#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ double new_score; -#endif SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { @@ -630,25 +597,12 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); + new_score = m_tracker.score(cur); + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif - m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); -#else -#if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif #endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -684,11 +638,7 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ run_serious_update(max_depth); -#else - run_update(max_depth); -#endif } void update(func_decl * fd, const mpz & new_value) { @@ -713,7 +663,6 @@ public: run_serious_update(cur_depth); } -#if _EARLY_PRUNE_ unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; @@ -727,19 +676,15 @@ public: expr * cur = cur_depth_exprs[i]; new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - //if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) pot_benefits = 1; if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - //if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { @@ -754,9 +699,6 @@ public: } } } - else - { - } } cur_depth_exprs.reset(); @@ -770,15 +712,11 @@ public: for (unsigned i = 0; i < cur_size; i++) { expr * cur = cur_depth_exprs[i]; -#if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -859,161 +797,18 @@ public: } return run_update_bool_prune(cur_depth); } -#endif - - unsigned run_update_bool_prune_new(unsigned cur_depth) { - expr_fast_mark1 visited; - - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); - - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - - for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - prune_score = m_tracker.get_score_prune(cur); - m_tracker.set_score(cur, new_score); - - if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; - - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - else - { - } - } - - cur_depth_exprs.reset(); - cur_depth--; - - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } - - return pot_benefits; - } - - unsigned update_prune_new(func_decl * fd, const mpz & new_value) { - m_tracker.set_value(fd, new_value); - expr * ep = m_tracker.get_entry_point(fd); - unsigned cur_depth = m_tracker.get_distance(ep); - - if (m_traversal_stack_bool.size() <= cur_depth) - m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); - - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune_new(cur_depth); - } void randomize_local(ptr_vector & unsat_constants) { - // Randomize _all_ candidates: - - //// bool did_something = false; - //for (unsigned i = 0; i < unsat_constants.size(); i++) { - // func_decl * fd = unsat_constants[i]; - // mpz temp = m_tracker.get_random(fd->get_range()); - // // if (m_mpz_manager.neq(temp, m_tracker.get_value(fd))) { - // // did_something = true; - // // } - // update(fd, temp); - // m_mpz_manager.del(temp); - //} - // Randomize _one_ candidate: unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); func_decl * fd = unsat_constants[r]; -#if _PERC_CHANGE_ - sort * srt = fd->get_range(); - mpz temp; - - if (m_manager.is_bool(srt)) - m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); - - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } -#else mpz temp = m_tracker.get_random(fd->get_range()); -#endif -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ serious_update(fd, temp); -#else - update(fd, temp); -#endif + m_mpz_manager.del(temp); - TRACE("sls", /*tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl;*/ - tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; + TRACE("sls", tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); @@ -1023,36 +818,9 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(goal_ref const & g, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(g, flip)); + void randomize_local(ptr_vector const & as) { + randomize_local(m_tracker.get_unsat_constants(as)); } - - void randomize_local_n(goal_ref const & g, ptr_vector & unsat_constants) { - unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); - func_decl * fd = unsat_constants[r]; - sort * srt = fd->get_range(); - unsigned bv_sz = m_manager.is_bool(srt) ? 1 : m_bv_util.get_bv_size(srt); - mpz max_val = m_tracker.get_random(srt); - update(fd, max_val); - double max_score = m_tracker.get_top_sum() / g->size(); - mpz temp_val; - double temp_score; - for (unsigned i = 1; i < 2; i++) - //for (unsigned i = 1; i < bv_sz; i++) - { - m_mpz_manager.set(temp_val, m_tracker.get_random(srt)); - update(fd, temp_val); - temp_score = m_tracker.get_top_sum() / g->size(); - if (temp_score > max_score) - { - m_mpz_manager.set(max_val, temp_val); - max_score = temp_score; - } - } - update(fd, max_val); - m_mpz_manager.del(temp_val); - m_mpz_manager.del(max_val); - } }; #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 0b6b01e7c..6e1102dd2 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -1507,16 +1507,12 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? - //mk_ctx_simplify_tactic(m, ctx_p), - // Andreas: This one at least eliminates top level duplicates ... but has very bad effects on performance! - //mk_simplify_tactic(m), mk_nnf_tactic(m, p)); } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); -// tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); + //tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 87c90f1f8..65011dc8d 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,7 +20,9 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"goal.h" +#include"for_each_expr.h" +#include"ast_smt2_pp.h" +#include"bv_decl_plugin.h" #include"model.h" #include"sls_compilation_settings.h" @@ -37,11 +39,7 @@ class sls_tracker { mpz m_zero, m_one, m_two; struct value_score { -#if _EARLY_PRUNE_ value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; -#else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; -#endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; @@ -78,24 +76,22 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; -#if _UCT_ + + unsigned m_walksat; + unsigned m_ucb; + double m_ucb_constant; + unsigned m_ucb_init; + double m_ucb_forget; unsigned m_touched; -#endif -#if _REAL_RS_ || _REAL_PBFS_ + double m_scale_unsat; + unsigned m_paws_init; +#if _REAL_RS_ ptr_vector m_unsat_expr; obj_map m_where_false; expr** m_list_false; #endif -#if _PAWS_ obj_map m_weights; - //obj_map m_weights; -#endif -#if _CACHE_TOP_SCORE_ double m_top_sum; -#endif -#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ - double m_weight_dist_factor; -#endif unsigned m_equal_scores; public: @@ -116,6 +112,17 @@ public: m_mpz_manager.del(m_two); } + void updt_params(params_ref const & _p) { + sls_params p(_p); + m_walksat = p.walksat(); + m_ucb = p.walksat_ucb(); + m_ucb_constant = p.walksat_ucb_constant(); + m_ucb_init = p.walksat_ucb_init(); + m_ucb_forget = p.walksat_ucb_forget(); + m_scale_unsat = p.scale_unsat(); + m_paws_init = p.paws_init(); + } + unsigned get_formula_size() { return m_scores.size(); } @@ -141,12 +148,6 @@ public: return sum / count; } -#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ - inline void set_weight_dist_factor(double val) { - m_weight_dist_factor = val; - } -#endif - void reset_equal_scores() { m_equal_scores = 1; } @@ -155,13 +156,8 @@ public: return ++m_equal_scores; } -#if _CACHE_TOP_SCORE_ inline void adapt_top_sum(expr * e, double add, double sub) { -#if _PAWS_ m_top_sum += m_weights.find(e) * (add - sub); -#else - m_top_sum += add - sub; -#endif } inline void set_top_sum(double new_score) { @@ -171,7 +167,6 @@ public: inline double get_top_sum() { return m_top_sum; } -#endif inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); @@ -217,7 +212,6 @@ public: return get_score(ep); } -#if _EARLY_PRUNE_ inline void set_score_prune(expr * n, double score) { SASSERT(m_scores.contains(n)); m_scores.find(n).score_prune = score; @@ -237,7 +231,6 @@ public: SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; } -#endif inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); @@ -271,7 +264,7 @@ public: return m_uplinks.find(n); } -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ void debug_real(goal_ref const & g, unsigned flip) { unsigned count = 0; @@ -318,21 +311,22 @@ public: } #endif -#if _UCT_ - void uct_forget(goal_ref const & g) { - expr * e; - unsigned touched_old, touched_new; - - for (unsigned i = 0; i < g->size(); i++) + inline void ucb_forget(ptr_vector & as) { + if (m_ucb_forget < 1.0) { - e = g->form(i); - touched_old = m_scores.find(e).touched; - touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); - m_scores.find(e).touched = touched_new; - m_touched += touched_new - touched_old; + expr * e; + unsigned touched_old, touched_new; + + for (unsigned i = 0; i < as.size(); i++) + { + e = as[i]; + touched_old = m_scores.find(e).touched; + touched_new = (unsigned)((touched_old - 1) * m_ucb_forget + 1); + m_scores.find(e).touched = touched_new; + m_touched += touched_new - touched_old; + } } } -#endif void initialize(app * n) { // Build score table @@ -409,12 +403,12 @@ public: } }; - void calculate_expr_distances(goal_ref const & g) { + void calculate_expr_distances(ptr_vector const & as) { // precondition: m_scores is set up. - unsigned sz = g->size(); + unsigned sz = as.size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(g->form(i))); + stack.push_back(to_app(as[i])); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -462,31 +456,24 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(goal_ref const & g) { + void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = g->size(); + unsigned sz = as.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); else printf("this is already in ...\n"); - // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 - initialize_recursive(proc, visited, e); -#endif for_each_expr(proc, visited, e); } visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 || _INTENSIFICATION_ - initialize_recursive(e); -#endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -494,11 +481,11 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(g); + calculate_expr_distances(as); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ m_list_false = new expr*[sz]; //for (unsigned i = 0; i < sz; i++) //{ @@ -507,50 +494,38 @@ public: //} #endif -#if _PAWS_ for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_weights.contains(e)) - m_weights.insert(e, _PAWS_INIT_); + m_weights.insert(e, m_paws_init); } -#endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(as[i]); #endif -#if _UCT_ - m_touched = _UCT_INIT_ ? g->size() : 1; -#endif + m_touched = m_ucb_init ? as.size() : 1; } -#if _PAWS_ void increase_weight(expr * e) { - //printf("Increasing %d to", m_weights.find(e)); m_weights.find(e)++; - //m_weights.find(e) *= 1.1; - //printf(" %d\n", m_weights.find(e)); } void decrease_weight(expr * e) { unsigned old_weight = m_weights.find(e); - m_weights.find(e) = old_weight > _PAWS_INIT_ ? old_weight - 1 : _PAWS_INIT_; - //m_weights.find(e) = old_weight > 1.1 ? old_weight / 1.1 : 1; - //printf("Decreasing %d to %d\n", old_weight, m_weights.find(e)); + m_weights.find(e) = old_weight > m_paws_init ? old_weight - 1 : m_paws_init; } unsigned get_weight(expr * e) - //double get_weight(expr * e) { return m_weights.find(e); } -#endif -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ void make_assertion(expr * e) { if (m_where_false.contains(e)) @@ -683,7 +658,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(goal_ref const & g) { + void randomize(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -695,15 +670,9 @@ public: } TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); - -#if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; -#endif } - void reset(goal_ref const & g) { + void reset(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -711,15 +680,8 @@ public: set_value(it->m_value, temp); m_mpz_manager.del(temp); } - -#if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; -#endif } -#if _EARLY_PRUNE_ void setup_occs(expr * n, bool negated = false) { if (m_manager.is_bool(n)) { @@ -752,7 +714,6 @@ public: else NOT_IMPLEMENTED_YET(); } -#endif double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); @@ -770,57 +731,29 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. -#if _SCORE_AND_AVG_ + /* Andreas: Seems to have no effect. But maybe you want to try it again at some point. double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) -#if _DIRTY_UP_ - sum += is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else sum += get_score(args[i]); -#endif - res = sum / (double) a->get_num_args(); -#else + res = sum / (double) a->get_num_args(); */ double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { -#if _DIRTY_UP_ - double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else double cur = get_score(args[i]); -#endif if (cur < min) min = cur; } res = min; -#endif } else if (m_manager.is_or(n)) { SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); // Andreas: Seems to have no effect. Probably it is still too similar to the original version. -#if _SCORE_OR_MUL_ - double inv = 1.0; - for (unsigned i = 0; i < a->get_num_args(); i++) { -#if _DIRTY_UP_ - double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else - double cur = get_score(args[i]); -#endif - inv *= (1.0 - get_score(args[i])); - } - res = 1.0 - inv; -#else double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { -#if _DIRTY_UP_ - double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else double cur = get_score(args[i]); -#endif if (cur > max) max = cur; } res = max; -#endif } else if (m_manager.is_ite(n)) { SASSERT(!negated); @@ -855,24 +788,14 @@ public: m_mpz_manager.bitwise_xor(v0, v1, diff); unsigned hamming_distance = 0; unsigned bv_sz = m_bv_util.get_bv_size(arg0); - #if 1 // unweighted hamming distance + // unweighted hamming distance while (!m_mpz_manager.is_zero(diff)) { - //m_mpz_manager.set(diff_m1, diff); - //m_mpz_manager.dec(diff_m1); - //m_mpz_manager.bitwise_and(diff, diff_m1, diff); - //hamming_distance++; if (!m_mpz_manager.is_even(diff)) { hamming_distance++; } m_mpz_manager.machine_div(diff, m_two, diff); } res = 1.0 - (hamming_distance / (double) bv_sz); - #else - rational r(diff); - r /= m_powers(bv_sz); - double dbl = r.get_double(); - res = (dbl < 0.0) ? 1.0 : (dbl > 1.0) ? 0.0 : 1.0 - dbl; - #endif TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << " ; HD = " << hamming_distance << " ; SZ = " << bv_sz << std::endl; ); @@ -891,205 +814,36 @@ public: if (negated) { if (m_mpz_manager.gt(x, y)) - { - /*mpz diff; - m_mpz_manager.sub(x, y, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -/* mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_gt = 0; - unsigned curr_gt = 0; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 1; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 0; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); - m_mpz_manager.del(x_copy); - m_mpz_manager.del(y_copy);*/ -#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = 1.0 - n.get_double(); + double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; - //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } } else { if (m_mpz_manager.le(x, y)) - { - /*mpz diff; - m_mpz_manager.sub(y, x, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -/* mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_le = 1; - unsigned curr_le = 1; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_le = curr_le; - curr_le = 0; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_le = curr_le; - curr_le = 1; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2);*/ -#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = 1.0 - n.get_double(); - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + double dbl = n.get_double(); + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } -/* else if (m_bv_util.is_bv_sle(n)) { // x <= y - app * a = to_app(n); - SASSERT(a->get_num_args() == 2); - const mpz & x = get_value(a->get_arg(0)); - const mpz & y = get_value(a->get_arg(1)); - int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); - - mpz x_unsigned; - mpz y_unsigned; - const mpz & p = m_powers(bv_sz); - const mpz & p_half = m_powers(bv_sz-1); - if (x >= p_half) { m_mpz_manager.sub(x, p, x_unsigned); } - if (y >= p_half) { m_mpz_manager.sub(y, p, y_unsigned); } - - if (negated) { - if (x_unsigned > y_unsigned) - res = 1.0; - else { - mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_gt = 0; - unsigned curr_gt = 0; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 1; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 0; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); - m_mpz_manager.del(x_copy); - m_mpz_manager.del(y_copy); - } - } - else { - if (x_unsigned <= y_unsigned) - res = 1.0; - else { - mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_le = 1; - unsigned curr_le = 1; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_le = curr_le; - curr_le = 0; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_le = curr_le; - curr_le = 1; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2); - } - } - TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << - m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); - - m_mpz_manager.del(x_unsigned); - m_mpz_manager.del(y_unsigned); - }*/ - else if (m_bv_util.is_bv_sle(n)) { // x <= y + else if (m_bv_util.is_bv_sle(n)) { // x <= y app * a = to_app(n); SASSERT(a->get_num_args() == 2); mpz x; m_mpz_manager.set(x, get_value(a->get_arg(0))); @@ -1102,61 +856,32 @@ public: if (negated) { if (x > y) - { - /*mpz diff; - m_mpz_manager.sub(x, y, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= p; - double dbl = 1.0 - n.get_double(); - //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + double dbl = n.get_double(); + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } else { if (x <= y) - { - /*mpz diff; - m_mpz_manager.sub(y, x, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); SASSERT(!m_mpz_manager.is_neg(diff)); rational n(diff); n /= p; - double dbl = 1.0 - n.get_double(); - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + double dbl = n.get_double(); + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); @@ -1171,11 +896,7 @@ public: expr * child = a->get_arg(0); if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. NOT_IMPLEMENTED_YET(); -#if _DIRTY_UP_ - res = is_top_expr(child) ? 0.0 : score_bool(child, true); -#else res = score_bool(child, true); -#endif } else if (m_manager.is_distinct(n)) { app * a = to_app(n); @@ -1199,25 +920,11 @@ public: SASSERT(res >= 0.0 && res <= 1.0); -#if _WEIGHT_DIST_ app * a = to_app(n); family_id afid = a->get_family_id(); if (afid == m_bv_util.get_family_id()) -#endif -#if _WEIGHT_DIST_ == 1 -#if _WEIGHT_TOGGLE_ - if (res < 1.0) res *= m_weight_dist_factor; -#else - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; -#endif -#elif _WEIGHT_DIST_ == 2 - res *= res; -#elif _WEIGHT_DIST_ == 3 - if (res < 1.0) res = 0.0; -#elif _WEIGHT_DIST_ == 4 - if (res < 1.0) res *= m_weight_dist_factor; -#endif + if (res < 1.0) res *= m_scale_unsat; TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; @@ -1268,33 +975,6 @@ public: NOT_IMPLEMENTED_YET(); } - expr * get_unsat_expression(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - } - } - return e; - } - ptr_vector & get_constants(expr * e) { ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); @@ -1306,13 +986,17 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { - if (sz == 1) - return get_constants(); + ptr_vector & get_unsat_constants_gsat(ptr_vector const & as) { + unsigned sz = as.size(); + if (sz == 1) { + if (m_mpz_manager.neq(get_value(as[0]), m_one)) + return get_constants(); + } + m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1326,35 +1010,6 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { - for (unsigned i = pos; i < sz; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - return 0; - } - - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); - // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. - if (!q) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - return m_temp_constants; - } - ptr_vector & get_unsat_constants_walksat(expr * e) { if (!e || m_temp_constants.size()) return m_temp_constants; @@ -1368,420 +1023,89 @@ public: return m_temp_constants; } - ptr_vector & go_deeper(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - } - ptr_vector const & this_decls = m_constants_occ.find(e); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - return m_temp_constants; - } + ptr_vector & get_unsat_constants(ptr_vector const & as) { + if (m_walksat) + { + expr * e = get_unsat_assertion(as); - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); - if (!q) - return m_temp_constants; - - return go_deeper(q); - } - - void go_deeper_only(expr * e) { - //if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned cnt_unsat = 0, pos = -1; - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - //if (m_mpz_manager.neq(get_value(q), m_one)) go_deeper(q); - } - go_deeper(args[pos]); - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - go_deeper(q); - } - } - //} - else - { - ptr_vector const & this_decls = m_constants_occ.find(e); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - } - } - - ptr_vector & get_unsat_constants_only(expr * e) { - if (e && !m_temp_constants.size()) - go_deeper_only(e); - - return m_temp_constants; - } - - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); - - if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + if (!e) { m_temp_constants.reset(); return m_temp_constants; } - else - return get_constants(); - } - else { - m_temp_constants.reset(); -#if _FOCUS_ == 1 -#if _UCT_ - unsigned pos = -1; - value_score vscore; -#if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - for (unsigned i = start_index; i < sz; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); - -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } -#else - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); -// for (unsigned i = 0; i < m_where_false.size(); i++) { -// expr * e = m_list_false[i]; - vscore = m_scores.find(e); -#if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); -#elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; -#elif _UCT_ == 3 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); -#endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } - } -#endif - if (pos == static_cast(-1)) - return m_temp_constants; - -#if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; - m_touched++; -#elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; -#endif - expr * e = g->form(pos); -// expr * e = m_list_false[pos]; - -#elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } - } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); -#elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } - } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); -#elif _BFS_ == 1 - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; - expr * e = get_unsat_assertion(g, sz, pos); -#elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); -#elif _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - expr * e = m_list_false[get_random_uint(16) % sz]; -#elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[flip % sz]; -#else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; - expr * e = get_unsat_assertion(g, sz, pos); -#endif return get_unsat_constants_walksat(e); -#elif _FOCUS_ == 2 -#if _BFS_ - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; -#else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; -#endif - return get_unsat_constants_crsat(g, sz, pos); -#else - return get_unsat_constants_gsat(g, sz); -#endif } + else + return get_unsat_constants_gsat(as); } - expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); - + expr * get_unsat_assertion(ptr_vector const & as) { + unsigned sz = as.size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_zero)) - return g->form(0); + if (m_mpz_manager.neq(get_value(as[0]), m_one)) + return as[0]; else return 0; } - m_temp_constants.reset(); -#if _FOCUS_ == 1 -#if _UCT_ + unsigned pos = -1; - value_score vscore; -#if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - - for (unsigned i = start_index; i < sz; i++) + if (m_ucb) { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score + _UCT_EPS_; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score + _UCT_EPS_; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } -#else - double max = -1.0; + value_score vscore; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); -#if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); -#elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; -#elif _UCT_ == 3 + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); +#if _UCT_ == 3 double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } -#endif - if (pos == static_cast(-1)) - return 0; + if (pos == static_cast(-1)) + return 0; -#if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; - m_touched++; -#elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; -#endif + m_scores.find(as[pos]).touched++; + m_touched++; // return m_list_false[pos]; - return g->form(pos); - -#elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } - if (pos == static_cast(-1)) - return 0; - return g->form(pos); -#elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } - if (pos == static_cast(-1)) - return 0; - return g->form(pos); -#elif _BFS_ == 1 - unsigned int pos = flip % sz; - return get_unsat_assertion(g, sz, pos); -#elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return 0; - return g->form(pos); -#elif _REAL_RS_ + else + { + unsigned cnt_unsat = 0; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return 0; + } + + return as[pos]; +#if _REAL_RS_ //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; sz = m_where_false.size(); if (sz == 0) return 0; return m_list_false[get_random_uint(16) % sz]; -#elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return0; - else - return m_list_false[flip % sz]; -#else - unsigned int pos = get_random_uint(16) % sz; - return get_unsat_assertion(g, sz, pos); -#endif - return g->form(pos); -#elif _FOCUS_ == 2 -#if _BFS_ - unsigned int pos = flip % sz; -#else - unsigned int pos = get_random_uint(16) % sz; -#endif - return get_unsat_constants_crsat(g, sz, pos); #endif } - expr * get_new_unsat_assertion(goal_ref const & g, expr * e) { - unsigned sz = g->size(); - + expr * get_new_unsat_assertion(ptr_vector const & as, expr * e) { + unsigned sz = as.size(); if (sz == 1) return 0; - m_temp_constants.reset(); - + unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (g->form(i) != e)) pos = i; + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (as[i] != e)) pos = i; if (pos == static_cast(-1)) return 0; - return g->form(pos); + return as[pos]; } }; From 39ea6234a4ae1b3588d1c4b6750c21382cae6b4d Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 01:07:30 +0100 Subject: [PATCH 166/507] Fixed bug with VNS repick. --- src/tactic/sls/sls_compilation_settings.h | 2 +- src/tactic/sls/sls_engine.cpp | 22 +++++++++++++++++----- src/tactic/sls/sls_tracker.h | 7 ++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 9add78daa..a649bc9ed 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -23,7 +23,7 @@ Notes: #define _SLS_COMPILATION_SETTINGS_H_ // shall we use addition/subtraction? -#define _USE_ADDSUB_ 0 +#define _USE_ADDSUB_ 1 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index c240a0c51..af8ae1df2 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -68,6 +68,12 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_base = p.restart_base(); m_restart_next = m_restart_base; m_restart_init = p.restart_init(); + + // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. + if (m_walksat_repick && !m_walksat) + NOT_IMPLEMENTED_YET(); + if (m_vns_repick && !m_walksat) + NOT_IMPLEMENTED_YET(); } void sls_engine::checkpoint() { @@ -435,19 +441,25 @@ lbool sls_engine::search() { if (m_vns_mc && (new_const == static_cast(-1))) score = find_best_move_mc(to_evaluate, score, new_const, new_value); - /*if (m_vns_repick && (new_const == static_cast(-1))) + if (m_vns_repick && (new_const == static_cast(-1))) { - expr * q = m_tracker.get_new_unsat_assertion(m_assertions, e); + expr * q = m_tracker.get_new_unsat_assertion(m_assertions); if (q) { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); + + if (new_const != static_cast(-1)) { + func_decl * fd = to_evaluate2[new_const]; + score = serious_score(fd, new_value); + continue; + } } - }*/ + } if (new_const == static_cast(-1)) { score = old_score; - if (m_walksat && m_walksat_repick) + if (m_walksat_repick) m_evaluator.randomize_local(m_assertions); else m_evaluator.randomize_local(to_evaluate); diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 65011dc8d..7b48057d4 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -76,7 +76,7 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; - + unsigned m_last_pos; unsigned m_walksat; unsigned m_ucb; double m_ucb_constant; @@ -1082,6 +1082,7 @@ public: return 0; } + m_last_pos = pos; return as[pos]; #if _REAL_RS_ //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; @@ -1093,7 +1094,7 @@ public: #endif } - expr * get_new_unsat_assertion(ptr_vector const & as, expr * e) { + expr * get_new_unsat_assertion(ptr_vector const & as) { unsigned sz = as.size(); if (sz == 1) return 0; @@ -1101,7 +1102,7 @@ public: unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (as[i] != e)) pos = i; + if ((i != m_last_pos) && m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return 0; From b5a9e0a1f5ab1cf5df67baa068eec0963df55be2 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 16:10:44 +0100 Subject: [PATCH 167/507] Backup before I touch early pruning ... --- src/tactic/sls/sls_compilation_settings.h | 3 --- src/tactic/sls/sls_engine.cpp | 30 +++++++++++++---------- src/tactic/sls/sls_engine.h | 1 + src/tactic/sls/sls_evaluator.h | 4 +-- src/tactic/sls/sls_tracker.h | 9 ------- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index a649bc9ed..5c837b4b2 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,9 +22,6 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index af8ae1df2..5d4df237e 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -61,6 +61,7 @@ void sls_engine::updt_params(params_ref const & _p) { m_walksat = p.walksat(); m_walksat_repick = p.walksat_repick(); m_paws_sp = p.paws_sp(); + m_paws = m_paws_sp < 1024; m_wp = p.wp(); m_vns_mc = p.vns_mc(); m_vns_repick = p.vns_repick(); @@ -173,7 +174,6 @@ bool sls_engine::what_if( // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { - m_tracker.reset_equal_scores(); best_score = r; best_const = fd_inx; m_mpz_manager.set(best_value, temp); @@ -244,16 +244,12 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); else { -#if _USE_ADDSUB_ if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; move_type mt = (move_type)rnd_mv; // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; -#else - move_type mt = MV_FLIP; -#endif unsigned bit = 0; switch (mt) @@ -308,8 +304,9 @@ double sls_engine::find_best_move( unsigned bv_sz; double new_score = score; - m_tracker.reset_equal_scores(); - + //unsigned offset = m_tracker.get_random_uint(16) % to_evaluate.size(); + //for (unsigned j = 0; j < to_evaluate.size(); j++) { + //unsigned i = (j + offset) % to_evaluate.size(); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -328,7 +325,6 @@ double sls_engine::find_best_move( } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); @@ -341,7 +337,6 @@ double sls_engine::find_best_move( if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } -#endif // try inverting mk_inv(bv_sz, old_value, temp); if (what_if(fd, i, temp, new_score, best_const, best_value)) @@ -418,7 +413,7 @@ lbool sls_engine::search() { #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif - + // get candidate variables ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) { @@ -426,6 +421,7 @@ lbool sls_engine::search() { goto bailout; } + // random walk with probability wp / 1024 if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); @@ -436,14 +432,18 @@ lbool sls_engine::search() { old_score = score; new_const = (unsigned)-1; + // find best increasing move score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + // use Monte Carlo 2-bit-flip sampling if no increasing move was found previously if (m_vns_mc && (new_const == static_cast(-1))) score = find_best_move_mc(to_evaluate, score, new_const, new_value); + // repick assertion if no increasing move was found previously if (m_vns_repick && (new_const == static_cast(-1))) { expr * q = m_tracker.get_new_unsat_assertion(m_assertions); + // only apply if another unsatisfied assertion actually exists if (q) { ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); @@ -457,6 +457,7 @@ lbool sls_engine::search() { } } + // randomize if no increasing move was found if (new_const == static_cast(-1)) { score = old_score; if (m_walksat_repick) @@ -466,16 +467,19 @@ lbool sls_engine::search() { score = m_tracker.get_top_sum() / m_assertions.size(); - if (m_paws_sp < 1024) + // update assertion weights if a weigthing is enabled (sp < 1024) + if (m_paws) { for (unsigned i = 0; i < sz; i++) { expr * q = m_assertions[i]; + // smooth weights with probability sp / 1024 if (m_tracker.get_random_uint(10) < m_paws_sp) { if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) m_tracker.decrease_weight(q); } + // increase weights otherwise else { if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) @@ -484,6 +488,7 @@ lbool sls_engine::search() { } } } + // otherwise, apply most increasing move else { func_decl * fd = to_evaluate[new_const]; score = serious_score(fd, new_value); @@ -507,7 +512,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; @@ -570,7 +574,7 @@ inline unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_next) { - /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save 1 parameter. + /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save one parameter. I leave the other versions as comments in case you want to try it again somewhen. #if _RESTART_SCHEME_ == 5 m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ff0e55f24..94f3fa626 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -76,6 +76,7 @@ protected: unsigned m_wp; unsigned m_vns_mc; unsigned m_vns_repick; + unsigned m_paws; unsigned m_paws_sp; unsigned m_restart_base; unsigned m_restart_next; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 37bfa5a2d..200a0e380 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -37,9 +37,7 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; -#if _EARLY_PRUNE_ vector > m_traversal_stack_bool; -#endif public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -753,7 +751,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // Andreas: Should actually always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 7b48057d4..a815c9ad3 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -92,7 +92,6 @@ private: #endif obj_map m_weights; double m_top_sum; - unsigned m_equal_scores; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -148,14 +147,6 @@ public: return sum / count; } - void reset_equal_scores() { - m_equal_scores = 1; - } - - unsigned inc_equal_scores() { - return ++m_equal_scores; - } - inline void adapt_top_sum(expr * e, double add, double sub) { m_top_sum += m_weights.find(e) * (add - sub); } From c4fb21cca1e1d01cddb2690bc3fa6a91746f36a5 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Wed, 23 Apr 2014 14:52:18 +0100 Subject: [PATCH 168/507] Moved parameters to the right file. Almost clean. --- src/tactic/sls/sls_compilation_settings.h | 5 +-- src/tactic/sls/sls_engine.cpp | 38 +++++++++++------------ src/tactic/sls/sls_engine.h | 3 +- src/tactic/sls/sls_evaluator.h | 5 --- src/tactic/sls/sls_params.pyg | 20 ++++++++++-- src/tactic/sls/sls_tracker.h | 33 +++++++++----------- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 5c837b4b2..707802cf4 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,10 +22,7 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +// should we use unsat-structures as done in SLS 4 SAT? #define _REAL_RS_ 0 -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 5d4df237e..a1c72609c 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -70,6 +70,8 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_next = m_restart_base; m_restart_init = p.restart_init(); + m_early_prune = p.early_prune(); + // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. if (m_walksat_repick && !m_walksat) NOT_IMPLEMENTED_YET(); @@ -117,7 +119,7 @@ double sls_engine::top_score() { m_tracker.set_top_sum(top_sum); - return top_sum / (double)sz; + return top_sum; } double sls_engine::rescore() { @@ -129,21 +131,21 @@ double sls_engine::rescore() { double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); } double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); } double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); else - return 0.0; + return -DBL_MAX; } // checks whether the score outcome of a given move is better than the previous score @@ -160,11 +162,11 @@ bool sls_engine::what_if( m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif -#if _EARLY_PRUNE_ - double r = incremental_score_prune(fd, temp); -#else - double r = incremental_score(fd, temp); -#endif + double r; + if (m_early_prune) + r = incremental_score_prune(fd, temp); + else + r = incremental_score(fd, temp); #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl;); @@ -342,11 +344,8 @@ double sls_engine::find_best_move( if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; } - // reset to what it was before - double check = incremental_score(fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); + incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -381,9 +380,8 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double } } } - // reset to what it was before - double check = incremental_score(fd, old_value); + incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -408,7 +406,10 @@ lbool sls_engine::search() { checkpoint(); m_stats.m_moves++; if (m_stats.m_moves % m_restart_base == 0) + { m_tracker.ucb_forget(m_assertions); + //score = rescore(); + } #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); @@ -425,7 +426,7 @@ lbool sls_engine::search() { if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); - score = m_tracker.get_top_sum() / sz; + score = m_tracker.get_top_sum(); continue; } @@ -465,7 +466,7 @@ lbool sls_engine::search() { else m_evaluator.randomize_local(to_evaluate); - score = m_tracker.get_top_sum() / m_assertions.size(); + score = m_tracker.get_top_sum(); // update assertion weights if a weigthing is enabled (sp < 1024) if (m_paws) @@ -513,7 +514,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { assert_expr(g->form(i)); verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; lbool res = operator()(); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 94f3fa626..ac8610871 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -81,8 +81,7 @@ protected: unsigned m_restart_base; unsigned m_restart_next; unsigned m_restart_init; - - ptr_vector m_old_values; + unsigned m_early_prune; typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 200a0e380..e4cf3c466 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -554,9 +554,7 @@ public: if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#if _EARLY_PRUNE_ m_tracker.set_score_prune(cur, new_score); -#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -599,9 +597,6 @@ public: if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#if _EARLY_PRUNE_ - m_tracker.set_score_prune(cur, new_score); -#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index cc3e05966..98875b20d 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -2,7 +2,21 @@ def_module_params('sls', export=True, description='Experimental Stochastic Local Search Solver (for QFBV only).', params=(max_memory_param(), - ('restarts', UINT, UINT_MAX, '(max) number of restarts'), - ('plateau_limit', UINT, 10, 'pleateau limit'), - ('random_seed', UINT, 0, 'random seed') + ('max_restarts', UINT, UINT_MAX, 'maximum number of restarts'), + ('walksat', BOOL, 1, 'use walksat assertion selection (instead of gsat)'), + ('walksat_ucb', BOOL, 1, 'use bandit heuristic for walksat assertion selection (instead of random)'), + ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), + ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), + ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), + ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), + ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), + ('paws_init', UINT, 40, 'initial/minimum assertion weights'), + ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), + ('wp', UINT, 0, 'random walk with probability wp / 1024'), + ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), + ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), + ('restart_base', UINT, 100, 'base restart interval given by moves per run'), + ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), + ('early_prune', BOOL, 1, 'use early pruning for score prediction'), + ('random_seed', UINT, 0, 'random seed') )) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index a815c9ad3..507596273 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -44,11 +44,9 @@ class sls_tracker { unsynch_mpz_manager * m; mpz value; double score; -#if _EARLY_PRUNE_ double score_prune; unsigned has_pos_occ; unsigned has_neg_occ; -#endif unsigned distance; // max distance from any root unsigned touched; value_score & operator=(const value_score & other) { @@ -122,6 +120,7 @@ public: m_paws_init = p.paws_init(); } + /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. unsigned get_formula_size() { return m_scores.size(); } @@ -145,7 +144,7 @@ public: } return sum / count; - } + }*/ inline void adapt_top_sum(expr * e, double add, double sub) { m_top_sum += m_weights.find(e) * (add - sub); @@ -417,6 +416,8 @@ public: } } + /* Andreas: Used this at some point to have values for the non-top-level expressions. + However, it did not give better performance but even cause some additional m/o - is not used currently. void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { if (m_manager.is_and(e) || m_manager.is_or(e)) { app * a = to_app(e); @@ -445,7 +446,7 @@ public: find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + }*/ void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); @@ -455,8 +456,6 @@ public: expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); - else - printf("this is already in ...\n"); for_each_expr(proc, visited, e); } @@ -464,7 +463,6 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; - // Andreas: Maybe not fully correct. ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -488,15 +486,16 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; - if (!m_weights.contains(e)) + + // initialize weights + if (!m_weights.contains(e)) m_weights.insert(e, m_paws_init); + + // positive/negative occurences used for early pruning + setup_occs(as[i]); } -#if _EARLY_PRUNE_ - for (unsigned i = 0; i < sz; i++) - setup_occs(as[i]); -#endif - + // initialize ucb total touched value (individual ones are always initialized to 1) m_touched = m_ucb_init ? as.size() : 1; } @@ -738,7 +737,6 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); @@ -764,7 +762,6 @@ public: const mpz & v1 = get_value(arg1); if (negated) { - //res = (m_mpz_manager.eq(v0, v1)) ? 0.5 * (m_bv_util.get_bv_size(arg0) - 1.0) / m_bv_util.get_bv_size(arg0) : 1.0; res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << std::endl; ); @@ -1051,10 +1048,8 @@ public: // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); -#if _UCT_ == 3 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); -#endif + //double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + (get_random_uint(8) * 0.0000002); if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } if (pos == static_cast(-1)) From b3924d85ed2e0db2daddc5ea31234685d9e84fc7 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Fri, 25 Apr 2014 13:56:15 +0100 Subject: [PATCH 169/507] Cleaned up final SLS version. Enjoy! --- src/tactic/sls/sls_compilation_settings.h | 28 ---- src/tactic/sls/sls_engine.cpp | 43 ++++-- src/tactic/sls/sls_engine.h | 2 + src/tactic/sls/sls_evaluator.h | 8 +- src/tactic/sls/sls_params.pyg | 6 +- src/tactic/sls/sls_tracker.h | 153 ++++++++-------------- 6 files changed, 94 insertions(+), 146 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 707802cf4..e69de29bb 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -1,28 +0,0 @@ -/*++ -Copyright (c) 2014 Microsoft Corporation - -Module Name: - - sls_compilation_constants.h - -Abstract: - - Stochastic Local Search (SLS) compilation constants - -Author: - - Christoph (cwinter) 2014-03-19 - -Notes: - - This file should go away completely once we have evaluated all options. - ---*/ - -#ifndef _SLS_COMPILATION_SETTINGS_H_ -#define _SLS_COMPILATION_SETTINGS_H_ - -// should we use unsat-structures as done in SLS 4 SAT? -#define _REAL_RS_ 0 - -#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index a1c72609c..269790902 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -71,6 +71,8 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_init = p.restart_init(); m_early_prune = p.early_prune(); + m_random_offset = p.random_offset(); + m_rescore = p.rescore(); // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. if (m_walksat_repick && !m_walksat) @@ -174,6 +176,9 @@ bool sls_engine::what_if( m_mpz_manager.del(old_value); #endif + // Andreas: Had this idea on my last day. Maybe we could add a noise here similar to the one that worked so well for ucb assertion selection. + // r += 0.0001 * m_tracker.get_random_uint(8); + // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { best_score = r; @@ -248,9 +253,15 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) { if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + + // Andreas: The other option would be to scale the probability for flips according to the bit-width. + /* unsigned bv_sz2 = m_bv_util.get_bv_size(srt); + rnd_mv = m_tracker.get_random_uint(16) % (bv_sz2 + 3); + if (rnd_mv > 3) rnd_mv = 0; */ + move_type mt = (move_type)rnd_mv; - // inversion doesn't make sense, let's do a flip instead. + // Andreas: Christoph claimed inversion doesn't make sense, let's do a flip instead. Is this really true? if (mt == MV_INV) mt = MV_FLIP; unsigned bit = 0; @@ -306,10 +317,13 @@ double sls_engine::find_best_move( unsigned bv_sz; double new_score = score; - //unsigned offset = m_tracker.get_random_uint(16) % to_evaluate.size(); - //for (unsigned j = 0; j < to_evaluate.size(); j++) { - //unsigned i = (j + offset) % to_evaluate.size(); - for (unsigned i = 0; i < to_evaluate.size(); i++) { + // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. + unsigned sz = to_evaluate.size(); + unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; + for (unsigned j = 0; j < sz; j++) { + unsigned i = j + offset; + if (i >= sz) i -= sz; + //for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -361,7 +375,13 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double unsigned bv_sz; double new_score = score; - for (unsigned i = 0; i < to_evaluate.size(); i++) { + // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. + unsigned sz = to_evaluate.size(); + unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; + for (unsigned j = 0; j < sz; j++) { + unsigned i = j + offset; + if (i >= sz) i -= sz; + //for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -405,15 +425,16 @@ lbool sls_engine::search() { while (check_restart(m_stats.m_moves)) { checkpoint(); m_stats.m_moves++; + + // Andreas: Every base restart interval ... if (m_stats.m_moves % m_restart_base == 0) { + // ... potentially smooth the touched counters ... m_tracker.ucb_forget(m_assertions); - //score = rescore(); + // ... or normalize the top-level score. + if (m_rescore) score = rescore(); } -#if _REAL_RS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif // get candidate variables ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) @@ -513,8 +534,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - lbool res = operator()(); if (res == l_true) { diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ac8610871..8158808fa 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -82,6 +82,8 @@ protected: unsigned m_restart_next; unsigned m_restart_init; unsigned m_early_prune; + unsigned m_random_offset; + unsigned m_rescore; typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index e4cf3c466..61afb7457 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -22,7 +22,6 @@ Notes: #include"model_evaluator.h" -#include"sls_compilation_settings.h" #include"sls_powers.h" #include"sls_tracker.h" @@ -540,19 +539,16 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); -#if _REAL_RS_ + new_score = m_tracker.score(cur); if (m_tracker.is_top_expr(cur)) { + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); if (m_mpz_manager.eq(new_value,m_one)) m_tracker.make_assertion(cur); else m_tracker.break_assertion(cur); } -#endif - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index 98875b20d..ad7a22675 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -8,15 +8,19 @@ def_module_params('sls', ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), + ('walksat_ucb_noise', DOUBLE, 0.0002, 'add noise 0 <= 256 * ucb_noise to ucb score for assertion selection'), ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), ('paws_init', UINT, 40, 'initial/minimum assertion weights'), ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), - ('wp', UINT, 0, 'random walk with probability wp / 1024'), + ('wp', UINT, 100, 'random walk with probability wp / 1024'), ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), + ('random_offset', BOOL, 1, 'use random offset vor candidate evaluation'), + ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), + ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') )) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 507596273..4356bcc9b 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -80,14 +80,13 @@ private: double m_ucb_constant; unsigned m_ucb_init; double m_ucb_forget; + double m_ucb_noise; unsigned m_touched; double m_scale_unsat; unsigned m_paws_init; -#if _REAL_RS_ - ptr_vector m_unsat_expr; obj_map m_where_false; expr** m_list_false; -#endif + unsigned m_track_unsat; obj_map m_weights; double m_top_sum; @@ -116,8 +115,12 @@ public: m_ucb_constant = p.walksat_ucb_constant(); m_ucb_init = p.walksat_ucb_init(); m_ucb_forget = p.walksat_ucb_forget(); + m_ucb_noise = p.walksat_ucb_noise(); m_scale_unsat = p.scale_unsat(); m_paws_init = p.paws_init(); + // Andreas: track_unsat is currently disabled because I cannot guarantee that it is not buggy. + // If you want to use it, you will also need to change comments in the assertion selection. + m_track_unsat = 0;//p.track_unsat(); } /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. @@ -254,53 +257,6 @@ public: return m_uplinks.find(n); } -#if _REAL_RS_ - void debug_real(goal_ref const & g, unsigned flip) - { - unsigned count = 0; - for (unsigned i = 0; i < g->size(); i++) - { - expr * e = g->form(i); - if (m_mpz_manager.eq(get_value(e),m_one) && m_where_false.contains(e)) - { - printf("iteration %d: ", flip); - printf("form %d is sat but in unsat list at position %d of %d\n", i, m_where_false.find(e), m_where_false.size()); - exit(4); - } - - if (m_mpz_manager.eq(get_value(e),m_zero) && !m_where_false.contains(e)) - { - printf("iteration %d: ", flip); - printf("form %d is unsat but not in unsat list\n", i); - exit(4); - } - - if (m_mpz_manager.eq(get_value(e),m_zero) && m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - expr * q = m_list_false[pos]; - if (q != e) - { - printf("iteration %d: ", flip); - printf("form %d is supposed to be at pos %d in unsat list but something else was there\n", i, pos); - exit(4); - } - } - - if (m_mpz_manager.eq(get_value(e),m_zero)) - count++; - } - - // should be true now that duplicate assertions are removed - if (count != m_where_false.size()) - { - printf("iteration %d: ", flip); - printf("%d are unsat but list is of size %d\n", count, m_where_false.size()); - exit(4); - } - } -#endif - inline void ucb_forget(ptr_vector & as) { if (m_ucb_forget < 1.0) { @@ -474,14 +430,15 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); -#if _REAL_RS_ - m_list_false = new expr*[sz]; - //for (unsigned i = 0; i < sz; i++) - //{ - // if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - // break_assertion(g->form(i)); - //} -#endif + if (m_track_unsat) + { + m_list_false = new expr*[sz]; + for (unsigned i = 0; i < sz; i++) + { + if (m_mpz_manager.eq(get_value(as[i]), m_zero)) + break_assertion(as[i]); + } + } for (unsigned i = 0; i < sz; i++) { @@ -515,44 +472,36 @@ public: return m_weights.find(e); } -#if _REAL_RS_ void make_assertion(expr * e) { - if (m_where_false.contains(e)) + if (m_track_unsat) { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) + if (m_where_false.contains(e)) { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - //printf("Moving %d from %d to %d\n", q, m_where_false.size(), pos); + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } } - //else - //printf("Erasing %d from %d to %d\n", e, pos); -// m_list_false[m_where_false.size()] = 0; -// printf("Going in %d\n", m_where_false.size()); } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); } void break_assertion(expr * e) { - //printf("I'm broken... that's still fine.\n"); - if (!m_where_false.contains(e)) + if (m_track_unsat) { - //printf("This however is not so cool...\n"); - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + } } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); } -#endif void show_model(std::ostream & out) { unsigned sz = get_num_constants(); @@ -1043,24 +992,38 @@ public: { value_score vscore; double max = -1.0; + // Andreas: Commented things here might be used for track_unsat data structures as done in SLS for SAT. But seems to have no benefit. + /* for (unsigned i = 0; i < m_where_false.size(); i++) { + expr * e = m_list_false[i]; */ for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; -// for (unsigned i = 0; i < m_where_false.size(); i++) { -// expr * e = m_list_false[i]; - vscore = m_scores.find(e); - //double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + (get_random_uint(8) * 0.0000002); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (m_mpz_manager.neq(get_value(e), m_one)) + { + vscore = m_scores.find(e); + // Andreas: Select the assertion with the greatest ucb score. Potentially add some noise. + // double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + m_ucb_noise * get_random_uint(8); + if (q > max) { max = q; pos = i; } + } } if (pos == static_cast(-1)) return 0; - m_scores.find(as[pos]).touched++; m_touched++; -// return m_list_false[pos]; + m_scores.find(as[pos]).touched++; + // Andreas: Also part of track_unsat data structures. Additionally disable the previous line! + /* m_last_pos = pos; + m_scores.find(m_list_false[pos]).touched++; + return m_list_false[pos]; */ } else { + // Andreas: The track_unsat data structures for random assertion selection. + /* sz = m_where_false.size(); + if (sz == 0) + return 0; + return m_list_false[get_random_uint(16) % sz]; */ + unsigned cnt_unsat = 0; for (unsigned i = 0; i < sz; i++) if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; @@ -1070,14 +1033,6 @@ public: m_last_pos = pos; return as[pos]; -#if _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return 0; - return m_list_false[get_random_uint(16) % sz]; -#endif } expr * get_new_unsat_assertion(ptr_vector const & as) { From e34b5edf27d91e5546264313c7027781dfac2c72 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 17:17:47 +0100 Subject: [PATCH 170/507] BVSLS comments Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_params.pyg | 2 +- src/tactic/sls/sls_tracker.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index ad7a22675..bf5bd181a 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -19,7 +19,7 @@ def_module_params('sls', ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), - ('random_offset', BOOL, 1, 'use random offset vor candidate evaluation'), + ('random_offset', BOOL, 1, 'use random offset for candidate evaluation'), ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 4356bcc9b..d58f94af2 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -831,7 +831,9 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. + // Precondition: Assertion set is in NNF. + // Also: careful about the unsat assertion scaling further down. + if (m_manager.is_and(child) || m_manager.is_or(child)) NOT_IMPLEMENTED_YET(); res = score_bool(child, true); } From a02c59c1bc76efe5c9905f073fd9ffcac2b7b617 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 18:03:35 +0100 Subject: [PATCH 171/507] removed unused file Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 0 src/tactic/sls/sls_engine.cpp | 1 - src/tactic/sls/sls_engine.h | 1 - src/tactic/sls/sls_tracker.h | 1 - 4 files changed, 3 deletions(-) delete mode 100644 src/tactic/sls/sls_compilation_settings.h diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 269790902..67dba0237 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -27,7 +27,6 @@ Notes: #include"cooperate.h" #include"luby.h" -#include"sls_compilation_settings.h" #include"sls_params.hpp" #include"sls_engine.h" diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8158808fa..8a8a57e0e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -24,7 +24,6 @@ Notes: #include"model_converter.h" #include"goal.h" -#include"sls_compilation_settings.h" #include"sls_tracker.h" #include"sls_evaluator.h" diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index d58f94af2..186fae250 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -25,7 +25,6 @@ Notes: #include"bv_decl_plugin.h" #include"model.h" -#include"sls_compilation_settings.h" #include"sls_powers.h" class sls_tracker { From fc0cdcfd2968b95bce0c9aee9a4363b5e0b9af9b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 18:11:30 +0100 Subject: [PATCH 172/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 186fae250..73355197a 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -25,6 +25,7 @@ Notes: #include"bv_decl_plugin.h" #include"model.h" +#include"sls_params.hpp" #include"sls_powers.h" class sls_tracker { @@ -1052,4 +1053,4 @@ public: } }; -#endif \ No newline at end of file +#endif From 60753bf46b822191969e6cd70fbb9e3d1aec0d06 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 21:49:35 +0100 Subject: [PATCH 173/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8a8a57e0e..b056c438e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -136,8 +136,8 @@ protected: void mk_random_move(ptr_vector & unsat_constants); - //inline double get_restart_armin(unsigned cnt_restarts); - inline unsigned check_restart(unsigned curr_value); + //double get_restart_armin(unsigned cnt_restarts); + unsigned check_restart(unsigned curr_value); }; #endif From 54cd1ea5e6ae90e0150ca712d190594c3812e451 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 21:54:08 +0100 Subject: [PATCH 174/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 67dba0237..5b32e5790 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -16,6 +16,7 @@ Author: Notes: --*/ +#include #include #include"map.h" From 6b9c5dbfc061eaa40a2e3a02a9505119ec8b71e2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 22:03:26 +0100 Subject: [PATCH 175/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 5b32e5790..c0c319ab4 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -581,7 +581,7 @@ lbool sls_engine::operator()() { } /* Andreas: Needed for Armin's restart scheme if we don't want to use loops. -inline double sls_engine::get_restart_armin(unsigned cnt_restarts) +double sls_engine::get_restart_armin(unsigned cnt_restarts) { unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; @@ -589,7 +589,7 @@ inline double sls_engine::get_restart_armin(unsigned cnt_restarts) } */ -inline unsigned sls_engine::check_restart(unsigned curr_value) +unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_next) { From aa0980b83b8d981e754e738d18ea1036391806a1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 11 Sep 2014 00:27:37 +0100 Subject: [PATCH 176/507] merge fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tactic.cpp | 1413 +-------------------------------- 1 file changed, 30 insertions(+), 1383 deletions(-) diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 6e1102dd2..9bbed20bb 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,1378 +16,30 @@ Author: Notes: --*/ -#include -#include"map.h" #include"nnf.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"model_pp.h" -#include"model_evaluator.h" #include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"stopwatch.h" #include"propagate_values_tactic.h" -#include"sls_tactic.h" +#include"ctx_simplify_tactic.h" +#include"elim_uncnstr_tactic.h" #include"nnf_tactic.h" -#include"luby.h" -#include "ctx_simplify_tactic.h" - -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 1 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 4.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.5 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick clause when randomizing in a plateau or use the current one? -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 20.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// do we gradually reduce the touched values of _UCT_? -#define _UCT_FORGET_ 0 -#define _UCT_FORGET_FACTOR_ 0.5 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 0 - -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 - -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? -#define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 - -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) - InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) - InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) - InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) - InvalidConfiguration; -#endif - +#include"stopwatch.h" +#include"sls_tactic.h" #include"sls_params.hpp" -#include"sls_evaluator.h" -#include"sls_tracker.h" +#include"sls_engine.h" -class sls_tactic : public tactic { - class stats { - public: - unsigned m_restarts; - stopwatch m_stopwatch; - unsigned m_full_evals; - unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; - - stats() : - m_restarts(0), - m_full_evals(0), - m_incr_evals(0), - m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), - m_flips(0), - m_incs(0), - m_decs(0), - m_invs(0) { - m_stopwatch.reset(); - m_stopwatch.start(); - } - void reset() { - m_full_evals = m_flips = m_incr_evals = 0; - m_stopwatch.reset(); - m_stopwatch.start(); - } - }; - - struct imp { - ast_manager & m_manager; - stats & m_stats; - unsynch_mpz_manager m_mpz_manager; - powers m_powers; - mpz m_zero, m_one, m_two; - bool m_produce_models; - volatile bool m_cancel; - bv_util m_bv_util; - sls_tracker m_tracker; - sls_evaluator m_evaluator; - - unsigned m_restart_limit; - unsigned m_max_restarts; - unsigned m_plateau_limit; - - ptr_vector m_old_values; - - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; - - imp(ast_manager & m, params_ref const & p, stats & s) : - m_manager(m), - m_stats(s), - m_powers(m_mpz_manager), - m_zero(m_mpz_manager.mk_z(0)), - m_one(m_mpz_manager.mk_z(1)), - m_two(m_mpz_manager.mk_z(2)), - m_cancel(false), - m_bv_util(m), - m_tracker(m, m_bv_util, m_mpz_manager, m_powers), - m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) - { - updt_params(p); - } - - ~imp() { - m_mpz_manager.del(m_zero); - m_mpz_manager.del(m_one); - m_mpz_manager.del(m_two); - } - - double get_restart_armin(unsigned cnt_restarts) - { - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow(_RESTART_CONST_ARMIN_, inner_id + 1); - } - - inline unsigned check_restart(unsigned curr_value) - { - if (curr_value > m_restart_limit) - { -#if _RESTART_SCHEME_ == 5 - m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); -#elif _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); -#elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 1 - if (m_stats.m_restarts & 1) - m_restart_limit += _RESTART_LIMIT_; - else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; -#else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif - return 0; - } - return 1; - } - - ast_manager & m() const { return m_manager; } - - void set_cancel(bool f) { m_cancel = f; } - void cancel() { set_cancel(true); } - void reset_cancel() { set_cancel(false); } - - static void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); - } - - void updt_params(params_ref const & _p) { - sls_params p(_p); - m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); - m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); - } - - void checkpoint() { - if (m_cancel) - throw tactic_exception(TACTIC_CANCELED_MSG); - cooperate("sls"); - } - - bool full_eval(goal_ref const & g, model & mdl) { - bool res = true; - - unsigned sz = g->size(); - for (unsigned i = 0; i < sz && res; i++) { - checkpoint(); - expr_ref o(m_manager); - - if (!mdl.eval(g->form(i), o, true)) - exit(ERR_INTERNAL_FATAL); - - res = m_manager.is_true(o.get()); - } - - TRACE("sls", tout << "Evaluation: " << res << std::endl;); - - return res; - } - - double top_score(goal_ref const & g) { - #if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl; ); - return min; - #else - double top_sum = 0.0; - unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - top_sum += m_tracker.get_score(e); - } - - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " AVG: " << top_sum / (double) sz << std::endl; ); - -#if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); -#endif - - return top_sum / (double) sz; - #endif - } - - double rescore(goal_ref const & g) { - m_evaluator.update_all(); - m_stats.m_full_evals++; - return top_score(g); - } - - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; - } -#endif - - // checks whether the score outcome of a given move is better than the previous score - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - #ifdef Z3DEBUG - mpz old_value; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - #endif - -#if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); -#else - double r = incremental_score(g, fd, temp); -#endif - #ifdef Z3DEBUG - TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << - " --> " << r << std::endl; ); - - m_mpz_manager.del(old_value); - #endif - -// if (r >= best_score) { - if (r > best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // same as what_if, but only applied to the score of a specific atom, not the total score - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.add(old_value, add_value, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - - } - - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - } - - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); - } - - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { - unsigned shift; - m_mpz_manager.add(old_value, m_one, incremented); - if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) - m_mpz_manager.set(incremented, m_zero); - } - - void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { - if (m_mpz_manager.is_zero(old_value)) { - m_mpz_manager.set(decremented, m_powers(bv_sz)); - m_mpz_manager.dec(decremented); - } - else - m_mpz_manager.sub(old_value, m_one, decremented); - } - - void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { - m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); - } - - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { - m_mpz_manager.set(flipped, m_zero); - - if (m_bv_util.is_bv_sort(s)) { - mpz mask; - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(old_value, mask, flipped); - m_mpz_manager.del(mask); - } - else if (m_manager.is_bool(s)) - m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); - else - NOT_IMPLEMENTED_YET(); - } - - void mk_random_move(ptr_vector & unsat_constants) - { - unsigned rnd_mv = 0; - unsigned ucc = unsat_constants.size(); - unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; - func_decl * fd = unsat_constants[rc]; - - mpz new_value; - - sort * srt = fd->get_range(); - if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { -#if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; -#else - mt = MV_FLIP; -#endif - unsigned bit = 0; - - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } - - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } - - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } - - void mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); - } - - // will use VNS to ignore some possible moves and increase the flips per second - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif - unsigned bv_sz; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { -#else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { -#endif - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } -#endif - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - return new_score; - } - - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - - m_old_values.reset(); - - return 0; - } - - // what_if version needed in the context of 2nd intensification try, combining local and global score - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // find_best_move version needed in the context of 2nd intensification try - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; - } - - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; - } - - // main search loop - lbool search(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - unsigned plateau_cnt = 0; - - score = rescore(g); - unsigned sz = g->size(); -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - checkpoint(); - m_stats.m_moves++; - -#if _UCT_FORGET_ - if (m_stats.m_moves % _UCT_FORGET_ == 0) - m_tracker.uct_forget(g); -#endif - -#if _REAL_RS_ || _REAL_PBFS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } - continue; -#endif - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - old_score = score; - new_const = (unsigned)-1; - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - - if (new_const == static_cast(-1)) { - score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); - else -#endif -#if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); -#else - m_evaluator.randomize_local(to_evaluate); -#endif -#endif - -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } else { - func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - // main search loop - lbool search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0 ; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl; ); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - } - - if (score >= 0.99999) { -// if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } - while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - void operator()(goal_ref const & g, model_converter_ref & mc) { - if (g->inconsistent()) { - mc = 0; - return; - } - - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_DIRTY_UP_ " << _DIRTY_UP_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_RESTART_CONST_ARMIN_ " << std::fixed << std::setprecision(2) << _RESTART_CONST_ARMIN_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; - verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout); ); - } - g->reset(); - } - else - mc = 0; - } - }; - +class sls_tactic : public tactic { ast_manager & m; params_ref m_params; - imp * m_imp; - stats m_stats; + sls_engine * m_engine; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_imp = alloc(imp, m, p, m_stats); + m_engine = alloc(sls_engine, m, p); } virtual tactic * translate(ast_manager & m) { @@ -1395,16 +47,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_imp); + dealloc(m_engine); } virtual void updt_params(params_ref const & p) { m_params = p; - m_imp->updt_params(p); + m_engine->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - imp::collect_param_descrs(r); + sls_params::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -1412,14 +64,13 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); - m_imp->m_produce_models = g->models_enabled(); + SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_imp->operator()(g, mc); + m_engine->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -1428,40 +79,36 @@ public: } virtual void cleanup() { - imp * d = m_imp; + sls_engine * d = alloc(sls_engine, m, m_params); #pragma omp critical (tactic_cancel) { - d = m_imp; + std::swap(d, m_engine); } dealloc(d); - d = alloc(imp, m, m_params, m_stats); - #pragma omp critical (tactic_cancel) - { - m_imp = d; - } } virtual void collect_statistics(statistics & st) const { - double seconds = m_stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", m_stats.m_restarts); - st.update("sls full evals", m_stats.m_full_evals); - st.update("sls incr evals", m_stats.m_incr_evals); - st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); - st.update("sls FLIP moves", m_stats.m_flips); - st.update("sls INC moves", m_stats.m_incs); - st.update("sls DEC moves", m_stats.m_decs); - st.update("sls INV moves", m_stats.m_invs); - st.update("sls moves", m_stats.m_moves); - st.update("sls moves/sec", m_stats.m_moves / seconds); + sls_engine::stats const & stats = m_engine->get_stats(); + double seconds = stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", stats.m_restarts); + st.update("sls full evals", stats.m_full_evals); + st.update("sls incr evals", stats.m_incr_evals); + st.update("sls incr evals/sec", stats.m_incr_evals / seconds); + st.update("sls FLIP moves", stats.m_flips); + st.update("sls INC moves", stats.m_incs); + st.update("sls DEC moves", stats.m_decs); + st.update("sls INV moves", stats.m_invs); + st.update("sls moves", stats.m_moves); + st.update("sls moves/sec", stats.m_moves / seconds); } virtual void reset_statistics() { - m_stats.reset(); + m_engine->reset_statistics(); } virtual void set_cancel(bool f) { - if (m_imp) - m_imp->set_cancel(f); + if (m_engine) + m_engine->set_cancel(f); } }; From 387f036f93287e912650b3738ef896d730b98152 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 19 Dec 2014 12:32:57 +0000 Subject: [PATCH 177/507] BV-SLS optimization Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 73355197a..89ef57871 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -89,6 +89,7 @@ private: unsigned m_track_unsat; obj_map m_weights; double m_top_sum; + obj_hashtable m_temp_seen; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -440,6 +441,7 @@ public: } } + m_temp_seen.reset(); for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; @@ -630,7 +632,14 @@ public: app * a = to_app(n); expr * const * args = a->get_args(); for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); + { + expr * child = args[i]; + if (!m_temp_seen.contains(child)) + { + setup_occs(child, false); + m_temp_seen.insert(child); + } + } } else if (m_manager.is_not(n)) { @@ -638,8 +647,7 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); + SASSERT(!m_manager.is_and(child) && !m_manager.is_or(child)); setup_occs(child, true); } else From 6818e850e99faf6d6c63a44e5aadddeaa2e992a2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 12 Jan 2015 15:59:20 +0000 Subject: [PATCH 178/507] Disabled BV-SLS as default tactic in anticipation for integration with the unstable branch. Signed-off-by: Christoph M. Wintersteiger --- src/tactic/portfolio/default_tactic.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 53da9a159..5a5cbcf94 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -32,8 +32,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), - // cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), From c982f870255edeed04c1e274fa0ff3213d358587 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 11 Feb 2014 17:44:59 +0000 Subject: [PATCH 179/507] sls tactic default --- src/tactic/portfolio/smt_strategic_solver.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index f63b4fd8c..586c3a349 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -37,14 +37,11 @@ Notes: #include"horn_tactic.h" #include"smt_solver.h" -#include"sls_tactic.h" - tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") - // return mk_qfbv_tactic(m, p); - return mk_qfbv_sls_tactic(m, p); + return mk_qfbv_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); else if (logic=="QF_LIA") From dfe2d945e94eb22b1e59958525a3ca0731f6aedb Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 18 Feb 2014 14:01:47 +0000 Subject: [PATCH 180/507] some extensions/modifications. versions added. --- src/tactic/portfolio/default_tactic.cpp | 2 +- src/tactic/sls/sls_evaluator.h | 243 +-------- src/tactic/sls/sls_tactic.cpp | 661 ++++++++++++++++++++++-- src/tactic/sls/sls_tracker.h | 640 ++++++++--------------- versions/z3-wsat-0.01.txt | 4 +- versions/z3-wsat-0.01b.txt | 4 +- 6 files changed, 872 insertions(+), 682 deletions(-) diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 5a5cbcf94..b28b7bec0 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -32,7 +32,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 61afb7457..61305386e 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -20,8 +20,6 @@ Notes: #ifndef _SLS_EVALUATOR_H_ #define _SLS_EVALUATOR_H_ -#include"model_evaluator.h" - #include"sls_powers.h" #include"sls_tracker.h" @@ -36,7 +34,6 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; - vector > m_traversal_stack_bool; public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -96,7 +93,7 @@ public: SASSERT(n_args == 1); const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); - m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); + m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); break; } case OP_EQ: { @@ -522,64 +519,11 @@ public: } } - void run_serious_update(unsigned cur_depth) { - // precondition: m_traversal_stack contains the entry point(s) - expr_fast_mark1 visited; - mpz new_value; - - double new_score; - - SASSERT(cur_depth < m_traversal_stack.size()); - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; - - for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { - expr * cur = cur_depth_exprs[i]; - - (*this)(to_app(cur), new_value); - m_tracker.set_value(cur, new_value); - - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - { - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - if (m_mpz_manager.eq(new_value,m_one)) - m_tracker.make_assertion(cur); - else - m_tracker.break_assertion(cur); - } - - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); - - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack[next_d].push_back(next); - visited.mark(next); - } - } - } - } - - cur_depth_exprs.reset(); - cur_depth--; - } - - m_mpz_manager.del(new_value); - } - void run_update(unsigned cur_depth) { // precondition: m_traversal_stack contains the entry point(s) expr_fast_mark1 visited; mpz new_value; - double new_score; - SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -589,10 +533,8 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + m_tracker.set_score(cur, m_tracker.score(cur)); + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -627,7 +569,8 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } - run_serious_update(max_depth); + + run_update(max_depth); } void update(func_decl * fd, const mpz & new_value) { @@ -641,174 +584,36 @@ public: run_update(cur_depth); } - void serious_update(func_decl * fd, const mpz & new_value) { - m_tracker.set_value(fd, new_value); - expr * ep = m_tracker.get_entry_point(fd); - unsigned cur_depth = m_tracker.get_distance(ep); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); - m_traversal_stack[cur_depth].push_back(ep); + void randomize_local(goal_ref const & g, unsigned int flip) { + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); - run_serious_update(cur_depth); - } + // Randomize _all_ candidates: - unsigned run_update_bool_prune(unsigned cur_depth) { - expr_fast_mark1 visited; + //// bool did_something = false; + //for (unsigned i = 0; i < unsat_constants.size(); i++) { + // func_decl * fd = unsat_constants[i]; + // mpz temp = m_tracker.get_random(fd->get_range()); + // // if (m_mpz_manager.neq(temp, m_tracker.get_value(fd))) { + // // did_something = true; + // // } + // update(fd, temp); + // m_mpz_manager.del(temp); + //} - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); - - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - - for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - - prune_score = m_tracker.get_score_prune(cur); - m_tracker.set_score(cur, new_score); - - if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; - - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - - cur_depth_exprs.reset(); - cur_depth--; - - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); - - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } - - return pot_benefits; - } - - void run_update_prune(unsigned max_depth) { - // precondition: m_traversal_stack contains the entry point(s) - expr_fast_mark1 visited; - mpz new_value; - - unsigned cur_depth = max_depth; - SASSERT(cur_depth < m_traversal_stack.size()); - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; - - for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { - expr * cur = cur_depth_exprs[i]; - - (*this)(to_app(cur), new_value); - m_tracker.set_value(cur, new_value); - // Andreas: Should actually always have uplinks ... - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - if (m_manager.is_bool(next)) - m_traversal_stack_bool[max_depth].push_back(next); - else - m_traversal_stack[next_d].push_back(next); - visited.mark(next); - } - } - } - } - - cur_depth_exprs.reset(); - cur_depth--; - } - - m_mpz_manager.del(new_value); - } - - unsigned update_prune(func_decl * fd, const mpz & new_value) { - m_tracker.set_value(fd, new_value); - expr * ep = m_tracker.get_entry_point(fd); - unsigned cur_depth = m_tracker.get_distance(ep); - - if (m_traversal_stack_bool.size() <= cur_depth) - m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); - - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune(cur_depth); - } - - void randomize_local(ptr_vector & unsat_constants) { // Randomize _one_ candidate: unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); func_decl * fd = unsat_constants[r]; mpz temp = m_tracker.get_random(fd->get_range()); - - serious_update(fd, temp); - + update(fd, temp); m_mpz_manager.del(temp); - TRACE("sls", tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; + TRACE("sls", /*tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl;*/ + tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - - } - - void randomize_local(expr * e) { - randomize_local(m_tracker.get_constants(e)); - } - - void randomize_local(ptr_vector const & as) { - randomize_local(m_tracker.get_unsat_constants(as)); } }; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 9bbed20bb..c194af267 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,30 +16,619 @@ Author: Notes: --*/ +#include +#include"map.h" #include"nnf.h" +#include"cooperate.h" +#include"ast_smt2_pp.h" +#include"ast_pp.h" +#include"var_subst.h" +#include"model_pp.h" +#include"model_evaluator.h" #include"solve_eqs_tactic.h" +#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"ctx_simplify_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"nnf_tactic.h" #include"stopwatch.h" +#include"propagate_values_tactic.h" #include"sls_tactic.h" -#include"sls_params.hpp" -#include"sls_engine.h" +#include"nnf_tactic.h" -class sls_tactic : public tactic { +#define _CNF_ 0 +#define _BFS_ 1 +#define _FOCUS_ 1 +#define _RESTARTS_ 0 +#define _TIMELIMIT_ 30 +#define _SCORE_AND_AVG_ 0 +#define _SCORE_OR_MUL_ 0 +#define _VNS_ 0 +#define _WEIGHT_DIST_ 3 +#define _WEIGHT_DIST_FACTOR_ 0.1 + +#include"sls_params.hpp" +#include"sls_evaluator.h" +#include"sls_tracker.h" + +class sls_tactic : public tactic { + class stats { + public: + unsigned m_restarts; + stopwatch m_stopwatch; + unsigned m_full_evals; + unsigned m_incr_evals; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs; + stats() : + m_restarts(0), + m_full_evals(0), + m_incr_evals(0), + m_moves(0), + m_flips(0), + m_incs(0), + m_decs(0), + m_invs(0) { + m_stopwatch.reset(); + m_stopwatch.start(); + } + void reset() { + m_full_evals = m_flips = m_incr_evals = 0; + m_stopwatch.reset(); + m_stopwatch.start(); + } + }; + + struct imp { + ast_manager & m_manager; + stats & m_stats; + unsynch_mpz_manager m_mpz_manager; + powers m_powers; + mpz m_zero, m_one, m_two; + bool m_produce_models; + volatile bool m_cancel; + bv_util m_bv_util; + sls_tracker m_tracker; + sls_evaluator m_evaluator; + + unsigned m_max_restarts; + unsigned m_plateau_limit; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; + + imp(ast_manager & m, params_ref const & p, stats & s) : + m_manager(m), + m_stats(s), + m_powers(m_mpz_manager), + m_zero(m_mpz_manager.mk_z(0)), + m_one(m_mpz_manager.mk_z(1)), + m_two(m_mpz_manager.mk_z(2)), + m_cancel(false), + m_bv_util(m), + m_tracker(m, m_bv_util, m_mpz_manager, m_powers), + m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) + { + updt_params(p); + } + + ~imp() { + m_mpz_manager.del(m_zero); + m_mpz_manager.del(m_one); + m_mpz_manager.del(m_two); + } + + ast_manager & m() const { return m_manager; } + + void set_cancel(bool f) { m_cancel = f; } + void cancel() { set_cancel(true); } + void reset_cancel() { set_cancel(false); } + + static void collect_param_descrs(param_descrs & r) { + sls_params::collect_param_descrs(r); + } + + void updt_params(params_ref const & _p) { + sls_params p(_p); + m_produce_models = _p.get_bool("model", false); + m_max_restarts = p.restarts(); + m_tracker.set_random_seed(p.random_seed()); + m_plateau_limit = p.plateau_limit(); + } + + void checkpoint() { + if (m_cancel) + throw tactic_exception(TACTIC_CANCELED_MSG); + cooperate("sls"); + } + + bool full_eval(goal_ref const & g, model & mdl) { + bool res = true; + + unsigned sz = g->size(); + for (unsigned i = 0; i < sz && res; i++) { + checkpoint(); + expr_ref o(m_manager); + + if (!mdl.eval(g->form(i), o, true)) + exit(ERR_INTERNAL_FATAL); + + res = m_manager.is_true(o.get()); + } + + TRACE("sls", tout << "Evaluation: " << res << std::endl;); + + return res; + } + + double top_score(goal_ref const & g) { + #if 0 + double min = m_tracker.get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + double q = m_tracker.get_score(g->form(i)); + if (q < min) min = q; + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " MIN: " << min << std::endl; ); + return min; + #else + double top_sum = 0.0; + unsigned sz = g->size(); + for (unsigned i = 0; i < sz; i++) { + top_sum += m_tracker.get_score(g->form(i)); + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " AVG: " << top_sum / (double) sz << std::endl; ); + return top_sum / (double) sz; + #endif + } + + double rescore(goal_ref const & g) { + m_evaluator.update_all(); + m_stats.m_full_evals++; + return top_score(g); + } + + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; + return top_score(g); + } + + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + + #ifdef Z3DEBUG + mpz old_value; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + #endif + + double r = incremental_score(g, fd, temp); + + #ifdef Z3DEBUG + TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << + " --> " << r << std::endl; ); + + m_mpz_manager.del(old_value); + #endif + + if (r >= best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + unsigned shift; + m_mpz_manager.add(old_value, m_one, incremented); + if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) + m_mpz_manager.set(incremented, m_zero); + } + + void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { + if (m_mpz_manager.is_zero(old_value)) { + m_mpz_manager.set(decremented, m_powers(bv_sz)); + m_mpz_manager.dec(decremented); + } + else + m_mpz_manager.sub(old_value, m_one, decremented); + } + + void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { + m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); + } + + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { + m_mpz_manager.set(flipped, m_zero); + + if (m_bv_util.is_bv_sort(s)) { + mpz mask; + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(old_value, mask, flipped); + m_mpz_manager.del(mask); + } + else if (m_manager.is_bool(s)) + m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); + else + NOT_IMPLEMENTED_YET(); + } + + void mk_random_move(goal_ref const & g) { + unsigned rnd_mv = 0; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; + + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; + + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); + unsigned ucc = unsat_constants.size(); + unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; + func_decl * fd = unsat_constants[rc]; + mpz new_value; + unsigned bit = 0; + + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(fd->get_range()); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + + m_evaluator.update(fd, new_value); + + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + + m_mpz_manager.del(new_value); + } + + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + + lbool search(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + + score = rescore(g); + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl; ); + + unsigned plateau_cnt = 0; + + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + do { + checkpoint(); + + old_score = score; + new_const = (unsigned)-1; + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + + TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; + for (unsigned i = 0 ; i < to_evaluate.size(); i++) + tout << to_evaluate[i]->get_name() << std::endl; ); + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + if (new_const == static_cast(-1)) { + TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + }); + + TRACE("sls_max", m_tracker.show_model(tout); + tout << "Scores: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl; ); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? + score = old_score; + } + else { + // Andreas: Why does randomizing not count as a move? (Now it does.) + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; + switch (move) { + case MV_FLIP: + tout << "Flip"; + if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; + break; + case MV_INC: + tout << "+1"; + break; + case MV_DEC: + tout << "-1"; + break; + case MV_INV: + tout << "NEG"; + break; + }; + tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + } + + score = incremental_score(g, fd, new_value); + + TRACE("sls", tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl; ); + } + + if (score >= 1.0) { + // score could theoretically be imprecise. + // Andreas: Can it only be imprecise in one direction? + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ + } + while (score > old_score && res == l_undef); + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); + plateau_cnt = 0; + } else { + m_stats.m_moves++; + plateau_cnt++; + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { + TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); + m_evaluator.randomize_local(g, m_stats.m_moves); + //mk_random_move(g); + score = top_score(g); + //} + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + void operator()(goal_ref const & g, model_converter_ref & mc) { + if (g->inconsistent()) { + mc = 0; + return; + } + + m_tracker.initialize(g); + lbool res = l_undef; + + do { + checkpoint(); + // Andreas: I think restarts are too impotant to ignore 99% of them are happening... + //if ((m_stats.m_restarts % 100) == 0) + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + + res = search(g); + + if (res == l_undef) + m_tracker.randomize(); + } + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout); ); + } + g->reset(); + } + else + mc = 0; + } + }; + ast_manager & m; params_ref m_params; - sls_engine * m_engine; + imp * m_imp; + stats m_stats; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_engine = alloc(sls_engine, m, p); + m_imp = alloc(imp, m, p, m_stats); } virtual tactic * translate(ast_manager & m) { @@ -47,16 +636,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_engine); + dealloc(m_imp); } virtual void updt_params(params_ref const & p) { m_params = p; - m_engine->updt_params(p); + m_imp->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); + imp::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -64,13 +653,14 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); + SASSERT(g->is_well_sorted()); + m_imp->m_produce_models = g->models_enabled(); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_engine->operator()(g, mc); + m_imp->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -79,36 +669,35 @@ public: } virtual void cleanup() { - sls_engine * d = alloc(sls_engine, m, m_params); + imp * d = alloc(imp, m, m_params, m_stats); #pragma omp critical (tactic_cancel) { - std::swap(d, m_engine); + std::swap(d, m_imp); } dealloc(d); } virtual void collect_statistics(statistics & st) const { - sls_engine::stats const & stats = m_engine->get_stats(); - double seconds = stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", stats.m_restarts); - st.update("sls full evals", stats.m_full_evals); - st.update("sls incr evals", stats.m_incr_evals); - st.update("sls incr evals/sec", stats.m_incr_evals / seconds); - st.update("sls FLIP moves", stats.m_flips); - st.update("sls INC moves", stats.m_incs); - st.update("sls DEC moves", stats.m_decs); - st.update("sls INV moves", stats.m_invs); - st.update("sls moves", stats.m_moves); - st.update("sls moves/sec", stats.m_moves / seconds); + double seconds = m_stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", m_stats.m_restarts); + st.update("sls full evals", m_stats.m_full_evals); + st.update("sls incr evals", m_stats.m_incr_evals); + st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); + st.update("sls FLIP moves", m_stats.m_flips); + st.update("sls INC moves", m_stats.m_incs); + st.update("sls DEC moves", m_stats.m_decs); + st.update("sls INV moves", m_stats.m_invs); + st.update("sls moves", m_stats.m_moves); + st.update("sls moves/sec", m_stats.m_moves / seconds); } virtual void reset_statistics() { - m_engine->reset_statistics(); + m_stats.reset(); } virtual void set_cancel(bool f) { - if (m_engine) - m_engine->set_cancel(f); + if (m_imp) + m_imp->set_cancel(f); } }; @@ -143,9 +732,6 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // conservative gaussian elimination. gaussian_p.set_uint("gaussian_max_occs", 2); - params_ref ctx_p; - ctx_p.set_uint("max_depth", 32); - ctx_p.set_uint("max_steps", 5000000); return and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), using_params(mk_solve_eqs_tactic(m), gaussian_p), @@ -154,12 +740,17 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), +#if _CNF_ + // Andreas: We will probably never use this. CNF sucks. + mk_cnf_tactic(m, p)); +#else + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); +#endif } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); - //tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 89ef57871..1061bd90e 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,14 +20,6 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"for_each_expr.h" -#include"ast_smt2_pp.h" -#include"bv_decl_plugin.h" -#include"model.h" - -#include"sls_params.hpp" -#include"sls_powers.h" - class sls_tracker { ast_manager & m_manager; unsynch_mpz_manager & m_mpz_manager; @@ -36,26 +28,21 @@ class sls_tracker { random_gen m_rng; unsigned m_random_bits; unsigned m_random_bits_cnt; - mpz m_zero, m_one, m_two; - + mpz m_zero, m_one, m_two; + struct value_score { - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0) { }; ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; - double score_prune; - unsigned has_pos_occ; - unsigned has_neg_occ; unsigned distance; // max distance from any root - unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; - touched = other.touched; return *this; } }; @@ -67,29 +54,12 @@ private: typedef obj_map scores_type; typedef obj_map > uplinks_type; typedef obj_map > occ_type; - obj_hashtable m_top_expr; scores_type m_scores; uplinks_type m_uplinks; entry_point_type m_entry_points; ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; - unsigned m_last_pos; - unsigned m_walksat; - unsigned m_ucb; - double m_ucb_constant; - unsigned m_ucb_init; - double m_ucb_forget; - double m_ucb_noise; - unsigned m_touched; - double m_scale_unsat; - unsigned m_paws_init; - obj_map m_where_false; - expr** m_list_false; - unsigned m_track_unsat; - obj_map m_weights; - double m_top_sum; - obj_hashtable m_temp_seen; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -109,59 +79,6 @@ public: m_mpz_manager.del(m_two); } - void updt_params(params_ref const & _p) { - sls_params p(_p); - m_walksat = p.walksat(); - m_ucb = p.walksat_ucb(); - m_ucb_constant = p.walksat_ucb_constant(); - m_ucb_init = p.walksat_ucb_init(); - m_ucb_forget = p.walksat_ucb_forget(); - m_ucb_noise = p.walksat_ucb_noise(); - m_scale_unsat = p.scale_unsat(); - m_paws_init = p.paws_init(); - // Andreas: track_unsat is currently disabled because I cannot guarantee that it is not buggy. - // If you want to use it, you will also need to change comments in the assertion selection. - m_track_unsat = 0;//p.track_unsat(); - } - - /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. - unsigned get_formula_size() { - return m_scores.size(); - } - - double get_avg_bw(goal_ref const & g) { - double sum = 0.0; - unsigned count = 0; - - for (unsigned i = 0; i < g->size(); i++) - { - m_temp_constants.reset(); - ptr_vector const & this_decls = m_constants_occ.find(g->form(i)); - unsigned sz = this_decls.size(); - for (unsigned i = 0; i < sz; i++) { - func_decl * fd = this_decls[i]; - m_temp_constants.push_back(fd); - sort * srt = fd->get_range(); - sum += (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - count++; - } - } - - return sum / count; - }*/ - - inline void adapt_top_sum(expr * e, double add, double sub) { - m_top_sum += m_weights.find(e) * (add - sub); - } - - inline void set_top_sum(double new_score) { - m_top_sum = new_score; - } - - inline double get_top_sum() { - return m_top_sum; - } - inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); m_mpz_manager.set(m_scores.find(n).value, r); @@ -206,26 +123,6 @@ public: return get_score(ep); } - inline void set_score_prune(expr * n, double score) { - SASSERT(m_scores.contains(n)); - m_scores.find(n).score_prune = score; - } - - inline double & get_score_prune(expr * n) { - SASSERT(m_scores.contains(n)); - return m_scores.find(n).score_prune; - } - - inline unsigned has_pos_occ(expr * n) { - SASSERT(m_scores.contains(n)); - return m_scores.find(n).has_pos_occ; - } - - inline unsigned has_neg_occ(expr * n) { - SASSERT(m_scores.contains(n)); - return m_scores.find(n).has_neg_occ; - } - inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).distance; @@ -249,32 +146,11 @@ public: return m_uplinks.contains(n); } - inline bool is_top_expr(expr * n) { - return m_top_expr.contains(n); - } - inline ptr_vector & get_uplinks(expr * n) { SASSERT(m_uplinks.contains(n)); return m_uplinks.find(n); } - inline void ucb_forget(ptr_vector & as) { - if (m_ucb_forget < 1.0) - { - expr * e; - unsigned touched_old, touched_new; - - for (unsigned i = 0; i < as.size(); i++) - { - e = as[i]; - touched_old = m_scores.find(e).touched; - touched_new = (unsigned)((touched_old - 1) * m_ucb_forget + 1); - m_scores.find(e).touched = touched_new; - m_touched += touched_new - touched_old; - } - } - } - void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -350,12 +226,12 @@ public: } }; - void calculate_expr_distances(ptr_vector const & as) { + void calculate_expr_distances(goal_ref const & g) { // precondition: m_scores is set up. - unsigned sz = as.size(); + unsigned sz = g->size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(as[i])); + stack.push_back(to_app(g->form(i))); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -373,53 +249,57 @@ public: } } - /* Andreas: Used this at some point to have values for the non-top-level expressions. - However, it did not give better performance but even cause some additional m/o - is not used currently. - void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(proc, visited, q); - } - } - for_each_expr(proc, visited, e); - } + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } - void initialize_recursive(expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(q); - } - } - ptr_vector t; + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - }*/ + } - void initialize(ptr_vector const & as) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = as.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; - if (!m_top_expr.contains(e)) - m_top_expr.insert(e); + expr * e = g->form(i); + // Andreas: Maybe not fully correct. +#if _FOCUS_ == 2 + initialize_recursive(proc, visited, e); +#endif for_each_expr(proc, visited, e); } visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); + // Andreas: Maybe not fully correct. +#if _FOCUS_ == 2 + initialize_recursive(e); +#endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -427,82 +307,9 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(as); + calculate_expr_distances(g); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); - - if (m_track_unsat) - { - m_list_false = new expr*[sz]; - for (unsigned i = 0; i < sz; i++) - { - if (m_mpz_manager.eq(get_value(as[i]), m_zero)) - break_assertion(as[i]); - } - } - - m_temp_seen.reset(); - for (unsigned i = 0; i < sz; i++) - { - expr * e = as[i]; - - // initialize weights - if (!m_weights.contains(e)) - m_weights.insert(e, m_paws_init); - - // positive/negative occurences used for early pruning - setup_occs(as[i]); - } - - // initialize ucb total touched value (individual ones are always initialized to 1) - m_touched = m_ucb_init ? as.size() : 1; - } - - void increase_weight(expr * e) - { - m_weights.find(e)++; - } - - void decrease_weight(expr * e) - { - unsigned old_weight = m_weights.find(e); - m_weights.find(e) = old_weight > m_paws_init ? old_weight - 1 : m_paws_init; - } - - unsigned get_weight(expr * e) - { - return m_weights.find(e); - } - - void make_assertion(expr * e) - { - if (m_track_unsat) - { - if (m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) - { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - } - } - } - } - - void break_assertion(expr * e) - { - if (m_track_unsat) - { - if (!m_where_false.contains(e)) - { - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - } - } } void show_model(std::ostream & out) { @@ -599,7 +406,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(ptr_vector const & as) { + void randomize() { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -613,55 +420,6 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); } - void reset(ptr_vector const & as) { - TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); - - for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { - mpz temp = m_zero; - set_value(it->m_value, temp); - m_mpz_manager.del(temp); - } - } - - void setup_occs(expr * n, bool negated = false) { - if (m_manager.is_bool(n)) - { - if (m_manager.is_and(n) || m_manager.is_or(n)) - { - SASSERT(!negated); - app * a = to_app(n); - expr * const * args = a->get_args(); - for (unsigned i = 0; i < a->get_num_args(); i++) - { - expr * child = args[i]; - if (!m_temp_seen.contains(child)) - { - setup_occs(child, false); - m_temp_seen.insert(child); - } - } - } - else if (m_manager.is_not(n)) - { - SASSERT(!negated); - app * a = to_app(n); - SASSERT(a->get_num_args() == 1); - expr * child = a->get_arg(0); - SASSERT(!m_manager.is_and(child) && !m_manager.is_or(child)); - setup_occs(child, true); - } - else - { - if (negated) - m_scores.find(n).has_neg_occ = 1; - else - m_scores.find(n).has_pos_occ = 1; - } - } - else - NOT_IMPLEMENTED_YET(); - } - double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); @@ -678,28 +436,41 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - /* Andreas: Seems to have no effect. But maybe you want to try it again at some point. + // Andreas: Seems to have no effect. Probably it does not even occur. +#if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) sum += get_score(args[i]); - res = sum / (double) a->get_num_args(); */ - double min = 1.0; + res = sum / (double) a->get_num_args(); +#else + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; } res = min; +#endif } else if (m_manager.is_or(n)) { SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - double max = 0.0; + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. +#if _SCORE_OR_MUL_ + double inv = 1.0; + for (unsigned i = 0; i < a->get_num_args(); i++) { + double cur = get_score(args[i]); + inv *= (1.0 - get_score(args[i])); + } + res = 1.0 - inv; +#else + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur > max) max = cur; } res = max; +#endif } else if (m_manager.is_ite(n)) { SASSERT(!negated); @@ -717,7 +488,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -733,14 +504,24 @@ public: m_mpz_manager.bitwise_xor(v0, v1, diff); unsigned hamming_distance = 0; unsigned bv_sz = m_bv_util.get_bv_size(arg0); - // unweighted hamming distance + #if 1 // unweighted hamming distance while (!m_mpz_manager.is_zero(diff)) { + //m_mpz_manager.set(diff_m1, diff); + //m_mpz_manager.dec(diff_m1); + //m_mpz_manager.bitwise_and(diff, diff_m1, diff); + //hamming_distance++; if (!m_mpz_manager.is_even(diff)) { hamming_distance++; } m_mpz_manager.machine_div(diff, m_two, diff); } res = 1.0 - (hamming_distance / (double) bv_sz); + #else + rational r(diff); + r /= m_powers(bv_sz); + double dbl = r.get_double(); + res = (dbl < 0.0) ? 1.0 : (dbl > 1.0) ? 0.0 : 1.0 - dbl; + #endif TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << " ; HD = " << hamming_distance << " ; SZ = " << bv_sz << std::endl; ); @@ -755,7 +536,7 @@ public: SASSERT(a->get_num_args() == 2); const mpz & x = get_value(a->get_arg(0)); const mpz & y = get_value(a->get_arg(1)); - int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + unsigned bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); if (negated) { if (m_mpz_manager.gt(x, y)) @@ -769,7 +550,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -781,7 +562,7 @@ public: rational n(diff); n /= rational(m_powers(bv_sz)); double dbl = n.get_double(); - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); } } @@ -801,7 +582,7 @@ public: if (negated) { if (x > y) - res = 1.0; + res = 1.0; else { mpz diff; m_mpz_manager.sub(y, x, diff); @@ -817,21 +598,20 @@ public: } else { if (x <= y) - res = 1.0; + res = 1.0; else { mpz diff; m_mpz_manager.sub(x, y, diff); - SASSERT(!m_mpz_manager.is_neg(diff)); rational n(diff); n /= p; double dbl = n.get_double(); - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -839,9 +619,7 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - // Precondition: Assertion set is in NNF. - // Also: careful about the unsat assertion scaling further down. - if (m_manager.is_and(child) || m_manager.is_or(child)) + if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. NOT_IMPLEMENTED_YET(); res = score_bool(child, true); } @@ -867,16 +645,24 @@ public: SASSERT(res >= 0.0 && res <= 1.0); - app * a = to_app(n); - family_id afid = a->get_family_id(); +#if _WEIGHT_DIST_ + app * a = to_app(n); + family_id afid = a->get_family_id(); + if (afid == m_bv_util.get_family_id()) +#endif +#if _WEIGHT_DIST_ == 1 + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#elif _WEIGHT_DIST_ == 2 + res *= res; +#elif _WEIGHT_DIST_ == 3 + if (res < 1.0) res = 0.0; +#endif - if (afid == m_bv_util.get_family_id()) - if (res < 1.0) res *= m_scale_unsat; TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -922,28 +708,9 @@ public: NOT_IMPLEMENTED_YET(); } - ptr_vector & get_constants(expr * e) { - ptr_vector const & this_decls = m_constants_occ.find(e); - unsigned sz = this_decls.size(); + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { - func_decl * fd = this_decls[i]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - return m_temp_constants; - } - - ptr_vector & get_unsat_constants_gsat(ptr_vector const & as) { - unsigned sz = as.size(); - if (sz == 1) { - if (m_mpz_manager.neq(get_value(as[0]), m_one)) - return get_constants(); - } - - m_temp_constants.reset(); - - for (unsigned i = 0; i < sz; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -955,110 +722,141 @@ public: } } return m_temp_constants; - } + } - ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e || m_temp_constants.size()) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(e); - unsigned sz = this_decls.size(); - for (unsigned j = 0; j < sz; j++) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } + + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); + // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. + if (!q) + return m_temp_constants; + + ptr_vector const & this_decls = m_constants_occ.find(q); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants(ptr_vector const & as) { - if (m_walksat) - { - expr * e = get_unsat_assertion(as); - - if (!e) - { - m_temp_constants.reset(); - return m_temp_constants; + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); } + return m_temp_constants; + } + + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); + if (!q) + return m_temp_constants; + + return go_deeper(q); + } + + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); - return get_unsat_constants_walksat(e); - } - else - return get_unsat_constants_gsat(as); - } - - expr * get_unsat_assertion(ptr_vector const & as) { - unsigned sz = as.size(); if (sz == 1) { - if (m_mpz_manager.neq(get_value(as[0]), m_one)) - return as[0]; - else - return 0; + return get_constants(); } - m_temp_constants.reset(); - - unsigned pos = -1; - if (m_ucb) - { - value_score vscore; - double max = -1.0; - // Andreas: Commented things here might be used for track_unsat data structures as done in SLS for SAT. But seems to have no benefit. - /* for (unsigned i = 0; i < m_where_false.size(); i++) { - expr * e = m_list_false[i]; */ - for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; - if (m_mpz_manager.neq(get_value(e), m_one)) - { - vscore = m_scores.find(e); - // Andreas: Select the assertion with the greatest ucb score. Potentially add some noise. - // double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + m_ucb_noise * get_random_uint(8); - if (q > max) { max = q; pos = i; } - } + else { + m_temp_constants.reset(); +#if _FOCUS_ == 1 +#if _BFS_ == 3 + unsigned int pos = 0; + double max = get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - if (pos == static_cast(-1)) - return 0; - - m_touched++; - m_scores.find(as[pos]).touched++; - // Andreas: Also part of track_unsat data structures. Additionally disable the previous line! - /* m_last_pos = pos; - m_scores.find(m_list_false[pos]).touched++; - return m_list_false[pos]; */ +#elif _BFS_ == 2 + unsigned int pos = 0; + double min = get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + } +#elif _BFS_ == 1 + unsigned int pos = flip % m_constants.size(); +#else + unsigned int pos = get_random_uint(16) % m_constants.size(); +#endif + return get_unsat_constants_walksat(g, sz, pos); +#elif _FOCUS_ == 2 +#if _BFS_ + unsigned int pos = flip % m_constants.size(); +#else + unsigned int pos = get_random_uint(16) % m_constants.size(); +#endif + return get_unsat_constants_crsat(g, sz, pos); +#else + return get_unsat_constants_gsat(g, sz); +#endif } - else - { - // Andreas: The track_unsat data structures for random assertion selection. - /* sz = m_where_false.size(); - if (sz == 0) - return 0; - return m_list_false[get_random_uint(16) % sz]; */ - - unsigned cnt_unsat = 0; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return 0; - } - - m_last_pos = pos; - return as[pos]; - } - - expr * get_new_unsat_assertion(ptr_vector const & as) { - unsigned sz = as.size(); - if (sz == 1) - return 0; - m_temp_constants.reset(); - - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if ((i != m_last_pos) && m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - - if (pos == static_cast(-1)) - return 0; - return as[pos]; } }; -#endif +#endif \ No newline at end of file diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt index fec38518d..141193f76 100644 --- a/versions/z3-wsat-0.01.txt +++ b/versions/z3-wsat-0.01.txt @@ -9,6 +9,4 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 - -BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file +#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt index 8bcf2ffeb..2c0c0e7ad 100644 --- a/versions/z3-wsat-0.01b.txt +++ b/versions/z3-wsat-0.01b.txt @@ -9,6 +9,4 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 - -BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file +#define _SCORE_OR_MUL_ 0 \ No newline at end of file From 140d28b6b3165ad4b2b3ccd7ff5eea203481cc34 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Sun, 9 Mar 2014 15:42:51 +0000 Subject: [PATCH 181/507] plenty of new stuff --- src/tactic/portfolio/default_tactic.cpp | 1 + src/tactic/portfolio/smt_strategic_solver.cpp | 5 +- src/tactic/sls/sls_evaluator.h | 323 ++++++++- src/tactic/sls/sls_tactic.cpp | 661 ++++++++++++++++-- src/tactic/sls/sls_tracker.h | 345 ++++++++- versions/z3-wsat-0.01.txt | 4 +- versions/z3-wsat-0.01b.txt | 4 +- 7 files changed, 1235 insertions(+), 108 deletions(-) diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index b28b7bec0..53da9a159 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -33,6 +33,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), + // cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index 586c3a349..f63b4fd8c 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -37,11 +37,14 @@ Notes: #include"horn_tactic.h" #include"smt_solver.h" +#include"sls_tactic.h" + tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") - return mk_qfbv_tactic(m, p); + // return mk_qfbv_tactic(m, p); + return mk_qfbv_sls_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); else if (logic=="QF_LIA") diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 61305386e..eec9524a9 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -34,6 +34,9 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; +#if _EARLY_PRUNE_ + vector > m_traversal_stack_bool; +#endif public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -519,11 +522,15 @@ public: } } - void run_update(unsigned cur_depth) { + void run_serious_update(unsigned cur_depth) { // precondition: m_traversal_stack contains the entry point(s) expr_fast_mark1 visited; mpz new_value; +#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ + double new_score; +#endif + SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -533,8 +540,92 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - m_tracker.set_score(cur, m_tracker.score(cur)); +#if _REAL_RS_ || _REAL_PBFS_ + if (!m_tracker.has_uplinks(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } +#endif + +#if _EARLY_PRUNE_ + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); +#else +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif +#endif + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack[next_d].push_back(next); + visited.mark(next); + } + } + } + } + + cur_depth_exprs.reset(); + cur_depth--; + } + + m_mpz_manager.del(new_value); + } + + void run_update(unsigned cur_depth) { + // precondition: m_traversal_stack contains the entry point(s) + expr_fast_mark1 visited; + mpz new_value; + +#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ + double new_score; +#endif + + SASSERT(cur_depth < m_traversal_stack.size()); + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + (*this)(to_app(cur), new_value); + m_tracker.set_value(cur, new_value); +#if _EARLY_PRUNE_ + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); +#else +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -569,8 +660,11 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } - +#if _REAL_RS_ || _REAL_PBFS_ + run_serious_update(max_depth); +#else run_update(max_depth); +#endif } void update(func_decl * fd, const mpz & new_value) { @@ -584,6 +678,196 @@ public: run_update(cur_depth); } + void serious_update(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + m_traversal_stack[cur_depth].push_back(ep); + + run_serious_update(cur_depth); + } + +#if _EARLY_PRUNE_ + unsigned run_update_bool_prune(unsigned cur_depth) { + expr_fast_mark1 visited; + + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); + + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); +#if _CACHE_TOP_SCORE_ + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); +#endif + prune_score = m_tracker.get_score_prune(cur); + m_tracker.set_score(cur, new_score); + + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; + + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + else + { + } + } + + cur_depth_exprs.reset(); + cur_depth--; + + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; + +#if _CACHE_TOP_SCORE_ + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); +#else + m_tracker.set_score(cur, m_tracker.score(cur)); +#endif + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } + + return pot_benefits; + } + + void run_update_prune(unsigned max_depth) { + // precondition: m_traversal_stack contains the entry point(s) + expr_fast_mark1 visited; + mpz new_value; + + unsigned cur_depth = max_depth; + SASSERT(cur_depth < m_traversal_stack.size()); + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + (*this)(to_app(cur), new_value); + m_tracker.set_value(cur, new_value); + // should always have uplinks ... + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); + visited.mark(next); + } + } + } + } + + cur_depth_exprs.reset(); + cur_depth--; + } + + m_mpz_manager.del(new_value); + } + + unsigned update_prune(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + + if (m_traversal_stack_bool.size() <= cur_depth) + m_traversal_stack_bool.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); + } +#endif + + void randomize_local(expr * e, unsigned int flip) { + ptr_vector & unsat_constants = m_tracker.get_constants(e); + + // Randomize _one_ candidate: + unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); + func_decl * fd = unsat_constants[r]; +#if _PERC_CHANGE_ + sort * srt = fd->get_range(); + mpz temp; + + if (m_manager.is_bool(srt)) + m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); + + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } +#else + mpz temp = m_tracker.get_random(fd->get_range()); +#endif + update(fd, temp); + m_mpz_manager.del(temp); + } + void randomize_local(goal_ref const & g, unsigned int flip) { ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); @@ -603,8 +887,37 @@ public: // Randomize _one_ candidate: unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); func_decl * fd = unsat_constants[r]; - mpz temp = m_tracker.get_random(fd->get_range()); - update(fd, temp); +#if _PERC_CHANGE_ + sort * srt = fd->get_range(); + mpz temp; + + if (m_manager.is_bool(srt)) + m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); + + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } +#else + mpz temp = m_tracker.get_random(fd->get_range()); +#endif + +#if _REAL_RS_ || _REAL_PBFS_ + serious_update(fd, temp); +#else + update(fd, temp); +#endif m_mpz_manager.del(temp); TRACE("sls", /*tout << "Randomization candidates: "; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index c194af267..a08588a51 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -35,16 +35,102 @@ Notes: #include"sls_tactic.h" #include"nnf_tactic.h" -#define _CNF_ 0 -#define _BFS_ 1 +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom #define _FOCUS_ 1 + +// do we use restarts? +// 0 = no, otherwise the value defines the maximum number of moves #define _RESTARTS_ 0 -#define _TIMELIMIT_ 30 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? #define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? #define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained #define _VNS_ 0 -#define _WEIGHT_DIST_ 3 -#define _WEIGHT_DIST_FACTOR_ 0.1 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 0 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.25 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 0 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 0.01 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +#define _PROBABILISTIC_UCT_ 0 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 1 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 1 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 1 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 1 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) + InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) + InvalidConfiguration; +#endif + #include"sls_params.hpp" #include"sls_evaluator.h" @@ -57,12 +143,17 @@ class sls_tactic : public tactic { stopwatch m_stopwatch; unsigned m_full_evals; unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + stats() : m_restarts(0), m_full_evals(0), m_incr_evals(0), m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -92,7 +183,9 @@ class sls_tactic : public tactic { unsigned m_max_restarts; unsigned m_plateau_limit; - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : m_manager(m), @@ -174,13 +267,20 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - top_sum += m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + return top_sum / (double) sz; #endif } @@ -191,22 +291,54 @@ class sls_tactic : public tactic { return top_score(g); } - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else return top_score(g); +#endif } + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; + } +#endif + + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { - + #ifdef Z3DEBUG mpz old_value; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else double r = incremental_score(g, fd, temp); - +#endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl; ); @@ -214,6 +346,22 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); #endif +// if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // same as what_if, but only applied to the score of a specific atom, not the total score + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -224,7 +372,35 @@ class sls_tactic : public tactic { return false; } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + + } + + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + } + + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); + } + + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -261,59 +437,73 @@ class sls_tactic : public tactic { void mk_random_move(goal_ref const & g) { unsigned rnd_mv = 0; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + if (m_stats.m_moves > 10000) + rnd_mv = 0; ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; - unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(fd->get_range()); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + mpz new_value; - m_evaluator.update(fd, new_value); + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; - m_mpz_manager.del(new_value); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } + + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -359,6 +549,7 @@ class sls_tactic : public tactic { SASSERT(check == score); } + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else @@ -390,9 +581,13 @@ class sls_tactic : public tactic { return new_score; } + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif unsigned bv_sz; double new_score = score; @@ -403,8 +598,12 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // first try to flip every bit - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { - // What would happen if we flipped bit #i ? +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -414,7 +613,8 @@ class sls_tactic : public tactic { } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -426,16 +626,99 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } - +#endif // try inverting mk_inv(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif } // reset to what it was before double check = incremental_score(g, fd, old_value); - SASSERT(check == score); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; + } + + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -443,7 +726,150 @@ class sls_tactic : public tactic { return new_score; } - lbool search(goal_ref const & g) { + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + + m_old_values.reset(); + + return 0; + } + + // what_if version needed in the context of 2nd intensification try, combining local and global score + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // find_best_move version needed in the context of 2nd intensification try + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) + { + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; + } + + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; + } + + // main search loop + lbool search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -463,16 +889,48 @@ class sls_tactic : public tactic { #if _RESTARTS_ while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { + if (m_stats.m_moves == 5590) checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif old_score = score; new_const = (unsigned)-1; ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -525,9 +983,17 @@ class sls_tactic : public tactic { case MV_INC: m_stats.m_incs++; break; case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - score = incremental_score(g, fd, new_value); +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif TRACE("sls", tout << "Score distribution:"; for (unsigned i = 0; i < g->size(); i++) @@ -535,9 +1001,10 @@ class sls_tactic : public tactic { tout << " TOP: " << score << std::endl; ); } - if (score >= 1.0) { + if (score >= 0.99999) { +// if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: Can it only be imprecise in one direction? + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -568,10 +1035,26 @@ class sls_tactic : public tactic { // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else m_evaluator.randomize_local(g, m_stats.m_moves); - //mk_random_move(g); +#endif + //mk_random_move(g); score = top_score(g); - //} + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } } } @@ -587,6 +1070,37 @@ class sls_tactic : public tactic { return; } + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif m_tracker.initialize(g); lbool res = l_undef; @@ -740,13 +1254,8 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), -#if _CNF_ - // Andreas: We will probably never use this. CNF sucks. - mk_cnf_tactic(m, p)); -#else // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); -#endif } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 1061bd90e..b26912e5c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -28,21 +28,32 @@ class sls_tracker { random_gen m_rng; unsigned m_random_bits; unsigned m_random_bits_cnt; - mpz m_zero, m_one, m_two; + mpz m_zero, m_one, m_two; struct value_score { - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0) { }; +#if _EARLY_PRUNE_ + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; +#else + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; +#endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; +#if _EARLY_PRUNE_ + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; +#endif unsigned distance; // max distance from any root + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; + touched = other.touched; return *this; } }; @@ -60,6 +71,20 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; +#if _UCT_ + unsigned m_touched; +#endif +#if _REAL_RS_ || _REAL_PBFS_ + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; +#endif +#if _CACHE_TOP_SCORE_ + double m_top_sum; +#endif +#if _WEIGHT_DIST_ == 4 + double m_weight_dist_factor; +#endif public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -79,6 +104,26 @@ public: m_mpz_manager.del(m_two); } +#if _WEIGHT_DIST_ == 4 + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } +#endif + +#if _CACHE_TOP_SCORE_ + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } + + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } + + inline double get_top_sum() { + return m_top_sum; + } +#endif + inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); m_mpz_manager.set(m_scores.find(n).value, r); @@ -123,6 +168,28 @@ public: return get_score(ep); } +#if _EARLY_PRUNE_ + inline void set_score_prune(expr * n, double score) { + SASSERT(m_scores.contains(n)); + m_scores.find(n).score_prune = score; + } + + inline double & get_score_prune(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).score_prune; + } + + inline unsigned has_pos_occ(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).has_pos_occ; + } + + inline unsigned has_neg_occ(expr * n) { + SASSERT(m_scores.contains(n)); + return m_scores.find(n).has_neg_occ; + } +#endif + inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).distance; @@ -297,7 +364,7 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 +#if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); #endif ptr_vector t; @@ -310,8 +377,57 @@ public: calculate_expr_distances(g); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); + +#if _REAL_RS_ || _REAL_PBFS_ + m_list_false = new expr*[sz]; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + break_assertion(g->form(i)); +#endif + +#if _EARLY_PRUNE_ + for (unsigned i = 0; i < sz; i++) + setup_occs(g->form(i)); +#endif + +#if _UCT_ + m_touched = 1; +#endif } +#if _REAL_RS_ || _REAL_PBFS_ + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } +// printf("Going in %d\n", m_where_false.size()); + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } + + void break_assertion(expr * e) + { + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } +#endif + void show_model(std::ostream & out) { unsigned sz = get_num_constants(); for (unsigned i = 0; i < sz; i++) { @@ -420,10 +536,45 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); } +#if _EARLY_PRUNE_ + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } + else + NOT_IMPLEMENTED_YET(); + } +#endif + double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -488,7 +639,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -648,6 +799,7 @@ public: #if _WEIGHT_DIST_ app * a = to_app(n); family_id afid = a->get_family_id(); + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 @@ -656,13 +808,14 @@ public: res *= res; #elif _WEIGHT_DIST_ == 3 if (res < 1.0) res = 0.0; +#elif _WEIGHT_DIST_ == 4 + if (res < 1.0) res *= m_weight_dist_factor; #endif - TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -708,6 +861,44 @@ public: NOT_IMPLEMENTED_YET(); } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } + + ptr_vector & get_constants(expr * e) { + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz = this_decls.size(); + for (unsigned i = 0; i < sz; i++) { + func_decl * fd = this_decls[i]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); @@ -743,7 +934,6 @@ public: // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { @@ -754,6 +944,19 @@ public: return m_temp_constants; } + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz = this_decls.size(); + for (unsigned j = 0; j < sz; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + return m_temp_constants; + } + ptr_vector & go_deeper(expr * e) { if (m_manager.is_bool(e)) { if (m_manager.is_and(e)) { @@ -812,44 +1015,138 @@ public: return go_deeper(q); } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 -#if _BFS_ == 3 - unsigned int pos = 0; - double max = get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { +#if _UCT_ + unsigned pos = -1; + value_score vscore; +#if _PROBABILISTIC_UCT_ + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + } +#endif + if (pos == static_cast(-1)) + return m_temp_constants; + +#if _UCT_ == 1 + m_scores.find(g->form(pos)).touched++; + m_touched++; +#elif _UCT_ == 2 + m_scores.find(g->form(pos)).touched = flip; +#endif + expr * e = g->form(pos); + +#elif _BFS_ == 3 + unsigned int pos = -1; + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); double q = get_score(e); if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = 0; - double min = get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { + unsigned int pos = -1; + double min = 2.0; + for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); double q = get_score(e); if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - unsigned int pos = flip % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); +#elif _UNIFORM_RANDOM_ + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); +#elif _REAL_RS_ + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[get_random_uint(16) % sz]; +#elif _REAL_PBFS_ + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - unsigned int pos = get_random_uint(16) % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(g, sz, pos); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - unsigned int pos = flip % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - unsigned int pos = get_random_uint(16) % m_constants.size(); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif return get_unsat_constants_crsat(g, sz, pos); #else diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt index 141193f76..fec38518d 100644 --- a/versions/z3-wsat-0.01.txt +++ b/versions/z3-wsat-0.01.txt @@ -9,4 +9,6 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file +#define _SCORE_OR_MUL_ 0 + +BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt index 2c0c0e7ad..8bcf2ffeb 100644 --- a/versions/z3-wsat-0.01b.txt +++ b/versions/z3-wsat-0.01b.txt @@ -9,4 +9,6 @@ No restarts. #define _RESTARTS_ 0 #define _TIMELIMIT_ 300 #define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file +#define _SCORE_OR_MUL_ 0 + +BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file From 664fa82c6cb752b08a3788af542a999464f0b930 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 09:40:01 +0000 Subject: [PATCH 182/507] removed tabs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_evaluator.h | 268 ++++++------- src/tactic/sls/sls_tactic.cpp | 572 ++++++++++++++-------------- src/tactic/sls/sls_tracker.h | 672 ++++++++++++++++----------------- 3 files changed, 756 insertions(+), 756 deletions(-) diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index eec9524a9..cdb08038f 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -528,7 +528,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -542,33 +542,33 @@ public: m_tracker.set_value(cur, new_value); #if _REAL_RS_ || _REAL_PBFS_ - if (!m_tracker.has_uplinks(cur)) - { - if (m_mpz_manager.eq(new_value,m_one)) - m_tracker.make_assertion(cur); - else - m_tracker.break_assertion(cur); - } + if (!m_tracker.has_uplinks(cur)) + { + if (m_mpz_manager.eq(new_value,m_one)) + m_tracker.make_assertion(cur); + else + m_tracker.break_assertion(cur); + } #endif #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -596,7 +596,7 @@ public: mpz new_value; #if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ - double new_score; + double new_score; #endif SASSERT(cur_depth < m_traversal_stack.size()); @@ -609,23 +609,23 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - m_tracker.set_score(cur, new_score); - m_tracker.set_score_prune(cur, new_score); + m_tracker.set_score(cur, new_score); + m_tracker.set_score_prune(cur, new_score); #else #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -661,7 +661,7 @@ public: if (cur_depth > max_depth) max_depth = cur_depth; } #if _REAL_RS_ || _REAL_PBFS_ - run_serious_update(max_depth); + run_serious_update(max_depth); #else run_update(max_depth); #endif @@ -693,27 +693,27 @@ public: unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { expr * cur = cur_depth_exprs[i]; - new_score = m_tracker.score(cur); + new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif - prune_score = m_tracker.get_score_prune(cur); + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); - if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; + if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -722,54 +722,54 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); + m_traversal_stack_bool[next_d].push_back(next); visited.mark(next); } } } - else - { - } - } + else + { + } + } - cur_depth_exprs.reset(); + cur_depth_exprs.reset(); cur_depth--; - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; #if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); + new_score = m_tracker.score(cur); + if (!m_tracker.has_uplinks(cur)) + m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #else - m_tracker.set_score(cur, m_tracker.score(cur)); + m_tracker.set_score(cur, m_tracker.score(cur)); #endif - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } - return pot_benefits; + return pot_benefits; } void run_update_prune(unsigned max_depth) { @@ -777,7 +777,7 @@ public: expr_fast_mark1 visited; mpz new_value; - unsigned cur_depth = max_depth; + unsigned cur_depth = max_depth; SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { ptr_vector & cur_depth_exprs = m_traversal_stack[cur_depth]; @@ -787,7 +787,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // should always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -795,10 +795,10 @@ public: unsigned next_d = m_tracker.get_distance(next); SASSERT(next_d < cur_depth); if (!visited.is_marked(next)) { - if (m_manager.is_bool(next)) - m_traversal_stack_bool[max_depth].push_back(next); - else - m_traversal_stack[next_d].push_back(next); + if (m_manager.is_bool(next)) + m_traversal_stack_bool[max_depth].push_back(next); + else + m_traversal_stack[next_d].push_back(next); visited.mark(next); } } @@ -817,23 +817,23 @@ public: expr * ep = m_tracker.get_entry_point(fd); unsigned cur_depth = m_tracker.get_distance(ep); - if (m_traversal_stack_bool.size() <= cur_depth) + if (m_traversal_stack_bool.size() <= cur_depth) m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune(cur_depth); + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune(cur_depth); } #endif - void randomize_local(expr * e, unsigned int flip) { + void randomize_local(expr * e, unsigned int flip) { ptr_vector & unsat_constants = m_tracker.get_constants(e); // Randomize _one_ candidate: @@ -841,30 +841,30 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif - update(fd, temp); + update(fd, temp); m_mpz_manager.del(temp); } @@ -889,34 +889,34 @@ public: func_decl * fd = unsat_constants[r]; #if _PERC_CHANGE_ sort * srt = fd->get_range(); - mpz temp; + mpz temp; - if (m_manager.is_bool(srt)) + if (m_manager.is_bool(srt)) m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else + else { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); + mpz temp2, mask; + unsigned bv_sz = m_bv_util.get_bv_size(srt); + m_mpz_manager.set(temp, m_tracker.get_value(fd)); - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } + for (unsigned bit = 0; bit < bv_sz; bit++) + if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) + { + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(temp, mask, temp2); + m_mpz_manager.set(temp, temp2); + } + m_mpz_manager.del(mask); + m_mpz_manager.del(temp2); + } #else - mpz temp = m_tracker.get_random(fd->get_range()); + mpz temp = m_tracker.get_random(fd->get_range()); #endif #if _REAL_RS_ || _REAL_PBFS_ - serious_update(fd, temp); + serious_update(fd, temp); #else - update(fd, temp); + update(fd, temp); #endif m_mpz_manager.del(temp); diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index a08588a51..553acc35a 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -125,10 +125,10 @@ Notes: #if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) - InvalidConfiguration; + InvalidConfiguration; #endif #if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; + InvalidConfiguration; #endif @@ -150,10 +150,10 @@ class sls_tactic : public tactic { m_full_evals(0), m_incr_evals(0), m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -183,8 +183,8 @@ class sls_tactic : public tactic { unsigned m_max_restarts; unsigned m_plateau_limit; - ptr_vector m_old_values; - + ptr_vector m_old_values; + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; imp(ast_manager & m, params_ref const & p, stats & s) : @@ -267,18 +267,18 @@ class sls_tactic : public tactic { #else double top_sum = 0.0; unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } - TRACE("sls_top", tout << "Score distribution:"; + TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double) sz << std::endl; ); #if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); + m_tracker.set_top_sum(top_sum); #endif return top_sum / (double) sz; @@ -292,20 +292,20 @@ class sls_tactic : public tactic { } double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif } double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else return top_score(g); #endif @@ -314,18 +314,18 @@ class sls_tactic : public tactic { #if _EARLY_PRUNE_ double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) + if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(g); + return top_score(g); #endif - else - return 0.0; + else + return 0.0; } #endif - // checks whether the score outcome of a given move is better than the previous score + // checks whether the score outcome of a given move is better than the previous score bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { @@ -357,11 +357,11 @@ class sls_tactic : public tactic { return false; } - // same as what_if, but only applied to the score of a specific atom, not the total score + // same as what_if, but only applied to the score of a specific atom, not the total score bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value) { m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); + double r = m_tracker.get_score(e); if (r >= best_score) { best_score = r; best_const = fd_inx; @@ -378,29 +378,29 @@ class sls_tactic : public tactic { m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); - } + } - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { mpz temp, mask, mask2; m_mpz_manager.mul(old_value, m_two, temp); m_mpz_manager.set(mask, m_powers(bv_sz)); m_mpz_manager.bitwise_not(bv_sz, mask, mask2); m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); } void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { m_mpz_manager.div(old_value, m_two, result); } - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) @@ -437,73 +437,73 @@ class sls_tactic : public tactic { void mk_random_move(goal_ref const & g) { unsigned rnd_mv = 0; - if (m_stats.m_moves > 10000) - rnd_mv = 0; + if (m_stats.m_moves > 10000) + rnd_mv = 0; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); + ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; - mpz new_value; + mpz new_value; - sort * srt = fd->get_range(); + sort * srt = fd->get_range(); if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { #if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + mt = MV_FLIP; #endif - unsigned bit = 0; + unsigned bit = 0; - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } - // will use VNS to ignore some possible moves and increase the flips per second + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; @@ -514,7 +514,7 @@ class sls_tactic : public tactic { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -536,12 +536,12 @@ class sls_tactic : public tactic { if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } } // reset to what it was before @@ -549,12 +549,12 @@ class sls_tactic : public tactic { SASSERT(check == score); } - // we can either check the condition once in the beginning or check it repeatedly after every bit + // we can either check the condition once in the beginning or check it repeatedly after every bit #if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) #else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) #endif for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { func_decl * fd = to_evaluate[i]; @@ -563,30 +563,30 @@ class sls_tactic : public tactic { m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } // reset to what it was before double check = incremental_score(g, fd, old_value); SASSERT(check == score); } - m_mpz_manager.del(old_value); + m_mpz_manager.del(old_value); m_mpz_manager.del(temp); return new_score; } - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; + mpz temp2; #endif unsigned bv_sz; double new_score = score; @@ -599,11 +599,11 @@ class sls_tactic : public tactic { // first try to flip every bit #if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { #else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { #endif - // What would happen if we flipped bit #i ? + // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { @@ -614,7 +614,7 @@ class sls_tactic : public tactic { if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { #if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { + if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); if (what_if(g, fd, i, temp, new_score, best_const, best_value)) @@ -660,7 +660,7 @@ class sls_tactic : public tactic { // reset to what it was before double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching + // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -669,17 +669,17 @@ class sls_tactic : public tactic { #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif - return new_score; + return new_score; } - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -718,7 +718,7 @@ class sls_tactic : public tactic { } // reset to what it was before - m_evaluator.update(fd, old_value); + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); @@ -726,37 +726,37 @@ class sls_tactic : public tactic { return new_score; } - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); #if _BFS_ - unsigned pos = m_stats.m_moves % sz; + unsigned pos = m_stats.m_moves % sz; #else - unsigned pos = m_tracker.get_random_uint(16) % sz; + unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); } else { m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -767,35 +767,35 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } - m_evaluator.update(fd, new_value); + m_evaluator.update(fd, new_value); } - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - m_old_values.reset(); + m_old_values.reset(); - return 0; - } + return 0; + } - // what_if version needed in the context of 2nd intensification try, combining local and global score + // what_if version needed in the context of 2nd intensification try, combining local and global score bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, double & best_score, mpz & best_value, unsigned i) { double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); + double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - if (new_score >= best_score) { + if (new_score >= best_score) { best_score = new_score; m_mpz_manager.set(best_value, temp); return true; @@ -804,17 +804,17 @@ class sls_tactic : public tactic { return false; } - // find_best_move version needed in the context of 2nd intensification try + // find_best_move version needed in the context of 2nd intensification try double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; + { + mpz old_value, temp; double best_score = 0; sort * srt = fd->get_range(); unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); what_if(g, e, fd, temp, best_score, best_value, i); } @@ -822,54 +822,54 @@ class sls_tactic : public tactic { m_mpz_manager.del(old_value); m_mpz_manager.del(temp); - return best_score; + return best_score; } - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); #if _BFS_ - unsigned new_const = m_stats.m_moves % sz; + unsigned new_const = m_stats.m_moves % sz; #else - unsigned new_const = m_tracker.get_random_uint(16) % sz; + unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { new_score = find_best_move_local(g, q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } - return 0; - } + return 0; + } - // main search loop - lbool search(goal_ref const & g) { + // main search loop + lbool search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -885,52 +885,52 @@ class sls_tactic : public tactic { unsigned plateau_cnt = 0; - // Andreas: Why do we only allow so few plateaus? + // Andreas: Why do we only allow so few plateaus? #if _RESTARTS_ - while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { - if (m_stats.m_moves == 5590) + if (m_stats.m_moves == 5590) checkpoint(); #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif #if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { #if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #elif _TYPE_RSTEP_ == 2 - mk_random_move(g); + mk_random_move(g); #endif score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } #endif old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; for (unsigned i = 0 ; i < to_evaluate.size(); i++) tout << to_evaluate[i]->get_name() << std::endl; ); @@ -952,11 +952,11 @@ class sls_tactic : public tactic { for (unsigned i = 0; i < g->size(); i++) tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? + // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } else { - // Andreas: Why does randomizing not count as a move? (Now it does.) + // Andreas: Why does randomizing not count as a move? (Now it does.) m_stats.m_moves++; func_decl * fd = to_evaluate[new_const]; @@ -984,15 +984,15 @@ class sls_tactic : public tactic { case MV_DEC: m_stats.m_decs++; break; case MV_INV: m_stats.m_invs++; break; case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(g, fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; @@ -1004,7 +1004,7 @@ class sls_tactic : public tactic { if (score >= 0.99999) { // if (score >= 1.0) { // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; for (unsigned i = 0; i < g->size() && all_true; i++) if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) @@ -1015,43 +1015,43 @@ class sls_tactic : public tactic { } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ } while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); + report_tactic_progress("This should not happen I guess.", plateau_cnt); plateau_cnt = 0; - } else { - m_stats.m_moves++; + } else { + m_stats.m_moves++; plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. //if (plateau_cnt < m_plateau_limit) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); #if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); + handle_plateau(g, score); + //handle_plateau(g); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #endif - //mk_random_move(g); + //mk_random_move(g); score = top_score(g); - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; } else TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); } @@ -1070,43 +1070,43 @@ class sls_tactic : public tactic { return; } - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); #endif m_tracker.initialize(g); lbool res = l_undef; do { checkpoint(); - // Andreas: I think restarts are too impotant to ignore 99% of them are happening... + // Andreas: I think restarts are too impotant to ignore 99% of them are happening... //if ((m_stats.m_restarts % 100) == 0) report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); @@ -1115,12 +1115,12 @@ class sls_tactic : public tactic { if (res == l_undef) m_tracker.randomize(); } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); + report_tactic_progress("Number of flips:", m_stats.m_moves); if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -1254,7 +1254,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? + // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index b26912e5c..006bbb888 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -29,31 +29,31 @@ class sls_tracker { unsigned m_random_bits; unsigned m_random_bits_cnt; mpz m_zero, m_one, m_two; - + struct value_score { #if _EARLY_PRUNE_ - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; #else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; #endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; double score; #if _EARLY_PRUNE_ - double score_prune; - unsigned has_pos_occ; - unsigned has_neg_occ; + double score_prune; + unsigned has_pos_occ; + unsigned has_neg_occ; #endif unsigned distance; // max distance from any root - unsigned touched; + unsigned touched; value_score & operator=(const value_score & other) { SASSERT(m == 0 || m == other.m); if (m) m->set(value, 0); else m = other.m; m->set(value, other.value); score = other.score; distance = other.distance; - touched = other.touched; + touched = other.touched; return *this; } }; @@ -72,18 +72,18 @@ private: ptr_vector m_temp_constants; occ_type m_constants_occ; #if _UCT_ - unsigned m_touched; + unsigned m_touched; #endif #if _REAL_RS_ || _REAL_PBFS_ - ptr_vector m_unsat_expr; - obj_map m_where_false; - expr** m_list_false; + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; #endif #if _CACHE_TOP_SCORE_ - double m_top_sum; + double m_top_sum; #endif #if _WEIGHT_DIST_ == 4 - double m_weight_dist_factor; + double m_weight_dist_factor; #endif public: @@ -105,23 +105,23 @@ public: } #if _WEIGHT_DIST_ == 4 - inline void set_weight_dist_factor(double val) { - m_weight_dist_factor = val; - } + inline void set_weight_dist_factor(double val) { + m_weight_dist_factor = val; + } #endif #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { - m_top_sum += add - sub; - } + inline void adapt_top_sum(double add, double sub) { + m_top_sum += add - sub; + } - inline void set_top_sum(double new_score) { - m_top_sum = new_score; - } + inline void set_top_sum(double new_score) { + m_top_sum = new_score; + } - inline double get_top_sum() { - return m_top_sum; - } + inline double get_top_sum() { + return m_top_sum; + } #endif inline void set_value(expr * n, const mpz & r) { @@ -174,20 +174,20 @@ public: m_scores.find(n).score_prune = score; } - inline double & get_score_prune(expr * n) { + inline double & get_score_prune(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).score_prune; } - inline unsigned has_pos_occ(expr * n) { + inline unsigned has_pos_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_pos_occ; - } + } - inline unsigned has_neg_occ(expr * n) { + inline unsigned has_neg_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; - } + } #endif inline unsigned get_distance(expr * n) { @@ -316,45 +316,45 @@ public: } } - void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(proc, visited, q); - } - } - for_each_expr(proc, visited, e); - } + void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(proc, visited, q); + } + } + for_each_expr(proc, visited, e); + } - void initialize_recursive(expr * e) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - initialize_recursive(q); - } - } - ptr_vector t; + void initialize_recursive(expr * e) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + initialize_recursive(q); + } + } + ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + } - void initialize(goal_ref const & g) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 - initialize_recursive(proc, visited, e); + initialize_recursive(proc, visited, e); #endif for_each_expr(proc, visited, e); } @@ -363,9 +363,9 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); - // Andreas: Maybe not fully correct. + // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ - initialize_recursive(e); + initialize_recursive(e); #endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); @@ -379,53 +379,53 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); #if _REAL_RS_ || _REAL_PBFS_ - m_list_false = new expr*[sz]; + m_list_false = new expr*[sz]; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - break_assertion(g->form(i)); + if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + break_assertion(g->form(i)); #endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = 1; + m_touched = 1; #endif } #if _REAL_RS_ || _REAL_PBFS_ - void make_assertion(expr * e) - { - if (m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) - { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - } -// printf("Going in %d\n", m_where_false.size()); - } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); - } + void make_assertion(expr * e) + { + if (m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } +// printf("Going in %d\n", m_where_false.size()); + } + //if (m_unsat_expr.contains(e)) + //m_unsat_expr.erase(e); + } - void break_assertion(expr * e) - { - if (!m_where_false.contains(e)) - { - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); - } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); - } + void break_assertion(expr * e) + { + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + // printf("Going in %d\n", m_where_false.size()); + } + //if (!m_unsat_expr.contains(e)) + //m_unsat_expr.push_back(e); + } #endif void show_model(std::ostream & out) { @@ -537,35 +537,35 @@ public: } #if _EARLY_PRUNE_ - void setup_occs(expr * n, bool negated = false) { - if (m_manager.is_bool(n)) - { - if (m_manager.is_and(n) || m_manager.is_or(n)) - { - SASSERT(!negated); - app * a = to_app(n); - expr * const * args = a->get_args(); - for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); - } - else if (m_manager.is_not(n)) - { - SASSERT(!negated); - app * a = to_app(n); - SASSERT(a->get_num_args() == 1); - expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); - setup_occs(child, true); - } - else - { - if (negated) - m_scores.find(n).has_neg_occ = 1; - else - m_scores.find(n).has_pos_occ = 1; - } - } + void setup_occs(expr * n, bool negated = false) { + if (m_manager.is_bool(n)) + { + if (m_manager.is_and(n) || m_manager.is_or(n)) + { + SASSERT(!negated); + app * a = to_app(n); + expr * const * args = a->get_args(); + for (unsigned i = 0; i < a->get_num_args(); i++) + setup_occs(args[i]); + } + else if (m_manager.is_not(n)) + { + SASSERT(!negated); + app * a = to_app(n); + SASSERT(a->get_num_args() == 1); + expr * child = a->get_arg(0); + if (m_manager.is_and(child) || m_manager.is_or(child)) + NOT_IMPLEMENTED_YET(); + setup_occs(child, true); + } + else + { + if (negated) + m_scores.find(n).has_neg_occ = 1; + else + m_scores.find(n).has_pos_occ = 1; + } + } else NOT_IMPLEMENTED_YET(); } @@ -574,7 +574,7 @@ public: double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); - double res = 0.0; + double res = 0.0; if (is_uninterp_const(n)) { const mpz & r = get_value(n); @@ -587,14 +587,14 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. + // Andreas: Seems to have no effect. Probably it does not even occur. #if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) sum += get_score(args[i]); res = sum / (double) a->get_num_args(); #else - double min = 1.0; + double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur < min) min = cur; @@ -606,16 +606,16 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. + // Andreas: Seems to have no effect. Probably it is still too similar to the original version. #if _SCORE_OR_MUL_ - double inv = 1.0; + double inv = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); inv *= (1.0 - get_score(args[i])); } res = 1.0 - inv; #else - double max = 0.0; + double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); if (cur > max) max = cur; @@ -639,7 +639,7 @@ public: expr * arg1 = a->get_arg(1); const mpz & v0 = get_value(arg0); const mpz & v1 = get_value(arg1); - + if (negated) { res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << @@ -701,7 +701,7 @@ public: double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - m_mpz_manager.del(diff); + m_mpz_manager.del(diff); } } else { @@ -762,7 +762,7 @@ public: TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - m_mpz_manager.del(x); + m_mpz_manager.del(x); m_mpz_manager.del(y); } else if (m_manager.is_not(n)) { @@ -797,25 +797,25 @@ public: SASSERT(res >= 0.0 && res <= 1.0); #if _WEIGHT_DIST_ - app * a = to_app(n); - family_id afid = a->get_family_id(); + app * a = to_app(n); + family_id afid = a->get_family_id(); - if (afid == m_bv_util.get_family_id()) + if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; + if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; #elif _WEIGHT_DIST_ == 2 - res *= res; + res *= res; #elif _WEIGHT_DIST_ == 3 - if (res < 1.0) res = 0.0; + if (res < 1.0) res = 0.0; #elif _WEIGHT_DIST_ == 4 - if (res < 1.0) res *= m_weight_dist_factor; + if (res < 1.0) res *= m_weight_dist_factor; #endif TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; } - + double score_bv(expr * n) { return 0.0; // a bv-expr is always scored as 0.0; we won't use those scores. } @@ -861,34 +861,34 @@ public: NOT_IMPLEMENTED_YET(); } - expr * get_unsat_expression(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - } - } - return e; - } + expr * get_unsat_expression(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e) || m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return get_unsat_expression(q); + } + } + } + return e; + } - ptr_vector & get_constants(expr * e) { + ptr_vector & get_constants(expr * e) { ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned i = 0; i < sz; i++) { @@ -897,9 +897,9 @@ public: m_temp_constants.push_back(fd); } return m_temp_constants; - } + } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) @@ -913,244 +913,244 @@ public: } } return m_temp_constants; - } + } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { - for (unsigned i = pos; i < sz; i++) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + for (unsigned i = pos; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; + return q; } - return 0; - } + for (unsigned i = 0; i < pos; i++) { + expr * q = g->form(i); + if (m_mpz_manager.neq(get_value(q), m_one)) + return q; + } + return 0; + } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. - if (!q) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); + if (!q) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(q); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & get_unsat_constants_walksat(expr * e) { + if (!e) + return m_temp_constants; + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); for (unsigned j = 0; j < sz; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & go_deeper(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - } - ptr_vector const & this_decls = m_constants_occ.find(e); + ptr_vector & go_deeper(expr * e) { + if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + // Andreas: might be used for guided branching + //for (unsigned i = 0; i < a->get_num_args(); i++) { + //double cur = get_score(args[i]); + //} + // Andreas: A random number is better here since reusing flip will cause patterns. + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned int pos = get_random_uint(16) % sz; + for (unsigned int i = pos; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + for (unsigned int i = 0; i < pos; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one)) + return go_deeper(q); + } + } + } + ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz2 = this_decls.size(); for (unsigned j = 0; j < sz2; j++) { func_decl * fd = this_decls[j]; if (!m_temp_constants.contains(fd)) m_temp_constants.push_back(fd); } - return m_temp_constants; - } + return m_temp_constants; + } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); if (!q) - return m_temp_constants; + return m_temp_constants; - return go_deeper(q); - } + return go_deeper(q); + } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { unsigned sz = g->size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) - return m_temp_constants; - else - return get_constants(); + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + return m_temp_constants; + else + return get_constants(); } else { m_temp_constants.reset(); #if _FOCUS_ == 1 #if _UCT_ - unsigned pos = -1; - value_score vscore; + unsigned pos = -1; + value_score vscore; #if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - for (unsigned i = start_index; i < sz; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } #else - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - vscore = m_scores.find(e); + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); #elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } #endif - if (pos == static_cast(-1)) - return m_temp_constants; + if (pos == static_cast(-1)) + return m_temp_constants; #if _UCT_ == 1 - m_scores.find(g->form(pos)).touched++; - m_touched++; + m_scores.find(g->form(pos)).touched++; + m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(g->form(pos)).touched = flip; #endif - expr * e = g->form(pos); + expr * e = g->form(pos); #elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; + unsigned int pos = -1; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; + unsigned int pos = -1; + double min = 2.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = g->form(i); double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _BFS_ == 1 - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; + expr * e = get_unsat_assertion(g, sz, pos); #elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return m_temp_constants; + expr * e = g->form(pos); #elif _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[get_random_uint(16) % sz]; + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[get_random_uint(16) % sz]; #elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[flip % sz]; + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return m_temp_constants; + else + expr * e = m_list_false[flip % sz]; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; - expr * e = get_unsat_assertion(g, sz, pos); + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; + expr * e = get_unsat_assertion(g, sz, pos); #endif - return get_unsat_constants_walksat(e); + return get_unsat_constants_walksat(e); #elif _FOCUS_ == 2 #if _BFS_ - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; + // I guess it was buggy ... + // unsigned int pos = flip % m_constants.size(); + unsigned int pos = flip % sz; #else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; + // I guess it was buggy ... + // unsigned int pos = get_random_uint(16) % m_constants.size(); + unsigned int pos = get_random_uint(16) % sz; #endif - return get_unsat_constants_crsat(g, sz, pos); + return get_unsat_constants_crsat(g, sz, pos); #else - return get_unsat_constants_gsat(g, sz); + return get_unsat_constants_gsat(g, sz); #endif } } From 442827e5236f2152b498f2cabe42a50d3b095a1c Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Wed, 19 Mar 2014 11:49:44 +0000 Subject: [PATCH 183/507] Current version for relocating. --- src/tactic/sls/sls_evaluator.h | 92 +++++----- src/tactic/sls/sls_tactic.cpp | 295 +++++++++++++++++++++++++++--- src/tactic/sls/sls_tracker.h | 315 ++++++++++++++++++++++++++++++--- 3 files changed, 600 insertions(+), 102 deletions(-) diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index cdb08038f..696d7664a 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -78,7 +78,11 @@ public: case OP_AND: { m_mpz_manager.set(result, m_one); for (unsigned i = 0; i < n_args; i++) +#if _DIRTY_UP_ + if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) && !m_tracker.is_top_expr(args[i])) { +#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { +#endif m_mpz_manager.set(result, m_zero); break; } @@ -86,7 +90,11 @@ public: } case OP_OR: { for (unsigned i = 0; i < n_args; i++) +#if _DIRTY_UP_ + if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) || m_tracker.is_top_expr(args[i])) { +#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { +#endif m_mpz_manager.set(result, m_one); break; } @@ -94,9 +102,16 @@ public: } case OP_NOT: { SASSERT(n_args == 1); +#if _DIRTY_UP_ + if (m_tracker.is_top_expr(args[0])) + m_mpz_manager.set(result, m_zero); + else + m_mpz_manager.set(result, (m_mpz_manager.is_zero(m_tracker.get_value(args[0]))) ? m_one : m_zero); +#else const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); - m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); + m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); +#endif break; } case OP_EQ: { @@ -542,7 +557,8 @@ public: m_tracker.set_value(cur, new_value); #if _REAL_RS_ || _REAL_PBFS_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) { if (m_mpz_manager.eq(new_value,m_one)) m_tracker.make_assertion(cur); @@ -554,7 +570,8 @@ public: #if _EARLY_PRUNE_ new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); @@ -562,13 +579,14 @@ public: #else #if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -611,7 +629,8 @@ public: #if _EARLY_PRUNE_ new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); @@ -619,13 +638,14 @@ public: #else #if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -695,7 +715,7 @@ public: double prune_score, new_score; unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); + SASSERT(cur_depth < m_traversal_stack_bool.size()); ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; @@ -704,7 +724,8 @@ public: new_score = m_tracker.score(cur); #if _CACHE_TOP_SCORE_ - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); #endif prune_score = m_tracker.get_score_prune(cur); @@ -745,7 +766,8 @@ public: #if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - if (!m_tracker.has_uplinks(cur)) + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else @@ -833,44 +855,7 @@ public: } #endif - void randomize_local(expr * e, unsigned int flip) { - ptr_vector & unsat_constants = m_tracker.get_constants(e); - - // Randomize _one_ candidate: - unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); - func_decl * fd = unsat_constants[r]; -#if _PERC_CHANGE_ - sort * srt = fd->get_range(); - mpz temp; - - if (m_manager.is_bool(srt)) - m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); - - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } -#else - mpz temp = m_tracker.get_random(fd->get_range()); -#endif - update(fd, temp); - m_mpz_manager.del(temp); - } - - void randomize_local(goal_ref const & g, unsigned int flip) { - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, flip); - + void randomize_local(ptr_vector & unsat_constants) { // Randomize _all_ candidates: //// bool did_something = false; @@ -927,6 +912,15 @@ public: tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + + } + + void randomize_local(expr * e) { + randomize_local(m_tracker.get_constants(e)); + } + + void randomize_local(goal_ref const & g, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(g, flip)); } }; diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 553acc35a..ada0ec359 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -34,6 +34,8 @@ Notes: #include"propagate_values_tactic.h" #include"sls_tactic.h" #include"nnf_tactic.h" +#include"luby.h" +#include "ctx_simplify_tactic.h" // which unsatisfied assertion is selected? only works with _FOCUS_ > 0 // 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score @@ -43,9 +45,23 @@ Notes: // 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom #define _FOCUS_ 1 +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 0 + // do we use restarts? -// 0 = no, otherwise the value defines the maximum number of moves -#define _RESTARTS_ 0 +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 3.0 // timelimit #define _TIMELIMIT_ 3600 @@ -66,38 +82,58 @@ Notes: // 2 = yes, by squaring it // 3 = yes, by setting it to zero // 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 0 +#define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 #define _WEIGHT_DIST_FACTOR_ 0.25 +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + // do we use intensification steps in local minima? if so, how many? #define _INTENSIFICATION_ 0 #define _INTENSIFICATION_TRIES_ 0 +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + // do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 0 +#define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 0.01 +#define _UCT_CONSTANT_ 10.0 // is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score #define _PROBABILISTIC_UCT_ 0 +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 1 + // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 // shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 1 +#define _USE_MUL2DIV2_ 0 // shall we try multiplication by 3? -#define _USE_MUL3_ 1 +#define _USE_MUL3_ 0 // shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 1 +#define _USE_UNARY_MINUS_ 0 // is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 1 +#define _UNIFORM_RANDOM_ 0 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 @@ -124,13 +160,21 @@ Notes: #define _CACHE_TOP_SCORE_ 1 -#if ((_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) || _BFS_ && (_UCT_ ||_UNIFORM_RANDOM_ ||_REAL_RS_ ||_REAL_PBFS_) +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) InvalidConfiguration; #endif #if (_PROBABILISTIC_UCT_ && !_UCT_) InvalidConfiguration; #endif - +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) + InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) + InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) + InvalidConfiguration; +#endif #include"sls_params.hpp" #include"sls_evaluator.h" @@ -180,6 +224,7 @@ class sls_tactic : public tactic { sls_tracker m_tracker; sls_evaluator m_evaluator; + unsigned m_restart_limit; unsigned m_max_restarts; unsigned m_plateau_limit; @@ -208,6 +253,41 @@ class sls_tactic : public tactic { m_mpz_manager.del(m_two); } + double get_restart_armin(unsigned cnt_restarts) + { + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow(_RESTART_CONST_ARMIN_, inner_id + 1); + } + + inline unsigned check_restart(unsigned curr_value) + { + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; + } + ast_manager & m() const { return m_manager; } void set_cancel(bool f) { m_cancel = f; } @@ -435,12 +515,10 @@ class sls_tactic : public tactic { NOT_IMPLEMENTED_YET(); } - void mk_random_move(goal_ref const & g) { + void mk_random_move(ptr_vector & unsat_constants) + { unsigned rnd_mv = 0; - if (m_stats.m_moves > 10000) - rnd_mv = 0; - ptr_vector & unsat_constants = m_tracker.get_unsat_constants(g, m_stats.m_moves); unsigned ucc = unsat_constants.size(); unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; func_decl * fd = unsat_constants[rc]; @@ -503,6 +581,10 @@ class sls_tactic : public tactic { m_mpz_manager.del(new_value); } + void mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); + } + // will use VNS to ignore some possible moves and increase the flips per second double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { @@ -857,7 +939,7 @@ class sls_tactic : public tactic { m_stats.m_flips++; global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); + local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -875,6 +957,130 @@ class sls_tactic : public tactic { unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + // main search loop + lbool search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; score = rescore(g); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; @@ -887,12 +1093,12 @@ class sls_tactic : public tactic { // Andreas: Why do we only allow so few plateaus? #if _RESTARTS_ - while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #else while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { #endif do { - if (m_stats.m_moves == 5590) checkpoint(); #if _WEIGHT_DIST_ == 4 @@ -1072,7 +1278,11 @@ class sls_tactic : public tactic { verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; @@ -1081,9 +1291,14 @@ class sls_tactic : public tactic { verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; verbose_stream() << "_UCT_ " << _UCT_ << std::endl; verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; @@ -1099,21 +1314,30 @@ class sls_tactic : public tactic { verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; #if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); #endif m_tracker.initialize(g); lbool res = l_undef; + m_restart_limit = _RESTART_LIMIT_; + do { checkpoint(); - // Andreas: I think restarts are too impotant to ignore 99% of them are happening... - //if ((m_stats.m_restarts % 100) == 0) - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); res = search(g); if (res == l_undef) - m_tracker.randomize(); + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); @@ -1121,6 +1345,13 @@ class sls_tactic : public tactic { if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + if (m_produce_models) { model_ref mdl = m_tracker.get_model(); mc = model2model_converter(mdl.get()); @@ -1183,12 +1414,17 @@ public: } virtual void cleanup() { - imp * d = alloc(imp, m, m_params, m_stats); + imp * d = m_imp; #pragma omp critical (tactic_cancel) { - std::swap(d, m_imp); + d = m_imp; } dealloc(d); + d = alloc(imp, m, m_params, m_stats); + #pragma omp critical (tactic_cancel) + { + m_imp = d; + } } virtual void collect_statistics(statistics & st) const { @@ -1246,6 +1482,9 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // conservative gaussian elimination. gaussian_p.set_uint("gaussian_max_occs", 2); + params_ref ctx_p; + ctx_p.set_uint("max_depth", 32); + ctx_p.set_uint("max_steps", 5000000); return and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), using_params(mk_solve_eqs_tactic(m), gaussian_p), @@ -1254,6 +1493,10 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), + // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? + //mk_ctx_simplify_tactic(m, ctx_p), + // Andreas: This one at least eliminates top level duplicates ... + mk_simplify_tactic(m), // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 006bbb888..0aca1f59c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -65,6 +65,7 @@ private: typedef obj_map scores_type; typedef obj_map > uplinks_type; typedef obj_map > occ_type; + obj_hashtable m_top_expr; scores_type m_scores; uplinks_type m_uplinks; entry_point_type m_entry_points; @@ -75,15 +76,15 @@ private: unsigned m_touched; #endif #if _REAL_RS_ || _REAL_PBFS_ - ptr_vector m_unsat_expr; - obj_map m_where_false; - expr** m_list_false; + ptr_vector m_unsat_expr; + obj_map m_where_false; + expr** m_list_false; #endif #if _CACHE_TOP_SCORE_ - double m_top_sum; + double m_top_sum; #endif -#if _WEIGHT_DIST_ == 4 - double m_weight_dist_factor; +#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ + double m_weight_dist_factor; #endif public: @@ -104,7 +105,7 @@ public: m_mpz_manager.del(m_two); } -#if _WEIGHT_DIST_ == 4 +#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ inline void set_weight_dist_factor(double val) { m_weight_dist_factor = val; } @@ -182,12 +183,12 @@ public: inline unsigned has_pos_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_pos_occ; - } + } inline unsigned has_neg_occ(expr * n) { SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; - } + } #endif inline unsigned get_distance(expr * n) { @@ -213,11 +214,62 @@ public: return m_uplinks.contains(n); } + inline bool is_top_expr(expr * n) { + return m_top_expr.contains(n); + } + inline ptr_vector & get_uplinks(expr * n) { SASSERT(m_uplinks.contains(n)); return m_uplinks.find(n); } +#if _REAL_RS_ || _REAL_PBFS_ + void debug_real(goal_ref const & g, unsigned flip) + { + unsigned count = 0; + for (unsigned i = 0; i < g->size(); i++) + { + expr * e = g->form(i); + if (m_mpz_manager.eq(get_value(e),m_one) && m_where_false.contains(e)) + { + printf("iteration %d: ", flip); + printf("form %d is sat but in unsat list at position %d of %d\n", i, m_where_false.find(e), m_where_false.size()); + exit(4); + } + + if (m_mpz_manager.eq(get_value(e),m_zero) && !m_where_false.contains(e)) + { + printf("iteration %d: ", flip); + printf("form %d is unsat but not in unsat list\n", i); + exit(4); + } + + if (m_mpz_manager.eq(get_value(e),m_zero) && m_where_false.contains(e)) + { + unsigned pos = m_where_false.find(e); + expr * q = m_list_false[pos]; + if (q != e) + { + printf("iteration %d: ", flip); + printf("form %d is supposed to be at pos %d in unsat list but something else was there\n", i, pos); + exit(4); + } + } + + if (m_mpz_manager.eq(get_value(e),m_zero)) + count++; + } + + // should be true now that duplicate assertions are removed + if (count != m_where_false.size()) + { + printf("iteration %d: ", flip); + printf("%d are unsat but list is of size %d\n", count, m_where_false.size()); + exit(4); + } + } +#endif + void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -327,7 +379,7 @@ public: } } for_each_expr(proc, visited, e); - } + } void initialize_recursive(expr * e) { if (m_manager.is_and(e) || m_manager.is_or(e)) { @@ -344,7 +396,7 @@ public: find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + } void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); @@ -352,6 +404,10 @@ public: unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); + if (!m_top_expr.contains(e)) + m_top_expr.insert(e); + else + printf("this is already in ...\n"); // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 initialize_recursive(proc, visited, e); @@ -380,18 +436,20 @@ public: #if _REAL_RS_ || _REAL_PBFS_ m_list_false = new expr*[sz]; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - break_assertion(g->form(i)); + //for (unsigned i = 0; i < sz; i++) + //{ + // if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) + // break_assertion(g->form(i)); + //} #endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; #endif } @@ -407,8 +465,12 @@ public: expr * q = m_list_false[m_where_false.size()]; m_list_false[pos] = q; m_where_false.find(q) = pos; + //printf("Moving %d from %d to %d\n", q, m_where_false.size(), pos); } -// printf("Going in %d\n", m_where_false.size()); + //else + //printf("Erasing %d from %d to %d\n", e, pos); +// m_list_false[m_where_false.size()] = 0; +// printf("Going in %d\n", m_where_false.size()); } //if (m_unsat_expr.contains(e)) //m_unsat_expr.erase(e); @@ -416,12 +478,14 @@ public: void break_assertion(expr * e) { + //printf("I'm broken... that's still fine.\n"); if (!m_where_false.contains(e)) { + //printf("This however is not so cool...\n"); unsigned pos = m_where_false.size(); m_list_false[pos] = e; m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); + // printf("Going in %d\n", m_where_false.size()); } //if (!m_unsat_expr.contains(e)) //m_unsat_expr.push_back(e); @@ -522,7 +586,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize() { + void randomize(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -534,6 +598,28 @@ public: } TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); + +#if _UCT_RESET_ + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; +#endif + } + + void reset(goal_ref const & g) { + TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); + + for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { + mpz temp = m_zero; + set_value(it->m_value, temp); + m_mpz_manager.del(temp); + } + +#if _UCT_RESET_ + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; +#endif } #if _EARLY_PRUNE_ @@ -591,12 +677,20 @@ public: #if _SCORE_AND_AVG_ double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) +#if _DIRTY_UP_ + sum += is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else sum += get_score(args[i]); +#endif res = sum / (double) a->get_num_args(); #else double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif if (cur < min) min = cur; } res = min; @@ -610,14 +704,22 @@ public: #if _SCORE_OR_MUL_ double inv = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif inv *= (1.0 - get_score(args[i])); } res = 1.0 - inv; #else double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { +#if _DIRTY_UP_ + double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); +#else double cur = get_score(args[i]); +#endif if (cur > max) max = cur; } res = max; @@ -772,7 +874,11 @@ public: expr * child = a->get_arg(0); if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. NOT_IMPLEMENTED_YET(); +#if _DIRTY_UP_ + res = is_top_expr(child) ? 0.0 : score_bool(child, true); +#else res = score_bool(child, true); +#endif } else if (m_manager.is_distinct(n)) { app * a = to_app(n); @@ -803,7 +909,11 @@ public: if (afid == m_bv_util.get_family_id()) #endif #if _WEIGHT_DIST_ == 1 +#if _WEIGHT_TOGGLE_ + if (res < 1.0) res *= m_weight_dist_factor; +#else if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; +#endif #elif _WEIGHT_DIST_ == 2 res *= res; #elif _WEIGHT_DIST_ == 3 @@ -900,6 +1010,10 @@ public: } ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + if (sz == 1) + return get_constants(); + m_temp_constants.reset(); + for (unsigned i = 0; i < sz; i++) { expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) @@ -945,7 +1059,7 @@ public: } ptr_vector & get_unsat_constants_walksat(expr * e) { - if (!e) + if (!e || m_temp_constants.size()) return m_temp_constants; ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); @@ -1033,32 +1147,43 @@ public: #if _PROBABILISTIC_UCT_ double sum_score = 0.0; unsigned start_index = get_random_uint(16) % sz; + for (unsigned i = start_index; i < sz; i++) { expr * e = g->form(i); vscore = m_scores.find(e); - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { sum_score += q; if (rand() <= (q * RAND_MAX / sum_score) + 1) pos = i; - } + } } for (unsigned i = 0; i < start_index; i++) { expr * e = g->form(i); vscore = m_scores.find(e); - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { sum_score += q; if (rand() <= (q * RAND_MAX / sum_score) + 1) pos = i; - } + } } #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { expr * e = g->form(i); +// for (unsigned i = 0; i < m_where_false.size(); i++) { +// expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); @@ -1078,6 +1203,7 @@ public: m_scores.find(g->form(pos)).touched = flip; #endif expr * e = g->form(pos); +// expr * e = m_list_false[pos]; #elif _BFS_ == 3 unsigned int pos = -1; @@ -1109,7 +1235,7 @@ public: #elif _UNIFORM_RANDOM_ unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return m_temp_constants; expr * e = g->form(pos); @@ -1120,8 +1246,7 @@ public: sz = m_where_false.size(); if (sz == 0) return m_temp_constants; - else - expr * e = m_list_false[get_random_uint(16) % sz]; + expr * e = m_list_false[get_random_uint(16) % sz]; #elif _REAL_PBFS_ //unsigned pos = m_false_list[flip % m_cnt_false]; //expr * e = get_unsat_assertion(g, sz, pos); @@ -1154,6 +1279,142 @@ public: #endif } } + + + expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); + + if (sz == 1) + return g->form(0); + + m_temp_constants.reset(); +#if _FOCUS_ == 1 +#if _UCT_ + unsigned pos = -1; + value_score vscore; +#if _PROBABILISTIC_UCT_ + double sum_score = 0.0; + unsigned start_index = get_random_uint(16) % sz; + + for (unsigned i = start_index; i < sz; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score + _UCT_EPS_; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } + for (unsigned i = 0; i < start_index; i++) + { + expr * e = g->form(i); + vscore = m_scores.find(e); +#if _PROBABILISTIC_UCT_ == 2 + double q = vscore.score * vscore.score + _UCT_EPS_; +#else + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; +#endif + if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { + sum_score += q; + if (rand() <= (q * RAND_MAX / sum_score) + 1) + pos = i; + } + } +#else + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); +// for (unsigned i = 0; i < m_where_false.size(); i++) { +// expr * e = m_list_false[i]; + vscore = m_scores.find(e); +#if _UCT_ == 1 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); +#elif _UCT_ == 2 + double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#endif + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + } +#endif + if (pos == static_cast(-1)) + return 0; + +#if _UCT_ == 1 + m_scores.find(g->form(pos)).touched++; + m_touched++; +#elif _UCT_ == 2 + m_scores.find(g->form(pos)).touched = flip; +#endif +// return m_list_false[pos]; + return g->form(pos); + +#elif _BFS_ == 3 + unsigned int pos = -1; + double max = -1.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _BFS_ == 2 + unsigned int pos = -1; + double min = 2.0; + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + double q = get_score(e); + if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } + } + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _BFS_ == 1 + unsigned int pos = flip % sz; + return get_unsat_assertion(g, sz, pos); +#elif _UNIFORM_RANDOM_ + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return 0; + return g->form(pos); +#elif _REAL_RS_ + //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return 0; + return m_list_false[get_random_uint(16) % sz]; +#elif _REAL_PBFS_ + //unsigned pos = m_false_list[flip % m_cnt_false]; + //expr * e = get_unsat_assertion(g, sz, pos); + //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; + sz = m_where_false.size(); + if (sz == 0) + return0; + else + return m_list_false[flip % sz]; +#else + unsigned int pos = get_random_uint(16) % sz; + return get_unsat_assertion(g, sz, pos); +#endif + return g->form(pos); +#elif _FOCUS_ == 2 +#if _BFS_ + unsigned int pos = flip % sz; +#else + unsigned int pos = get_random_uint(16) % sz; +#endif + return get_unsat_constants_crsat(g, sz, pos); +#endif + } }; #endif \ No newline at end of file From 7451e5cae0ccdf110065453d8918f7f2e7726d4a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 17:04:38 +0000 Subject: [PATCH 184/507] SLS refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 158 +++ src/tactic/sls/sls_engine.cpp | 1027 +++++++++++---- src/tactic/sls/sls_engine.h | 88 +- src/tactic/sls/sls_evaluator.h | 3 + src/tactic/sls/sls_tactic.cpp | 1397 +-------------------- src/tactic/sls/sls_tracker.h | 10 +- 6 files changed, 1036 insertions(+), 1647 deletions(-) create mode 100644 src/tactic/sls/sls_compilation_settings.h diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h new file mode 100644 index 000000000..aea4787b0 --- /dev/null +++ b/src/tactic/sls/sls_compilation_settings.h @@ -0,0 +1,158 @@ +/*++ +Copyright (c) 2014 Microsoft Corporation + +Module Name: + + sls_compilation_constants.h + +Abstract: + + Stochastic Local Search (SLS) compilation constants + +Author: + + Christoph (cwinter) 2014-03-19 + +Notes: + + This file should go away completely once we have evaluated all options. + +--*/ +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom +#define _FOCUS_ 1 + +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 0 + +// do we use restarts? +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 3.0 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? +#define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? +#define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained +#define _VNS_ 0 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 1 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.25 + +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 1 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 10.0 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score +#define _PROBABILISTIC_UCT_ 0 + +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 1 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 0 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 0 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 0 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 0 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) +InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) +InvalidConfiguration; +#endif +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) +InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) +InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) +InvalidConfiguration; +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index c0c319ab4..92471aad8 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -16,7 +16,6 @@ Author: Notes: --*/ -#include #include #include"map.h" @@ -28,6 +27,7 @@ Notes: #include"cooperate.h" #include"luby.h" +#include"sls_compilation_settings.h" #include"sls_params.hpp" #include"sls_engine.h" @@ -44,7 +44,6 @@ sls_engine::sls_engine(ast_manager & m, params_ref const & p) : m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) { updt_params(p); - m_tracker.updt_params(p); } sls_engine::~sls_engine() { @@ -53,32 +52,20 @@ sls_engine::~sls_engine() { m_mpz_manager.del(m_two); } +double sls_engine::get_restart_armin(unsigned cnt_restarts) +{ + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); +} + void sls_engine::updt_params(params_ref const & _p) { sls_params p(_p); m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.max_restarts(); + m_max_restarts = p.restarts(); m_tracker.set_random_seed(p.random_seed()); - m_walksat = p.walksat(); - m_walksat_repick = p.walksat_repick(); - m_paws_sp = p.paws_sp(); - m_paws = m_paws_sp < 1024; - m_wp = p.wp(); - m_vns_mc = p.vns_mc(); - m_vns_repick = p.vns_repick(); - - m_restart_base = p.restart_base(); - m_restart_next = m_restart_base; - m_restart_init = p.restart_init(); - - m_early_prune = p.early_prune(); - m_random_offset = p.random_offset(); - m_rescore = p.rescore(); - - // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. - if (m_walksat_repick && !m_walksat) - NOT_IMPLEMENTED_YET(); - if (m_vns_repick && !m_walksat) - NOT_IMPLEMENTED_YET(); + m_plateau_limit = p.plateau_limit(); } void sls_engine::checkpoint() { @@ -87,15 +74,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(model & mdl) { +bool sls_engine::full_eval(goal_ref const & g, model & mdl) { bool res = true; - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(m_assertions[i], o, true)) + if (!mdl.eval(g->form(i), o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -106,69 +93,96 @@ bool sls_engine::full_eval(model & mdl) { return res; } -double sls_engine::top_score() { +double sls_engine::top_score(goal_ref const & g) { +#if 0 + double min = m_tracker.get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + double q = m_tracker.get_score(g->form(i)); + if (q < min) min = q; + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " MIN: " << min << std::endl;); + return min; +#else double top_sum = 0.0; - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = m_assertions[i]; + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(m_assertions[i]); + tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double)sz << std::endl;); +#if _CACHE_TOP_SCORE_ m_tracker.set_top_sum(top_sum); +#endif - return top_sum; + return top_sum / (double)sz; +#endif } -double sls_engine::rescore() { +double sls_engine::rescore(goal_ref const & g) { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(); + return top_score(g); } -double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; - return m_tracker.get_top_sum(); +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif } -double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; - return m_tracker.get_top_sum(); +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif } -double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { +#if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) - return m_tracker.get_top_sum(); +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif else - return -DBL_MAX; + return 0.0; +#else + NOT_IMPLEMENTED_YET(); +#endif } // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if( - func_decl * fd, - const unsigned & fd_inx, - const mpz & temp, - double & best_score, - unsigned & best_const, - mpz & best_value) { +bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { #ifdef Z3DEBUG mpz old_value; m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif - double r; - if (m_early_prune) - r = incremental_score_prune(fd, temp); - else - r = incremental_score(fd, temp); +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else + double r = incremental_score(g, fd, temp); +#endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl;); @@ -176,10 +190,7 @@ bool sls_engine::what_if( m_mpz_manager.del(old_value); #endif - // Andreas: Had this idea on my last day. Maybe we could add a noise here similar to the one that worked so well for ucb assertion selection. - // r += 0.0001 * m_tracker.get_random_uint(8); - - // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. + // if (r >= best_score) { if (r > best_score) { best_score = r; best_const = fd_inx; @@ -190,6 +201,21 @@ bool sls_engine::what_if( return false; } +// same as what_if, but only applied to the score of a specific atom, not the total score +bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); + if (r >= best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + void sls_engine::mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { mpz temp, mask, mask2; m_mpz_manager.add(old_value, add_value, temp); @@ -202,6 +228,22 @@ void sls_engine::mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, } +// Andreas: do we really need all those temporary mpzs? +void sls_engine::mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); +} + +void sls_engine::mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); +} + void sls_engine::mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); @@ -251,18 +293,16 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); else { +#if _USE_ADDSUB_ if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - - // Andreas: The other option would be to scale the probability for flips according to the bit-width. - /* unsigned bv_sz2 = m_bv_util.get_bv_size(srt); - rnd_mv = m_tracker.get_random_uint(16) % (bv_sz2 + 3); - if (rnd_mv > 3) rnd_mv = 0; */ - move_type mt = (move_type)rnd_mv; - // Andreas: Christoph claimed inversion doesn't make sense, let's do a flip instead. Is this really true? + // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif unsigned bit = 0; switch (mt) @@ -300,30 +340,192 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout);); } - m_evaluator.serious_update(fd, new_value); + m_evaluator.update(fd, new_value); m_mpz_manager.del(new_value); } -// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move( - ptr_vector & to_evaluate, - double score, - unsigned & best_const, - mpz & best_value, - unsigned & new_bit, - move_type & move) -{ +void sls_engine::mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); +} + +// will use VNS to ignore some possible moves and increase the flips per second +double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + // we can either check the condition once in the beginning or check it repeatedly after every bit +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif unsigned bv_sz; double new_score = score; - // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. - unsigned sz = to_evaluate.size(); - unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; - for (unsigned j = 0; j < sz; j++) { - unsigned i = j + offset; - if (i >= sz) i -= sz; - //for (unsigned i = 0; i < to_evaluate.size(); i++) { + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } +#endif + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; +} + +// same as find_best_move but only considers the score of the current expression instead of the overall score +double sls_engine::find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -334,7 +536,7 @@ double sls_engine::find_best_move( // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } @@ -344,176 +546,489 @@ double sls_engine::find_best_move( if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } + // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; } + // reset to what it was before - incremental_score(fd, old_value); + m_evaluator.update(fd, old_value); } m_mpz_manager.del(old_value); m_mpz_manager.del(temp); - return new_score; } -// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value) { - mpz old_value, temp, temp2; - unsigned bv_sz; - double new_score = score; +// first try of intensification ... does not seem to be efficient +bool sls_engine::handle_plateau(goal_ref const & g) +{ + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; - // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. - unsigned sz = to_evaluate.size(); - unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; - for (unsigned j = 0; j < sz; j++) { - unsigned i = j + offset; - if (i >= sz) i -= sz; - //for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back(&m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { - for (unsigned j = 0; j < bv_sz; j++) { - mk_flip(srt, old_value, j, temp); - for (unsigned l = 0; l < m_vns_mc && l < bv_sz / 2; l++) - { - unsigned k = m_tracker.get_random_uint(16) % bv_sz; - while (k == j) - k = m_tracker.get_random_uint(16) % bv_sz; - mk_flip(srt, temp, k, temp2); - what_if(fd, i, temp2, new_score, best_const, best_value); - } - } + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); } - // reset to what it was before - incremental_score(fd, old_value); + else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], *m_old_values[i]); + + m_old_values.reset(); + + return 0; +} + +// what_if version needed in the context of 2nd intensification try, combining local and global score +bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; +} + +// find_best_move version needed in the context of 2nd intensification try +double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) +{ + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); } m_mpz_manager.del(old_value); m_mpz_manager.del(temp); - m_mpz_manager.del(temp2); - return new_score; + return best_score; +} + +// second try to use intensification ... also not very effective +bool sls_engine::handle_plateau(goal_ref const & g, double old_score) +{ + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; } // main search loop -lbool sls_engine::search() { +lbool sls_engine::search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit; + unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; + unsigned plateau_cnt = 0; - score = rescore(); - unsigned sz = m_assertions.size(); + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif - while (check_restart(m_stats.m_moves)) { +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif checkpoint(); m_stats.m_moves++; - // Andreas: Every base restart interval ... - if (m_stats.m_moves % m_restart_base == 0) - { - // ... potentially smooth the touched counters ... - m_tracker.ucb_forget(m_assertions); - // ... or normalize the top-level score. - if (m_rescore) score = rescore(); - } +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif - // get candidate variables - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); if (!to_evaluate.size()) { res = l_true; goto bailout; } +#endif - // random walk with probability wp / 1024 - if (m_wp && m_tracker.get_random_uint(10) < m_wp) +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 mk_random_move(to_evaluate); - score = m_tracker.get_top_sum(); - continue; +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif } + continue; +#endif +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif old_score = score; new_const = (unsigned)-1; - // find best increasing move - score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif - // use Monte Carlo 2-bit-flip sampling if no increasing move was found previously - if (m_vns_mc && (new_const == static_cast(-1))) - score = find_best_move_mc(to_evaluate, score, new_const, new_value); - - // repick assertion if no increasing move was found previously - if (m_vns_repick && (new_const == static_cast(-1))) - { - expr * q = m_tracker.get_new_unsat_assertion(m_assertions); - // only apply if another unsatisfied assertion actually exists - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); - score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); - - if (new_const != static_cast(-1)) { - func_decl * fd = to_evaluate2[new_const]; - score = serious_score(fd, new_value); - continue; - } - } - } - - // randomize if no increasing move was found if (new_const == static_cast(-1)) { score = old_score; - if (m_walksat_repick) - m_evaluator.randomize_local(m_assertions); + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else m_evaluator.randomize_local(to_evaluate); +#endif +#endif - score = m_tracker.get_top_sum(); - - // update assertion weights if a weigthing is enabled (sp < 1024) - if (m_paws) - { - for (unsigned i = 0; i < sz; i++) - { - expr * q = m_assertions[i]; - // smooth weights with probability sp / 1024 - if (m_tracker.get_random_uint(10) < m_paws_sp) - { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) - m_tracker.decrease_weight(q); - } - // increase weights otherwise - else - { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) - m_tracker.increase_weight(q); - } - } - } +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif } - // otherwise, apply most increasing move else { func_decl * fd = to_evaluate[new_const]; - score = serious_score(fd, new_value); +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + +bailout: + m_mpz_manager.del(new_value); + + return res; +} + +// main search loop +lbool sls_engine::search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + + score = rescore(g); + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + + unsigned plateau_cnt = 0; + + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { +#endif + do { + checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif + old_score = score; + new_const = (unsigned)-1; + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } + TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; + for (unsigned i = 0; i < to_evaluate.size(); i++) + tout << to_evaluate[i]->get_name() << std::endl;); + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + if (new_const == static_cast(-1)) { + TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + }); + + TRACE("sls_max", m_tracker.show_model(tout); + tout << "Scores: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl;); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? + score = old_score; + } + else { + // Andreas: Why does randomizing not count as a move? (Now it does.) + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; + switch (move) { + case MV_FLIP: + tout << "Flip"; + if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; + break; + case MV_INC: + tout << "+1"; + break; + case MV_DEC: + tout << "-1"; + break; + case MV_INV: + tout << "NEG"; + break; + }; + tout << ") ; new score = " << std::setprecision(32) << score << std::endl;); + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + + TRACE("sls", tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + } + + if (score >= 0.99999) { + // if (score >= 1.0) { + // score could theoretically be imprecise. + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ + } while (score > old_score && res == l_undef); + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); + plateau_cnt = 0; + } + else { + m_stats.m_moves++; + plateau_cnt++; + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { + TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else + m_evaluator.randomize_local(g, m_stats.m_moves); +#endif + //mk_random_move(g); + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true = false; + if (all_true) { + res = l_true; // sat + goto bailout; + } + else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } } } @@ -531,10 +1046,71 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); - for (unsigned i = 0; i < g->size(); i++) - assert_expr(g->form(i)); + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - lbool res = operator()(); +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); @@ -556,66 +1132,29 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { mc = 0; } -lbool sls_engine::operator()() { - m_tracker.initialize(m_assertions); - lbool res = l_undef; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(); - - if (res == l_undef) - { - if (m_restart_init) - m_tracker.randomize(m_assertions); - else - m_tracker.reset(m_assertions); - } - } while (res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - return res; -} - -/* Andreas: Needed for Armin's restart scheme if we don't want to use loops. -double sls_engine::get_restart_armin(unsigned cnt_restarts) -{ - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); -} -*/ - unsigned sls_engine::check_restart(unsigned curr_value) { - if (curr_value > m_restart_next) + if (curr_value > m_restart_limit) { - /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save one parameter. - I leave the other versions as comments in case you want to try it again somewhen. -#if _RESTART_SCHEME_ == 5 - m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); -#elif _RESTART_SCHEME_ == 4 - m_restart_next += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? m_restart_base : (m_restart_base * m_stats.m_restarts + 1); +#if _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 - m_restart_next += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * m_restart_base; + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; #elif _RESTART_SCHEME_ == 2 - m_restart_next += get_luby(m_stats.m_restarts + 1) * m_restart_base; + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) - m_restart_next += m_restart_base; + m_restart_limit += _RESTART_LIMIT_; else - m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; #else - m_restart_limit += m_restart_base; -#endif */ - if (m_stats.m_restarts & 1) - m_restart_next += m_restart_base; - else - m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif return 0; } return 1; -} +} \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index b056c438e..878354c6d 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,8 +22,8 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" -#include"goal.h" +#include"sls_compilation_settings.h" #include"sls_tracker.h" #include"sls_evaluator.h" @@ -35,13 +35,17 @@ public: stopwatch m_stopwatch; unsigned m_full_evals; unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; stats() : m_restarts(0), m_full_evals(0), m_incr_evals(0), m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -67,24 +71,14 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; - ptr_vector m_assertions; + unsigned m_restart_limit; unsigned m_max_restarts; - unsigned m_walksat; - unsigned m_walksat_repick; - unsigned m_wp; - unsigned m_vns_mc; - unsigned m_vns_repick; - unsigned m_paws; - unsigned m_paws_sp; - unsigned m_restart_base; - unsigned m_restart_next; - unsigned m_restart_init; - unsigned m_early_prune; - unsigned m_random_offset; - unsigned m_rescore; + unsigned m_plateau_limit; - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; public: sls_engine(ast_manager & m, params_ref const & p); @@ -98,46 +92,68 @@ public: void updt_params(params_ref const & _p); - void assert_expr(expr * e) { m_assertions.push_back(e); } - stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(model & mdl); + bool full_eval(goal_ref const & g, model & mdl); + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result); void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - lbool search(void); + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + + + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); + + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); + + + lbool search(goal_ref const & g); - lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); + lbool search_old(goal_ref const & g); + double get_restart_armin(unsigned cnt_restarts); - bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - double top_score(); - double rescore(); - double serious_score(func_decl * fd, const mpz & new_value); - double incremental_score(func_decl * fd, const mpz & new_value); + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); - double incremental_score_prune(func_decl * fd, const mpz & new_value); - double find_best_move(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double top_score(goal_ref const & g); + double rescore(goal_ref const & g); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - double find_best_move_mc(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value); +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); +#endif + + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); void mk_random_move(ptr_vector & unsat_constants); + void mk_random_move(goal_ref const & g); - //double get_restart_armin(unsigned cnt_restarts); - unsigned check_restart(unsigned curr_value); + bool handle_plateau(goal_ref const & g); + bool handle_plateau(goal_ref const & g, double old_score); + + inline unsigned check_restart(unsigned curr_value); }; -#endif +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 696d7664a..9daf93c32 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -20,6 +20,9 @@ Notes: #ifndef _SLS_EVALUATOR_H_ #define _SLS_EVALUATOR_H_ +#include"model_evaluator.h" + +#include"sls_compilation_settings.h" #include"sls_powers.h" #include"sls_tracker.h" diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index ada0ec359..0f157d3a6 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,1364 +16,31 @@ Author: Notes: --*/ -#include -#include"map.h" #include"nnf.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"model_pp.h" -#include"model_evaluator.h" #include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"stopwatch.h" #include"propagate_values_tactic.h" -#include"sls_tactic.h" +#include"ctx_simplify_tactic.h" +#include"elim_uncnstr_tactic.h" #include"nnf_tactic.h" -#include"luby.h" -#include "ctx_simplify_tactic.h" - -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 0 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick clause when randomizing in a plateau or use the current one? -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 - -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 - -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? -#define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 - -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) - InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) - InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) - InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) - InvalidConfiguration; -#endif +#include"stopwatch.h" +#include"sls_tactic.h" #include"sls_params.hpp" -#include"sls_evaluator.h" -#include"sls_tracker.h" +#include"sls_engine.h" -class sls_tactic : public tactic { - class stats { - public: - unsigned m_restarts; - stopwatch m_stopwatch; - unsigned m_full_evals; - unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; - - stats() : - m_restarts(0), - m_full_evals(0), - m_incr_evals(0), - m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), - m_flips(0), - m_incs(0), - m_decs(0), - m_invs(0) { - m_stopwatch.reset(); - m_stopwatch.start(); - } - void reset() { - m_full_evals = m_flips = m_incr_evals = 0; - m_stopwatch.reset(); - m_stopwatch.start(); - } - }; - - struct imp { - ast_manager & m_manager; - stats & m_stats; - unsynch_mpz_manager m_mpz_manager; - powers m_powers; - mpz m_zero, m_one, m_two; - bool m_produce_models; - volatile bool m_cancel; - bv_util m_bv_util; - sls_tracker m_tracker; - sls_evaluator m_evaluator; - - unsigned m_restart_limit; - unsigned m_max_restarts; - unsigned m_plateau_limit; - - ptr_vector m_old_values; - - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; - - imp(ast_manager & m, params_ref const & p, stats & s) : - m_manager(m), - m_stats(s), - m_powers(m_mpz_manager), - m_zero(m_mpz_manager.mk_z(0)), - m_one(m_mpz_manager.mk_z(1)), - m_two(m_mpz_manager.mk_z(2)), - m_cancel(false), - m_bv_util(m), - m_tracker(m, m_bv_util, m_mpz_manager, m_powers), - m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) - { - updt_params(p); - } - - ~imp() { - m_mpz_manager.del(m_zero); - m_mpz_manager.del(m_one); - m_mpz_manager.del(m_two); - } - - double get_restart_armin(unsigned cnt_restarts) - { - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow(_RESTART_CONST_ARMIN_, inner_id + 1); - } - - inline unsigned check_restart(unsigned curr_value) - { - if (curr_value > m_restart_limit) - { -#if _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); -#elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 1 - if (m_stats.m_restarts & 1) - m_restart_limit += _RESTART_LIMIT_; - else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; -#else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif - return 0; - } - return 1; - } - - ast_manager & m() const { return m_manager; } - - void set_cancel(bool f) { m_cancel = f; } - void cancel() { set_cancel(true); } - void reset_cancel() { set_cancel(false); } - - static void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); - } - - void updt_params(params_ref const & _p) { - sls_params p(_p); - m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); - m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); - } - - void checkpoint() { - if (m_cancel) - throw tactic_exception(TACTIC_CANCELED_MSG); - cooperate("sls"); - } - - bool full_eval(goal_ref const & g, model & mdl) { - bool res = true; - - unsigned sz = g->size(); - for (unsigned i = 0; i < sz && res; i++) { - checkpoint(); - expr_ref o(m_manager); - - if (!mdl.eval(g->form(i), o, true)) - exit(ERR_INTERNAL_FATAL); - - res = m_manager.is_true(o.get()); - } - - TRACE("sls", tout << "Evaluation: " << res << std::endl;); - - return res; - } - - double top_score(goal_ref const & g) { - #if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl; ); - return min; - #else - double top_sum = 0.0; - unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - top_sum += m_tracker.get_score(e); - } - - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " AVG: " << top_sum / (double) sz << std::endl; ); - -#if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); -#endif - - return top_sum / (double) sz; - #endif - } - - double rescore(goal_ref const & g) { - m_evaluator.update_all(); - m_stats.m_full_evals++; - return top_score(g); - } - - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; - } -#endif - - // checks whether the score outcome of a given move is better than the previous score - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - #ifdef Z3DEBUG - mpz old_value; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - #endif - -#if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); -#else - double r = incremental_score(g, fd, temp); -#endif - #ifdef Z3DEBUG - TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << - " --> " << r << std::endl; ); - - m_mpz_manager.del(old_value); - #endif - -// if (r >= best_score) { - if (r > best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // same as what_if, but only applied to the score of a specific atom, not the total score - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.add(old_value, add_value, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - - } - - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - } - - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); - } - - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { - unsigned shift; - m_mpz_manager.add(old_value, m_one, incremented); - if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) - m_mpz_manager.set(incremented, m_zero); - } - - void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { - if (m_mpz_manager.is_zero(old_value)) { - m_mpz_manager.set(decremented, m_powers(bv_sz)); - m_mpz_manager.dec(decremented); - } - else - m_mpz_manager.sub(old_value, m_one, decremented); - } - - void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { - m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); - } - - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { - m_mpz_manager.set(flipped, m_zero); - - if (m_bv_util.is_bv_sort(s)) { - mpz mask; - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(old_value, mask, flipped); - m_mpz_manager.del(mask); - } - else if (m_manager.is_bool(s)) - m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); - else - NOT_IMPLEMENTED_YET(); - } - - void mk_random_move(ptr_vector & unsat_constants) - { - unsigned rnd_mv = 0; - - unsigned ucc = unsat_constants.size(); - unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; - func_decl * fd = unsat_constants[rc]; - - mpz new_value; - - sort * srt = fd->get_range(); - if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { -#if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; -#else - mt = MV_FLIP; -#endif - unsigned bit = 0; - - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } - - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } - - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } - - void mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); - } - - // will use VNS to ignore some possible moves and increase the flips per second - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif - unsigned bv_sz; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { -#else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { -#endif - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } -#endif - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - return new_score; - } - - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - - m_old_values.reset(); - - return 0; - } - - // what_if version needed in the context of 2nd intensification try, combining local and global score - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // find_best_move version needed in the context of 2nd intensification try - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; - } - - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; - } - - // main search loop - lbool search(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - unsigned plateau_cnt = 0; - - score = rescore(g); - unsigned sz = g->size(); -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - checkpoint(); - m_stats.m_moves++; - -#if _REAL_RS_ || _REAL_PBFS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } - continue; -#endif - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - old_score = score; - new_const = (unsigned)-1; - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - - if (new_const == static_cast(-1)) { - score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); - else -#endif -#if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); -#else - m_evaluator.randomize_local(to_evaluate); -#endif -#endif - -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } else { - func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - // main search loop - lbool search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0 ; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl; ); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - } - - if (score >= 0.99999) { -// if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } - while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - void operator()(goal_ref const & g, model_converter_ref & mc) { - if (g->inconsistent()) { - mc = 0; - return; - } - - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout); ); - } - g->reset(); - } - else - mc = 0; - } - }; - +class sls_tactic : public tactic { ast_manager & m; params_ref m_params; - imp * m_imp; - stats m_stats; + sls_engine * m_engine; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_imp = alloc(imp, m, p, m_stats); + m_engine = alloc(sls_engine, m, p); } virtual tactic * translate(ast_manager & m) { @@ -1381,16 +48,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_imp); + dealloc(m_engine); } virtual void updt_params(params_ref const & p) { m_params = p; - m_imp->updt_params(p); + m_engine->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - imp::collect_param_descrs(r); + sls_params::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -1398,14 +65,13 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); - m_imp->m_produce_models = g->models_enabled(); + SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_imp->operator()(g, mc); + m_engine->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -1414,40 +80,41 @@ public: } virtual void cleanup() { - imp * d = m_imp; + sls_engine * d = m_engine; #pragma omp critical (tactic_cancel) { - d = m_imp; + d = m_engine; } dealloc(d); - d = alloc(imp, m, m_params, m_stats); + d = alloc(sls_engine, m, m_params); #pragma omp critical (tactic_cancel) { - m_imp = d; + m_engine = d; } } virtual void collect_statistics(statistics & st) const { - double seconds = m_stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", m_stats.m_restarts); - st.update("sls full evals", m_stats.m_full_evals); - st.update("sls incr evals", m_stats.m_incr_evals); - st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); - st.update("sls FLIP moves", m_stats.m_flips); - st.update("sls INC moves", m_stats.m_incs); - st.update("sls DEC moves", m_stats.m_decs); - st.update("sls INV moves", m_stats.m_invs); - st.update("sls moves", m_stats.m_moves); - st.update("sls moves/sec", m_stats.m_moves / seconds); + sls_engine::stats const & stats = m_engine->get_stats(); + double seconds = stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", stats.m_restarts); + st.update("sls full evals", stats.m_full_evals); + st.update("sls incr evals", stats.m_incr_evals); + st.update("sls incr evals/sec", stats.m_incr_evals / seconds); + st.update("sls FLIP moves", stats.m_flips); + st.update("sls INC moves", stats.m_incs); + st.update("sls DEC moves", stats.m_decs); + st.update("sls INV moves", stats.m_invs); + st.update("sls moves", stats.m_moves); + st.update("sls moves/sec", stats.m_moves / seconds); } virtual void reset_statistics() { - m_stats.reset(); + m_engine->reset_statistics(); } virtual void set_cancel(bool f) { - if (m_imp) - m_imp->set_cancel(f); + if (m_engine) + m_engine->set_cancel(f); } }; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 0aca1f59c..3675265ee 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,12 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include"goal.h" +#include"model.h" + +#include"sls_compilation_settings.h" +#include"sls_powers.h" + class sls_tracker { ast_manager & m_manager; unsynch_mpz_manager & m_mpz_manager; @@ -1186,7 +1192,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif @@ -1334,7 +1340,7 @@ public: // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #endif From 13307a1d51c1c21e421b6a1e28fc8b5476f7b53e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Mar 2014 17:26:05 +0000 Subject: [PATCH 185/507] SLS refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index aea4787b0..8e52596e0 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -18,6 +18,10 @@ Notes: This file should go away completely once we have evaluated all options. --*/ + +#ifndef _SLS_COMPILATION_SETTINGS_H_ +#define _SLS_COMPILATION_SETTINGS_H_ + // which unsatisfied assertion is selected? only works with _FOCUS_ > 0 // 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score #define _BFS_ 0 @@ -155,4 +159,6 @@ InvalidConfiguration; #endif #if (_PERC_STICKY_ && !_FOCUS_) InvalidConfiguration; +#endif + #endif \ No newline at end of file From ad8cac7d886d1dc6e9255990fc192c83662c2277 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Thu, 20 Mar 2014 15:58:53 +0000 Subject: [PATCH 186/507] uct forget and minisat restarts added --- src/tactic/sls/sls_tactic.cpp | 1417 ++++++++++++++++++++++++++++++++- src/tactic/sls/sls_tracker.h | 22 +- 2 files changed, 1402 insertions(+), 37 deletions(-) diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 0f157d3a6..b2b7035e0 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,31 +16,1378 @@ Author: Notes: --*/ +#include +#include"map.h" #include"nnf.h" +#include"cooperate.h" +#include"ast_smt2_pp.h" +#include"ast_pp.h" +#include"var_subst.h" +#include"model_pp.h" +#include"model_evaluator.h" #include"solve_eqs_tactic.h" +#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"propagate_values_tactic.h" -#include"ctx_simplify_tactic.h" -#include"elim_uncnstr_tactic.h" -#include"nnf_tactic.h" #include"stopwatch.h" - +#include"propagate_values_tactic.h" #include"sls_tactic.h" -#include"sls_params.hpp" -#include"sls_engine.h" +#include"nnf_tactic.h" +#include"luby.h" +#include "ctx_simplify_tactic.h" -class sls_tactic : public tactic { +// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 +// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score +#define _BFS_ 0 + +// how many terms are considered for variable selection? +// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom +#define _FOCUS_ 1 + +// probability of choosing the same assertion again in the next step +#define _PERC_STICKY_ 0 + +// do we use dirty unit propagation to get rid of nested top level assertions? +#define _DIRTY_UP_ 1 + +// do we use restarts? +// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time +#define _RESTARTS_ 3 +// limit of moves/plateaus/seconds until first restart occurs +#define _RESTART_LIMIT_ 10 +// 0 = initialize with all zero, 1 initialize with random value +#define _RESTART_INIT_ 0 +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat +#define _RESTART_SCHEME_ 1 +// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 +#define _RESTART_CONST_ARMIN_ 4.0 + +// timelimit +#define _TIMELIMIT_ 3600 + +// should score of conjunctions be calculated by average rather than max? +#define _SCORE_AND_AVG_ 0 + +// should score of discunctions be calculated by multiplication of the inverse score rather than min? +#define _SCORE_OR_MUL_ 0 + +// do we use some kind of variable neighbourhood-search? +// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained +#define _VNS_ 0 + +// do we reduce the score of unsatisfied literals? +// 0 = no +// 1 = yes, by multiplying it with some factor +// 2 = yes, by squaring it +// 3 = yes, by setting it to zero +// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) +#define _WEIGHT_DIST_ 1 + +// the factor used for _WEIGHT_DIST_ = 1 +#define _WEIGHT_DIST_FACTOR_ 0.5 + +// shall we toggle the weight after each restart? +#define _WEIGHT_TOGGLE_ 0 + +// do we use intensification steps in local minima? if so, how many? +#define _INTENSIFICATION_ 0 +#define _INTENSIFICATION_TRIES_ 0 + +// what is the percentage of random moves in plateaus (instead of full randomization)? +#define _PERC_PLATEAU_MOVES_ 0 + +// shall we repick clause when randomizing in a plateau or use the current one? +#define _REPICK_ 1 + +// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ +#define _UCT_ 1 + +// how much diversification is used in the UCT-scheme? +#define _UCT_CONSTANT_ 20.0 + +// is uct clause selection probabilistic similar to variable selection in sparrow? +// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score +#define _PROBABILISTIC_UCT_ 0 + +// additive constants for probabilistic uct > 0 +#define _UCT_EPS_ 0.0001 + +// shall we reset _UCT_ touched values after restart? +#define _UCT_RESET_ 0 + +// do we gradually reduce the touched values of _UCT_? +#define _UCT_FORGET_ 0 +#define _UCT_FORGET_FACTOR_ 0.5 + +// how shall we initialize the _UCT_ total touched counter? +// 0 = initialize with one, 1 = initialize with number of assertions +#define _UCT_INIT_ 0 + +// shall we use addition/subtraction? +#define _USE_ADDSUB_ 1 + +// shall we try multilication and division by 2? +#define _USE_MUL2DIV2_ 0 + +// shall we try multiplication by 3? +#define _USE_MUL3_ 0 + +// shall we try unary minus (= inverting and incrementing) +#define _USE_UNARY_MINUS_ 0 + +// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 +#define _UNIFORM_RANDOM_ 0 + +// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +#define _REAL_RS_ 0 +#define _REAL_PBFS_ 0 + +// how many bits do we neglect in each iteration? +#define _SKIP_BITS_ 0 + +// when randomizing local, what is the probability for changing a single bit? +// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage +#define _PERC_CHANGE_ 0 + +// do we use random steps for noise? +// 0 = no, 1 = randomize local, 2 = make random move +#define _TYPE_RSTEP_ 0 + +// with what probability _PERM_STEP_/1000 will the random step happen? +#define _PERM_RSTEP_ 0 + +// shall we use early pruning for incremental update? +#define _EARLY_PRUNE_ 1 + +// shall we use caching for top_score? +#define _CACHE_TOP_SCORE_ 1 + + +#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) + InvalidConfiguration; +#endif +#if (_PROBABILISTIC_UCT_ && !_UCT_) + InvalidConfiguration; +#endif +#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) + InvalidConfiguration; +#endif +#if (_PERC_CHANGE_ == 50) + InvalidConfiguration; +#endif +#if (_PERC_STICKY_ && !_FOCUS_) + InvalidConfiguration; +#endif + +#include"sls_params.hpp" +#include"sls_evaluator.h" +#include"sls_tracker.h" + +class sls_tactic : public tactic { + class stats { + public: + unsigned m_restarts; + stopwatch m_stopwatch; + unsigned m_full_evals; + unsigned m_incr_evals; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + + stats() : + m_restarts(0), + m_full_evals(0), + m_incr_evals(0), + m_moves(0), + m_umins(0), + m_mul2s(0), + m_mul3s(0), + m_div2s(0), + m_flips(0), + m_incs(0), + m_decs(0), + m_invs(0) { + m_stopwatch.reset(); + m_stopwatch.start(); + } + void reset() { + m_full_evals = m_flips = m_incr_evals = 0; + m_stopwatch.reset(); + m_stopwatch.start(); + } + }; + + struct imp { + ast_manager & m_manager; + stats & m_stats; + unsynch_mpz_manager m_mpz_manager; + powers m_powers; + mpz m_zero, m_one, m_two; + bool m_produce_models; + volatile bool m_cancel; + bv_util m_bv_util; + sls_tracker m_tracker; + sls_evaluator m_evaluator; + + unsigned m_restart_limit; + unsigned m_max_restarts; + unsigned m_plateau_limit; + + ptr_vector m_old_values; + + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; + + imp(ast_manager & m, params_ref const & p, stats & s) : + m_manager(m), + m_stats(s), + m_powers(m_mpz_manager), + m_zero(m_mpz_manager.mk_z(0)), + m_one(m_mpz_manager.mk_z(1)), + m_two(m_mpz_manager.mk_z(2)), + m_cancel(false), + m_bv_util(m), + m_tracker(m, m_bv_util, m_mpz_manager, m_powers), + m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) + { + updt_params(p); + } + + ~imp() { + m_mpz_manager.del(m_zero); + m_mpz_manager.del(m_one); + m_mpz_manager.del(m_two); + } + + double get_restart_armin(unsigned cnt_restarts) + { + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + //printf("armin: %f\n", pow(1.1, inner_id + 1)); + return pow(_RESTART_CONST_ARMIN_, inner_id + 1); + } + + inline unsigned check_restart(unsigned curr_value) + { + if (curr_value > m_restart_limit) + { +#if _RESTART_SCHEME_ == 5 + m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); +#elif _RESTART_SCHEME_ == 4 + m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); +#elif _RESTART_SCHEME_ == 3 + m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 2 + m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; +#elif _RESTART_SCHEME_ == 1 + if (m_stats.m_restarts & 1) + m_restart_limit += _RESTART_LIMIT_; + else + m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; +#else + m_restart_limit += _RESTART_LIMIT_; +#endif +#if _WEIGHT_TOGGLE_ + printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); +#endif + return 0; + } + return 1; + } + + ast_manager & m() const { return m_manager; } + + void set_cancel(bool f) { m_cancel = f; } + void cancel() { set_cancel(true); } + void reset_cancel() { set_cancel(false); } + + static void collect_param_descrs(param_descrs & r) { + sls_params::collect_param_descrs(r); + } + + void updt_params(params_ref const & _p) { + sls_params p(_p); + m_produce_models = _p.get_bool("model", false); + m_max_restarts = p.restarts(); + m_tracker.set_random_seed(p.random_seed()); + m_plateau_limit = p.plateau_limit(); + } + + void checkpoint() { + if (m_cancel) + throw tactic_exception(TACTIC_CANCELED_MSG); + cooperate("sls"); + } + + bool full_eval(goal_ref const & g, model & mdl) { + bool res = true; + + unsigned sz = g->size(); + for (unsigned i = 0; i < sz && res; i++) { + checkpoint(); + expr_ref o(m_manager); + + if (!mdl.eval(g->form(i), o, true)) + exit(ERR_INTERNAL_FATAL); + + res = m_manager.is_true(o.get()); + } + + TRACE("sls", tout << "Evaluation: " << res << std::endl;); + + return res; + } + + double top_score(goal_ref const & g) { + #if 0 + double min = m_tracker.get_score(g->form(0)); + unsigned sz = g->size(); + for (unsigned i = 1; i < sz; i++) { + double q = m_tracker.get_score(g->form(i)); + if (q < min) min = q; + } + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " MIN: " << min << std::endl; ); + return min; + #else + double top_sum = 0.0; + unsigned sz = g->size(); + for (unsigned i = 0; i < sz; i++) { + expr * e = g->form(i); + top_sum += m_tracker.get_score(e); + } + + TRACE("sls_top", tout << "Score distribution:"; + for (unsigned i = 0; i < sz; i++) + tout << " " << m_tracker.get_score(g->form(i)); + tout << " AVG: " << top_sum / (double) sz << std::endl; ); + +#if _CACHE_TOP_SCORE_ + m_tracker.set_top_sum(top_sum); +#endif + + return top_sum / (double) sz; + #endif + } + + double rescore(goal_ref const & g) { + m_evaluator.update_all(); + m_stats.m_full_evals++; + return top_score(g); + } + + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.serious_update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_evaluator.update(fd, new_value); + m_stats.m_incr_evals++; +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + } + +#if _EARLY_PRUNE_ + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune(fd, new_value)) +#if _CACHE_TOP_SCORE_ + return (m_tracker.get_top_sum() / g->size()); +#else + return top_score(g); +#endif + else + return 0.0; + } +#endif + + // checks whether the score outcome of a given move is better than the previous score + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + + #ifdef Z3DEBUG + mpz old_value; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + #endif + +#if _EARLY_PRUNE_ + double r = incremental_score_prune(g, fd, temp); +#else + double r = incremental_score(g, fd, temp); +#endif + #ifdef Z3DEBUG + TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << + " --> " << r << std::endl; ); + + m_mpz_manager.del(old_value); + #endif + +// if (r >= best_score) { + if (r > best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // same as what_if, but only applied to the score of a specific atom, not the total score + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + m_evaluator.update(fd, temp); + double r = m_tracker.get_score(e); + if (r >= best_score) { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.add(old_value, add_value, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + + } + + // Andreas: do we really need all those temporary mpzs? + void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { + mpz temp, mask, mask2; + m_mpz_manager.mul(old_value, m_two, temp); + m_mpz_manager.set(mask, m_powers(bv_sz)); + m_mpz_manager.bitwise_not(bv_sz, mask, mask2); + m_mpz_manager.bitwise_and(temp, mask2, result); + m_mpz_manager.del(temp); + m_mpz_manager.del(mask); + m_mpz_manager.del(mask2); + } + + void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { + m_mpz_manager.div(old_value, m_two, result); + } + + void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { + unsigned shift; + m_mpz_manager.add(old_value, m_one, incremented); + if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) + m_mpz_manager.set(incremented, m_zero); + } + + void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { + if (m_mpz_manager.is_zero(old_value)) { + m_mpz_manager.set(decremented, m_powers(bv_sz)); + m_mpz_manager.dec(decremented); + } + else + m_mpz_manager.sub(old_value, m_one, decremented); + } + + void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { + m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); + } + + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { + m_mpz_manager.set(flipped, m_zero); + + if (m_bv_util.is_bv_sort(s)) { + mpz mask; + m_mpz_manager.set(mask, m_powers(bit)); + m_mpz_manager.bitwise_xor(old_value, mask, flipped); + m_mpz_manager.del(mask); + } + else if (m_manager.is_bool(s)) + m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); + else + NOT_IMPLEMENTED_YET(); + } + + void mk_random_move(ptr_vector & unsat_constants) + { + unsigned rnd_mv = 0; + unsigned ucc = unsat_constants.size(); + unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; + func_decl * fd = unsat_constants[rc]; + + mpz new_value; + + sort * srt = fd->get_range(); + if (m_manager.is_bool(srt)) + m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); + else + { +#if _USE_ADDSUB_ + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; + if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + move_type mt = (move_type) rnd_mv; + + // inversion doesn't make sense, let's do a flip instead. + if (mt == MV_INV) mt = MV_FLIP; +#else + mt = MV_FLIP; +#endif + unsigned bit = 0; + + switch (mt) + { + case MV_FLIP: { + unsigned bv_sz = m_bv_util.get_bv_size(srt); + bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; + mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); + break; + } + case MV_INC: + mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_DEC: + mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + case MV_INV: + mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); + break; + default: + NOT_IMPLEMENTED_YET(); + } + + TRACE("sls", tout << "Randomization candidates: "; + for (unsigned i = 0; i < unsat_constants.size(); i++) + tout << unsat_constants[i]->get_name() << ", "; + tout << std::endl; + tout << "Random move: "; + switch (mt) { + case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; + case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; + case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; + case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; + } + tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); + } + + m_evaluator.update(fd, new_value); + m_mpz_manager.del(new_value); + } + + void mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); + } + + // will use VNS to ignore some possible moves and increase the flips per second + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + // we can either check the condition once in the beginning or check it repeatedly after every bit +#if _VNS_ == 1 + for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) +#else + if (new_score <= score) + for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) +#endif + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; +#if _USE_MUL3_ || _USE_UNARY_MINUS_ + mpz temp2; +#endif + unsigned bv_sz; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit +#if _SKIP_BITS_ + for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { +#else + for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +#endif + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { +#if _USE_ADDSUB_ + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } +#endif + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + +#if _USE_UNARY_MINUS_ + mk_inc(bv_sz, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_UMIN; +#endif + +#if _USE_MUL2DIV2_ + // try multiplication by 2 + mk_mul2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_MUL2; + +#if _USE_MUL3_ + // try multiplication by 3 + mk_add(bv_sz, old_value, temp, temp2); + if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) + move = MV_MUL3; +#endif + + // try division by 2 + mk_div2(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DIV2; +#endif + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + // Andreas: does not hold anymore now that we use top level score caching + //SASSERT(check == score); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); +#if _USE_MUL3_ + m_mpz_manager.del(temp2); +#endif + return new_score; + } + + // same as find_best_move but only considers the score of the current expression instead of the overall score + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz; + double new_score = m_tracker.get_score(e); + // Andreas: tie breaking not implemented yet + // double tie_score = top_score(g); + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // first try to flip every bit + for (unsigned j = 0; j < bv_sz; j++) { + // What would happen if we flipped bit #i ? + mk_flip(srt, old_value, j, temp); + + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + } + + // reset to what it was before + m_evaluator.update(fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; + } + + // first try of intensification ... does not seem to be efficient + bool handle_plateau(goal_ref const & g) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned pos = m_stats.m_moves % sz; +#else + unsigned pos = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + for (unsigned i = 0; i < to_evaluate.size(); i++) + { + m_tracker.get_value(to_evaluate[i]); + m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); + } + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) + { + // Andreas: Could be extended to use (best) score but this is computationally more expensive. + find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); + + if (new_const == static_cast(-1)) { + // Andreas: Actually this should never happen. + NOT_IMPLEMENTED_YET(); + } else { + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + + m_evaluator.update(fd, new_value); + } + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + for (unsigned i = 0; i < to_evaluate.size(); i++) + m_tracker.set_value(to_evaluate[i], * m_old_values[i]); + + m_old_values.reset(); + + return 0; + } + + // what_if version needed in the context of 2nd intensification try, combining local and global score + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); + double local_score = m_tracker.get_score(e); + double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; + + if (new_score >= best_score) { + best_score = new_score; + m_mpz_manager.set(best_value, temp); + return true; + } + + return false; + } + + // find_best_move version needed in the context of 2nd intensification try + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) + { + mpz old_value, temp; + double best_score = 0; + + sort * srt = fd->get_range(); + unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { + mk_flip(srt, old_value, j, temp); + what_if(g, e, fd, temp, best_score, best_value, i); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + + return best_score; + } + + // second try to use intensification ... also not very effective + bool handle_plateau(goal_ref const & g, double old_score) + { + unsigned sz = g->size(); +#if _BFS_ + unsigned new_const = m_stats.m_moves % sz; +#else + unsigned new_const = m_tracker.get_random_uint(16) % sz; +#endif + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + if (!e) + return 0; + + expr * q = m_tracker.get_unsat_expression(e); + ptr_vector & to_evaluate = m_tracker.get_constants(q); + + new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); + func_decl * fd = to_evaluate[new_const]; + + mpz new_value; + //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); + unsigned new_bit = 0; + double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; + + for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) + { + new_score = find_best_move_local(g, q, fd, new_value, i); + + m_stats.m_moves++; + m_stats.m_flips++; + + global_score = incremental_score(g, fd, new_value); + local_score = m_tracker.get_score(q); + + SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); + + if (m_mpz_manager.is_one(m_tracker.get_value(q))) + return 1; + } + + return 0; + } + + // main search loop + lbool search(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + unsigned plateau_cnt = 0; + + score = rescore(g); + unsigned sz = g->size(); +#if _PERC_STICKY_ + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + +#if _RESTARTS_ == 1 + while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 2 + while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#elif _RESTARTS_ == 3 + while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#endif + checkpoint(); + m_stats.m_moves++; + +#if _UCT_FORGET_ + if (m_stats.m_moves % _UCT_FORGET_ == 0) + m_tracker.uct_forget(g); +#endif + +#if _REAL_RS_ || _REAL_PBFS_ + //m_tracker.debug_real(g, m_stats.m_moves); +#endif + +#if _FOCUS_ +#if _PERC_STICKY_ + if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) + e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#else + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); +#endif + if (!e) + { + res = l_true; + goto bailout; + } + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else + ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(to_evaluate); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(to_evaluate); +#endif +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } + continue; +#endif + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + old_score = score; + new_const = (unsigned)-1; + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + + if (new_const == static_cast(-1)) { + score = old_score; + plateau_cnt++; +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); + //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + //to_evaluate = m_tracker.get_unsat_constants_walksat(e); +#else +#if _PERC_PLATEAU_MOVES_ + if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) + mk_random_move(to_evaluate); + else +#endif +#if _REPICK_ + m_evaluator.randomize_local(g, m_stats.m_moves); +#else + m_evaluator.randomize_local(to_evaluate); +#endif +#endif + +#if _CACHE_TOP_SCORE_ + score = m_tracker.get_top_sum() / g->size(); +#else + score = top_score(g); +#endif + } else { + func_decl * fd = to_evaluate[new_const]; +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + // main search loop + lbool search_old(goal_ref const & g) { + lbool res = l_undef; + double score = 0.0, old_score = 0.0; + unsigned new_const = (unsigned)-1, new_bit = 0; + mpz new_value; + move_type move; + + score = rescore(g); + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl; ); + + unsigned plateau_cnt = 0; + + // Andreas: Why do we only allow so few plateaus? +#if _RESTARTS_ + while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { + //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { +#else + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { +#endif + do { + checkpoint(); + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif + +#if _TYPE_RSTEP_ + if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + { +#if _TYPE_RSTEP_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _TYPE_RSTEP_ == 2 + mk_random_move(g); +#endif + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } +#endif + old_score = score; + new_const = (unsigned)-1; + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + if (!to_evaluate.size()) + { + res = l_true; + goto bailout; + } + TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; + for (unsigned i = 0 ; i < to_evaluate.size(); i++) + tout << to_evaluate[i]->get_name() << std::endl; ); + +#if _VNS_ + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); +#else + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); +#endif + if (new_const == static_cast(-1)) { + TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + }); + + TRACE("sls_max", m_tracker.show_model(tout); + tout << "Scores: " << std::endl; + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl; ); + // Andreas: If new_const == -1, shouldn't score = old_score anyway? + score = old_score; + } + else { + // Andreas: Why does randomizing not count as a move? (Now it does.) + m_stats.m_moves++; + func_decl * fd = to_evaluate[new_const]; + + TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; + switch (move) { + case MV_FLIP: + tout << "Flip"; + if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; + break; + case MV_INC: + tout << "+1"; + break; + case MV_DEC: + tout << "-1"; + break; + case MV_INV: + tout << "NEG"; + break; + }; + tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); + + switch (move) { + case MV_FLIP: m_stats.m_flips++; break; + case MV_INC: m_stats.m_incs++; break; + case MV_DEC: m_stats.m_decs++; break; + case MV_INV: m_stats.m_invs++; break; + case MV_UMIN: m_stats.m_umins++; break; + case MV_MUL2: m_stats.m_mul2s++; break; + case MV_MUL3: m_stats.m_mul3s++; break; + case MV_DIV2: m_stats.m_div2s++; break; + } + +#if _REAL_RS_ || _REAL_PBFS_ + score = serious_score(g, fd, new_value); +#else + score = incremental_score(g, fd, new_value); +#endif + + TRACE("sls", tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl; ); + } + + if (score >= 0.99999) { +// if (score >= 1.0) { + // score could theoretically be imprecise. + // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + /* + if (m_stats.m_moves % 100 == 0) + { + verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; + verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + }*/ + } + while (score > old_score && res == l_undef); + + // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. + if (score != old_score) { + report_tactic_progress("This should not happen I guess.", plateau_cnt); + plateau_cnt = 0; + } else { + m_stats.m_moves++; + plateau_cnt++; + //report_tactic_progress("Plateau.", plateau_cnt); + // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. + //if (plateau_cnt < m_plateau_limit) { + TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); +#if _INTENSIFICATION_ + handle_plateau(g, score); + //handle_plateau(g); +#else + m_evaluator.randomize_local(g, m_stats.m_moves); +#endif + //mk_random_move(g); + score = top_score(g); + + if (score >= 1.0) { + bool all_true = true; + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + all_true=false; + if (all_true) { + res = l_true; // sat + goto bailout; + } else + TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); + } + } + } + + bailout: + m_mpz_manager.del(new_value); + + return res; + } + + void operator()(goal_ref const & g, model_converter_ref & mc) { + if (g->inconsistent()) { + mc = 0; + return; + } + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; + verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; + verbose_stream() << "_DIRTY_UP_ " << _DIRTY_UP_ << std::endl; + verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; + verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; + verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; + verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; + verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; + verbose_stream() << "_RESTART_CONST_ARMIN_ " << std::fixed << std::setprecision(2) << _RESTART_CONST_ARMIN_ << std::endl; + verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; + verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; + verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; + verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; + verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; + verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; + verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; + verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; + verbose_stream() << "_UCT_ " << _UCT_ << std::endl; + verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; + verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; + verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; + verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; + verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; + verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; + verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; + verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; + verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; + verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; + verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; + verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; + verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; + verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; + verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; + verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; + verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } + while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout); ); + } + g->reset(); + } + else + mc = 0; + } + }; + ast_manager & m; params_ref m_params; - sls_engine * m_engine; + imp * m_imp; + stats m_stats; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_engine = alloc(sls_engine, m, p); + m_imp = alloc(imp, m, p, m_stats); } virtual tactic * translate(ast_manager & m) { @@ -48,16 +1395,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_engine); + dealloc(m_imp); } virtual void updt_params(params_ref const & p) { m_params = p; - m_engine->updt_params(p); + m_imp->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); + imp::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -65,13 +1412,14 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); + SASSERT(g->is_well_sorted()); + m_imp->m_produce_models = g->models_enabled(); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_engine->operator()(g, mc); + m_imp->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -80,41 +1428,40 @@ public: } virtual void cleanup() { - sls_engine * d = m_engine; + imp * d = m_imp; #pragma omp critical (tactic_cancel) { - d = m_engine; + d = m_imp; } dealloc(d); - d = alloc(sls_engine, m, m_params); + d = alloc(imp, m, m_params, m_stats); #pragma omp critical (tactic_cancel) { - m_engine = d; + m_imp = d; } } virtual void collect_statistics(statistics & st) const { - sls_engine::stats const & stats = m_engine->get_stats(); - double seconds = stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", stats.m_restarts); - st.update("sls full evals", stats.m_full_evals); - st.update("sls incr evals", stats.m_incr_evals); - st.update("sls incr evals/sec", stats.m_incr_evals / seconds); - st.update("sls FLIP moves", stats.m_flips); - st.update("sls INC moves", stats.m_incs); - st.update("sls DEC moves", stats.m_decs); - st.update("sls INV moves", stats.m_invs); - st.update("sls moves", stats.m_moves); - st.update("sls moves/sec", stats.m_moves / seconds); + double seconds = m_stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", m_stats.m_restarts); + st.update("sls full evals", m_stats.m_full_evals); + st.update("sls incr evals", m_stats.m_incr_evals); + st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); + st.update("sls FLIP moves", m_stats.m_flips); + st.update("sls INC moves", m_stats.m_incs); + st.update("sls DEC moves", m_stats.m_decs); + st.update("sls INV moves", m_stats.m_invs); + st.update("sls moves", m_stats.m_moves); + st.update("sls moves/sec", m_stats.m_moves / seconds); } virtual void reset_statistics() { - m_engine->reset_statistics(); + m_stats.reset(); } virtual void set_cancel(bool f) { - if (m_engine) - m_engine->set_cancel(f); + if (m_imp) + m_imp->set_cancel(f); } }; @@ -163,7 +1510,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? //mk_ctx_simplify_tactic(m, ctx_p), // Andreas: This one at least eliminates top level duplicates ... - mk_simplify_tactic(m), + //mk_simplify_tactic(m), // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 3675265ee..1c33d42a7 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -276,6 +276,20 @@ public: } #endif + void uct_forget(goal_ref const & g) { + expr * e; + unsigned touched_old, touched_new; + + for (unsigned i = 0; i < g->size(); i++) + { + e = g->form(i); + touched_old = m_scores.find(e).touched; + touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); + m_scores.find(e).touched = touched_new; + m_touched += touched_new - touched_old; + } + } + void initialize(app * n) { // Build score table if (!m_scores.contains(n)) { @@ -1195,6 +1209,8 @@ public: double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#elif _UCT_ == 3 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } @@ -1202,7 +1218,7 @@ public: if (pos == static_cast(-1)) return m_temp_constants; -#if _UCT_ == 1 +#if _UCT_ == 1 || _UCT_ == 3 m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 @@ -1343,6 +1359,8 @@ public: double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; +#elif _UCT_ == 3 + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } @@ -1350,7 +1368,7 @@ public: if (pos == static_cast(-1)) return 0; -#if _UCT_ == 1 +#if _UCT_ == 1 || _UCT_ == 3 m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 From 1f326d9e72157ec15d617ac804533809f8803573 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 26 Mar 2014 17:26:06 +0000 Subject: [PATCH 187/507] removed dependency of bvsls on goal_refs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 219 +++++++++++++++++++-------------- src/tactic/sls/sls_engine.h | 58 ++++----- src/tactic/sls/sls_evaluator.h | 4 +- src/tactic/sls/sls_tracker.h | 84 ++++++------- 4 files changed, 195 insertions(+), 170 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 92471aad8..9fa2cc263 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -74,15 +74,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(goal_ref const & g, model & mdl) { +bool sls_engine::full_eval(model & mdl) { bool res = true; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(g->form(i), o, true)) + if (!mdl.eval(m_assertions[i], o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,7 +93,7 @@ bool sls_engine::full_eval(goal_ref const & g, model & mdl) { return res; } -double sls_engine::top_score(goal_ref const & g) { +double sls_engine::top_score() { #if 0 double min = m_tracker.get_score(g->form(0)); unsigned sz = g->size(); @@ -108,15 +108,15 @@ double sls_engine::top_score(goal_ref const & g) { return min; #else double top_sum = 0.0; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = m_assertions[i]; top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); + tout << " " << m_tracker.get_score(m_assertions[i]); tout << " AVG: " << top_sum / (double)sz << std::endl;); #if _CACHE_TOP_SCORE_ @@ -127,40 +127,40 @@ double sls_engine::top_score(goal_ref const & g) { #endif } -double sls_engine::rescore(goal_ref const & g) { +double sls_engine::rescore() { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(g); + return top_score(); } -double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif } -double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif } -double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { #if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); #else - return top_score(g); + return top_score(); #endif else return 0.0; @@ -170,8 +170,13 @@ double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, c } // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if( + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -179,9 +184,9 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); + double r = incremental_score_prune(fd, temp); #else - double r = incremental_score(g, fd, temp); + double r = incremental_score(fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -202,8 +207,15 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd } // same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if_local( + expr * e, + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) +{ m_evaluator.update(fd, temp); double r = m_tracker.get_score(e); if (r >= best_score) { @@ -344,13 +356,19 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); +void sls_engine::mk_random_move() { + mk_random_move(m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves)); } // will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move_vns( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; unsigned bv_sz, max_bv_sz = 0; double new_score = score; @@ -366,31 +384,31 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; // try to flip lsb mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = 0; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); SASSERT(check == score); } @@ -412,13 +430,13 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector { mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); SASSERT(check == score); } m_mpz_manager.del(old_value); @@ -427,8 +445,14 @@ double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector } // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ mpz temp2; @@ -451,7 +475,7 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } @@ -462,19 +486,19 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; #if _USE_UNARY_MINUS_ @@ -504,7 +528,7 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -572,15 +596,15 @@ double sls_engine::find_best_move_local(expr * e, ptr_vector & to_eva } // first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau(goal_ref const & g) +bool sls_engine::handle_plateau() { - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); #if _BFS_ unsigned pos = m_stats.m_moves % sz; #else unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); + expr * e = m_tracker.get_unsat_assertion(sz, pos); if (!e) return 0; @@ -634,10 +658,15 @@ bool sls_engine::handle_plateau(goal_ref const & g) } // what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); +bool sls_engine::what_if( + expr * e, + func_decl * fd, + const mpz & temp, + double & best_score, + mpz & best_value, + unsigned i) +{ + double global_score = incremental_score(fd, temp); double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; @@ -651,7 +680,7 @@ bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz } // find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) +double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i) { mpz old_value, temp; double best_score = 0; @@ -662,7 +691,7 @@ double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); + what_if(e, fd, temp, best_score, best_value, i); } m_mpz_manager.del(old_value); @@ -672,15 +701,15 @@ double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl } // second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(goal_ref const & g, double old_score) +bool sls_engine::handle_plateau(double old_score) { - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); #if _BFS_ unsigned new_const = m_stats.m_moves % sz; #else unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); + expr * e = m_tracker.get_unsat_assertion(m_assertions, sz, new_const); if (!e) return 0; @@ -697,12 +726,12 @@ bool sls_engine::handle_plateau(goal_ref const & g, double old_score) for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) { - new_score = find_best_move_local(g, q, fd, new_value, i); + new_score = find_best_move_local(q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(g, fd, new_value); + global_score = incremental_score(fd, new_value); local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -715,7 +744,7 @@ bool sls_engine::handle_plateau(goal_ref const & g, double old_score) } // main search loop -lbool sls_engine::search(goal_ref const & g) { +lbool sls_engine::search() { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -723,8 +752,8 @@ lbool sls_engine::search(goal_ref const & g) { move_type move; unsigned plateau_cnt = 0; - score = rescore(g); - unsigned sz = g->size(); + score = rescore(); + unsigned sz = m_assertions.size(); #if _PERC_STICKY_ expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif @@ -750,7 +779,7 @@ lbool sls_engine::search(goal_ref const & g) { if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); + expr * e = m_tracker.get_unsat_assertion(m_assertions, m_stats.m_moves); #endif if (!e) { @@ -793,7 +822,7 @@ lbool sls_engine::search(goal_ref const & g) { #if _VNS_ score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { @@ -811,14 +840,14 @@ lbool sls_engine::search(goal_ref const & g) { else #endif #if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(m_assertions, m_stats.m_moves); #else m_evaluator.randomize_local(to_evaluate); #endif #endif #if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); + score = m_tracker.get_top_sum() / m_assertions.size(); #else score = top_score(g); #endif @@ -828,7 +857,7 @@ lbool sls_engine::search(goal_ref const & g) { #if _REAL_RS_ || _REAL_PBFS_ score = serious_score(g, fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(fd, new_value); #endif } } @@ -840,18 +869,18 @@ bailout: } // main search loop -lbool sls_engine::search_old(goal_ref const & g) { +lbool sls_engine::search_old() { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - score = rescore(g); + score = rescore(); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); tout << " TOP: " << score << std::endl;); unsigned plateau_cnt = 0; @@ -897,7 +926,7 @@ lbool sls_engine::search_old(goal_ref const & g) { old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves); if (!to_evaluate.size()) { res = l_true; @@ -908,22 +937,22 @@ lbool sls_engine::search_old(goal_ref const & g) { tout << to_evaluate[i]->get_name() << std::endl;); #if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move_vns(to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; + for (unsigned i = 0; i < m_assertions.size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + tout << mk_ismt2_pp(m_assertions[i], m_manager) << std::endl; }); TRACE("sls_max", m_tracker.show_model(tout); tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl;); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << mk_ismt2_pp(m_assertions[i], m_manager) << " ---> " << + m_tracker.get_score(m_assertions[i]) << std::endl;); // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } @@ -962,14 +991,14 @@ lbool sls_engine::search_old(goal_ref const & g) { } #if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); + score = serious_score(fd, new_value); #else - score = incremental_score(g, fd, new_value); + score = incremental_score(fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + for (unsigned i = 0; i < m_assertions.size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); tout << " TOP: " << score << std::endl;); } @@ -978,8 +1007,8 @@ lbool sls_engine::search_old(goal_ref const & g) { // score could theoretically be imprecise. // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + for (unsigned i = 0; i < m_assertions.size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) all_true = false; if (all_true) { res = l_true; // sat @@ -1010,17 +1039,17 @@ lbool sls_engine::search_old(goal_ref const & g) { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); #if _INTENSIFICATION_ handle_plateau(g, score); - //handle_plateau(g); + //handle_plateau(); #else - m_evaluator.randomize_local(g, m_stats.m_moves); + m_evaluator.randomize_local(m_assertions, m_stats.m_moves); #endif - //mk_random_move(g); - score = top_score(g); + //mk_random_move(); + score = top_score(); if (score >= 1.0) { bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + for (unsigned i = 0; i < m_assertions.size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) all_true = false; if (all_true) { res = l_true; // sat @@ -1046,6 +1075,10 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); + for (unsigned i = 0; i < g->size(); i++) + assert_expr(g->form(i)); + + verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; @@ -1089,7 +1122,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { #if _WEIGHT_TOGGLE_ m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); #endif - m_tracker.initialize(g); + m_tracker.initialize(m_assertions); lbool res = l_undef; m_restart_limit = _RESTART_LIMIT_; @@ -1098,14 +1131,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { checkpoint(); report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); + res = search(); if (res == l_undef) { #if _RESTART_INIT_ - m_tracker.randomize(g); + m_tracker.randomize(); #else - m_tracker.reset(g); + m_tracker.reset(m_assertions); #endif } } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 878354c6d..8458817b6 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -71,6 +71,7 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; + ptr_vector m_assertions; unsigned m_restart_limit; unsigned m_max_restarts; @@ -92,11 +93,12 @@ public: void updt_params(params_ref const & _p); + void assert_expr(expr * e) { m_assertions.push_back(e); } + stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(goal_ref const & g, model & mdl); - + bool full_eval(model & mdl); void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); @@ -104,54 +106,44 @@ public: void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - - - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); - - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); - - - lbool search(goal_ref const & g); + lbool search(void); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); - lbool search_old(goal_ref const & g); + lbool search_old(void); double get_restart_armin(unsigned cnt_restarts); - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - + bool what_if(expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - double top_score(goal_ref const & g); - double rescore(goal_ref const & g); - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double top_score(); + double rescore(); + double serious_score(func_decl * fd, const mpz & new_value); + double incremental_score(func_decl * fd, const mpz & new_value); #if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score_prune(func_decl * fd, const mpz & new_value); #endif - - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - + double find_best_move(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i); + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_vns(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(goal_ref const & g); + void mk_random_move(); - bool handle_plateau(goal_ref const & g); - bool handle_plateau(goal_ref const & g, double old_score); + bool handle_plateau(void); + bool handle_plateau(double old_score); inline unsigned check_restart(unsigned curr_value); }; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 9daf93c32..7638ba5f4 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -922,8 +922,8 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(goal_ref const & g, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(g, flip)); + void randomize_local(ptr_vector const & as, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(as, flip)); } }; diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 1c33d42a7..c49257692 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,7 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"goal.h" +#include"bv_decl_plugin.h" #include"model.h" #include"sls_compilation_settings.h" @@ -365,12 +365,12 @@ public: } }; - void calculate_expr_distances(goal_ref const & g) { + void calculate_expr_distances(ptr_vector const & as) { // precondition: m_scores is set up. - unsigned sz = g->size(); + unsigned sz = as.size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(g->form(i))); + stack.push_back(to_app(as[i])); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -418,12 +418,12 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(goal_ref const & g) { + void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = g->size(); + unsigned sz = as.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); else @@ -438,7 +438,7 @@ public: visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); @@ -450,7 +450,7 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(g); + calculate_expr_distances(as); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); @@ -465,11 +465,11 @@ public: #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(as[i]); #endif #if _UCT_ - m_touched = _UCT_INIT_ ? g->size() : 1; + m_touched = _UCT_INIT_ ? as.size() : 1; #endif } @@ -606,7 +606,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(goal_ref const & g) { + void randomize(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -620,13 +620,13 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; + m_touched = _UCT_INIT_ ? as.size() : 1; + for (unsigned i = 0; i < as.size(); i++) + m_scores.find(as[i]).touched = 1; #endif } - void reset(goal_ref const & g) { + void reset(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -636,9 +636,9 @@ public: } #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; + m_touched = _UCT_INIT_ ? as.size() : 1; + for (unsigned i = 0; i < as.size(); i++) + m_scores.find(as[i]).touched = 1; #endif } @@ -1029,13 +1029,13 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(ptr_vector const & as, unsigned sz) { if (sz == 1) return get_constants(); m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1049,22 +1049,22 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * get_unsat_assertion(ptr_vector const & as, unsigned sz, unsigned int pos) { for (unsigned i = pos; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.neq(get_value(q), m_one)) return q; } for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.neq(get_value(q), m_one)) return q; } return 0; } - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_walksat(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(as, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; @@ -1141,19 +1141,19 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); + ptr_vector & get_unsat_constants_crsat(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(as, sz, pos); if (!q) return m_temp_constants; return go_deeper(q); } - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); + ptr_vector & get_unsat_constants(ptr_vector const & as, unsigned int flip) { + unsigned sz = as.size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + if (m_mpz_manager.eq(get_value(as[0]), m_one)) return m_temp_constants; else return get_constants(); @@ -1201,7 +1201,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1219,12 +1219,12 @@ public: return m_temp_constants; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; + m_scores.find(as[pos]).touched++; m_touched++; #elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; + m_scores.find(as[pos]).touched = flip; #endif - expr * e = g->form(pos); + expr * e = as[pos]; // expr * e = m_list_false[pos]; #elif _BFS_ == 3 @@ -1303,11 +1303,11 @@ public: } - expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); + expr * get_unsat_assertion(ptr_vector const & as, unsigned int flip) { + unsigned sz = as.size(); if (sz == 1) - return g->form(0); + return as[0]; m_temp_constants.reset(); #if _FOCUS_ == 1 @@ -1351,7 +1351,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1369,13 +1369,13 @@ public: return 0; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; + m_scores.find(as[pos]).touched++; m_touched++; #elif _UCT_ == 2 m_scores.find(g->form(pos)).touched = flip; #endif // return m_list_false[pos]; - return g->form(pos); + return as[pos]; #elif _BFS_ == 3 unsigned int pos = -1; @@ -1429,7 +1429,7 @@ public: unsigned int pos = get_random_uint(16) % sz; return get_unsat_assertion(g, sz, pos); #endif - return g->form(pos); + return as[pos]; #elif _FOCUS_ == 2 #if _BFS_ unsigned int pos = flip % sz; From 1834bb59504733a159ae6f1832eae01d5ec0fc02 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Mar 2014 13:34:21 +0000 Subject: [PATCH 188/507] disabled old code --- src/tactic/sls/sls_engine.cpp | 4 +++- src/tactic/sls/sls_engine.h | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 9fa2cc263..cc06e4f78 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -868,6 +868,7 @@ bailout: return res; } +#if 0 // Old code. // main search loop lbool sls_engine::search_old() { lbool res = l_undef; @@ -1060,6 +1061,7 @@ lbool sls_engine::search_old() { } } } +#endif bailout: m_mpz_manager.del(new_value); @@ -1190,4 +1192,4 @@ unsigned sls_engine::check_restart(unsigned curr_value) return 0; } return 1; -} \ No newline at end of file +} diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8458817b6..5d4c9a0fc 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -114,7 +114,6 @@ public: protected: void checkpoint(); - lbool search_old(void); double get_restart_armin(unsigned cnt_restarts); bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, @@ -148,4 +147,4 @@ protected: inline unsigned check_restart(unsigned curr_value); }; -#endif \ No newline at end of file +#endif From e9797c392272e90dd7b9ffb43e537098c9f354dd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Mar 2014 13:37:04 +0000 Subject: [PATCH 189/507] bugfix --- src/tactic/sls/sls_engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index cc06e4f78..10aaf6601 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1061,13 +1061,13 @@ lbool sls_engine::search_old() { } } } -#endif bailout: m_mpz_manager.del(new_value); return res; } +#endif void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { From 71fdb597475d5178ac3a6ec8309cf2cc6b659bce Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:27:06 +0000 Subject: [PATCH 190/507] removed dependency of bvsls on goal_refs Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index c49257692..cf1ad9ea3 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -276,13 +276,13 @@ public: } #endif - void uct_forget(goal_ref const & g) { + void uct_forget(ptr_vector & as) { expr * e; unsigned touched_old, touched_new; - for (unsigned i = 0; i < g->size(); i++) + for (unsigned i = 0; i < as.size(); i++) { - e = g->form(i); + e = as[i]; touched_old = m_scores.find(e).touched; touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); m_scores.find(e).touched = touched_new; From b76ffddf49c0d42472573c41d20c072b503d3e78 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:28:40 +0000 Subject: [PATCH 191/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index cf1ad9ea3..fac080ee7 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include"for_each_expr.h" #include"bv_decl_plugin.h" #include"model.h" From 1b98e6002b7a70ee51f00227ecdecb663a2fe113 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 12:30:15 +0000 Subject: [PATCH 192/507] compilation fixes Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.h | 1 + src/tactic/sls/sls_tracker.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 5d4c9a0fc..96041d09e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,6 +22,7 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" +#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index fac080ee7..537492213 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -21,6 +21,7 @@ Notes: #define _SLS_TRACKER_H_ #include"for_each_expr.h" +#include"ast_smt2_pp.h" #include"bv_decl_plugin.h" #include"model.h" From ad412d4f08f63e61778f940fef7afdb0f54c7f51 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 14:58:59 +0000 Subject: [PATCH 193/507] bvsls refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 21 ++++++++++++--------- src/tactic/sls/sls_engine.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 10aaf6601..e7ee2abbd 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1069,6 +1069,16 @@ bailout: } #endif +void sls_engine::init_tracker() { +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(m_assertions); +} + void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { mc = 0; @@ -1078,8 +1088,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); for (unsigned i = 0; i < g->size(); i++) - assert_expr(g->form(i)); - + assert_expr(g->form(i)); verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; @@ -1118,13 +1127,7 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(m_assertions); + init_tracker(); lbool res = l_undef; m_restart_limit = _RESTART_LIMIT_; diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 96041d09e..c56d6ec40 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -109,6 +109,8 @@ public: void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void init_tracker(void); + lbool search(void); void operator()(goal_ref const & g, model_converter_ref & mc); From e382742a29f06e818bf361e2829abe18d118d710 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 15:26:52 +0000 Subject: [PATCH 194/507] bvsls refactoring Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 44 +++++++++++++++++++---------------- src/tactic/sls/sls_engine.h | 1 + 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index e7ee2abbd..2b359608a 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1125,8 +1125,31 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + lbool res = operator()(); + + if (res == l_true) { + report_tactic_progress("Number of flips:", m_stats.m_moves); + for (unsigned i = 0; i < g->size(); i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + { + verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; + NOT_IMPLEMENTED_YET(); + } + + if (m_produce_models) { + model_ref mdl = m_tracker.get_model(); + mc = model2model_converter(mdl.get()); + TRACE("sls_model", mc->display(tout);); + } + g->reset(); + } + else + mc = 0; +} + +lbool sls_engine::operator()() { init_tracker(); lbool res = l_undef; @@ -1149,25 +1172,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout);); - } - g->reset(); - } - else - mc = 0; } unsigned sls_engine::check_restart(unsigned curr_value) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index c56d6ec40..c6e3af155 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -113,6 +113,7 @@ public: lbool search(void); + lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: From a48bb976e9ae28e0eb60600ef8d9e43cb1c906e7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 28 Mar 2014 15:28:02 +0000 Subject: [PATCH 195/507] bvsls bugfix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 2b359608a..dc4451bb5 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -1172,6 +1172,8 @@ lbool sls_engine::operator()() { } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + return res; } unsigned sls_engine::check_restart(unsigned curr_value) From c56e55b2305d0c26023a588b5c6d5dba1e79da87 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Sun, 20 Apr 2014 16:38:49 +0100 Subject: [PATCH 196/507] Current version before integration ... --- src/tactic/sls/sls_compilation_settings.h | 40 +- src/tactic/sls/sls_engine.cpp | 586 +++++++++++++++------- src/tactic/sls/sls_engine.h | 73 +-- src/tactic/sls/sls_evaluator.h | 152 +++++- src/tactic/sls/sls_tactic.cpp | 4 +- src/tactic/sls/sls_tracker.h | 472 ++++++++++++++--- 6 files changed, 1040 insertions(+), 287 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 8e52596e0..d2b899dd8 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -36,17 +36,21 @@ Notes: // do we use dirty unit propagation to get rid of nested top level assertions? #define _DIRTY_UP_ 0 +// shall we use additive weighting scheme? +#define _PAWS_ 5 +#define _PAWS_INIT_ 40 + // do we use restarts? // 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 +#define _RESTARTS_ 1 // limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 +#define _RESTART_LIMIT_ 100 // 0 = initialize with all zero, 1 initialize with random value #define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid +// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat #define _RESTART_SCHEME_ 1 // base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 3.0 +#define _RESTART_CONST_ARMIN_ 2.0 // timelimit #define _TIMELIMIT_ 3600 @@ -61,6 +65,21 @@ Notes: // 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained #define _VNS_ 0 +// shall we check 2-bit flips in plateaus using Monte Carlo? +#define _VNS_MC_ 0 + +// how many 2-bit flips shall we try per bit? +#define _VNS_MC_TRIES_ 1 + +// shall we check another assertion if no improving step was found in the first one? +#define _VNS_REPICK_ 0 + +// what is the probability of doing so (percentage)? +#define _VNS_PERC_ 100 + +// do a decreasing move with percentage ... +#define _INSIST_PERC_ 0 + // do we reduce the score of unsatisfied literals? // 0 = no // 1 = yes, by multiplying it with some factor @@ -70,7 +89,7 @@ Notes: #define _WEIGHT_DIST_ 1 // the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.25 +#define _WEIGHT_DIST_FACTOR_ 0.5 // shall we toggle the weight after each restart? #define _WEIGHT_TOGGLE_ 0 @@ -82,14 +101,15 @@ Notes: // what is the percentage of random moves in plateaus (instead of full randomization)? #define _PERC_PLATEAU_MOVES_ 0 -// shall we repick clause when randomizing in a plateau or use the current one? +// shall we repick assertion when randomizing in a plateau or use the current one? +// 0 = use old one, 1 = repick according to usual scheme, 2 = repick randomly and force different one #define _REPICK_ 1 // do we use some UCT-like scheme for assertion-selection? overrides _BFS_ #define _UCT_ 1 // how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 10.0 +#define _UCT_CONSTANT_ 20.0 // is uct clause selection probabilistic similar to variable selection in sparrow? // 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score @@ -103,7 +123,11 @@ Notes: // how shall we initialize the _UCT_ total touched counter? // 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 1 +#define _UCT_INIT_ 0 + +// do we gradually reduce the touched values of _UCT_? +#define _UCT_FORGET_ 0 +#define _UCT_FORGET_FACTOR_ 0.9 // shall we use addition/subtraction? #define _USE_ADDSUB_ 1 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index dc4451bb5..342e649af 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -74,15 +74,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(model & mdl) { +bool sls_engine::full_eval(goal_ref const & g, model & mdl) { bool res = true; - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(m_assertions[i], o, true)) + if (!mdl.eval(g->form(i), o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,7 +93,7 @@ bool sls_engine::full_eval(model & mdl) { return res; } -double sls_engine::top_score() { +double sls_engine::top_score(goal_ref const & g) { #if 0 double min = m_tracker.get_score(g->form(0)); unsigned sz = g->size(); @@ -108,15 +108,15 @@ double sls_engine::top_score() { return min; #else double top_sum = 0.0; - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = m_assertions[i]; + expr * e = g->form(i); top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(m_assertions[i]); + tout << " " << m_tracker.get_score(g->form(i)); tout << " AVG: " << top_sum / (double)sz << std::endl;); #if _CACHE_TOP_SCORE_ @@ -127,40 +127,40 @@ double sls_engine::top_score() { #endif } -double sls_engine::rescore() { +double sls_engine::rescore(goal_ref const & g) { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(); + return top_score(g); } -double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / m_assertions.size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(); + return top_score(g); #endif } -double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / m_assertions.size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(); + return top_score(g); #endif } -double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { #if _EARLY_PRUNE_ m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) #if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / m_assertions.size()); + return (m_tracker.get_top_sum() / g->size()); #else - return top_score(); + return top_score(g); #endif else return 0.0; @@ -169,14 +169,17 @@ double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value #endif } +double sls_engine::incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value) { + m_stats.m_incr_evals++; + if (m_evaluator.update_prune_new(fd, new_value)) + return (m_tracker.get_top_sum() / g->size()); + else + return 0.0; +} + // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if( - func_decl * fd, - const unsigned & fd_inx, - const mpz & temp, - double & best_score, - unsigned & best_const, - mpz & best_value) { +bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -184,9 +187,9 @@ bool sls_engine::what_if( #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(fd, temp); + double r = incremental_score_prune(g, fd, temp); #else - double r = incremental_score(fd, temp); + double r = incremental_score(g, fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -195,8 +198,33 @@ bool sls_engine::what_if( m_mpz_manager.del(old_value); #endif - // if (r >= best_score) { + //if (r >= best_score) { if (r > best_score) { + m_tracker.reset_equal_scores(); + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + /*else if (r == best_score) { + if (m_tracker.get_random_uint(16) % m_tracker.inc_equal_scores() == 0) + { + best_score = r; + best_const = fd_inx; + m_mpz_manager.set(best_value, temp); + return true; + } + }*/ + + return false; +} + +bool sls_engine::what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { + + double r = incremental_score_prune_new(g, fd, temp); + + if (r >= best_score) { best_score = r; best_const = fd_inx; m_mpz_manager.set(best_value, temp); @@ -207,15 +235,8 @@ bool sls_engine::what_if( } // same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local( - expr * e, - func_decl * fd, - const unsigned & fd_inx, - const mpz & temp, - double & best_score, - unsigned & best_const, - mpz & best_value) -{ +bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value) { m_evaluator.update(fd, temp); double r = m_tracker.get_score(e); if (r >= best_score) { @@ -356,19 +377,13 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move() { - mk_random_move(m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves)); +void sls_engine::mk_random_move(goal_ref const & g) { + mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); } // will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns( - ptr_vector & to_evaluate, - double score, - unsigned & best_const, - mpz & best_value, - unsigned & new_bit, - move_type & move) -{ +double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; unsigned bv_sz, max_bv_sz = 0; double new_score = score; @@ -384,31 +399,31 @@ double sls_engine::find_best_move_vns( if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; // try to flip lsb mk_flip(srt, old_value, 0, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { new_bit = 0; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(fd, old_value); + double check = incremental_score(g, fd, old_value); SASSERT(check == score); } @@ -430,13 +445,13 @@ double sls_engine::find_best_move_vns( { mk_flip(srt, old_value, j, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } } // reset to what it was before - double check = incremental_score(fd, old_value); + double check = incremental_score(g, fd, old_value); SASSERT(check == score); } m_mpz_manager.del(old_value); @@ -444,23 +459,99 @@ double sls_engine::find_best_move_vns( return new_score; } +double sls_engine::find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { + mpz old_value, temp; + unsigned bv_sz, max_bv_sz = 0; + double new_score = score; + + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { + // try inverting + mk_inv(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INV; + + if (!m_mpz_manager.is_even(old_value)) { + // for odd values, try +1 + mk_inc(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_INC; + } + else { + // for even values, try -1 + mk_dec(bv_sz, old_value, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + move = MV_DEC; + } + + // try to flip lsb + mk_flip(srt, old_value, 0, temp); + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = 0; + move = MV_FLIP; + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + + for (unsigned j = 1; j < max_bv_sz; j++) + { + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + // What would happen if we flipped bit #j ? + if (j < bv_sz) + { + mk_flip(srt, old_value, j, temp); + + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + new_bit = j; + move = MV_FLIP; + } + } + // reset to what it was before + double check = incremental_score(g, fd, old_value); + SASSERT(check == score); + } + } + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + return new_score; +} + // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move( - ptr_vector & to_evaluate, - double score, - unsigned & best_const, - mpz & best_value, - unsigned & new_bit, - move_type & move) -{ +double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { mpz old_value, temp; #if _USE_MUL3_ || _USE_UNARY_MINUS_ mpz temp2; #endif unsigned bv_sz; +#if _INSIST_PERC_ + double new_score = m_tracker.get_random_uint(16) % 100 < _INSIST_PERC_ ? 0.0 : score; +#else double new_score = score; +#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + m_tracker.reset_equal_scores(); + +// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { +// for (unsigned i = m_tracker.get_random_uint(16) % to_evaluate.size(); i != to_evaluate.size(); i = to_evaluate.size()) { +// for (unsigned i = to_evaluate.size(); i-- > 0; ) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -470,15 +561,28 @@ double sls_engine::find_best_move( #if _SKIP_BITS_ for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { #else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { +// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz; j++) { +// for (unsigned j = bv_sz; j-- > 0; ) { #endif // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) { + //if (m_tracker.get_random_uint(1)) + //if ((move != MV_FLIP) || (new_bit > j)) + //{ + //if (what_if_new(g, fd, i, temp, new_score, best_const, best_value)) { + // new_bit = j; + // move = MV_FLIP; + //} + //} + //else + //{ + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } + //} } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -486,19 +590,22 @@ double sls_engine::find_best_move( if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - if (what_if(fd, i, temp, new_score, best_const, best_value)) + //if (m_tracker.get_random_uint(1)) + if (what_if(g, fd, i, temp, new_score, best_const, best_value)) move = MV_INV; #if _USE_UNARY_MINUS_ @@ -528,7 +635,7 @@ double sls_engine::find_best_move( } // reset to what it was before - double check = incremental_score(fd, old_value); + double check = incremental_score(g, fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } @@ -538,6 +645,50 @@ double sls_engine::find_best_move( #if _USE_MUL3_ m_mpz_manager.del(temp2); #endif + + if ((new_score == score) && 1)// (m_tracker.get_random_uint(1))) + best_const = -1; + + return new_score; +} + +// finds the move that increased score the most. returns best_const = -1, if no increasing move exists. +double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value) { + mpz old_value, temp, temp2; + unsigned bv_sz; + double new_score = score; + +// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { + for (unsigned i = 0; i < to_evaluate.size(); i++) { + func_decl * fd = to_evaluate[i]; + sort * srt = fd->get_range(); + bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + m_mpz_manager.set(old_value, m_tracker.get_value(fd)); + + if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { +// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { + for (unsigned j = 0; j < bv_sz; j++) { + mk_flip(srt, old_value, j, temp); + for (unsigned l = 0; l < _VNS_MC_TRIES_ && l < bv_sz / 2; l++) + { + unsigned k = m_tracker.get_random_uint(16) % bv_sz; + while (k == j) + k = m_tracker.get_random_uint(16) % bv_sz; + mk_flip(srt, temp, k, temp2); + what_if(g, fd, i, temp2, new_score, best_const, best_value); + } + } + } + + // reset to what it was before + double check = incremental_score(g, fd, old_value); + } + + m_mpz_manager.del(old_value); + m_mpz_manager.del(temp); + m_mpz_manager.del(temp2); + return new_score; } @@ -596,15 +747,15 @@ double sls_engine::find_best_move_local(expr * e, ptr_vector & to_eva } // first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau() +bool sls_engine::handle_plateau(goal_ref const & g) { - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); #if _BFS_ unsigned pos = m_stats.m_moves % sz; #else unsigned pos = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(sz, pos); + expr * e = m_tracker.get_unsat_assertion(g, sz, pos); if (!e) return 0; @@ -658,15 +809,10 @@ bool sls_engine::handle_plateau() } // what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if( - expr * e, - func_decl * fd, - const mpz & temp, - double & best_score, - mpz & best_value, - unsigned i) -{ - double global_score = incremental_score(fd, temp); +bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i) { + + double global_score = incremental_score(g, fd, temp); double local_score = m_tracker.get_score(e); double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; @@ -680,7 +826,7 @@ bool sls_engine::what_if( } // find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i) +double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) { mpz old_value, temp; double best_score = 0; @@ -691,7 +837,7 @@ double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_val for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { mk_flip(srt, old_value, j, temp); - what_if(e, fd, temp, best_score, best_value, i); + what_if(g, e, fd, temp, best_score, best_value, i); } m_mpz_manager.del(old_value); @@ -701,15 +847,15 @@ double sls_engine::find_best_move_local(expr * e, func_decl * fd, mpz & best_val } // second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(double old_score) +bool sls_engine::handle_plateau(goal_ref const & g, double old_score) { - unsigned sz = m_assertions.size(); + unsigned sz = g->size(); #if _BFS_ unsigned new_const = m_stats.m_moves % sz; #else unsigned new_const = m_tracker.get_random_uint(16) % sz; #endif - expr * e = m_tracker.get_unsat_assertion(m_assertions, sz, new_const); + expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); if (!e) return 0; @@ -726,12 +872,12 @@ bool sls_engine::handle_plateau(double old_score) for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) { - new_score = find_best_move_local(q, fd, new_value, i); + new_score = find_best_move_local(g, q, fd, new_value, i); m_stats.m_moves++; m_stats.m_flips++; - global_score = incremental_score(fd, new_value); + global_score = incremental_score(g, fd, new_value); local_score = m_tracker.get_score(q); SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); @@ -744,7 +890,7 @@ bool sls_engine::handle_plateau(double old_score) } // main search loop -lbool sls_engine::search() { +lbool sls_engine::search(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; @@ -752,8 +898,15 @@ lbool sls_engine::search() { move_type move; unsigned plateau_cnt = 0; - score = rescore(); - unsigned sz = m_assertions.size(); + score = rescore(g); + unsigned sz = g->size(); + + TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; + tout << "Score distribution:"; + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); + tout << " TOP: " << score << std::endl;); + #if _PERC_STICKY_ expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif @@ -767,9 +920,18 @@ lbool sls_engine::search() { #else while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { #endif + //if (m_stats.m_stopwatch.get_current_seconds() > 10.0) + //{printf("Got %f fps and size is %d with avg bw %f\n", m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds(), m_tracker.get_formula_size(), m_tracker.get_avg_bw(g)); exit(0);} + checkpoint(); m_stats.m_moves++; +#if _UCT_FORGET_ + //if (m_stats.m_moves % sz == 0) + if (m_stats.m_moves % _UCT_FORGET_ == 0) + m_tracker.uct_forget(g); +#endif + #if _REAL_RS_ || _REAL_PBFS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif @@ -779,13 +941,14 @@ lbool sls_engine::search() { if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #else - expr * e = m_tracker.get_unsat_assertion(m_assertions, m_stats.m_moves); + expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); #endif if (!e) { res = l_true; goto bailout; } + //ptr_vector & to_evaluate = m_tracker.get_unsat_constants_only(e); ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); #else ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); @@ -818,13 +981,69 @@ lbool sls_engine::search() { #endif old_score = score; new_const = (unsigned)-1; + move = MV_FLIP; + new_bit = 0; #if _VNS_ score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); #endif +#if _VNS_MC_ > _VNS_REPICK_ +#if _VNS_MC_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); +#endif +#if _VNS_REPICK_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } +#endif +#endif + +#if _VNS_MC_ < _VNS_REPICK_ +#if _VNS_REPICK_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } +#endif +#if _VNS_MC_ + if (new_const == static_cast(-1)) + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); +#endif +#endif + +#if (_VNS_MC_ == _VNS_REPICK_) && _VNS_MC_ && _VNS_REPICK_ + if (new_const == static_cast(-1)) { + if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) + score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); + else { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); + } + } + } +#endif + + if (new_const == static_cast(-1)) { score = old_score; plateau_cnt++; @@ -839,25 +1058,52 @@ lbool sls_engine::search() { mk_random_move(to_evaluate); else #endif -#if _REPICK_ - m_evaluator.randomize_local(m_assertions, m_stats.m_moves); +#if _REPICK_ == 1 + m_evaluator.randomize_local(g, m_stats.m_moves); +#elif _REPICK_ == 2 + { + expr * q = m_tracker.get_new_unsat_assertion(g, e); + if (q) + m_evaluator.randomize_local(q); + else + m_evaluator.randomize_local(e); + } #else - m_evaluator.randomize_local(to_evaluate); + m_evaluator.randomize_local_n(g, to_evaluate); + //m_evaluator.randomize_local(to_evaluate); #endif #endif #if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / m_assertions.size(); + score = m_tracker.get_top_sum() / g->size(); #else score = top_score(g); #endif + +#if _PAWS_ + for (unsigned i = 0; i < sz; i++) + { + expr * q = g->form(i); + if (m_tracker.get_random_uint(16) % 100 < _PAWS_) + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) + m_tracker.decrease_weight(q); + } + else + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) + m_tracker.increase_weight(q); + } + } +#endif + } else { func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ score = serious_score(g, fd, new_value); #else - score = incremental_score(fd, new_value); + score = incremental_score(g, fd, new_value); #endif } } @@ -868,20 +1114,19 @@ bailout: return res; } -#if 0 // Old code. // main search loop -lbool sls_engine::search_old() { +lbool sls_engine::search_old(goal_ref const & g) { lbool res = l_undef; double score = 0.0, old_score = 0.0; unsigned new_const = (unsigned)-1, new_bit = 0; mpz new_value; move_type move; - score = rescore(); + score = rescore(g); TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; tout << "Score distribution:"; - for (unsigned i = 0; i < m_assertions.size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); tout << " TOP: " << score << std::endl;); unsigned plateau_cnt = 0; @@ -927,7 +1172,7 @@ lbool sls_engine::search_old() { old_score = score; new_const = (unsigned)-1; - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions, m_stats.m_moves); + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); if (!to_evaluate.size()) { res = l_true; @@ -938,22 +1183,22 @@ lbool sls_engine::search_old() { tout << to_evaluate[i]->get_name() << std::endl;); #if _VNS_ - score = find_best_move_vns(to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); #else - score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); #endif if (new_const == static_cast(-1)) { TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < m_assertions.size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) - tout << mk_ismt2_pp(m_assertions[i], m_manager) << std::endl; + for (unsigned i = 0; i < g->size(); i++) { + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) + tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; }); TRACE("sls_max", m_tracker.show_model(tout); tout << "Scores: " << std::endl; - for (unsigned i = 0; i < m_assertions.size(); i++) - tout << mk_ismt2_pp(m_assertions[i], m_manager) << " ---> " << - m_tracker.get_score(m_assertions[i]) << std::endl;); + for (unsigned i = 0; i < g->size(); i++) + tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << + m_tracker.get_score(g->form(i)) << std::endl;); // Andreas: If new_const == -1, shouldn't score = old_score anyway? score = old_score; } @@ -991,15 +1236,15 @@ lbool sls_engine::search_old() { case MV_DIV2: m_stats.m_div2s++; break; } -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(fd, new_value); +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ + score = serious_score(g, fd, new_value); #else - score = incremental_score(fd, new_value); + score = incremental_score(g, fd, new_value); #endif TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < m_assertions.size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(m_assertions[i]); + for (unsigned i = 0; i < g->size(); i++) + tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); tout << " TOP: " << score << std::endl;); } @@ -1008,8 +1253,8 @@ lbool sls_engine::search_old() { // score could theoretically be imprecise. // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! bool all_true = true; - for (unsigned i = 0; i < m_assertions.size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) all_true = false; if (all_true) { res = l_true; // sat @@ -1040,17 +1285,17 @@ lbool sls_engine::search_old() { TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); #if _INTENSIFICATION_ handle_plateau(g, score); - //handle_plateau(); + //handle_plateau(g); #else - m_evaluator.randomize_local(m_assertions, m_stats.m_moves); + m_evaluator.randomize_local(g, m_stats.m_moves); #endif - //mk_random_move(); - score = top_score(); + //mk_random_move(g); + score = top_score(g); if (score >= 1.0) { bool all_true = true; - for (unsigned i = 0; i < m_assertions.size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(m_assertions[i]))) + for (unsigned i = 0; i < g->size() && all_true; i++) + if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) all_true = false; if (all_true) { res = l_true; // sat @@ -1067,17 +1312,6 @@ bailout: return res; } -#endif - -void sls_engine::init_tracker() { -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(m_assertions); -} void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { if (g->inconsistent()) { @@ -1087,9 +1321,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); - for (unsigned i = 0; i < g->size(); i++) - assert_expr(g->form(i)); - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; @@ -1100,7 +1331,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; + verbose_stream() << "_PAWS_ " << _PAWS_ << std::endl; + verbose_stream() << "_PAWS_INIT_ " << _PAWS_INIT_ << std::endl; verbose_stream() << "_VNS_ " << _VNS_ << std::endl; + verbose_stream() << "_VNS_MC_ " << _VNS_MC_ << std::endl; + verbose_stream() << "_VNS_MC_TRIES_ " << _VNS_MC_TRIES_ << std::endl; + verbose_stream() << "_VNS_REPICK_ " << _VNS_REPICK_ << std::endl; + verbose_stream() << "_VNS_PERC_ " << _VNS_PERC_ << std::endl; + verbose_stream() << "_INSIST_PERC_ " << _INSIST_PERC_ << std::endl; verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; @@ -1111,6 +1349,8 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; + verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; + verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; @@ -1125,9 +1365,36 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; + verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - lbool res = operator()(); +#if _WEIGHT_DIST_ == 4 + m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); +#endif +#if _WEIGHT_TOGGLE_ + m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); +#endif + m_tracker.initialize(g); + lbool res = l_undef; + + m_restart_limit = _RESTART_LIMIT_; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(g); + + if (res == l_undef) + { +#if _RESTART_INIT_ + m_tracker.randomize(g); +#else + m_tracker.reset(g); +#endif + } + } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); @@ -1149,38 +1416,13 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { mc = 0; } -lbool sls_engine::operator()() { - init_tracker(); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(); -#else - m_tracker.reset(m_assertions); -#endif - } - } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - return res; -} - unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_limit) { -#if _RESTART_SCHEME_ == 4 +#if _RESTART_SCHEME_ == 5 + m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); +#elif _RESTART_SCHEME_ == 4 m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; @@ -1188,9 +1430,11 @@ unsigned sls_engine::check_restart(unsigned curr_value) m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) + //if (m_stats.m_restarts % 3 == 2) m_restart_limit += _RESTART_LIMIT_; else m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; + //m_restart_limit += (2 << (m_stats.m_restarts / 3)) * _RESTART_LIMIT_; #else m_restart_limit += _RESTART_LIMIT_; #endif @@ -1201,4 +1445,4 @@ unsigned sls_engine::check_restart(unsigned curr_value) return 0; } return 1; -} +} \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index c6e3af155..902c6b7a0 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,7 +22,6 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" -#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" @@ -72,7 +71,6 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; - ptr_vector m_assertions; unsigned m_restart_limit; unsigned m_max_restarts; @@ -94,12 +92,11 @@ public: void updt_params(params_ref const & _p); - void assert_expr(expr * e) { m_assertions.push_back(e); } - stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(model & mdl); + bool full_eval(goal_ref const & g, model & mdl); + void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); @@ -107,48 +104,66 @@ public: void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - void init_tracker(void); + double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - lbool search(void); + double find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + double find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value); + + double find_best_move_local(expr * e, ptr_vector & to_evaluate, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + + + bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, + double & best_score, mpz & best_value, unsigned i); + + double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); + + + lbool search(goal_ref const & g); - lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); + lbool search_old(goal_ref const & g); double get_restart_armin(unsigned cnt_restarts); - bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - bool what_if(expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); + + bool what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + double & best_score, unsigned & best_const, mpz & best_value); + double incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value); + bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - double top_score(); - double rescore(); - double serious_score(func_decl * fd, const mpz & new_value); - double incremental_score(func_decl * fd, const mpz & new_value); + double top_score(goal_ref const & g); + double rescore(goal_ref const & g); + double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); + double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); #if _EARLY_PRUNE_ - double incremental_score_prune(func_decl * fd, const mpz & new_value); + double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); #endif - double find_best_move(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - double find_best_move_local(expr * e, func_decl * fd, mpz & best_value, unsigned i); - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - double find_best_move_vns(ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(); - bool handle_plateau(void); - bool handle_plateau(double old_score); + double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + + void mk_random_move(ptr_vector & unsat_constants); + void mk_random_move(goal_ref const & g); + + bool handle_plateau(goal_ref const & g); + bool handle_plateau(goal_ref const & g, double old_score); inline unsigned check_restart(unsigned curr_value); }; -#endif +#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 7638ba5f4..78f2cb79a 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -575,7 +575,7 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); @@ -584,12 +584,13 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -634,7 +635,7 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); @@ -643,12 +644,12 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); #endif -#endif +#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -683,7 +684,7 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ run_serious_update(max_depth); #else run_update(max_depth); @@ -729,14 +730,16 @@ public: #if _CACHE_TOP_SCORE_ //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); #endif prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) + //if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) pot_benefits = 1; if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) + //if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { @@ -771,7 +774,7 @@ public: new_score = m_tracker.score(cur); //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(new_score, m_tracker.get_score(cur)); + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); #else m_tracker.set_score(cur, m_tracker.score(cur)); @@ -858,6 +861,104 @@ public: } #endif + unsigned run_update_bool_prune_new(unsigned cur_depth) { + expr_fast_mark1 visited; + + double prune_score, new_score; + unsigned pot_benefits = 0; + SASSERT(cur_depth < m_traversal_stack_bool.size()); + + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + + for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + prune_score = m_tracker.get_score_prune(cur); + m_tracker.set_score(cur, new_score); + + if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) + pot_benefits = 1; + if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) + pot_benefits = 1; + + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + else + { + } + } + + cur_depth_exprs.reset(); + cur_depth--; + + while (cur_depth != static_cast(-1)) { + ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; + if (pot_benefits) + { + unsigned cur_size = cur_depth_exprs.size(); + for (unsigned i = 0; i < cur_size; i++) { + expr * cur = cur_depth_exprs[i]; + + new_score = m_tracker.score(cur); + //if (!m_tracker.has_uplinks(cur)) + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); + if (m_tracker.has_uplinks(cur)) { + ptr_vector & ups = m_tracker.get_uplinks(cur); + for (unsigned j = 0; j < ups.size(); j++) { + expr * next = ups[j]; + unsigned next_d = m_tracker.get_distance(next); + SASSERT(next_d < cur_depth); + if (!visited.is_marked(next)) { + m_traversal_stack_bool[next_d].push_back(next); + visited.mark(next); + } + } + } + } + } + cur_depth_exprs.reset(); + cur_depth--; + } + + return pot_benefits; + } + + unsigned update_prune_new(func_decl * fd, const mpz & new_value) { + m_tracker.set_value(fd, new_value); + expr * ep = m_tracker.get_entry_point(fd); + unsigned cur_depth = m_tracker.get_distance(ep); + + if (m_traversal_stack_bool.size() <= cur_depth) + m_traversal_stack_bool.resize(cur_depth+1); + if (m_traversal_stack.size() <= cur_depth) + m_traversal_stack.resize(cur_depth+1); + + if (m_manager.is_bool(ep)) + m_traversal_stack_bool[cur_depth].push_back(ep); + else + { + m_traversal_stack[cur_depth].push_back(ep); + run_update_prune(cur_depth); + } + return run_update_bool_prune_new(cur_depth); + } + void randomize_local(ptr_vector & unsat_constants) { // Randomize _all_ candidates: @@ -901,7 +1002,7 @@ public: mpz temp = m_tracker.get_random(fd->get_range()); #endif -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ serious_update(fd, temp); #else update(fd, temp); @@ -922,9 +1023,36 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(ptr_vector const & as, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(as, flip)); + void randomize_local(goal_ref const & g, unsigned int flip) { + randomize_local(m_tracker.get_unsat_constants(g, flip)); } + + void randomize_local_n(goal_ref const & g, ptr_vector & unsat_constants) { + unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); + func_decl * fd = unsat_constants[r]; + sort * srt = fd->get_range(); + unsigned bv_sz = m_manager.is_bool(srt) ? 1 : m_bv_util.get_bv_size(srt); + mpz max_val = m_tracker.get_random(srt); + update(fd, max_val); + double max_score = m_tracker.get_top_sum() / g->size(); + mpz temp_val; + double temp_score; + for (unsigned i = 1; i < 2; i++) + //for (unsigned i = 1; i < bv_sz; i++) + { + m_mpz_manager.set(temp_val, m_tracker.get_random(srt)); + update(fd, temp_val); + temp_score = m_tracker.get_top_sum() / g->size(); + if (temp_score > max_score) + { + m_mpz_manager.set(max_val, temp_val); + max_score = temp_score; + } + } + update(fd, max_val); + m_mpz_manager.del(temp_val); + m_mpz_manager.del(max_val); + } }; #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index b2b7035e0..0b6b01e7c 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -1509,14 +1509,14 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { mk_max_bv_sharing_tactic(m), // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? //mk_ctx_simplify_tactic(m, ctx_p), - // Andreas: This one at least eliminates top level duplicates ... + // Andreas: This one at least eliminates top level duplicates ... but has very bad effects on performance! //mk_simplify_tactic(m), - // Andreas: How does a NNF actually look like? Can it contain ITE operators? mk_nnf_tactic(m, p)); } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); +// tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 537492213..87c90f1f8 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,9 +20,7 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"for_each_expr.h" -#include"ast_smt2_pp.h" -#include"bv_decl_plugin.h" +#include"goal.h" #include"model.h" #include"sls_compilation_settings.h" @@ -88,12 +86,17 @@ private: obj_map m_where_false; expr** m_list_false; #endif +#if _PAWS_ + obj_map m_weights; + //obj_map m_weights; +#endif #if _CACHE_TOP_SCORE_ double m_top_sum; #endif #if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ double m_weight_dist_factor; #endif + unsigned m_equal_scores; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -113,15 +116,52 @@ public: m_mpz_manager.del(m_two); } + unsigned get_formula_size() { + return m_scores.size(); + } + + double get_avg_bw(goal_ref const & g) { + double sum = 0.0; + unsigned count = 0; + + for (unsigned i = 0; i < g->size(); i++) + { + m_temp_constants.reset(); + ptr_vector const & this_decls = m_constants_occ.find(g->form(i)); + unsigned sz = this_decls.size(); + for (unsigned i = 0; i < sz; i++) { + func_decl * fd = this_decls[i]; + m_temp_constants.push_back(fd); + sort * srt = fd->get_range(); + sum += (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); + count++; + } + } + + return sum / count; + } + #if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ inline void set_weight_dist_factor(double val) { m_weight_dist_factor = val; } #endif + void reset_equal_scores() { + m_equal_scores = 1; + } + + unsigned inc_equal_scores() { + return ++m_equal_scores; + } + #if _CACHE_TOP_SCORE_ - inline void adapt_top_sum(double add, double sub) { + inline void adapt_top_sum(expr * e, double add, double sub) { +#if _PAWS_ + m_top_sum += m_weights.find(e) * (add - sub); +#else m_top_sum += add - sub; +#endif } inline void set_top_sum(double new_score) { @@ -278,19 +318,21 @@ public: } #endif - void uct_forget(ptr_vector & as) { +#if _UCT_ + void uct_forget(goal_ref const & g) { expr * e; unsigned touched_old, touched_new; - for (unsigned i = 0; i < as.size(); i++) + for (unsigned i = 0; i < g->size(); i++) { - e = as[i]; + e = g->form(i); touched_old = m_scores.find(e).touched; touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); m_scores.find(e).touched = touched_new; m_touched += touched_new - touched_old; } } +#endif void initialize(app * n) { // Build score table @@ -367,12 +409,12 @@ public: } }; - void calculate_expr_distances(ptr_vector const & as) { + void calculate_expr_distances(goal_ref const & g) { // precondition: m_scores is set up. - unsigned sz = as.size(); + unsigned sz = g->size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(as[i])); + stack.push_back(to_app(g->form(i))); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -420,12 +462,12 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(ptr_vector const & as) { + void initialize(goal_ref const & g) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = as.size(); + unsigned sz = g->size(); for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); if (!m_top_expr.contains(e)) m_top_expr.insert(e); else @@ -440,7 +482,7 @@ public: visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); // Andreas: Maybe not fully correct. #if _FOCUS_ == 2 || _INTENSIFICATION_ initialize_recursive(e); @@ -452,7 +494,7 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(as); + calculate_expr_distances(g); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); @@ -465,16 +507,49 @@ public: //} #endif +#if _PAWS_ + for (unsigned i = 0; i < sz; i++) + { + expr * e = g->form(i); + if (!m_weights.contains(e)) + m_weights.insert(e, _PAWS_INIT_); + } +#endif + #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(as[i]); + setup_occs(g->form(i)); #endif #if _UCT_ - m_touched = _UCT_INIT_ ? as.size() : 1; + m_touched = _UCT_INIT_ ? g->size() : 1; #endif } +#if _PAWS_ + void increase_weight(expr * e) + { + //printf("Increasing %d to", m_weights.find(e)); + m_weights.find(e)++; + //m_weights.find(e) *= 1.1; + //printf(" %d\n", m_weights.find(e)); + } + + void decrease_weight(expr * e) + { + unsigned old_weight = m_weights.find(e); + m_weights.find(e) = old_weight > _PAWS_INIT_ ? old_weight - 1 : _PAWS_INIT_; + //m_weights.find(e) = old_weight > 1.1 ? old_weight / 1.1 : 1; + //printf("Decreasing %d to %d\n", old_weight, m_weights.find(e)); + } + + unsigned get_weight(expr * e) + //double get_weight(expr * e) + { + return m_weights.find(e); + } +#endif + #if _REAL_RS_ || _REAL_PBFS_ void make_assertion(expr * e) { @@ -608,7 +683,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(ptr_vector const & as) { + void randomize(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -622,13 +697,13 @@ public: TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? as.size() : 1; - for (unsigned i = 0; i < as.size(); i++) - m_scores.find(as[i]).touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; #endif } - void reset(ptr_vector const & as) { + void reset(goal_ref const & g) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -638,9 +713,9 @@ public: } #if _UCT_RESET_ - m_touched = _UCT_INIT_ ? as.size() : 1; - for (unsigned i = 0; i < as.size(); i++) - m_scores.find(as[i]).touched = 1; + m_touched = _UCT_INIT_ ? g->size() : 1; + for (unsigned i = 0; i < g->size(); i++) + m_scores.find(g->form(i)).touched = 1; #endif } @@ -765,6 +840,7 @@ public: const mpz & v1 = get_value(arg1); if (negated) { + //res = (m_mpz_manager.eq(v0, v1)) ? 0.5 * (m_bv_util.get_bv_size(arg0) - 1.0) / m_bv_util.get_bv_size(arg0) : 1.0; res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << std::endl; ); @@ -811,40 +887,209 @@ public: SASSERT(a->get_num_args() == 2); const mpz & x = get_value(a->get_arg(0)); const mpz & y = get_value(a->get_arg(1)); - unsigned bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); if (negated) { if (m_mpz_manager.gt(x, y)) + { + /*mpz diff; + m_mpz_manager.sub(x, y, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +/* mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_gt = 0; + unsigned curr_gt = 0; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 1; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 0; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); + m_mpz_manager.del(x_copy); + m_mpz_manager.del(y_copy);*/ +#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= rational(m_powers(bv_sz)); + double dbl = 1.0 - n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + m_mpz_manager.del(diff); +#endif + } + } + else { + if (m_mpz_manager.le(x, y)) + { + /*mpz diff; + m_mpz_manager.sub(y, x, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); - } - } - else { - if (m_mpz_manager.le(x, y)) + res = 1.0 + 0.5 * dbl;*/ res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +/* mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_le = 1; + unsigned curr_le = 1; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_le = curr_le; + curr_le = 0; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_le = curr_le; + curr_le = 1; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2);*/ +#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); + double dbl = 1.0 - n.get_double(); res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } - else if (m_bv_util.is_bv_sle(n)) { // x <= y +/* else if (m_bv_util.is_bv_sle(n)) { // x <= y + app * a = to_app(n); + SASSERT(a->get_num_args() == 2); + const mpz & x = get_value(a->get_arg(0)); + const mpz & y = get_value(a->get_arg(1)); + int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); + + mpz x_unsigned; + mpz y_unsigned; + const mpz & p = m_powers(bv_sz); + const mpz & p_half = m_powers(bv_sz-1); + if (x >= p_half) { m_mpz_manager.sub(x, p, x_unsigned); } + if (y >= p_half) { m_mpz_manager.sub(y, p, y_unsigned); } + + if (negated) { + if (x_unsigned > y_unsigned) + res = 1.0; + else { + mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_gt = 0; + unsigned curr_gt = 0; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 1; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_gt = curr_gt; + curr_gt = 0; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); + m_mpz_manager.del(x_copy); + m_mpz_manager.del(y_copy); + } + } + else { + if (x_unsigned <= y_unsigned) + res = 1.0; + else { + mpz x_copy, y_copy; + m_mpz_manager.set(x_copy, x); + m_mpz_manager.set(y_copy, y); + unsigned lower_le = 1; + unsigned curr_le = 1; + int last_pos = -1; + for (int i = 0; i < bv_sz; i++) + { + if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) + { + lower_le = curr_le; + curr_le = 0; + last_pos = i; + } + else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) + { + lower_le = curr_le; + curr_le = 1; + last_pos = i; + } + + m_mpz_manager.machine_div(x_copy, m_two, x_copy); + m_mpz_manager.machine_div(y_copy, m_two, y_copy); + } + + res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2); + } + } + TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << + m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); + + m_mpz_manager.del(x_unsigned); + m_mpz_manager.del(y_unsigned); + }*/ + else if (m_bv_util.is_bv_sle(n)) { // x <= y app * a = to_app(n); SASSERT(a->get_num_args() == 2); mpz x; m_mpz_manager.set(x, get_value(a->get_arg(0))); @@ -857,31 +1102,61 @@ public: if (negated) { if (x > y) - res = 1.0; + { + /*mpz diff; + m_mpz_manager.sub(x, y, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ + res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= p; - double dbl = n.get_double(); - res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + double dbl = 1.0 - n.get_double(); + //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } else { if (x <= y) - res = 1.0; + { + /*mpz diff; + m_mpz_manager.sub(y, x, diff); + m_mpz_manager.inc(diff); + rational n(diff); + n /= rational(m_powers(bv_sz)); + double dbl = n.get_double(); + // In extreme cases, n is 0.9999 but to_double returns something > 1.0 + m_mpz_manager.del(diff); + res = 1.0 + 0.5 * dbl;*/ + res = 1.0; + } else { + //res = (bv_sz - 1.0) / bv_sz; +#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); + SASSERT(!m_mpz_manager.is_neg(diff)); rational n(diff); n /= p; - double dbl = n.get_double(); + double dbl = 1.0 - n.get_double(); res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; m_mpz_manager.del(diff); +#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); @@ -1031,13 +1306,13 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(ptr_vector const & as, unsigned sz) { + ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { if (sz == 1) return get_constants(); m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1051,22 +1326,22 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(ptr_vector const & as, unsigned sz, unsigned int pos) { + expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { for (unsigned i = pos; i < sz; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) return q; } for (unsigned i = 0; i < pos; i++) { - expr * q = as[i]; + expr * q = g->form(i); if (m_mpz_manager.neq(get_value(q), m_one)) return q; } return 0; } - ptr_vector & get_unsat_constants_walksat(ptr_vector const & as, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(as, sz, pos); + ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. if (!q) return m_temp_constants; @@ -1143,20 +1418,66 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_crsat(ptr_vector const & as, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(as, sz, pos); + ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { + expr * q = get_unsat_assertion(g, sz, pos); if (!q) return m_temp_constants; return go_deeper(q); } - ptr_vector & get_unsat_constants(ptr_vector const & as, unsigned int flip) { - unsigned sz = as.size(); + void go_deeper_only(expr * e) { + //if (m_manager.is_bool(e)) { + if (m_manager.is_and(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + unsigned cnt_unsat = 0, pos = -1; + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + if (m_mpz_manager.neq(get_value(q), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + //if (m_mpz_manager.neq(get_value(q), m_one)) go_deeper(q); + } + go_deeper(args[pos]); + } + else if (m_manager.is_or(e)) { + app * a = to_app(e); + expr * const * args = a->get_args(); + unsigned int sz = a->get_num_args(); + for (unsigned int i = 0; i < sz; i++) { + expr * q = args[i]; + go_deeper(q); + } + } + //} + else + { + ptr_vector const & this_decls = m_constants_occ.find(e); + unsigned sz2 = this_decls.size(); + for (unsigned j = 0; j < sz2; j++) { + func_decl * fd = this_decls[j]; + if (!m_temp_constants.contains(fd)) + m_temp_constants.push_back(fd); + } + } + } + + ptr_vector & get_unsat_constants_only(expr * e) { + if (e && !m_temp_constants.size()) + go_deeper_only(e); + + return m_temp_constants; + } + + ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(as[0]), m_one)) + if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + { + m_temp_constants.reset(); return m_temp_constants; + } else return get_constants(); } @@ -1169,11 +1490,12 @@ public: #if _PROBABILISTIC_UCT_ double sum_score = 0.0; unsigned start_index = get_random_uint(16) % sz; - + for (unsigned i = start_index; i < sz; i++) { expr * e = g->form(i); vscore = m_scores.find(e); + #if _PROBABILISTIC_UCT_ == 2 double q = vscore.score * vscore.score; #else @@ -1203,7 +1525,7 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); @@ -1221,12 +1543,12 @@ public: return m_temp_constants; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(as[pos]).touched++; + m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 - m_scores.find(as[pos]).touched = flip; + m_scores.find(g->form(pos)).touched = flip; #endif - expr * e = as[pos]; + expr * e = g->form(pos); // expr * e = m_list_false[pos]; #elif _BFS_ == 3 @@ -1304,12 +1626,15 @@ public: } } + expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { + unsigned sz = g->size(); - expr * get_unsat_assertion(ptr_vector const & as, unsigned int flip) { - unsigned sz = as.size(); - - if (sz == 1) - return as[0]; + if (sz == 1) { + if (m_mpz_manager.eq(get_value(g->form(0)), m_zero)) + return g->form(0); + else + return 0; + } m_temp_constants.reset(); #if _FOCUS_ == 1 @@ -1353,12 +1678,12 @@ public: #else double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = as[i]; + expr * e = g->form(i); // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); #if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); #elif _UCT_ == 2 double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; #elif _UCT_ == 3 @@ -1371,13 +1696,13 @@ public: return 0; #if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(as[pos]).touched++; + m_scores.find(g->form(pos)).touched++; m_touched++; #elif _UCT_ == 2 m_scores.find(g->form(pos)).touched = flip; #endif // return m_list_false[pos]; - return as[pos]; + return g->form(pos); #elif _BFS_ == 3 unsigned int pos = -1; @@ -1431,7 +1756,7 @@ public: unsigned int pos = get_random_uint(16) % sz; return get_unsat_assertion(g, sz, pos); #endif - return as[pos]; + return g->form(pos); #elif _FOCUS_ == 2 #if _BFS_ unsigned int pos = flip % sz; @@ -1441,6 +1766,23 @@ public: return get_unsat_constants_crsat(g, sz, pos); #endif } + + expr * get_new_unsat_assertion(goal_ref const & g, expr * e) { + unsigned sz = g->size(); + + if (sz == 1) + return 0; + + m_temp_constants.reset(); + + unsigned cnt_unsat = 0, pos = -1; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (g->form(i) != e)) pos = i; + + if (pos == static_cast(-1)) + return 0; + return g->form(pos); + } }; #endif \ No newline at end of file From de028e7a30df593547b47262e98d9673f00adfa9 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 00:32:45 +0100 Subject: [PATCH 197/507] Almost cleaned up version. --- src/tactic/sls/sls_compilation_settings.h | 156 +-- src/tactic/sls/sls_engine.cpp | 1168 +++------------------ src/tactic/sls/sls_engine.h | 89 +- src/tactic/sls/sls_evaluator.h | 262 +---- src/tactic/sls/sls_tactic.cpp | 6 +- src/tactic/sls/sls_tracker.h | 904 ++-------------- 6 files changed, 315 insertions(+), 2270 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index d2b899dd8..9add78daa 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,167 +22,13 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 0 - -// shall we use additive weighting scheme? -#define _PAWS_ 5 -#define _PAWS_INIT_ 40 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 1 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 100 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 2.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// shall we check 2-bit flips in plateaus using Monte Carlo? -#define _VNS_MC_ 0 - -// how many 2-bit flips shall we try per bit? -#define _VNS_MC_TRIES_ 1 - -// shall we check another assertion if no improving step was found in the first one? -#define _VNS_REPICK_ 0 - -// what is the probability of doing so (percentage)? -#define _VNS_PERC_ 100 - -// do a decreasing move with percentage ... -#define _INSIST_PERC_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.5 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick assertion when randomizing in a plateau or use the current one? -// 0 = use old one, 1 = repick according to usual scheme, 2 = repick randomly and force different one -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 20.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 0 - -// do we gradually reduce the touched values of _UCT_? -#define _UCT_FORGET_ 0 -#define _UCT_FORGET_FACTOR_ 0.9 - // shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 +#define _USE_ADDSUB_ 0 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 // shall we use early pruning for incremental update? #define _EARLY_PRUNE_ 1 -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) -InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) -InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) -InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) -InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) -InvalidConfiguration; -#endif - #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 342e649af..c240a0c51 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -44,6 +44,7 @@ sls_engine::sls_engine(ast_manager & m, params_ref const & p) : m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) { updt_params(p); + m_tracker.updt_params(p); } sls_engine::~sls_engine() { @@ -52,20 +53,21 @@ sls_engine::~sls_engine() { m_mpz_manager.del(m_two); } -double sls_engine::get_restart_armin(unsigned cnt_restarts) -{ - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); -} - void sls_engine::updt_params(params_ref const & _p) { sls_params p(_p); m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); + m_max_restarts = p.max_restarts(); m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); + m_walksat = p.walksat(); + m_walksat_repick = p.walksat_repick(); + m_paws_sp = p.paws_sp(); + m_wp = p.wp(); + m_vns_mc = p.vns_mc(); + m_vns_repick = p.vns_repick(); + + m_restart_base = p.restart_base(); + m_restart_next = m_restart_base; + m_restart_init = p.restart_init(); } void sls_engine::checkpoint() { @@ -74,15 +76,15 @@ void sls_engine::checkpoint() { cooperate("sls"); } -bool sls_engine::full_eval(goal_ref const & g, model & mdl) { +bool sls_engine::full_eval(model & mdl) { bool res = true; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz && res; i++) { checkpoint(); expr_ref o(m_manager); - if (!mdl.eval(g->form(i), o, true)) + if (!mdl.eval(m_assertions[i], o, true)) exit(ERR_INTERNAL_FATAL); res = m_manager.is_true(o.get()); @@ -93,93 +95,58 @@ bool sls_engine::full_eval(goal_ref const & g, model & mdl) { return res; } -double sls_engine::top_score(goal_ref const & g) { -#if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl;); - return min; -#else +double sls_engine::top_score() { double top_sum = 0.0; - unsigned sz = g->size(); + unsigned sz = m_assertions.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = m_assertions[i]; top_sum += m_tracker.get_score(e); } TRACE("sls_top", tout << "Score distribution:"; for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); + tout << " " << m_tracker.get_score(m_assertions[i]); tout << " AVG: " << top_sum / (double)sz << std::endl;); -#if _CACHE_TOP_SCORE_ m_tracker.set_top_sum(top_sum); -#endif return top_sum / (double)sz; -#endif } -double sls_engine::rescore(goal_ref const & g) { +double sls_engine::rescore() { m_evaluator.update_all(); m_stats.m_full_evals++; - return top_score(g); + return top_score(); } -double sls_engine::serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif + return (m_tracker.get_top_sum() / m_assertions.size()); } -double sls_engine::incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { +double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif + return (m_tracker.get_top_sum() / m_assertions.size()); } -double sls_engine::incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { -#if _EARLY_PRUNE_ +double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; -#else - NOT_IMPLEMENTED_YET(); -#endif -} - -double sls_engine::incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune_new(fd, new_value)) - return (m_tracker.get_top_sum() / g->size()); + return (m_tracker.get_top_sum() / m_assertions.size()); else return 0.0; } // checks whether the score outcome of a given move is better than the previous score -bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { +bool sls_engine::what_if( + func_decl * fd, + const unsigned & fd_inx, + const mpz & temp, + double & best_score, + unsigned & best_const, + mpz & best_value) { #ifdef Z3DEBUG mpz old_value; @@ -187,9 +154,9 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd #endif #if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); + double r = incremental_score_prune(fd, temp); #else - double r = incremental_score(g, fd, temp); + double r = incremental_score(fd, temp); #endif #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << @@ -198,7 +165,7 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd m_mpz_manager.del(old_value); #endif - //if (r >= best_score) { + // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { m_tracker.reset_equal_scores(); best_score = r; @@ -206,45 +173,6 @@ bool sls_engine::what_if(goal_ref const & g, func_decl * fd, const unsigned & fd m_mpz_manager.set(best_value, temp); return true; } - /*else if (r == best_score) { - if (m_tracker.get_random_uint(16) % m_tracker.inc_equal_scores() == 0) - { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - }*/ - - return false; -} - -bool sls_engine::what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - double r = incremental_score_prune_new(g, fd, temp); - - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; -} - -// same as what_if, but only applied to the score of a specific atom, not the total score -bool sls_engine::what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } return false; } @@ -261,22 +189,6 @@ void sls_engine::mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, } -// Andreas: do we really need all those temporary mpzs? -void sls_engine::mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); -} - -void sls_engine::mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); -} - void sls_engine::mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { unsigned shift; m_mpz_manager.add(old_value, m_one, incremented); @@ -334,7 +246,7 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; #else - mt = MV_FLIP; + move_type mt = MV_FLIP; #endif unsigned bit = 0; @@ -373,216 +285,40 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout);); } - m_evaluator.update(fd, new_value); + m_evaluator.serious_update(fd, new_value); m_mpz_manager.del(new_value); } -void sls_engine::mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); -} - -// will use VNS to ignore some possible moves and increase the flips per second -double sls_engine::find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; -} - -double sls_engine::find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - for (unsigned j = 1; j < max_bv_sz; j++) - { - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; -} - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { +double sls_engine::find_best_move( + ptr_vector & to_evaluate, + double score, + unsigned & best_const, + mpz & best_value, + unsigned & new_bit, + move_type & move) +{ mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif unsigned bv_sz; -#if _INSIST_PERC_ - double new_score = m_tracker.get_random_uint(16) % 100 < _INSIST_PERC_ ? 0.0 : score; -#else double new_score = score; -#endif m_tracker.reset_equal_scores(); -// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { for (unsigned i = 0; i < to_evaluate.size(); i++) { -// for (unsigned i = m_tracker.get_random_uint(16) % to_evaluate.size(); i != to_evaluate.size(); i = to_evaluate.size()) { -// for (unsigned i = to_evaluate.size(); i-- > 0; ) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); m_mpz_manager.set(old_value, m_tracker.get_value(fd)); // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j += (_SKIP_BITS_ + 1)) { -#else -// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { for (unsigned j = 0; j < bv_sz; j++) { -// for (unsigned j = bv_sz; j-- > 0; ) { -#endif // What would happen if we flipped bit #i ? mk_flip(srt, old_value, j, temp); - //if (m_tracker.get_random_uint(1)) - //if ((move != MV_FLIP) || (new_bit > j)) - //{ - //if (what_if_new(g, fd, i, temp, new_score, best_const, best_value)) { - // new_bit = j; - // move = MV_FLIP; - //} - //} - //else - //{ - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { + if (what_if(fd, i, temp, new_score, best_const, best_value)) { new_bit = j; move = MV_FLIP; } - //} } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { @@ -590,76 +326,41 @@ double sls_engine::find_best_move(goal_ref const & g, ptr_vector & to if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); - //if (m_tracker.get_random_uint(1)) - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INC; } else { // for even values, try -1 mk_dec(bv_sz, old_value, temp); - //if (m_tracker.get_random_uint(1)) - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } #endif // try inverting mk_inv(bv_sz, old_value, temp); - //if (m_tracker.get_random_uint(1)) - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) + if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); // Andreas: does not hold anymore now that we use top level score caching //SASSERT(check == score); } m_mpz_manager.del(old_value); m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - - if ((new_score == score) && 1)// (m_tracker.get_random_uint(1))) - best_const = -1; return new_score; } // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. -double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, +double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double score, unsigned & best_const, mpz & best_value) { mpz old_value, temp, temp2; unsigned bv_sz; double new_score = score; -// for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0; i++) { for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -667,22 +368,21 @@ double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & m_mpz_manager.set(old_value, m_tracker.get_value(fd)); if (m_bv_util.is_bv_sort(srt) && bv_sz > 2) { -// for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { for (unsigned j = 0; j < bv_sz; j++) { mk_flip(srt, old_value, j, temp); - for (unsigned l = 0; l < _VNS_MC_TRIES_ && l < bv_sz / 2; l++) + for (unsigned l = 0; l < m_vns_mc && l < bv_sz / 2; l++) { unsigned k = m_tracker.get_random_uint(16) % bv_sz; while (k == j) k = m_tracker.get_random_uint(16) % bv_sz; mk_flip(srt, temp, k, temp2); - what_if(g, fd, i, temp2, new_score, best_const, best_value); + what_if(fd, i, temp2, new_score, best_const, best_value); } } } // reset to what it was before - double check = incremental_score(g, fd, old_value); + double check = incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -692,618 +392,89 @@ double sls_engine::find_best_move_mc(goal_ref const & g, ptr_vector & return new_score; } -// same as find_best_move but only considers the score of the current expression instead of the overall score -double sls_engine::find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; -} - -// first try of intensification ... does not seem to be efficient -bool sls_engine::handle_plateau(goal_ref const & g) -{ - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back(&m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } - else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], *m_old_values[i]); - - m_old_values.reset(); - - return 0; -} - -// what_if version needed in the context of 2nd intensification try, combining local and global score -bool sls_engine::what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; -} - -// find_best_move version needed in the context of 2nd intensification try -double sls_engine::find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) -{ - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; -} - -// second try to use intensification ... also not very effective -bool sls_engine::handle_plateau(goal_ref const & g, double old_score) -{ - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; -} - // main search loop -lbool sls_engine::search(goal_ref const & g) { +lbool sls_engine::search() { lbool res = l_undef; double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; + unsigned new_const = (unsigned)-1, new_bit; mpz new_value; move_type move; - unsigned plateau_cnt = 0; - score = rescore(g); - unsigned sz = g->size(); - - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl;); - -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - //if (m_stats.m_stopwatch.get_current_seconds() > 10.0) - //{printf("Got %f fps and size is %d with avg bw %f\n", m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds(), m_tracker.get_formula_size(), m_tracker.get_avg_bw(g)); exit(0);} + score = rescore(); + unsigned sz = m_assertions.size(); + while (check_restart(m_stats.m_moves)) { checkpoint(); m_stats.m_moves++; + if (m_stats.m_moves % m_restart_base == 0) + m_tracker.ucb_forget(m_assertions); -#if _UCT_FORGET_ - //if (m_stats.m_moves % sz == 0) - if (m_stats.m_moves % _UCT_FORGET_ == 0) - m_tracker.uct_forget(g); -#endif - -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - //ptr_vector & to_evaluate = m_tracker.get_unsat_constants_only(e); - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); + + ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) { res = l_true; goto bailout; } -#endif -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) + if (m_wp && m_tracker.get_random_uint(10) < m_wp) { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif + score = m_tracker.get_top_sum() / sz; + continue; } - continue; -#endif -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif old_score = score; new_const = (unsigned)-1; - move = MV_FLIP; - new_bit = 0; -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif + score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); -#if _VNS_MC_ > _VNS_REPICK_ -#if _VNS_MC_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); -#endif -#if _VNS_REPICK_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } + if (m_vns_mc && (new_const == static_cast(-1))) + score = find_best_move_mc(to_evaluate, score, new_const, new_value); + + /*if (m_vns_repick && (new_const == static_cast(-1))) + { + expr * q = m_tracker.get_new_unsat_assertion(m_assertions, e); + if (q) + { + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); } -#endif -#endif - -#if _VNS_MC_ < _VNS_REPICK_ -#if _VNS_REPICK_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } - } -#endif -#if _VNS_MC_ - if (new_const == static_cast(-1)) - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); -#endif -#endif - -#if (_VNS_MC_ == _VNS_REPICK_) && _VNS_MC_ && _VNS_REPICK_ - if (new_const == static_cast(-1)) { - if (m_tracker.get_random_uint(16) % 100 < _VNS_PERC_) - score = find_best_move_mc(g, to_evaluate, score, new_const, new_value); - else { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); - score = find_best_move(g, to_evaluate2, score, new_const, new_value, new_bit, move); - } - } - } -#endif - + }*/ if (new_const == static_cast(-1)) { score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); + if (m_walksat && m_walksat_repick) + m_evaluator.randomize_local(m_assertions); else -#endif -#if _REPICK_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _REPICK_ == 2 - { - expr * q = m_tracker.get_new_unsat_assertion(g, e); - if (q) - m_evaluator.randomize_local(q); - else - m_evaluator.randomize_local(e); - } -#else - m_evaluator.randomize_local_n(g, to_evaluate); - //m_evaluator.randomize_local(to_evaluate); -#endif -#endif + m_evaluator.randomize_local(to_evaluate); -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif + score = m_tracker.get_top_sum() / m_assertions.size(); -#if _PAWS_ - for (unsigned i = 0; i < sz; i++) + if (m_paws_sp < 1024) { - expr * q = g->form(i); - if (m_tracker.get_random_uint(16) % 100 < _PAWS_) + for (unsigned i = 0; i < sz; i++) { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) - m_tracker.decrease_weight(q); - } - else - { - if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) - m_tracker.increase_weight(q); + expr * q = m_assertions[i]; + if (m_tracker.get_random_uint(10) < m_paws_sp) + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) + m_tracker.decrease_weight(q); + } + else + { + if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) + m_tracker.increase_weight(q); + } } } -#endif - } else { func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - -bailout: - m_mpz_manager.del(new_value); - - return res; -} - -// main search loop -lbool sls_engine::search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl;); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true = false; - if (all_true) { - res = l_true; // sat - goto bailout; - } - else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl;); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl;); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl;); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl;); - } - - if (score >= 0.99999) { - // if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true = false; - if (all_true) { - res = l_true; // sat - goto bailout; - } - else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } - else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl;); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true = false; - if (all_true) { - res = l_true; // sat - goto bailout; - } - else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } + score = serious_score(fd, new_value); } } @@ -1321,80 +492,14 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { m_produce_models = g->models_enabled(); - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_PAWS_ " << _PAWS_ << std::endl; - verbose_stream() << "_PAWS_INIT_ " << _PAWS_INIT_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_VNS_MC_ " << _VNS_MC_ << std::endl; - verbose_stream() << "_VNS_MC_TRIES_ " << _VNS_MC_TRIES_ << std::endl; - verbose_stream() << "_VNS_REPICK_ " << _VNS_REPICK_ << std::endl; - verbose_stream() << "_VNS_PERC_ " << _VNS_PERC_ << std::endl; - verbose_stream() << "_INSIST_PERC_ " << _INSIST_PERC_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; - verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; + for (unsigned i = 0; i < g->size(); i++) + assert_expr(g->form(i)); + verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + lbool res = operator()(); if (res == l_true) { report_tactic_progress("Number of flips:", m_stats.m_moves); @@ -1416,33 +521,66 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { mc = 0; } -unsigned sls_engine::check_restart(unsigned curr_value) +lbool sls_engine::operator()() { + m_tracker.initialize(m_assertions); + lbool res = l_undef; + + do { + checkpoint(); + + report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); + res = search(); + + if (res == l_undef) + { + if (m_restart_init) + m_tracker.randomize(m_assertions); + else + m_tracker.reset(m_assertions); + } + } while (res != l_true && m_stats.m_restarts++ < m_max_restarts); + + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + + return res; +} + +/* Andreas: Needed for Armin's restart scheme if we don't want to use loops. +inline double sls_engine::get_restart_armin(unsigned cnt_restarts) { - if (curr_value > m_restart_limit) + unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); + unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; + return pow((double) _RESTART_CONST_ARMIN_, (int) inner_id + 1); +} +*/ + +inline unsigned sls_engine::check_restart(unsigned curr_value) +{ + if (curr_value > m_restart_next) { + /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save 1 parameter. + I leave the other versions as comments in case you want to try it again somewhen. #if _RESTART_SCHEME_ == 5 - m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); + m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); #elif _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); + m_restart_next += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? m_restart_base : (m_restart_base * m_stats.m_restarts + 1); #elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; + m_restart_next += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * m_restart_base; #elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; + m_restart_next += get_luby(m_stats.m_restarts + 1) * m_restart_base; #elif _RESTART_SCHEME_ == 1 if (m_stats.m_restarts & 1) - //if (m_stats.m_restarts % 3 == 2) - m_restart_limit += _RESTART_LIMIT_; + m_restart_next += m_restart_base; else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; - //m_restart_limit += (2 << (m_stats.m_restarts / 3)) * _RESTART_LIMIT_; + m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; #else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif + m_restart_limit += m_restart_base; +#endif */ + if (m_stats.m_restarts & 1) + m_restart_next += m_restart_base; + else + m_restart_next += (2 << (m_stats.m_restarts >> 1)) * m_restart_base; return 0; } return 1; -} \ No newline at end of file +} diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 902c6b7a0..ff0e55f24 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -22,6 +22,7 @@ Notes: #include"stopwatch.h" #include"lbool.h" #include"model_converter.h" +#include"goal.h" #include"sls_compilation_settings.h" #include"sls_tracker.h" @@ -35,17 +36,13 @@ public: stopwatch m_stopwatch; unsigned m_full_evals; unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; + unsigned m_moves, m_flips, m_incs, m_decs, m_invs; stats() : m_restarts(0), m_full_evals(0), m_incr_evals(0), m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), m_flips(0), m_incs(0), m_decs(0), @@ -71,14 +68,22 @@ protected: bv_util m_bv_util; sls_tracker m_tracker; sls_evaluator m_evaluator; + ptr_vector m_assertions; - unsigned m_restart_limit; unsigned m_max_restarts; - unsigned m_plateau_limit; + unsigned m_walksat; + unsigned m_walksat_repick; + unsigned m_wp; + unsigned m_vns_mc; + unsigned m_vns_repick; + unsigned m_paws_sp; + unsigned m_restart_base; + unsigned m_restart_next; + unsigned m_restart_init; ptr_vector m_old_values; - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; + typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; public: sls_engine(ast_manager & m, params_ref const & p); @@ -92,78 +97,46 @@ public: void updt_params(params_ref const & _p); + void assert_expr(expr * e) { m_assertions.push_back(e); } + stats const & get_stats(void) { return m_stats; } void reset_statistics(void) { m_stats.reset(); } - bool full_eval(goal_ref const & g, model & mdl); - + bool full_eval(model & mdl); void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result); - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result); - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result); void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented); void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented); void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted); - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); + void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped); - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_lsb(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - double find_best_move_mc(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value); - - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - - - - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i); - - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i); - - - lbool search(goal_ref const & g); + lbool search(void); + lbool operator()(); void operator()(goal_ref const & g, model_converter_ref & mc); protected: void checkpoint(); - lbool search_old(goal_ref const & g); - double get_restart_armin(unsigned cnt_restarts); - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, + bool what_if(func_decl * fd, const unsigned & fd_inx, const mpz & temp, double & best_score, unsigned & best_const, mpz & best_value); - bool what_if_new(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value); - double incremental_score_prune_new(goal_ref const & g, func_decl * fd, const mpz & new_value); + double top_score(); + double rescore(); + double serious_score(func_decl * fd, const mpz & new_value); + double incremental_score(func_decl * fd, const mpz & new_value); - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value); + double incremental_score_prune(func_decl * fd, const mpz & new_value); + double find_best_move(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); - double top_score(goal_ref const & g); - double rescore(goal_ref const & g); - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value); - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value); -#endif - - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move); + double find_best_move_mc(ptr_vector & to_evaluate, double score, + unsigned & best_const, mpz & best_value); void mk_random_move(ptr_vector & unsat_constants); - void mk_random_move(goal_ref const & g); - - bool handle_plateau(goal_ref const & g); - bool handle_plateau(goal_ref const & g, double old_score); + //inline double get_restart_armin(unsigned cnt_restarts); inline unsigned check_restart(unsigned curr_value); }; -#endif \ No newline at end of file +#endif diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 78f2cb79a..37bfa5a2d 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -81,11 +81,7 @@ public: case OP_AND: { m_mpz_manager.set(result, m_one); for (unsigned i = 0; i < n_args; i++) -#if _DIRTY_UP_ - if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) && !m_tracker.is_top_expr(args[i])) { -#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { -#endif m_mpz_manager.set(result, m_zero); break; } @@ -93,11 +89,7 @@ public: } case OP_OR: { for (unsigned i = 0; i < n_args; i++) -#if _DIRTY_UP_ - if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result) || m_tracker.is_top_expr(args[i])) { -#else if (m_mpz_manager.neq(m_tracker.get_value(args[i]), result)) { -#endif m_mpz_manager.set(result, m_one); break; } @@ -105,16 +97,9 @@ public: } case OP_NOT: { SASSERT(n_args == 1); -#if _DIRTY_UP_ - if (m_tracker.is_top_expr(args[0])) - m_mpz_manager.set(result, m_zero); - else - m_mpz_manager.set(result, (m_mpz_manager.is_zero(m_tracker.get_value(args[0]))) ? m_one : m_zero); -#else const mpz & child = m_tracker.get_value(args[0]); SASSERT(m_mpz_manager.is_one(child) || m_mpz_manager.is_zero(child)); m_mpz_manager.set(result, (m_mpz_manager.is_zero(child)) ? m_one : m_zero); -#endif break; } case OP_EQ: { @@ -545,9 +530,7 @@ public: expr_fast_mark1 visited; mpz new_value; -#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ double new_score; -#endif SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { @@ -559,8 +542,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); -#if _REAL_RS_ || _REAL_PBFS_ - //if (!m_tracker.has_uplinks(cur)) +#if _REAL_RS_ if (m_tracker.is_top_expr(cur)) { if (m_mpz_manager.eq(new_value,m_one)) @@ -570,25 +552,12 @@ public: } #endif + new_score = m_tracker.score(cur); + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif - m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); -#else -#if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif #endif if (m_tracker.has_uplinks(cur)) { @@ -617,9 +586,7 @@ public: expr_fast_mark1 visited; mpz new_value; -#if _EARLY_PRUNE_ || _CACHE_TOP_SCORE_ double new_score; -#endif SASSERT(cur_depth < m_traversal_stack.size()); while (cur_depth != static_cast(-1)) { @@ -630,25 +597,12 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); + new_score = m_tracker.score(cur); + if (m_tracker.is_top_expr(cur)) + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); + m_tracker.set_score(cur, new_score); #if _EARLY_PRUNE_ - new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif - m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); -#else -#if _CACHE_TOP_SCORE_ - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif #endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -684,11 +638,7 @@ public: m_traversal_stack[cur_depth].push_back(ep); if (cur_depth > max_depth) max_depth = cur_depth; } -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ run_serious_update(max_depth); -#else - run_update(max_depth); -#endif } void update(func_decl * fd, const mpz & new_value) { @@ -713,7 +663,6 @@ public: run_serious_update(cur_depth); } -#if _EARLY_PRUNE_ unsigned run_update_bool_prune(unsigned cur_depth) { expr_fast_mark1 visited; @@ -727,19 +676,15 @@ public: expr * cur = cur_depth_exprs[i]; new_score = m_tracker.score(cur); -#if _CACHE_TOP_SCORE_ - //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); -#endif + prune_score = m_tracker.get_score_prune(cur); m_tracker.set_score(cur, new_score); if ((new_score > prune_score) && (m_tracker.has_pos_occ(cur))) - //if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) pot_benefits = 1; if ((new_score <= prune_score) && (m_tracker.has_neg_occ(cur))) - //if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) pot_benefits = 1; if (m_tracker.has_uplinks(cur)) { @@ -754,9 +699,6 @@ public: } } } - else - { - } } cur_depth_exprs.reset(); @@ -770,15 +712,11 @@ public: for (unsigned i = 0; i < cur_size; i++) { expr * cur = cur_depth_exprs[i]; -#if _CACHE_TOP_SCORE_ new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#else - m_tracker.set_score(cur, m_tracker.score(cur)); -#endif + if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { @@ -859,161 +797,18 @@ public: } return run_update_bool_prune(cur_depth); } -#endif - - unsigned run_update_bool_prune_new(unsigned cur_depth) { - expr_fast_mark1 visited; - - double prune_score, new_score; - unsigned pot_benefits = 0; - SASSERT(cur_depth < m_traversal_stack_bool.size()); - - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - - for (unsigned i = 0; i < cur_depth_exprs.size(); i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - prune_score = m_tracker.get_score_prune(cur); - m_tracker.set_score(cur, new_score); - - if ((new_score >= prune_score) && (m_tracker.has_pos_occ(cur))) - pot_benefits = 1; - if ((new_score < prune_score) && (m_tracker.has_neg_occ(cur))) - pot_benefits = 1; - - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - else - { - } - } - - cur_depth_exprs.reset(); - cur_depth--; - - while (cur_depth != static_cast(-1)) { - ptr_vector & cur_depth_exprs = m_traversal_stack_bool[cur_depth]; - if (pot_benefits) - { - unsigned cur_size = cur_depth_exprs.size(); - for (unsigned i = 0; i < cur_size; i++) { - expr * cur = cur_depth_exprs[i]; - - new_score = m_tracker.score(cur); - //if (!m_tracker.has_uplinks(cur)) - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); - m_tracker.set_score(cur, new_score); - if (m_tracker.has_uplinks(cur)) { - ptr_vector & ups = m_tracker.get_uplinks(cur); - for (unsigned j = 0; j < ups.size(); j++) { - expr * next = ups[j]; - unsigned next_d = m_tracker.get_distance(next); - SASSERT(next_d < cur_depth); - if (!visited.is_marked(next)) { - m_traversal_stack_bool[next_d].push_back(next); - visited.mark(next); - } - } - } - } - } - cur_depth_exprs.reset(); - cur_depth--; - } - - return pot_benefits; - } - - unsigned update_prune_new(func_decl * fd, const mpz & new_value) { - m_tracker.set_value(fd, new_value); - expr * ep = m_tracker.get_entry_point(fd); - unsigned cur_depth = m_tracker.get_distance(ep); - - if (m_traversal_stack_bool.size() <= cur_depth) - m_traversal_stack_bool.resize(cur_depth+1); - if (m_traversal_stack.size() <= cur_depth) - m_traversal_stack.resize(cur_depth+1); - - if (m_manager.is_bool(ep)) - m_traversal_stack_bool[cur_depth].push_back(ep); - else - { - m_traversal_stack[cur_depth].push_back(ep); - run_update_prune(cur_depth); - } - return run_update_bool_prune_new(cur_depth); - } void randomize_local(ptr_vector & unsat_constants) { - // Randomize _all_ candidates: - - //// bool did_something = false; - //for (unsigned i = 0; i < unsat_constants.size(); i++) { - // func_decl * fd = unsat_constants[i]; - // mpz temp = m_tracker.get_random(fd->get_range()); - // // if (m_mpz_manager.neq(temp, m_tracker.get_value(fd))) { - // // did_something = true; - // // } - // update(fd, temp); - // m_mpz_manager.del(temp); - //} - // Randomize _one_ candidate: unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); func_decl * fd = unsat_constants[r]; -#if _PERC_CHANGE_ - sort * srt = fd->get_range(); - mpz temp; - - if (m_manager.is_bool(srt)) - m_mpz_manager.set(temp, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { - mpz temp2, mask; - unsigned bv_sz = m_bv_util.get_bv_size(srt); - m_mpz_manager.set(temp, m_tracker.get_value(fd)); - - for (unsigned bit = 0; bit < bv_sz; bit++) - if (m_tracker.get_random_uint(16) % 100 < _PERC_CHANGE_) - { - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(temp, mask, temp2); - m_mpz_manager.set(temp, temp2); - } - m_mpz_manager.del(mask); - m_mpz_manager.del(temp2); - } -#else mpz temp = m_tracker.get_random(fd->get_range()); -#endif -#if _REAL_RS_ || _REAL_PBFS_ || _PAWS_ serious_update(fd, temp); -#else - update(fd, temp); -#endif + m_mpz_manager.del(temp); - TRACE("sls", /*tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl;*/ - tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; + TRACE("sls", tout << "Randomization candidate: " << unsat_constants[r]->get_name() << std::endl; tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); @@ -1023,36 +818,9 @@ public: randomize_local(m_tracker.get_constants(e)); } - void randomize_local(goal_ref const & g, unsigned int flip) { - randomize_local(m_tracker.get_unsat_constants(g, flip)); + void randomize_local(ptr_vector const & as) { + randomize_local(m_tracker.get_unsat_constants(as)); } - - void randomize_local_n(goal_ref const & g, ptr_vector & unsat_constants) { - unsigned r = m_tracker.get_random_uint(16) % unsat_constants.size(); - func_decl * fd = unsat_constants[r]; - sort * srt = fd->get_range(); - unsigned bv_sz = m_manager.is_bool(srt) ? 1 : m_bv_util.get_bv_size(srt); - mpz max_val = m_tracker.get_random(srt); - update(fd, max_val); - double max_score = m_tracker.get_top_sum() / g->size(); - mpz temp_val; - double temp_score; - for (unsigned i = 1; i < 2; i++) - //for (unsigned i = 1; i < bv_sz; i++) - { - m_mpz_manager.set(temp_val, m_tracker.get_random(srt)); - update(fd, temp_val); - temp_score = m_tracker.get_top_sum() / g->size(); - if (temp_score > max_score) - { - m_mpz_manager.set(max_val, temp_val); - max_score = temp_score; - } - } - update(fd, max_val); - m_mpz_manager.del(temp_val); - m_mpz_manager.del(max_val); - } }; #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 0b6b01e7c..6e1102dd2 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -1507,16 +1507,12 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { using_params(mk_simplify_tactic(m), simp2_p)), using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m), - // Andreas: It would be cool to get rid of shared top level assertions but which simplification is doing this? - //mk_ctx_simplify_tactic(m, ctx_p), - // Andreas: This one at least eliminates top level duplicates ... but has very bad effects on performance! - //mk_simplify_tactic(m), mk_nnf_tactic(m, p)); } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); -// tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); + //tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 87c90f1f8..65011dc8d 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,7 +20,9 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ -#include"goal.h" +#include"for_each_expr.h" +#include"ast_smt2_pp.h" +#include"bv_decl_plugin.h" #include"model.h" #include"sls_compilation_settings.h" @@ -37,11 +39,7 @@ class sls_tracker { mpz m_zero, m_one, m_two; struct value_score { -#if _EARLY_PRUNE_ value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; -#else - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1) { }; -#endif ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; @@ -78,24 +76,22 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; -#if _UCT_ + + unsigned m_walksat; + unsigned m_ucb; + double m_ucb_constant; + unsigned m_ucb_init; + double m_ucb_forget; unsigned m_touched; -#endif -#if _REAL_RS_ || _REAL_PBFS_ + double m_scale_unsat; + unsigned m_paws_init; +#if _REAL_RS_ ptr_vector m_unsat_expr; obj_map m_where_false; expr** m_list_false; #endif -#if _PAWS_ obj_map m_weights; - //obj_map m_weights; -#endif -#if _CACHE_TOP_SCORE_ double m_top_sum; -#endif -#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ - double m_weight_dist_factor; -#endif unsigned m_equal_scores; public: @@ -116,6 +112,17 @@ public: m_mpz_manager.del(m_two); } + void updt_params(params_ref const & _p) { + sls_params p(_p); + m_walksat = p.walksat(); + m_ucb = p.walksat_ucb(); + m_ucb_constant = p.walksat_ucb_constant(); + m_ucb_init = p.walksat_ucb_init(); + m_ucb_forget = p.walksat_ucb_forget(); + m_scale_unsat = p.scale_unsat(); + m_paws_init = p.paws_init(); + } + unsigned get_formula_size() { return m_scores.size(); } @@ -141,12 +148,6 @@ public: return sum / count; } -#if _WEIGHT_DIST_ == 4 || _WEIGHT_TOGGLE_ - inline void set_weight_dist_factor(double val) { - m_weight_dist_factor = val; - } -#endif - void reset_equal_scores() { m_equal_scores = 1; } @@ -155,13 +156,8 @@ public: return ++m_equal_scores; } -#if _CACHE_TOP_SCORE_ inline void adapt_top_sum(expr * e, double add, double sub) { -#if _PAWS_ m_top_sum += m_weights.find(e) * (add - sub); -#else - m_top_sum += add - sub; -#endif } inline void set_top_sum(double new_score) { @@ -171,7 +167,6 @@ public: inline double get_top_sum() { return m_top_sum; } -#endif inline void set_value(expr * n, const mpz & r) { SASSERT(m_scores.contains(n)); @@ -217,7 +212,6 @@ public: return get_score(ep); } -#if _EARLY_PRUNE_ inline void set_score_prune(expr * n, double score) { SASSERT(m_scores.contains(n)); m_scores.find(n).score_prune = score; @@ -237,7 +231,6 @@ public: SASSERT(m_scores.contains(n)); return m_scores.find(n).has_neg_occ; } -#endif inline unsigned get_distance(expr * n) { SASSERT(m_scores.contains(n)); @@ -271,7 +264,7 @@ public: return m_uplinks.find(n); } -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ void debug_real(goal_ref const & g, unsigned flip) { unsigned count = 0; @@ -318,21 +311,22 @@ public: } #endif -#if _UCT_ - void uct_forget(goal_ref const & g) { - expr * e; - unsigned touched_old, touched_new; - - for (unsigned i = 0; i < g->size(); i++) + inline void ucb_forget(ptr_vector & as) { + if (m_ucb_forget < 1.0) { - e = g->form(i); - touched_old = m_scores.find(e).touched; - touched_new = (unsigned)((touched_old - 1) * _UCT_FORGET_FACTOR_ + 1); - m_scores.find(e).touched = touched_new; - m_touched += touched_new - touched_old; + expr * e; + unsigned touched_old, touched_new; + + for (unsigned i = 0; i < as.size(); i++) + { + e = as[i]; + touched_old = m_scores.find(e).touched; + touched_new = (unsigned)((touched_old - 1) * m_ucb_forget + 1); + m_scores.find(e).touched = touched_new; + m_touched += touched_new - touched_old; + } } } -#endif void initialize(app * n) { // Build score table @@ -409,12 +403,12 @@ public: } }; - void calculate_expr_distances(goal_ref const & g) { + void calculate_expr_distances(ptr_vector const & as) { // precondition: m_scores is set up. - unsigned sz = g->size(); + unsigned sz = as.size(); ptr_vector stack; for (unsigned i = 0; i < sz; i++) - stack.push_back(to_app(g->form(i))); + stack.push_back(to_app(as[i])); while (!stack.empty()) { app * cur = stack.back(); stack.pop_back(); @@ -462,31 +456,24 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - void initialize(goal_ref const & g) { + void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); expr_mark visited; - unsigned sz = g->size(); + unsigned sz = as.size(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); else printf("this is already in ...\n"); - // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 - initialize_recursive(proc, visited, e); -#endif for_each_expr(proc, visited, e); } visited.reset(); for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // Andreas: Maybe not fully correct. -#if _FOCUS_ == 2 || _INTENSIFICATION_ - initialize_recursive(e); -#endif ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -494,11 +481,11 @@ public: quick_for_each_expr(ffd_proc, visited, e); } - calculate_expr_distances(g); + calculate_expr_distances(as); TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ m_list_false = new expr*[sz]; //for (unsigned i = 0; i < sz; i++) //{ @@ -507,50 +494,38 @@ public: //} #endif -#if _PAWS_ for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; if (!m_weights.contains(e)) - m_weights.insert(e, _PAWS_INIT_); + m_weights.insert(e, m_paws_init); } -#endif #if _EARLY_PRUNE_ for (unsigned i = 0; i < sz; i++) - setup_occs(g->form(i)); + setup_occs(as[i]); #endif -#if _UCT_ - m_touched = _UCT_INIT_ ? g->size() : 1; -#endif + m_touched = m_ucb_init ? as.size() : 1; } -#if _PAWS_ void increase_weight(expr * e) { - //printf("Increasing %d to", m_weights.find(e)); m_weights.find(e)++; - //m_weights.find(e) *= 1.1; - //printf(" %d\n", m_weights.find(e)); } void decrease_weight(expr * e) { unsigned old_weight = m_weights.find(e); - m_weights.find(e) = old_weight > _PAWS_INIT_ ? old_weight - 1 : _PAWS_INIT_; - //m_weights.find(e) = old_weight > 1.1 ? old_weight / 1.1 : 1; - //printf("Decreasing %d to %d\n", old_weight, m_weights.find(e)); + m_weights.find(e) = old_weight > m_paws_init ? old_weight - 1 : m_paws_init; } unsigned get_weight(expr * e) - //double get_weight(expr * e) { return m_weights.find(e); } -#endif -#if _REAL_RS_ || _REAL_PBFS_ +#if _REAL_RS_ void make_assertion(expr * e) { if (m_where_false.contains(e)) @@ -683,7 +658,7 @@ public: NOT_IMPLEMENTED_YET(); // This only works for bit-vectors for now. } - void randomize(goal_ref const & g) { + void randomize(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -695,15 +670,9 @@ public: } TRACE("sls", tout << "Randomized model:" << std::endl; show_model(tout); ); - -#if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; -#endif } - void reset(goal_ref const & g) { + void reset(ptr_vector const & as) { TRACE("sls", tout << "Abandoned model:" << std::endl; show_model(tout); ); for (entry_point_type::iterator it = m_entry_points.begin(); it != m_entry_points.end(); it++) { @@ -711,15 +680,8 @@ public: set_value(it->m_value, temp); m_mpz_manager.del(temp); } - -#if _UCT_RESET_ - m_touched = _UCT_INIT_ ? g->size() : 1; - for (unsigned i = 0; i < g->size(); i++) - m_scores.find(g->form(i)).touched = 1; -#endif } -#if _EARLY_PRUNE_ void setup_occs(expr * n, bool negated = false) { if (m_manager.is_bool(n)) { @@ -752,7 +714,6 @@ public: else NOT_IMPLEMENTED_YET(); } -#endif double score_bool(expr * n, bool negated = false) { TRACE("sls_score", tout << ((negated)?"NEG ":"") << "BOOL: " << mk_ismt2_pp(n, m_manager) << std::endl; ); @@ -770,57 +731,29 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it does not even occur. -#if _SCORE_AND_AVG_ + /* Andreas: Seems to have no effect. But maybe you want to try it again at some point. double sum = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) -#if _DIRTY_UP_ - sum += is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else sum += get_score(args[i]); -#endif - res = sum / (double) a->get_num_args(); -#else + res = sum / (double) a->get_num_args(); */ double min = 1.0; for (unsigned i = 0; i < a->get_num_args(); i++) { -#if _DIRTY_UP_ - double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else double cur = get_score(args[i]); -#endif if (cur < min) min = cur; } res = min; -#endif } else if (m_manager.is_or(n)) { SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); // Andreas: Seems to have no effect. Probably it is still too similar to the original version. -#if _SCORE_OR_MUL_ - double inv = 1.0; - for (unsigned i = 0; i < a->get_num_args(); i++) { -#if _DIRTY_UP_ - double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else - double cur = get_score(args[i]); -#endif - inv *= (1.0 - get_score(args[i])); - } - res = 1.0 - inv; -#else double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { -#if _DIRTY_UP_ - double cur = is_top_expr(args[i]) ? 1.0 : get_score(args[i]); -#else double cur = get_score(args[i]); -#endif if (cur > max) max = cur; } res = max; -#endif } else if (m_manager.is_ite(n)) { SASSERT(!negated); @@ -855,24 +788,14 @@ public: m_mpz_manager.bitwise_xor(v0, v1, diff); unsigned hamming_distance = 0; unsigned bv_sz = m_bv_util.get_bv_size(arg0); - #if 1 // unweighted hamming distance + // unweighted hamming distance while (!m_mpz_manager.is_zero(diff)) { - //m_mpz_manager.set(diff_m1, diff); - //m_mpz_manager.dec(diff_m1); - //m_mpz_manager.bitwise_and(diff, diff_m1, diff); - //hamming_distance++; if (!m_mpz_manager.is_even(diff)) { hamming_distance++; } m_mpz_manager.machine_div(diff, m_two, diff); } res = 1.0 - (hamming_distance / (double) bv_sz); - #else - rational r(diff); - r /= m_powers(bv_sz); - double dbl = r.get_double(); - res = (dbl < 0.0) ? 1.0 : (dbl > 1.0) ? 0.0 : 1.0 - dbl; - #endif TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << " ; HD = " << hamming_distance << " ; SZ = " << bv_sz << std::endl; ); @@ -891,205 +814,36 @@ public: if (negated) { if (m_mpz_manager.gt(x, y)) - { - /*mpz diff; - m_mpz_manager.sub(x, y, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -/* mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_gt = 0; - unsigned curr_gt = 0; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 1; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 0; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); - m_mpz_manager.del(x_copy); - m_mpz_manager.del(y_copy);*/ -#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = 1.0 - n.get_double(); + double dbl = n.get_double(); // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; - //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } } else { if (m_mpz_manager.le(x, y)) - { - /*mpz diff; - m_mpz_manager.sub(y, x, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -/* mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_le = 1; - unsigned curr_le = 1; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_le = curr_le; - curr_le = 0; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_le = curr_le; - curr_le = 1; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2);*/ -#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); rational n(diff); n /= rational(m_powers(bv_sz)); - double dbl = 1.0 - n.get_double(); - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + double dbl = n.get_double(); + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } -/* else if (m_bv_util.is_bv_sle(n)) { // x <= y - app * a = to_app(n); - SASSERT(a->get_num_args() == 2); - const mpz & x = get_value(a->get_arg(0)); - const mpz & y = get_value(a->get_arg(1)); - int bv_sz = m_bv_util.get_bv_size(a->get_decl()->get_domain()[0]); - - mpz x_unsigned; - mpz y_unsigned; - const mpz & p = m_powers(bv_sz); - const mpz & p_half = m_powers(bv_sz-1); - if (x >= p_half) { m_mpz_manager.sub(x, p, x_unsigned); } - if (y >= p_half) { m_mpz_manager.sub(y, p, y_unsigned); } - - if (negated) { - if (x_unsigned > y_unsigned) - res = 1.0; - else { - mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_gt = 0; - unsigned curr_gt = 0; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 1; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_gt = curr_gt; - curr_gt = 0; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_gt) / (double)(bv_sz + 2); - m_mpz_manager.del(x_copy); - m_mpz_manager.del(y_copy); - } - } - else { - if (x_unsigned <= y_unsigned) - res = 1.0; - else { - mpz x_copy, y_copy; - m_mpz_manager.set(x_copy, x); - m_mpz_manager.set(y_copy, y); - unsigned lower_le = 1; - unsigned curr_le = 1; - int last_pos = -1; - for (int i = 0; i < bv_sz; i++) - { - if (m_mpz_manager.is_odd(x_copy) && m_mpz_manager.is_even(y_copy)) - { - lower_le = curr_le; - curr_le = 0; - last_pos = i; - } - else if (m_mpz_manager.is_even(x_copy) && m_mpz_manager.is_odd(y_copy)) - { - lower_le = curr_le; - curr_le = 1; - last_pos = i; - } - - m_mpz_manager.machine_div(x_copy, m_two, x_copy); - m_mpz_manager.machine_div(y_copy, m_two, y_copy); - } - - res = (double)(bv_sz - last_pos - 1 + 2 * lower_le) / (double)(bv_sz + 2); - } - } - TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << - m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); - - m_mpz_manager.del(x_unsigned); - m_mpz_manager.del(y_unsigned); - }*/ - else if (m_bv_util.is_bv_sle(n)) { // x <= y + else if (m_bv_util.is_bv_sle(n)) { // x <= y app * a = to_app(n); SASSERT(a->get_num_args() == 2); mpz x; m_mpz_manager.set(x, get_value(a->get_arg(0))); @@ -1102,61 +856,32 @@ public: if (negated) { if (x > y) - { - /*mpz diff; - m_mpz_manager.sub(x, y, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -#if 1 mpz diff; m_mpz_manager.sub(y, x, diff); m_mpz_manager.inc(diff); rational n(diff); n /= p; - double dbl = 1.0 - n.get_double(); - //res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + double dbl = n.get_double(); + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); } else { if (x <= y) - { - /*mpz diff; - m_mpz_manager.sub(y, x, diff); - m_mpz_manager.inc(diff); - rational n(diff); - n /= rational(m_powers(bv_sz)); - double dbl = n.get_double(); - // In extreme cases, n is 0.9999 but to_double returns something > 1.0 - m_mpz_manager.del(diff); - res = 1.0 + 0.5 * dbl;*/ res = 1.0; - } else { - //res = (bv_sz - 1.0) / bv_sz; -#if 1 mpz diff; m_mpz_manager.sub(x, y, diff); SASSERT(!m_mpz_manager.is_neg(diff)); rational n(diff); n /= p; - double dbl = 1.0 - n.get_double(); - res = (dbl > 1.0) ? 1.0 : (dbl < 0.0) ? 0.0 : dbl; + double dbl = n.get_double(); + res = (dbl > 1.0) ? 0.0 : (dbl < 0.0) ? 1.0 : 1.0 - dbl; m_mpz_manager.del(diff); -#endif } TRACE("sls_score", tout << "x = " << m_mpz_manager.to_string(x) << " ; y = " << m_mpz_manager.to_string(y) << " ; SZ = " << bv_sz << std::endl; ); @@ -1171,11 +896,7 @@ public: expr * child = a->get_arg(0); if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. NOT_IMPLEMENTED_YET(); -#if _DIRTY_UP_ - res = is_top_expr(child) ? 0.0 : score_bool(child, true); -#else res = score_bool(child, true); -#endif } else if (m_manager.is_distinct(n)) { app * a = to_app(n); @@ -1199,25 +920,11 @@ public: SASSERT(res >= 0.0 && res <= 1.0); -#if _WEIGHT_DIST_ app * a = to_app(n); family_id afid = a->get_family_id(); if (afid == m_bv_util.get_family_id()) -#endif -#if _WEIGHT_DIST_ == 1 -#if _WEIGHT_TOGGLE_ - if (res < 1.0) res *= m_weight_dist_factor; -#else - if (res < 1.0) res *= _WEIGHT_DIST_FACTOR_; -#endif -#elif _WEIGHT_DIST_ == 2 - res *= res; -#elif _WEIGHT_DIST_ == 3 - if (res < 1.0) res = 0.0; -#elif _WEIGHT_DIST_ == 4 - if (res < 1.0) res *= m_weight_dist_factor; -#endif + if (res < 1.0) res *= m_scale_unsat; TRACE("sls_score", tout << "SCORE = " << res << std::endl; ); return res; @@ -1268,33 +975,6 @@ public: NOT_IMPLEMENTED_YET(); } - expr * get_unsat_expression(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e) || m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return get_unsat_expression(q); - } - } - } - return e; - } - ptr_vector & get_constants(expr * e) { ptr_vector const & this_decls = m_constants_occ.find(e); unsigned sz = this_decls.size(); @@ -1306,13 +986,17 @@ public: return m_temp_constants; } - ptr_vector & get_unsat_constants_gsat(goal_ref const & g, unsigned sz) { - if (sz == 1) - return get_constants(); + ptr_vector & get_unsat_constants_gsat(ptr_vector const & as) { + unsigned sz = as.size(); + if (sz == 1) { + if (m_mpz_manager.neq(get_value(as[0]), m_one)) + return get_constants(); + } + m_temp_constants.reset(); for (unsigned i = 0; i < sz; i++) { - expr * q = g->form(i); + expr * q = as[i]; if (m_mpz_manager.eq(get_value(q), m_one)) continue; ptr_vector const & this_decls = m_constants_occ.find(q); @@ -1326,35 +1010,6 @@ public: return m_temp_constants; } - expr * get_unsat_assertion(goal_ref const & g, unsigned sz, unsigned int pos) { - for (unsigned i = pos; i < sz; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - for (unsigned i = 0; i < pos; i++) { - expr * q = g->form(i); - if (m_mpz_manager.neq(get_value(q), m_one)) - return q; - } - return 0; - } - - ptr_vector & get_unsat_constants_walksat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); - // Andreas: I should probably fix this. If this is the case then the formula is SAT anyway but this is not checked in the first iteration. - if (!q) - return m_temp_constants; - ptr_vector const & this_decls = m_constants_occ.find(q); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - return m_temp_constants; - } - ptr_vector & get_unsat_constants_walksat(expr * e) { if (!e || m_temp_constants.size()) return m_temp_constants; @@ -1368,420 +1023,89 @@ public: return m_temp_constants; } - ptr_vector & go_deeper(expr * e) { - if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - // Andreas: might be used for guided branching - //for (unsigned i = 0; i < a->get_num_args(); i++) { - //double cur = get_score(args[i]); - //} - // Andreas: A random number is better here since reusing flip will cause patterns. - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned int pos = get_random_uint(16) % sz; - for (unsigned int i = pos; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - for (unsigned int i = 0; i < pos; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one)) - return go_deeper(q); - } - } - } - ptr_vector const & this_decls = m_constants_occ.find(e); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - return m_temp_constants; - } + ptr_vector & get_unsat_constants(ptr_vector const & as) { + if (m_walksat) + { + expr * e = get_unsat_assertion(as); - ptr_vector & get_unsat_constants_crsat(goal_ref const & g, unsigned sz, unsigned int pos) { - expr * q = get_unsat_assertion(g, sz, pos); - if (!q) - return m_temp_constants; - - return go_deeper(q); - } - - void go_deeper_only(expr * e) { - //if (m_manager.is_bool(e)) { - if (m_manager.is_and(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - unsigned cnt_unsat = 0, pos = -1; - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - if (m_mpz_manager.neq(get_value(q), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - //if (m_mpz_manager.neq(get_value(q), m_one)) go_deeper(q); - } - go_deeper(args[pos]); - } - else if (m_manager.is_or(e)) { - app * a = to_app(e); - expr * const * args = a->get_args(); - unsigned int sz = a->get_num_args(); - for (unsigned int i = 0; i < sz; i++) { - expr * q = args[i]; - go_deeper(q); - } - } - //} - else - { - ptr_vector const & this_decls = m_constants_occ.find(e); - unsigned sz2 = this_decls.size(); - for (unsigned j = 0; j < sz2; j++) { - func_decl * fd = this_decls[j]; - if (!m_temp_constants.contains(fd)) - m_temp_constants.push_back(fd); - } - } - } - - ptr_vector & get_unsat_constants_only(expr * e) { - if (e && !m_temp_constants.size()) - go_deeper_only(e); - - return m_temp_constants; - } - - ptr_vector & get_unsat_constants(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); - - if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_one)) + if (!e) { m_temp_constants.reset(); return m_temp_constants; } - else - return get_constants(); - } - else { - m_temp_constants.reset(); -#if _FOCUS_ == 1 -#if _UCT_ - unsigned pos = -1; - value_score vscore; -#if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - for (unsigned i = start_index; i < sz; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); - -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } -#else - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); -// for (unsigned i = 0; i < m_where_false.size(); i++) { -// expr * e = m_list_false[i]; - vscore = m_scores.find(e); -#if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched)/vscore.touched); -#elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; -#elif _UCT_ == 3 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); -#endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } - } -#endif - if (pos == static_cast(-1)) - return m_temp_constants; - -#if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; - m_touched++; -#elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; -#endif - expr * e = g->form(pos); -// expr * e = m_list_false[pos]; - -#elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } - } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); -#elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } - } - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); -#elif _BFS_ == 1 - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; - expr * e = get_unsat_assertion(g, sz, pos); -#elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return m_temp_constants; - expr * e = g->form(pos); -#elif _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - expr * e = m_list_false[get_random_uint(16) % sz]; -#elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return m_temp_constants; - else - expr * e = m_list_false[flip % sz]; -#else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; - expr * e = get_unsat_assertion(g, sz, pos); -#endif return get_unsat_constants_walksat(e); -#elif _FOCUS_ == 2 -#if _BFS_ - // I guess it was buggy ... - // unsigned int pos = flip % m_constants.size(); - unsigned int pos = flip % sz; -#else - // I guess it was buggy ... - // unsigned int pos = get_random_uint(16) % m_constants.size(); - unsigned int pos = get_random_uint(16) % sz; -#endif - return get_unsat_constants_crsat(g, sz, pos); -#else - return get_unsat_constants_gsat(g, sz); -#endif } + else + return get_unsat_constants_gsat(as); } - expr * get_unsat_assertion(goal_ref const & g, unsigned int flip) { - unsigned sz = g->size(); - + expr * get_unsat_assertion(ptr_vector const & as) { + unsigned sz = as.size(); if (sz == 1) { - if (m_mpz_manager.eq(get_value(g->form(0)), m_zero)) - return g->form(0); + if (m_mpz_manager.neq(get_value(as[0]), m_one)) + return as[0]; else return 0; } - m_temp_constants.reset(); -#if _FOCUS_ == 1 -#if _UCT_ + unsigned pos = -1; - value_score vscore; -#if _PROBABILISTIC_UCT_ - double sum_score = 0.0; - unsigned start_index = get_random_uint(16) % sz; - - for (unsigned i = start_index; i < sz; i++) + if (m_ucb) { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score + _UCT_EPS_; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } - for (unsigned i = 0; i < start_index; i++) - { - expr * e = g->form(i); - vscore = m_scores.find(e); -#if _PROBABILISTIC_UCT_ == 2 - double q = vscore.score * vscore.score + _UCT_EPS_; -#else - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + _UCT_EPS_; -#endif - if (m_mpz_manager.neq(get_value(g->form(i)), m_one)) { - sum_score += q; - if (rand() <= (q * RAND_MAX / sum_score) + 1) - pos = i; - } - } -#else - double max = -1.0; + value_score vscore; + double max = -1.0; for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); + expr * e = as[i]; // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); -#if _UCT_ == 1 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log((double)m_touched) / vscore.touched); -#elif _UCT_ == 2 - double q = vscore.score + (_UCT_CONSTANT_ * (flip - vscore.touched)) / sz; -#elif _UCT_ == 3 + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); +#if _UCT_ == 3 double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); #endif - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } -#endif - if (pos == static_cast(-1)) - return 0; + if (pos == static_cast(-1)) + return 0; -#if _UCT_ == 1 || _UCT_ == 3 - m_scores.find(g->form(pos)).touched++; - m_touched++; -#elif _UCT_ == 2 - m_scores.find(g->form(pos)).touched = flip; -#endif + m_scores.find(as[pos]).touched++; + m_touched++; // return m_list_false[pos]; - return g->form(pos); - -#elif _BFS_ == 3 - unsigned int pos = -1; - double max = -1.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } - if (pos == static_cast(-1)) - return 0; - return g->form(pos); -#elif _BFS_ == 2 - unsigned int pos = -1; - double min = 2.0; - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - double q = get_score(e); - if (q < min && m_mpz_manager.neq(get_value(e), m_one) ) { min = q; pos = i; } } - if (pos == static_cast(-1)) - return 0; - return g->form(pos); -#elif _BFS_ == 1 - unsigned int pos = flip % sz; - return get_unsat_assertion(g, sz, pos); -#elif _UNIFORM_RANDOM_ - unsigned cnt_unsat = 0, pos = -1; - for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; - if (pos == static_cast(-1)) - return 0; - return g->form(pos); -#elif _REAL_RS_ + else + { + unsigned cnt_unsat = 0; + for (unsigned i = 0; i < sz; i++) + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; + if (pos == static_cast(-1)) + return 0; + } + + return as[pos]; +#if _REAL_RS_ //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; sz = m_where_false.size(); if (sz == 0) return 0; return m_list_false[get_random_uint(16) % sz]; -#elif _REAL_PBFS_ - //unsigned pos = m_false_list[flip % m_cnt_false]; - //expr * e = get_unsat_assertion(g, sz, pos); - //expr * e = m_unsat_expr[flip % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return0; - else - return m_list_false[flip % sz]; -#else - unsigned int pos = get_random_uint(16) % sz; - return get_unsat_assertion(g, sz, pos); -#endif - return g->form(pos); -#elif _FOCUS_ == 2 -#if _BFS_ - unsigned int pos = flip % sz; -#else - unsigned int pos = get_random_uint(16) % sz; -#endif - return get_unsat_constants_crsat(g, sz, pos); #endif } - expr * get_new_unsat_assertion(goal_ref const & g, expr * e) { - unsigned sz = g->size(); - + expr * get_new_unsat_assertion(ptr_vector const & as, expr * e) { + unsigned sz = as.size(); if (sz == 1) return 0; - m_temp_constants.reset(); - + unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(g->form(i)), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (g->form(i) != e)) pos = i; + if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (as[i] != e)) pos = i; if (pos == static_cast(-1)) return 0; - return g->form(pos); + return as[pos]; } }; From fb18547a5f12be7db71b04aea7198df2c5dcfad7 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 01:07:30 +0100 Subject: [PATCH 198/507] Fixed bug with VNS repick. --- src/tactic/sls/sls_compilation_settings.h | 2 +- src/tactic/sls/sls_engine.cpp | 22 +++++++++++++++++----- src/tactic/sls/sls_tracker.h | 7 ++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 9add78daa..a649bc9ed 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -23,7 +23,7 @@ Notes: #define _SLS_COMPILATION_SETTINGS_H_ // shall we use addition/subtraction? -#define _USE_ADDSUB_ 0 +#define _USE_ADDSUB_ 1 // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index c240a0c51..af8ae1df2 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -68,6 +68,12 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_base = p.restart_base(); m_restart_next = m_restart_base; m_restart_init = p.restart_init(); + + // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. + if (m_walksat_repick && !m_walksat) + NOT_IMPLEMENTED_YET(); + if (m_vns_repick && !m_walksat) + NOT_IMPLEMENTED_YET(); } void sls_engine::checkpoint() { @@ -435,19 +441,25 @@ lbool sls_engine::search() { if (m_vns_mc && (new_const == static_cast(-1))) score = find_best_move_mc(to_evaluate, score, new_const, new_value); - /*if (m_vns_repick && (new_const == static_cast(-1))) + if (m_vns_repick && (new_const == static_cast(-1))) { - expr * q = m_tracker.get_new_unsat_assertion(m_assertions, e); + expr * q = m_tracker.get_new_unsat_assertion(m_assertions); if (q) { - ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(e); + ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); score = find_best_move(to_evaluate2, score, new_const, new_value, new_bit, move); + + if (new_const != static_cast(-1)) { + func_decl * fd = to_evaluate2[new_const]; + score = serious_score(fd, new_value); + continue; + } } - }*/ + } if (new_const == static_cast(-1)) { score = old_score; - if (m_walksat && m_walksat_repick) + if (m_walksat_repick) m_evaluator.randomize_local(m_assertions); else m_evaluator.randomize_local(to_evaluate); diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 65011dc8d..7b48057d4 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -76,7 +76,7 @@ private: ptr_vector m_constants; ptr_vector m_temp_constants; occ_type m_constants_occ; - + unsigned m_last_pos; unsigned m_walksat; unsigned m_ucb; double m_ucb_constant; @@ -1082,6 +1082,7 @@ public: return 0; } + m_last_pos = pos; return as[pos]; #if _REAL_RS_ //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; @@ -1093,7 +1094,7 @@ public: #endif } - expr * get_new_unsat_assertion(ptr_vector const & as, expr * e) { + expr * get_new_unsat_assertion(ptr_vector const & as) { unsigned sz = as.size(); if (sz == 1) return 0; @@ -1101,7 +1102,7 @@ public: unsigned cnt_unsat = 0, pos = -1; for (unsigned i = 0; i < sz; i++) - if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0) && (as[i] != e)) pos = i; + if ((i != m_last_pos) && m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; if (pos == static_cast(-1)) return 0; From ca1e3c3d9fe5974fbd2f358a40b6319250131ef2 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Tue, 22 Apr 2014 16:10:44 +0100 Subject: [PATCH 199/507] Backup before I touch early pruning ... --- src/tactic/sls/sls_compilation_settings.h | 3 --- src/tactic/sls/sls_engine.cpp | 30 +++++++++++++---------- src/tactic/sls/sls_engine.h | 1 + src/tactic/sls/sls_evaluator.h | 4 +-- src/tactic/sls/sls_tracker.h | 9 ------- 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index a649bc9ed..5c837b4b2 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,9 +22,6 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - // should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? #define _REAL_RS_ 0 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index af8ae1df2..5d4df237e 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -61,6 +61,7 @@ void sls_engine::updt_params(params_ref const & _p) { m_walksat = p.walksat(); m_walksat_repick = p.walksat_repick(); m_paws_sp = p.paws_sp(); + m_paws = m_paws_sp < 1024; m_wp = p.wp(); m_vns_mc = p.vns_mc(); m_vns_repick = p.vns_repick(); @@ -173,7 +174,6 @@ bool sls_engine::what_if( // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { - m_tracker.reset_equal_scores(); best_score = r; best_const = fd_inx; m_mpz_manager.set(best_value, temp); @@ -244,16 +244,12 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); else { -#if _USE_ADDSUB_ if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; move_type mt = (move_type)rnd_mv; // inversion doesn't make sense, let's do a flip instead. if (mt == MV_INV) mt = MV_FLIP; -#else - move_type mt = MV_FLIP; -#endif unsigned bit = 0; switch (mt) @@ -308,8 +304,9 @@ double sls_engine::find_best_move( unsigned bv_sz; double new_score = score; - m_tracker.reset_equal_scores(); - + //unsigned offset = m_tracker.get_random_uint(16) % to_evaluate.size(); + //for (unsigned j = 0; j < to_evaluate.size(); j++) { + //unsigned i = (j + offset) % to_evaluate.size(); for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); @@ -328,7 +325,6 @@ double sls_engine::find_best_move( } if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ if (!m_mpz_manager.is_even(old_value)) { // for odd values, try +1 mk_inc(bv_sz, old_value, temp); @@ -341,7 +337,6 @@ double sls_engine::find_best_move( if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_DEC; } -#endif // try inverting mk_inv(bv_sz, old_value, temp); if (what_if(fd, i, temp, new_score, best_const, best_value)) @@ -418,7 +413,7 @@ lbool sls_engine::search() { #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); #endif - + // get candidate variables ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) { @@ -426,6 +421,7 @@ lbool sls_engine::search() { goto bailout; } + // random walk with probability wp / 1024 if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); @@ -436,14 +432,18 @@ lbool sls_engine::search() { old_score = score; new_const = (unsigned)-1; + // find best increasing move score = find_best_move(to_evaluate, score, new_const, new_value, new_bit, move); + // use Monte Carlo 2-bit-flip sampling if no increasing move was found previously if (m_vns_mc && (new_const == static_cast(-1))) score = find_best_move_mc(to_evaluate, score, new_const, new_value); + // repick assertion if no increasing move was found previously if (m_vns_repick && (new_const == static_cast(-1))) { expr * q = m_tracker.get_new_unsat_assertion(m_assertions); + // only apply if another unsatisfied assertion actually exists if (q) { ptr_vector & to_evaluate2 = m_tracker.get_unsat_constants_walksat(q); @@ -457,6 +457,7 @@ lbool sls_engine::search() { } } + // randomize if no increasing move was found if (new_const == static_cast(-1)) { score = old_score; if (m_walksat_repick) @@ -466,16 +467,19 @@ lbool sls_engine::search() { score = m_tracker.get_top_sum() / m_assertions.size(); - if (m_paws_sp < 1024) + // update assertion weights if a weigthing is enabled (sp < 1024) + if (m_paws) { for (unsigned i = 0; i < sz; i++) { expr * q = m_assertions[i]; + // smooth weights with probability sp / 1024 if (m_tracker.get_random_uint(10) < m_paws_sp) { if (m_mpz_manager.eq(m_tracker.get_value(q),m_one)) m_tracker.decrease_weight(q); } + // increase weights otherwise else { if (m_mpz_manager.eq(m_tracker.get_value(q),m_zero)) @@ -484,6 +488,7 @@ lbool sls_engine::search() { } } } + // otherwise, apply most increasing move else { func_decl * fd = to_evaluate[new_const]; score = serious_score(fd, new_value); @@ -507,7 +512,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; @@ -570,7 +574,7 @@ inline unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_next) { - /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save 1 parameter. + /* Andreas: My own scheme (= 1) seems to work best. Other schemes are disabled so that we save one parameter. I leave the other versions as comments in case you want to try it again somewhen. #if _RESTART_SCHEME_ == 5 m_restart_next += (unsigned)(m_restart_base * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ff0e55f24..94f3fa626 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -76,6 +76,7 @@ protected: unsigned m_wp; unsigned m_vns_mc; unsigned m_vns_repick; + unsigned m_paws; unsigned m_paws_sp; unsigned m_restart_base; unsigned m_restart_next; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 37bfa5a2d..200a0e380 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -37,9 +37,7 @@ class sls_evaluator { powers & m_powers; expr_ref_buffer m_temp_exprs; vector > m_traversal_stack; -#if _EARLY_PRUNE_ vector > m_traversal_stack_bool; -#endif public: sls_evaluator(ast_manager & m, bv_util & bvu, sls_tracker & t, unsynch_mpz_manager & mm, powers & p) : @@ -753,7 +751,7 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); - // should always have uplinks ... + // Andreas: Should actually always have uplinks ... if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 7b48057d4..a815c9ad3 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -92,7 +92,6 @@ private: #endif obj_map m_weights; double m_top_sum; - unsigned m_equal_scores; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -148,14 +147,6 @@ public: return sum / count; } - void reset_equal_scores() { - m_equal_scores = 1; - } - - unsigned inc_equal_scores() { - return ++m_equal_scores; - } - inline void adapt_top_sum(expr * e, double add, double sub) { m_top_sum += m_weights.find(e) * (add - sub); } From 80c94ef0b63efe68d125fb7f6548da4630313db8 Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Wed, 23 Apr 2014 14:52:18 +0100 Subject: [PATCH 200/507] Moved parameters to the right file. Almost clean. --- src/tactic/sls/sls_compilation_settings.h | 5 +-- src/tactic/sls/sls_engine.cpp | 38 +++++++++++------------ src/tactic/sls/sls_engine.h | 3 +- src/tactic/sls/sls_evaluator.h | 5 --- src/tactic/sls/sls_params.pyg | 6 +--- src/tactic/sls/sls_tracker.h | 33 +++++++++----------- 6 files changed, 36 insertions(+), 54 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 5c837b4b2..707802cf4 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -22,10 +22,7 @@ Notes: #ifndef _SLS_COMPILATION_SETTINGS_H_ #define _SLS_COMPILATION_SETTINGS_H_ -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? +// should we use unsat-structures as done in SLS 4 SAT? #define _REAL_RS_ 0 -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - #endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 5d4df237e..a1c72609c 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -70,6 +70,8 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_next = m_restart_base; m_restart_init = p.restart_init(); + m_early_prune = p.early_prune(); + // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. if (m_walksat_repick && !m_walksat) NOT_IMPLEMENTED_YET(); @@ -117,7 +119,7 @@ double sls_engine::top_score() { m_tracker.set_top_sum(top_sum); - return top_sum / (double)sz; + return top_sum; } double sls_engine::rescore() { @@ -129,21 +131,21 @@ double sls_engine::rescore() { double sls_engine::serious_score(func_decl * fd, const mpz & new_value) { m_evaluator.serious_update(fd, new_value); m_stats.m_incr_evals++; - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); } double sls_engine::incremental_score(func_decl * fd, const mpz & new_value) { m_evaluator.update(fd, new_value); m_stats.m_incr_evals++; - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); } double sls_engine::incremental_score_prune(func_decl * fd, const mpz & new_value) { m_stats.m_incr_evals++; if (m_evaluator.update_prune(fd, new_value)) - return (m_tracker.get_top_sum() / m_assertions.size()); + return m_tracker.get_top_sum(); else - return 0.0; + return -DBL_MAX; } // checks whether the score outcome of a given move is better than the previous score @@ -160,11 +162,11 @@ bool sls_engine::what_if( m_mpz_manager.set(old_value, m_tracker.get_value(fd)); #endif -#if _EARLY_PRUNE_ - double r = incremental_score_prune(fd, temp); -#else - double r = incremental_score(fd, temp); -#endif + double r; + if (m_early_prune) + r = incremental_score_prune(fd, temp); + else + r = incremental_score(fd, temp); #ifdef Z3DEBUG TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << " --> " << r << std::endl;); @@ -342,11 +344,8 @@ double sls_engine::find_best_move( if (what_if(fd, i, temp, new_score, best_const, best_value)) move = MV_INV; } - // reset to what it was before - double check = incremental_score(fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); + incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -381,9 +380,8 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double } } } - // reset to what it was before - double check = incremental_score(fd, old_value); + incremental_score(fd, old_value); } m_mpz_manager.del(old_value); @@ -408,7 +406,10 @@ lbool sls_engine::search() { checkpoint(); m_stats.m_moves++; if (m_stats.m_moves % m_restart_base == 0) + { m_tracker.ucb_forget(m_assertions); + //score = rescore(); + } #if _REAL_RS_ //m_tracker.debug_real(g, m_stats.m_moves); @@ -425,7 +426,7 @@ lbool sls_engine::search() { if (m_wp && m_tracker.get_random_uint(10) < m_wp) { mk_random_move(to_evaluate); - score = m_tracker.get_top_sum() / sz; + score = m_tracker.get_top_sum(); continue; } @@ -465,7 +466,7 @@ lbool sls_engine::search() { else m_evaluator.randomize_local(to_evaluate); - score = m_tracker.get_top_sum() / m_assertions.size(); + score = m_tracker.get_top_sum(); // update assertion weights if a weigthing is enabled (sp < 1024) if (m_paws) @@ -513,7 +514,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { assert_expr(g->form(i)); verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; lbool res = operator()(); diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 94f3fa626..ac8610871 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -81,8 +81,7 @@ protected: unsigned m_restart_base; unsigned m_restart_next; unsigned m_restart_init; - - ptr_vector m_old_values; + unsigned m_early_prune; typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index 200a0e380..e4cf3c466 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -554,9 +554,7 @@ public: if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#if _EARLY_PRUNE_ m_tracker.set_score_prune(cur, new_score); -#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); @@ -599,9 +597,6 @@ public: if (m_tracker.is_top_expr(cur)) m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); -#if _EARLY_PRUNE_ - m_tracker.set_score_prune(cur, new_score); -#endif if (m_tracker.has_uplinks(cur)) { ptr_vector & ups = m_tracker.get_uplinks(cur); for (unsigned j = 0; j < ups.size(); j++) { diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index bf5bd181a..98875b20d 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -8,19 +8,15 @@ def_module_params('sls', ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), - ('walksat_ucb_noise', DOUBLE, 0.0002, 'add noise 0 <= 256 * ucb_noise to ucb score for assertion selection'), ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), ('paws_init', UINT, 40, 'initial/minimum assertion weights'), ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), - ('wp', UINT, 100, 'random walk with probability wp / 1024'), + ('wp', UINT, 0, 'random walk with probability wp / 1024'), ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), - ('random_offset', BOOL, 1, 'use random offset for candidate evaluation'), - ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), - ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') )) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index a815c9ad3..507596273 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -44,11 +44,9 @@ class sls_tracker { unsynch_mpz_manager * m; mpz value; double score; -#if _EARLY_PRUNE_ double score_prune; unsigned has_pos_occ; unsigned has_neg_occ; -#endif unsigned distance; // max distance from any root unsigned touched; value_score & operator=(const value_score & other) { @@ -122,6 +120,7 @@ public: m_paws_init = p.paws_init(); } + /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. unsigned get_formula_size() { return m_scores.size(); } @@ -145,7 +144,7 @@ public: } return sum / count; - } + }*/ inline void adapt_top_sum(expr * e, double add, double sub) { m_top_sum += m_weights.find(e) * (add - sub); @@ -417,6 +416,8 @@ public: } } + /* Andreas: Used this at some point to have values for the non-top-level expressions. + However, it did not give better performance but even cause some additional m/o - is not used currently. void initialize_recursive(init_proc proc, expr_mark visited, expr * e) { if (m_manager.is_and(e) || m_manager.is_or(e)) { app * a = to_app(e); @@ -445,7 +446,7 @@ public: find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); expr_fast_mark1 visited; quick_for_each_expr(ffd_proc, visited, e); - } + }*/ void initialize(ptr_vector const & as) { init_proc proc(m_manager, *this); @@ -455,8 +456,6 @@ public: expr * e = as[i]; if (!m_top_expr.contains(e)) m_top_expr.insert(e); - else - printf("this is already in ...\n"); for_each_expr(proc, visited, e); } @@ -464,7 +463,6 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; - // Andreas: Maybe not fully correct. ptr_vector t; m_constants_occ.insert_if_not_there(e, t); find_func_decls_proc ffd_proc(m_manager, m_constants_occ.find(e)); @@ -488,15 +486,16 @@ public: for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; - if (!m_weights.contains(e)) + + // initialize weights + if (!m_weights.contains(e)) m_weights.insert(e, m_paws_init); + + // positive/negative occurences used for early pruning + setup_occs(as[i]); } -#if _EARLY_PRUNE_ - for (unsigned i = 0; i < sz; i++) - setup_occs(as[i]); -#endif - + // initialize ucb total touched value (individual ones are always initialized to 1) m_touched = m_ucb_init ? as.size() : 1; } @@ -738,7 +737,6 @@ public: SASSERT(!negated); app * a = to_app(n); expr * const * args = a->get_args(); - // Andreas: Seems to have no effect. Probably it is still too similar to the original version. double max = 0.0; for (unsigned i = 0; i < a->get_num_args(); i++) { double cur = get_score(args[i]); @@ -764,7 +762,6 @@ public: const mpz & v1 = get_value(arg1); if (negated) { - //res = (m_mpz_manager.eq(v0, v1)) ? 0.5 * (m_bv_util.get_bv_size(arg0) - 1.0) / m_bv_util.get_bv_size(arg0) : 1.0; res = (m_mpz_manager.eq(v0, v1)) ? 0.0 : 1.0; TRACE("sls_score", tout << "V0 = " << m_mpz_manager.to_string(v0) << " ; V1 = " << m_mpz_manager.to_string(v1) << std::endl; ); @@ -1051,10 +1048,8 @@ public: // for (unsigned i = 0; i < m_where_false.size(); i++) { // expr * e = m_list_false[i]; vscore = m_scores.find(e); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); -#if _UCT_ == 3 - double q = vscore.score + _UCT_CONSTANT_ * sqrt(log(m_touched)/vscore.touched) + (get_random_uint(16) * 0.1 / (2<<16)); -#endif + //double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + (get_random_uint(8) * 0.0000002); if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } } if (pos == static_cast(-1)) From 7d18a17bb38ca701a49a17595e926dd5edf7933a Mon Sep 17 00:00:00 2001 From: Andreas Froehlich Date: Fri, 25 Apr 2014 13:56:15 +0100 Subject: [PATCH 201/507] Cleaned up final SLS version. Enjoy! --- src/tactic/sls/sls_compilation_settings.h | 28 ---- src/tactic/sls/sls_engine.cpp | 43 ++++-- src/tactic/sls/sls_engine.h | 2 + src/tactic/sls/sls_evaluator.h | 8 +- src/tactic/sls/sls_params.pyg | 6 +- src/tactic/sls/sls_tracker.h | 153 ++++++++-------------- 6 files changed, 94 insertions(+), 146 deletions(-) diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h index 707802cf4..e69de29bb 100644 --- a/src/tactic/sls/sls_compilation_settings.h +++ b/src/tactic/sls/sls_compilation_settings.h @@ -1,28 +0,0 @@ -/*++ -Copyright (c) 2014 Microsoft Corporation - -Module Name: - - sls_compilation_constants.h - -Abstract: - - Stochastic Local Search (SLS) compilation constants - -Author: - - Christoph (cwinter) 2014-03-19 - -Notes: - - This file should go away completely once we have evaluated all options. - ---*/ - -#ifndef _SLS_COMPILATION_SETTINGS_H_ -#define _SLS_COMPILATION_SETTINGS_H_ - -// should we use unsat-structures as done in SLS 4 SAT? -#define _REAL_RS_ 0 - -#endif \ No newline at end of file diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index a1c72609c..269790902 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -71,6 +71,8 @@ void sls_engine::updt_params(params_ref const & _p) { m_restart_init = p.restart_init(); m_early_prune = p.early_prune(); + m_random_offset = p.random_offset(); + m_rescore = p.rescore(); // Andreas: Would cause trouble because repick requires an assertion being picked before which is not the case in GSAT. if (m_walksat_repick && !m_walksat) @@ -174,6 +176,9 @@ bool sls_engine::what_if( m_mpz_manager.del(old_value); #endif + // Andreas: Had this idea on my last day. Maybe we could add a noise here similar to the one that worked so well for ucb assertion selection. + // r += 0.0001 * m_tracker.get_random_uint(8); + // Andreas: For some reason it is important to use > here instead of >=. Probably related to prefering the LSB. if (r > best_score) { best_score = r; @@ -248,9 +253,15 @@ void sls_engine::mk_random_move(ptr_vector & unsat_constants) { if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv = 2; if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; + + // Andreas: The other option would be to scale the probability for flips according to the bit-width. + /* unsigned bv_sz2 = m_bv_util.get_bv_size(srt); + rnd_mv = m_tracker.get_random_uint(16) % (bv_sz2 + 3); + if (rnd_mv > 3) rnd_mv = 0; */ + move_type mt = (move_type)rnd_mv; - // inversion doesn't make sense, let's do a flip instead. + // Andreas: Christoph claimed inversion doesn't make sense, let's do a flip instead. Is this really true? if (mt == MV_INV) mt = MV_FLIP; unsigned bit = 0; @@ -306,10 +317,13 @@ double sls_engine::find_best_move( unsigned bv_sz; double new_score = score; - //unsigned offset = m_tracker.get_random_uint(16) % to_evaluate.size(); - //for (unsigned j = 0; j < to_evaluate.size(); j++) { - //unsigned i = (j + offset) % to_evaluate.size(); - for (unsigned i = 0; i < to_evaluate.size(); i++) { + // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. + unsigned sz = to_evaluate.size(); + unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; + for (unsigned j = 0; j < sz; j++) { + unsigned i = j + offset; + if (i >= sz) i -= sz; + //for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -361,7 +375,13 @@ double sls_engine::find_best_move_mc(ptr_vector & to_evaluate, double unsigned bv_sz; double new_score = score; - for (unsigned i = 0; i < to_evaluate.size(); i++) { + // Andreas: Introducting a bit of randomization by using a random offset and a random direction to go through the candidate list. + unsigned sz = to_evaluate.size(); + unsigned offset = (m_random_offset) ? m_tracker.get_random_uint(16) % sz : 0; + for (unsigned j = 0; j < sz; j++) { + unsigned i = j + offset; + if (i >= sz) i -= sz; + //for (unsigned i = 0; i < to_evaluate.size(); i++) { func_decl * fd = to_evaluate[i]; sort * srt = fd->get_range(); bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); @@ -405,15 +425,16 @@ lbool sls_engine::search() { while (check_restart(m_stats.m_moves)) { checkpoint(); m_stats.m_moves++; + + // Andreas: Every base restart interval ... if (m_stats.m_moves % m_restart_base == 0) { + // ... potentially smooth the touched counters ... m_tracker.ucb_forget(m_assertions); - //score = rescore(); + // ... or normalize the top-level score. + if (m_rescore) score = rescore(); } -#if _REAL_RS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif // get candidate variables ptr_vector & to_evaluate = m_tracker.get_unsat_constants(m_assertions); if (!to_evaluate.size()) @@ -513,8 +534,6 @@ void sls_engine::operator()(goal_ref const & g, model_converter_ref & mc) { for (unsigned i = 0; i < g->size(); i++) assert_expr(g->form(i)); - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - lbool res = operator()(); if (res == l_true) { diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index ac8610871..8158808fa 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -82,6 +82,8 @@ protected: unsigned m_restart_next; unsigned m_restart_init; unsigned m_early_prune; + unsigned m_random_offset; + unsigned m_rescore; typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV } move_type; diff --git a/src/tactic/sls/sls_evaluator.h b/src/tactic/sls/sls_evaluator.h index e4cf3c466..61afb7457 100644 --- a/src/tactic/sls/sls_evaluator.h +++ b/src/tactic/sls/sls_evaluator.h @@ -22,7 +22,6 @@ Notes: #include"model_evaluator.h" -#include"sls_compilation_settings.h" #include"sls_powers.h" #include"sls_tracker.h" @@ -540,19 +539,16 @@ public: (*this)(to_app(cur), new_value); m_tracker.set_value(cur, new_value); -#if _REAL_RS_ + new_score = m_tracker.score(cur); if (m_tracker.is_top_expr(cur)) { + m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); if (m_mpz_manager.eq(new_value,m_one)) m_tracker.make_assertion(cur); else m_tracker.break_assertion(cur); } -#endif - new_score = m_tracker.score(cur); - if (m_tracker.is_top_expr(cur)) - m_tracker.adapt_top_sum(cur, new_score, m_tracker.get_score(cur)); m_tracker.set_score(cur, new_score); m_tracker.set_score_prune(cur, new_score); diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index 98875b20d..ad7a22675 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -8,15 +8,19 @@ def_module_params('sls', ('walksat_ucb_constant', DOUBLE, 20.0, 'the ucb constant c in the term score + c * f(touched)'), ('walksat_ucb_init', BOOL, 0, 'initialize total ucb touched to formula size'), ('walksat_ucb_forget', DOUBLE, 1.0, 'scale touched by this factor every base restart interval'), + ('walksat_ucb_noise', DOUBLE, 0.0002, 'add noise 0 <= 256 * ucb_noise to ucb score for assertion selection'), ('walksat_repick', BOOL, 1, 'repick assertion if randomizing in local minima'), ('scale_unsat', DOUBLE, 0.5, 'scale score of unsat expressions by this factor'), ('paws_init', UINT, 40, 'initial/minimum assertion weights'), ('paws_sp', UINT, 52, 'smooth assertion weights with probability paws_sp / 1024'), - ('wp', UINT, 0, 'random walk with probability wp / 1024'), + ('wp', UINT, 100, 'random walk with probability wp / 1024'), ('vns_mc', UINT, 0, 'in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit'), ('vns_repick', BOOL, 0, 'in local minima, try picking a different assertion (only for walksat)'), ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), + ('random_offset', BOOL, 1, 'use random offset vor candidate evaluation'), + ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), + ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') )) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 507596273..4356bcc9b 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -80,14 +80,13 @@ private: double m_ucb_constant; unsigned m_ucb_init; double m_ucb_forget; + double m_ucb_noise; unsigned m_touched; double m_scale_unsat; unsigned m_paws_init; -#if _REAL_RS_ - ptr_vector m_unsat_expr; obj_map m_where_false; expr** m_list_false; -#endif + unsigned m_track_unsat; obj_map m_weights; double m_top_sum; @@ -116,8 +115,12 @@ public: m_ucb_constant = p.walksat_ucb_constant(); m_ucb_init = p.walksat_ucb_init(); m_ucb_forget = p.walksat_ucb_forget(); + m_ucb_noise = p.walksat_ucb_noise(); m_scale_unsat = p.scale_unsat(); m_paws_init = p.paws_init(); + // Andreas: track_unsat is currently disabled because I cannot guarantee that it is not buggy. + // If you want to use it, you will also need to change comments in the assertion selection. + m_track_unsat = 0;//p.track_unsat(); } /* Andreas: Tried to give some measure for the formula size by the following two methods but both are not used currently. @@ -254,53 +257,6 @@ public: return m_uplinks.find(n); } -#if _REAL_RS_ - void debug_real(goal_ref const & g, unsigned flip) - { - unsigned count = 0; - for (unsigned i = 0; i < g->size(); i++) - { - expr * e = g->form(i); - if (m_mpz_manager.eq(get_value(e),m_one) && m_where_false.contains(e)) - { - printf("iteration %d: ", flip); - printf("form %d is sat but in unsat list at position %d of %d\n", i, m_where_false.find(e), m_where_false.size()); - exit(4); - } - - if (m_mpz_manager.eq(get_value(e),m_zero) && !m_where_false.contains(e)) - { - printf("iteration %d: ", flip); - printf("form %d is unsat but not in unsat list\n", i); - exit(4); - } - - if (m_mpz_manager.eq(get_value(e),m_zero) && m_where_false.contains(e)) - { - unsigned pos = m_where_false.find(e); - expr * q = m_list_false[pos]; - if (q != e) - { - printf("iteration %d: ", flip); - printf("form %d is supposed to be at pos %d in unsat list but something else was there\n", i, pos); - exit(4); - } - } - - if (m_mpz_manager.eq(get_value(e),m_zero)) - count++; - } - - // should be true now that duplicate assertions are removed - if (count != m_where_false.size()) - { - printf("iteration %d: ", flip); - printf("%d are unsat but list is of size %d\n", count, m_where_false.size()); - exit(4); - } - } -#endif - inline void ucb_forget(ptr_vector & as) { if (m_ucb_forget < 1.0) { @@ -474,14 +430,15 @@ public: TRACE("sls", tout << "Initial model:" << std::endl; show_model(tout); ); -#if _REAL_RS_ - m_list_false = new expr*[sz]; - //for (unsigned i = 0; i < sz; i++) - //{ - // if (m_mpz_manager.eq(get_value(g->form(i)),m_zero)) - // break_assertion(g->form(i)); - //} -#endif + if (m_track_unsat) + { + m_list_false = new expr*[sz]; + for (unsigned i = 0; i < sz; i++) + { + if (m_mpz_manager.eq(get_value(as[i]), m_zero)) + break_assertion(as[i]); + } + } for (unsigned i = 0; i < sz; i++) { @@ -515,44 +472,36 @@ public: return m_weights.find(e); } -#if _REAL_RS_ void make_assertion(expr * e) { - if (m_where_false.contains(e)) + if (m_track_unsat) { - unsigned pos = m_where_false.find(e); - m_where_false.erase(e); - if (pos != m_where_false.size()) + if (m_where_false.contains(e)) { - expr * q = m_list_false[m_where_false.size()]; - m_list_false[pos] = q; - m_where_false.find(q) = pos; - //printf("Moving %d from %d to %d\n", q, m_where_false.size(), pos); + unsigned pos = m_where_false.find(e); + m_where_false.erase(e); + if (pos != m_where_false.size()) + { + expr * q = m_list_false[m_where_false.size()]; + m_list_false[pos] = q; + m_where_false.find(q) = pos; + } } - //else - //printf("Erasing %d from %d to %d\n", e, pos); -// m_list_false[m_where_false.size()] = 0; -// printf("Going in %d\n", m_where_false.size()); } - //if (m_unsat_expr.contains(e)) - //m_unsat_expr.erase(e); } void break_assertion(expr * e) { - //printf("I'm broken... that's still fine.\n"); - if (!m_where_false.contains(e)) + if (m_track_unsat) { - //printf("This however is not so cool...\n"); - unsigned pos = m_where_false.size(); - m_list_false[pos] = e; - m_where_false.insert(e, pos); - // printf("Going in %d\n", m_where_false.size()); + if (!m_where_false.contains(e)) + { + unsigned pos = m_where_false.size(); + m_list_false[pos] = e; + m_where_false.insert(e, pos); + } } - //if (!m_unsat_expr.contains(e)) - //m_unsat_expr.push_back(e); } -#endif void show_model(std::ostream & out) { unsigned sz = get_num_constants(); @@ -1043,24 +992,38 @@ public: { value_score vscore; double max = -1.0; + // Andreas: Commented things here might be used for track_unsat data structures as done in SLS for SAT. But seems to have no benefit. + /* for (unsigned i = 0; i < m_where_false.size(); i++) { + expr * e = m_list_false[i]; */ for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; -// for (unsigned i = 0; i < m_where_false.size(); i++) { -// expr * e = m_list_false[i]; - vscore = m_scores.find(e); - //double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); - double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + (get_random_uint(8) * 0.0000002); - if (q > max && m_mpz_manager.neq(get_value(e), m_one) ) { max = q; pos = i; } + if (m_mpz_manager.neq(get_value(e), m_one)) + { + vscore = m_scores.find(e); + // Andreas: Select the assertion with the greatest ucb score. Potentially add some noise. + // double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched); + double q = vscore.score + m_ucb_constant * sqrt(log((double)m_touched) / vscore.touched) + m_ucb_noise * get_random_uint(8); + if (q > max) { max = q; pos = i; } + } } if (pos == static_cast(-1)) return 0; - m_scores.find(as[pos]).touched++; m_touched++; -// return m_list_false[pos]; + m_scores.find(as[pos]).touched++; + // Andreas: Also part of track_unsat data structures. Additionally disable the previous line! + /* m_last_pos = pos; + m_scores.find(m_list_false[pos]).touched++; + return m_list_false[pos]; */ } else { + // Andreas: The track_unsat data structures for random assertion selection. + /* sz = m_where_false.size(); + if (sz == 0) + return 0; + return m_list_false[get_random_uint(16) % sz]; */ + unsigned cnt_unsat = 0; for (unsigned i = 0; i < sz; i++) if (m_mpz_manager.neq(get_value(as[i]), m_one) && (get_random_uint(16) % ++cnt_unsat == 0)) pos = i; @@ -1070,14 +1033,6 @@ public: m_last_pos = pos; return as[pos]; -#if _REAL_RS_ - //unsigned pos = m_false_list[get_random_uint(16) % m_cnt_false]; - //expr * e = m_unsat_expr[get_random_uint(16) % m_unsat_expr.size()]; - sz = m_where_false.size(); - if (sz == 0) - return 0; - return m_list_false[get_random_uint(16) % sz]; -#endif } expr * get_new_unsat_assertion(ptr_vector const & as) { From 992d150b8180c8d0e5b059e3c4c186f35dae7d7c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 17:17:47 +0100 Subject: [PATCH 202/507] BVSLS comments Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_params.pyg | 2 +- src/tactic/sls/sls_tracker.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_params.pyg b/src/tactic/sls/sls_params.pyg index ad7a22675..bf5bd181a 100644 --- a/src/tactic/sls/sls_params.pyg +++ b/src/tactic/sls/sls_params.pyg @@ -19,7 +19,7 @@ def_module_params('sls', ('restart_base', UINT, 100, 'base restart interval given by moves per run'), ('restart_init', BOOL, 0, 'initialize to 0 or random value (= 1) after restart'), ('early_prune', BOOL, 1, 'use early pruning for score prediction'), - ('random_offset', BOOL, 1, 'use random offset vor candidate evaluation'), + ('random_offset', BOOL, 1, 'use random offset for candidate evaluation'), ('rescore', BOOL, 1, 'rescore/normalize top-level score every base restart interval'), ('track_unsat', BOOL, 0, 'keep a list of unsat assertions as done in SAT - currently disabled internally'), ('random_seed', UINT, 0, 'random seed') diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 4356bcc9b..d58f94af2 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -831,7 +831,9 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) // Precondition: Assertion set is in NNF. + // Precondition: Assertion set is in NNF. + // Also: careful about the unsat assertion scaling further down. + if (m_manager.is_and(child) || m_manager.is_or(child)) NOT_IMPLEMENTED_YET(); res = score_bool(child, true); } From bec5938d9c06be6512ab2df49134ce33d09c0eb2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 18:03:35 +0100 Subject: [PATCH 203/507] removed unused file Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_compilation_settings.h | 0 src/tactic/sls/sls_engine.cpp | 1 - src/tactic/sls/sls_engine.h | 1 - src/tactic/sls/sls_tracker.h | 1 - 4 files changed, 3 deletions(-) delete mode 100644 src/tactic/sls/sls_compilation_settings.h diff --git a/src/tactic/sls/sls_compilation_settings.h b/src/tactic/sls/sls_compilation_settings.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 269790902..67dba0237 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -27,7 +27,6 @@ Notes: #include"cooperate.h" #include"luby.h" -#include"sls_compilation_settings.h" #include"sls_params.hpp" #include"sls_engine.h" diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8158808fa..8a8a57e0e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -24,7 +24,6 @@ Notes: #include"model_converter.h" #include"goal.h" -#include"sls_compilation_settings.h" #include"sls_tracker.h" #include"sls_evaluator.h" diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index d58f94af2..186fae250 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -25,7 +25,6 @@ Notes: #include"bv_decl_plugin.h" #include"model.h" -#include"sls_compilation_settings.h" #include"sls_powers.h" class sls_tracker { From 7a7566f39e183f8cc5cbe9f1ae251f96aafc1e6f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 18:11:30 +0100 Subject: [PATCH 204/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 186fae250..73355197a 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -25,6 +25,7 @@ Notes: #include"bv_decl_plugin.h" #include"model.h" +#include"sls_params.hpp" #include"sls_powers.h" class sls_tracker { @@ -1052,4 +1053,4 @@ public: } }; -#endif \ No newline at end of file +#endif From 7105e4d213ded77b3be3e8d9ea13b0a40076f0fa Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 21:49:35 +0100 Subject: [PATCH 205/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_engine.h b/src/tactic/sls/sls_engine.h index 8a8a57e0e..b056c438e 100644 --- a/src/tactic/sls/sls_engine.h +++ b/src/tactic/sls/sls_engine.h @@ -136,8 +136,8 @@ protected: void mk_random_move(ptr_vector & unsat_constants); - //inline double get_restart_armin(unsigned cnt_restarts); - inline unsigned check_restart(unsigned curr_value); + //double get_restart_armin(unsigned cnt_restarts); + unsigned check_restart(unsigned curr_value); }; #endif From 0016ba5f3e768d2669dc41a3b951b5d34269d329 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 21:54:08 +0100 Subject: [PATCH 206/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 67dba0237..5b32e5790 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -16,6 +16,7 @@ Author: Notes: --*/ +#include #include #include"map.h" From 8745872d28db43740c5e3fe029375f1a3cf1ba36 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 25 Apr 2014 22:03:26 +0100 Subject: [PATCH 207/507] compilation fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 5b32e5790..c0c319ab4 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -581,7 +581,7 @@ lbool sls_engine::operator()() { } /* Andreas: Needed for Armin's restart scheme if we don't want to use loops. -inline double sls_engine::get_restart_armin(unsigned cnt_restarts) +double sls_engine::get_restart_armin(unsigned cnt_restarts) { unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; @@ -589,7 +589,7 @@ inline double sls_engine::get_restart_armin(unsigned cnt_restarts) } */ -inline unsigned sls_engine::check_restart(unsigned curr_value) +unsigned sls_engine::check_restart(unsigned curr_value) { if (curr_value > m_restart_next) { From 85ff954bc6d4f87ecb5adbf2063980fbe0eb879f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 11 Sep 2014 00:27:37 +0100 Subject: [PATCH 208/507] merge fix Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tactic.cpp | 1413 +-------------------------------- 1 file changed, 30 insertions(+), 1383 deletions(-) diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 6e1102dd2..9bbed20bb 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -16,1378 +16,30 @@ Author: Notes: --*/ -#include -#include"map.h" #include"nnf.h" -#include"cooperate.h" -#include"ast_smt2_pp.h" -#include"ast_pp.h" -#include"var_subst.h" -#include"model_pp.h" -#include"model_evaluator.h" #include"solve_eqs_tactic.h" -#include"elim_uncnstr_tactic.h" #include"bv_size_reduction_tactic.h" #include"max_bv_sharing_tactic.h" #include"simplify_tactic.h" -#include"stopwatch.h" #include"propagate_values_tactic.h" -#include"sls_tactic.h" +#include"ctx_simplify_tactic.h" +#include"elim_uncnstr_tactic.h" #include"nnf_tactic.h" -#include"luby.h" -#include "ctx_simplify_tactic.h" - -// which unsatisfied assertion is selected? only works with _FOCUS_ > 0 -// 0 = random, 1 = #moves, 2 = assertion with min score, 3 = assertion with max score -#define _BFS_ 0 - -// how many terms are considered for variable selection? -// 0 = all terms (GSAT), 1 = only one top level assertion (WSAT), 2 = only one bottom level atom -#define _FOCUS_ 1 - -// probability of choosing the same assertion again in the next step -#define _PERC_STICKY_ 0 - -// do we use dirty unit propagation to get rid of nested top level assertions? -#define _DIRTY_UP_ 1 - -// do we use restarts? -// 0 = no, 1 = use #moves, 2 = use #plateaus, 3 = use time -#define _RESTARTS_ 3 -// limit of moves/plateaus/seconds until first restart occurs -#define _RESTART_LIMIT_ 10 -// 0 = initialize with all zero, 1 initialize with random value -#define _RESTART_INIT_ 0 -// 0 = even intervals, 1 = pseudo luby, 2 = real luby, 3 = armin, 4 = rapid, 5 = minisat -#define _RESTART_SCHEME_ 1 -// base value c for armin restart scheme using c^inner - only applies for _RESTART_SCHEME_ 3 -#define _RESTART_CONST_ARMIN_ 4.0 - -// timelimit -#define _TIMELIMIT_ 3600 - -// should score of conjunctions be calculated by average rather than max? -#define _SCORE_AND_AVG_ 0 - -// should score of discunctions be calculated by multiplication of the inverse score rather than min? -#define _SCORE_OR_MUL_ 0 - -// do we use some kind of variable neighbourhood-search? -// 0 = no, 1 = only consider flipping bits if no better score can be obtained otherwise, 2 = only consider flipping bits until a better score can be obtained -#define _VNS_ 0 - -// do we reduce the score of unsatisfied literals? -// 0 = no -// 1 = yes, by multiplying it with some factor -// 2 = yes, by squaring it -// 3 = yes, by setting it to zero -// 4 = by progessively increasing weight (_TIMELIMIT_ needs to be set appropriately!) -#define _WEIGHT_DIST_ 1 - -// the factor used for _WEIGHT_DIST_ = 1 -#define _WEIGHT_DIST_FACTOR_ 0.5 - -// shall we toggle the weight after each restart? -#define _WEIGHT_TOGGLE_ 0 - -// do we use intensification steps in local minima? if so, how many? -#define _INTENSIFICATION_ 0 -#define _INTENSIFICATION_TRIES_ 0 - -// what is the percentage of random moves in plateaus (instead of full randomization)? -#define _PERC_PLATEAU_MOVES_ 0 - -// shall we repick clause when randomizing in a plateau or use the current one? -#define _REPICK_ 1 - -// do we use some UCT-like scheme for assertion-selection? overrides _BFS_ -#define _UCT_ 1 - -// how much diversification is used in the UCT-scheme? -#define _UCT_CONSTANT_ 20.0 - -// is uct clause selection probabilistic similar to variable selection in sparrow? -// 0 = no, 1 = yes, use uct-value, 2 = yes, use score-value (_UCT_CONSTANT_ = 0.0) with squared score -#define _PROBABILISTIC_UCT_ 0 - -// additive constants for probabilistic uct > 0 -#define _UCT_EPS_ 0.0001 - -// shall we reset _UCT_ touched values after restart? -#define _UCT_RESET_ 0 - -// do we gradually reduce the touched values of _UCT_? -#define _UCT_FORGET_ 0 -#define _UCT_FORGET_FACTOR_ 0.5 - -// how shall we initialize the _UCT_ total touched counter? -// 0 = initialize with one, 1 = initialize with number of assertions -#define _UCT_INIT_ 0 - -// shall we use addition/subtraction? -#define _USE_ADDSUB_ 1 - -// shall we try multilication and division by 2? -#define _USE_MUL2DIV2_ 0 - -// shall we try multiplication by 3? -#define _USE_MUL3_ 0 - -// shall we try unary minus (= inverting and incrementing) -#define _USE_UNARY_MINUS_ 0 - -// is random selection for assertions uniform? only works with _BFS_ = _UCT_ = 0 -#define _UNIFORM_RANDOM_ 0 - -// should we use unsat-structures as done in SLS 4 SAT instead for random or bfs selection? -#define _REAL_RS_ 0 -#define _REAL_PBFS_ 0 - -// how many bits do we neglect in each iteration? -#define _SKIP_BITS_ 0 - -// when randomizing local, what is the probability for changing a single bit? -// 0 = use standard scheme and pick a new value at random (= 50), otherwise the value (as int) gives the percentage -#define _PERC_CHANGE_ 0 - -// do we use random steps for noise? -// 0 = no, 1 = randomize local, 2 = make random move -#define _TYPE_RSTEP_ 0 - -// with what probability _PERM_STEP_/1000 will the random step happen? -#define _PERM_RSTEP_ 0 - -// shall we use early pruning for incremental update? -#define _EARLY_PRUNE_ 1 - -// shall we use caching for top_score? -#define _CACHE_TOP_SCORE_ 1 - - -#if ((_BFS_ > 0) + (_UCT_ > 0) + _UNIFORM_RANDOM_ + _REAL_RS_ + _REAL_PBFS_ > 1) - InvalidConfiguration; -#endif -#if (_PROBABILISTIC_UCT_ && !_UCT_) - InvalidConfiguration; -#endif -#if (_PERM_RSTEP_ && !_TYPE_RSTEP_) - InvalidConfiguration; -#endif -#if (_PERC_CHANGE_ == 50) - InvalidConfiguration; -#endif -#if (_PERC_STICKY_ && !_FOCUS_) - InvalidConfiguration; -#endif - +#include"stopwatch.h" +#include"sls_tactic.h" #include"sls_params.hpp" -#include"sls_evaluator.h" -#include"sls_tracker.h" +#include"sls_engine.h" -class sls_tactic : public tactic { - class stats { - public: - unsigned m_restarts; - stopwatch m_stopwatch; - unsigned m_full_evals; - unsigned m_incr_evals; - unsigned m_moves, m_flips, m_incs, m_decs, m_invs, m_umins, m_mul2s, m_mul3s, m_div2s; - - stats() : - m_restarts(0), - m_full_evals(0), - m_incr_evals(0), - m_moves(0), - m_umins(0), - m_mul2s(0), - m_mul3s(0), - m_div2s(0), - m_flips(0), - m_incs(0), - m_decs(0), - m_invs(0) { - m_stopwatch.reset(); - m_stopwatch.start(); - } - void reset() { - m_full_evals = m_flips = m_incr_evals = 0; - m_stopwatch.reset(); - m_stopwatch.start(); - } - }; - - struct imp { - ast_manager & m_manager; - stats & m_stats; - unsynch_mpz_manager m_mpz_manager; - powers m_powers; - mpz m_zero, m_one, m_two; - bool m_produce_models; - volatile bool m_cancel; - bv_util m_bv_util; - sls_tracker m_tracker; - sls_evaluator m_evaluator; - - unsigned m_restart_limit; - unsigned m_max_restarts; - unsigned m_plateau_limit; - - ptr_vector m_old_values; - - typedef enum { MV_FLIP = 0, MV_INC, MV_DEC, MV_INV, MV_UMIN, MV_MUL2, MV_MUL3, MV_DIV2 } move_type; - - imp(ast_manager & m, params_ref const & p, stats & s) : - m_manager(m), - m_stats(s), - m_powers(m_mpz_manager), - m_zero(m_mpz_manager.mk_z(0)), - m_one(m_mpz_manager.mk_z(1)), - m_two(m_mpz_manager.mk_z(2)), - m_cancel(false), - m_bv_util(m), - m_tracker(m, m_bv_util, m_mpz_manager, m_powers), - m_evaluator(m, m_bv_util, m_tracker, m_mpz_manager, m_powers) - { - updt_params(p); - } - - ~imp() { - m_mpz_manager.del(m_zero); - m_mpz_manager.del(m_one); - m_mpz_manager.del(m_two); - } - - double get_restart_armin(unsigned cnt_restarts) - { - unsigned outer_id = (unsigned)(0.5 + sqrt(0.25 + 2 * cnt_restarts)); - unsigned inner_id = cnt_restarts - (outer_id - 1) * outer_id / 2; - //printf("armin: %f\n", pow(1.1, inner_id + 1)); - return pow(_RESTART_CONST_ARMIN_, inner_id + 1); - } - - inline unsigned check_restart(unsigned curr_value) - { - if (curr_value > m_restart_limit) - { -#if _RESTART_SCHEME_ == 5 - m_restart_limit += (unsigned)(_RESTART_LIMIT_ * pow(_RESTART_CONST_ARMIN_, m_stats.m_restarts)); -#elif _RESTART_SCHEME_ == 4 - m_restart_limit += (m_stats.m_restarts & (m_stats.m_restarts + 1)) ? _RESTART_LIMIT_ : (_RESTART_LIMIT_ * m_stats.m_restarts + 1); -#elif _RESTART_SCHEME_ == 3 - m_restart_limit += (unsigned)get_restart_armin(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 2 - m_restart_limit += get_luby(m_stats.m_restarts + 1) * _RESTART_LIMIT_; -#elif _RESTART_SCHEME_ == 1 - if (m_stats.m_restarts & 1) - m_restart_limit += _RESTART_LIMIT_; - else - m_restart_limit += (2 << (m_stats.m_restarts >> 1)) * _RESTART_LIMIT_; -#else - m_restart_limit += _RESTART_LIMIT_; -#endif -#if _WEIGHT_TOGGLE_ - printf("Setting weight: %f\n", _WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_ * (((m_stats.m_restarts & 2) == 0) + 1)); -#endif - return 0; - } - return 1; - } - - ast_manager & m() const { return m_manager; } - - void set_cancel(bool f) { m_cancel = f; } - void cancel() { set_cancel(true); } - void reset_cancel() { set_cancel(false); } - - static void collect_param_descrs(param_descrs & r) { - sls_params::collect_param_descrs(r); - } - - void updt_params(params_ref const & _p) { - sls_params p(_p); - m_produce_models = _p.get_bool("model", false); - m_max_restarts = p.restarts(); - m_tracker.set_random_seed(p.random_seed()); - m_plateau_limit = p.plateau_limit(); - } - - void checkpoint() { - if (m_cancel) - throw tactic_exception(TACTIC_CANCELED_MSG); - cooperate("sls"); - } - - bool full_eval(goal_ref const & g, model & mdl) { - bool res = true; - - unsigned sz = g->size(); - for (unsigned i = 0; i < sz && res; i++) { - checkpoint(); - expr_ref o(m_manager); - - if (!mdl.eval(g->form(i), o, true)) - exit(ERR_INTERNAL_FATAL); - - res = m_manager.is_true(o.get()); - } - - TRACE("sls", tout << "Evaluation: " << res << std::endl;); - - return res; - } - - double top_score(goal_ref const & g) { - #if 0 - double min = m_tracker.get_score(g->form(0)); - unsigned sz = g->size(); - for (unsigned i = 1; i < sz; i++) { - double q = m_tracker.get_score(g->form(i)); - if (q < min) min = q; - } - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " MIN: " << min << std::endl; ); - return min; - #else - double top_sum = 0.0; - unsigned sz = g->size(); - for (unsigned i = 0; i < sz; i++) { - expr * e = g->form(i); - top_sum += m_tracker.get_score(e); - } - - TRACE("sls_top", tout << "Score distribution:"; - for (unsigned i = 0; i < sz; i++) - tout << " " << m_tracker.get_score(g->form(i)); - tout << " AVG: " << top_sum / (double) sz << std::endl; ); - -#if _CACHE_TOP_SCORE_ - m_tracker.set_top_sum(top_sum); -#endif - - return top_sum / (double) sz; - #endif - } - - double rescore(goal_ref const & g) { - m_evaluator.update_all(); - m_stats.m_full_evals++; - return top_score(g); - } - - double serious_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.serious_update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - - double incremental_score(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_evaluator.update(fd, new_value); - m_stats.m_incr_evals++; -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - } - -#if _EARLY_PRUNE_ - double incremental_score_prune(goal_ref const & g, func_decl * fd, const mpz & new_value) { - m_stats.m_incr_evals++; - if (m_evaluator.update_prune(fd, new_value)) -#if _CACHE_TOP_SCORE_ - return (m_tracker.get_top_sum() / g->size()); -#else - return top_score(g); -#endif - else - return 0.0; - } -#endif - - // checks whether the score outcome of a given move is better than the previous score - bool what_if(goal_ref const & g, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - - #ifdef Z3DEBUG - mpz old_value; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - #endif - -#if _EARLY_PRUNE_ - double r = incremental_score_prune(g, fd, temp); -#else - double r = incremental_score(g, fd, temp); -#endif - #ifdef Z3DEBUG - TRACE("sls_whatif", tout << "WHAT IF " << fd->get_name() << " WERE " << m_mpz_manager.to_string(temp) << - " --> " << r << std::endl; ); - - m_mpz_manager.del(old_value); - #endif - -// if (r >= best_score) { - if (r > best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // same as what_if, but only applied to the score of a specific atom, not the total score - bool what_if_local(expr * e, func_decl * fd, const unsigned & fd_inx, const mpz & temp, - double & best_score, unsigned & best_const, mpz & best_value) { - m_evaluator.update(fd, temp); - double r = m_tracker.get_score(e); - if (r >= best_score) { - best_score = r; - best_const = fd_inx; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - void mk_add(unsigned bv_sz, const mpz & old_value, mpz & add_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.add(old_value, add_value, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - - } - - // Andreas: do we really need all those temporary mpzs? - void mk_mul2(unsigned bv_sz, const mpz & old_value, mpz & result) { - mpz temp, mask, mask2; - m_mpz_manager.mul(old_value, m_two, temp); - m_mpz_manager.set(mask, m_powers(bv_sz)); - m_mpz_manager.bitwise_not(bv_sz, mask, mask2); - m_mpz_manager.bitwise_and(temp, mask2, result); - m_mpz_manager.del(temp); - m_mpz_manager.del(mask); - m_mpz_manager.del(mask2); - } - - void mk_div2(unsigned bv_sz, const mpz & old_value, mpz & result) { - m_mpz_manager.div(old_value, m_two, result); - } - - void mk_inc(unsigned bv_sz, const mpz & old_value, mpz & incremented) { - unsigned shift; - m_mpz_manager.add(old_value, m_one, incremented); - if (m_mpz_manager.is_power_of_two(incremented, shift) && shift == bv_sz) - m_mpz_manager.set(incremented, m_zero); - } - - void mk_dec(unsigned bv_sz, const mpz & old_value, mpz & decremented) { - if (m_mpz_manager.is_zero(old_value)) { - m_mpz_manager.set(decremented, m_powers(bv_sz)); - m_mpz_manager.dec(decremented); - } - else - m_mpz_manager.sub(old_value, m_one, decremented); - } - - void mk_inv(unsigned bv_sz, const mpz & old_value, mpz & inverted) { - m_mpz_manager.bitwise_not(bv_sz, old_value, inverted); - } - - void mk_flip(sort * s, const mpz & old_value, unsigned bit, mpz & flipped) { - m_mpz_manager.set(flipped, m_zero); - - if (m_bv_util.is_bv_sort(s)) { - mpz mask; - m_mpz_manager.set(mask, m_powers(bit)); - m_mpz_manager.bitwise_xor(old_value, mask, flipped); - m_mpz_manager.del(mask); - } - else if (m_manager.is_bool(s)) - m_mpz_manager.set(flipped, (m_mpz_manager.is_zero(old_value)) ? m_one : m_zero); - else - NOT_IMPLEMENTED_YET(); - } - - void mk_random_move(ptr_vector & unsat_constants) - { - unsigned rnd_mv = 0; - unsigned ucc = unsat_constants.size(); - unsigned rc = (m_tracker.get_random_uint((ucc < 16) ? 4 : (ucc < 256) ? 8 : (ucc < 4096) ? 12 : (ucc < 65536) ? 16 : 32)) % ucc; - func_decl * fd = unsat_constants[rc]; - - mpz new_value; - - sort * srt = fd->get_range(); - if (m_manager.is_bool(srt)) - m_mpz_manager.set(new_value, (m_mpz_manager.is_zero(m_tracker.get_value(fd))) ? m_one : m_zero); - else - { -#if _USE_ADDSUB_ - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv=2; - if (m_mpz_manager.is_one(m_tracker.get_random_bool())) rnd_mv++; - move_type mt = (move_type) rnd_mv; - - // inversion doesn't make sense, let's do a flip instead. - if (mt == MV_INV) mt = MV_FLIP; -#else - mt = MV_FLIP; -#endif - unsigned bit = 0; - - switch (mt) - { - case MV_FLIP: { - unsigned bv_sz = m_bv_util.get_bv_size(srt); - bit = (m_tracker.get_random_uint((bv_sz < 16) ? 4 : (bv_sz < 256) ? 8 : (bv_sz < 4096) ? 12 : (bv_sz < 65536) ? 16 : 32)) % bv_sz; - mk_flip(fd->get_range(), m_tracker.get_value(fd), bit, new_value); - break; - } - case MV_INC: - mk_inc(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_DEC: - mk_dec(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - case MV_INV: - mk_inv(m_bv_util.get_bv_size(fd->get_range()), m_tracker.get_value(fd), new_value); - break; - default: - NOT_IMPLEMENTED_YET(); - } - - TRACE("sls", tout << "Randomization candidates: "; - for (unsigned i = 0; i < unsat_constants.size(); i++) - tout << unsat_constants[i]->get_name() << ", "; - tout << std::endl; - tout << "Random move: "; - switch (mt) { - case MV_FLIP: tout << "Flip #" << bit << " in " << fd->get_name() << std::endl; break; - case MV_INC: tout << "+1 for " << fd->get_name() << std::endl; break; - case MV_DEC: tout << "-1 for " << fd->get_name() << std::endl; break; - case MV_INV: tout << "NEG for " << fd->get_name() << std::endl; break; - } - tout << "Locally randomized model: " << std::endl; m_tracker.show_model(tout); ); - } - - m_evaluator.update(fd, new_value); - m_mpz_manager.del(new_value); - } - - void mk_random_move(goal_ref const & g) { - mk_random_move(m_tracker.get_unsat_constants(g, m_stats.m_moves)); - } - - // will use VNS to ignore some possible moves and increase the flips per second - double find_best_move_vns(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz, max_bv_sz = 0; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - if (max_bv_sz < bv_sz) max_bv_sz = bv_sz; - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - - // try to flip lsb - mk_flip(srt, old_value, 0, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = 0; - move = MV_FLIP; - } - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - - // we can either check the condition once in the beginning or check it repeatedly after every bit -#if _VNS_ == 1 - for (unsigned j = 1; j < max_bv_sz && new_score <= score; j++) -#else - if (new_score <= score) - for (unsigned j = 1; j < max_bv_sz && new_score < 1.0; j++) -#endif - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // What would happen if we flipped bit #j ? - if (j < bv_sz) - { - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - // reset to what it was before - double check = incremental_score(g, fd, old_value); - SASSERT(check == score); - } - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // finds the move that increased score the most. returns best_const = -1, if no increasing move exists. - double find_best_move(goal_ref const & g, ptr_vector & to_evaluate, double score, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; -#if _USE_MUL3_ || _USE_UNARY_MINUS_ - mpz temp2; -#endif - unsigned bv_sz; - double new_score = score; - - for (unsigned i = 0; i < to_evaluate.size() && new_score < 1.0 ; i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit -#if _SKIP_BITS_ - for (unsigned j = (i + m_stats.m_moves) % (_SKIP_BITS_ + 1); j < bv_sz && new_score < 1.0; j+=(_SKIP_BITS_ + 1)) { -#else - for (unsigned j = 0; j < bv_sz && new_score < 1.0; j++) { -#endif - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { -#if _USE_ADDSUB_ - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } -#endif - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - -#if _USE_UNARY_MINUS_ - mk_inc(bv_sz, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_UMIN; -#endif - -#if _USE_MUL2DIV2_ - // try multiplication by 2 - mk_mul2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_MUL2; - -#if _USE_MUL3_ - // try multiplication by 3 - mk_add(bv_sz, old_value, temp, temp2); - if (what_if(g, fd, i, temp2, new_score, best_const, best_value)) - move = MV_MUL3; -#endif - - // try division by 2 - mk_div2(bv_sz, old_value, temp); - if (what_if(g, fd, i, temp, new_score, best_const, best_value)) - move = MV_DIV2; -#endif - } - - // reset to what it was before - double check = incremental_score(g, fd, old_value); - // Andreas: does not hold anymore now that we use top level score caching - //SASSERT(check == score); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); -#if _USE_MUL3_ - m_mpz_manager.del(temp2); -#endif - return new_score; - } - - // same as find_best_move but only considers the score of the current expression instead of the overall score - double find_best_move_local(expr * e, ptr_vector & to_evaluate, - unsigned & best_const, mpz & best_value, unsigned & new_bit, move_type & move) { - mpz old_value, temp; - unsigned bv_sz; - double new_score = m_tracker.get_score(e); - // Andreas: tie breaking not implemented yet - // double tie_score = top_score(g); - for (unsigned i = 0; i < to_evaluate.size(); i++) { - func_decl * fd = to_evaluate[i]; - sort * srt = fd->get_range(); - bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - // first try to flip every bit - for (unsigned j = 0; j < bv_sz; j++) { - // What would happen if we flipped bit #i ? - mk_flip(srt, old_value, j, temp); - - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) { - new_bit = j; - move = MV_FLIP; - } - } - - if (m_bv_util.is_bv_sort(srt) && bv_sz > 1) { - if (!m_mpz_manager.is_even(old_value)) { - // for odd values, try +1 - mk_inc(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INC; - } - else { - // for even values, try -1 - mk_dec(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_DEC; - } - - // try inverting - mk_inv(bv_sz, old_value, temp); - if (what_if_local(e, fd, i, temp, new_score, best_const, best_value)) - move = MV_INV; - } - - // reset to what it was before - m_evaluator.update(fd, old_value); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - return new_score; - } - - // first try of intensification ... does not seem to be efficient - bool handle_plateau(goal_ref const & g) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned pos = m_stats.m_moves % sz; -#else - unsigned pos = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, pos); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - for (unsigned i = 0; i < to_evaluate.size(); i++) - { - m_tracker.get_value(to_evaluate[i]); - m_old_values.push_back( & m_tracker.get_value(to_evaluate[i])); - } - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - for (unsigned i = 0; i < _INTENSIFICATION_TRIES_; i++) - { - // Andreas: Could be extended to use (best) score but this is computationally more expensive. - find_best_move_local(q, to_evaluate, new_const, new_value, new_bit, move); - - if (new_const == static_cast(-1)) { - // Andreas: Actually this should never happen. - NOT_IMPLEMENTED_YET(); - } else { - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - - m_evaluator.update(fd, new_value); - } - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - for (unsigned i = 0; i < to_evaluate.size(); i++) - m_tracker.set_value(to_evaluate[i], * m_old_values[i]); - - m_old_values.reset(); - - return 0; - } - - // what_if version needed in the context of 2nd intensification try, combining local and global score - bool what_if(goal_ref const & g, expr * e, func_decl * fd, const mpz & temp, - double & best_score, mpz & best_value, unsigned i) { - - double global_score = incremental_score(g, fd, temp); - double local_score = m_tracker.get_score(e); - double new_score = i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_; - - if (new_score >= best_score) { - best_score = new_score; - m_mpz_manager.set(best_value, temp); - return true; - } - - return false; - } - - // find_best_move version needed in the context of 2nd intensification try - double find_best_move_local(goal_ref const & g, expr * e, func_decl * fd, mpz & best_value, unsigned i) - { - mpz old_value, temp; - double best_score = 0; - - sort * srt = fd->get_range(); - unsigned bv_sz = (m_manager.is_bool(srt)) ? 1 : m_bv_util.get_bv_size(srt); - m_mpz_manager.set(old_value, m_tracker.get_value(fd)); - - for (unsigned j = 0; j < bv_sz && best_score < 1.0; j++) { - mk_flip(srt, old_value, j, temp); - what_if(g, e, fd, temp, best_score, best_value, i); - } - - m_mpz_manager.del(old_value); - m_mpz_manager.del(temp); - - return best_score; - } - - // second try to use intensification ... also not very effective - bool handle_plateau(goal_ref const & g, double old_score) - { - unsigned sz = g->size(); -#if _BFS_ - unsigned new_const = m_stats.m_moves % sz; -#else - unsigned new_const = m_tracker.get_random_uint(16) % sz; -#endif - expr * e = m_tracker.get_unsat_assertion(g, sz, new_const); - if (!e) - return 0; - - expr * q = m_tracker.get_unsat_expression(e); - ptr_vector & to_evaluate = m_tracker.get_constants(q); - - new_const = m_tracker.get_random_uint(16) % to_evaluate.size(); - func_decl * fd = to_evaluate[new_const]; - - mpz new_value; - //m_mpz_manager.set(new_value, m_tracker.get_value(fd)); - unsigned new_bit = 0; - double global_score = old_score, local_score = m_tracker.get_score(q), new_score = old_score; - - for (unsigned i = 1; i <= _INTENSIFICATION_TRIES_; i++) - { - new_score = find_best_move_local(g, q, fd, new_value, i); - - m_stats.m_moves++; - m_stats.m_flips++; - - global_score = incremental_score(g, fd, new_value); - local_score = m_tracker.get_score(q); - - SASSERT(new_score == i * local_score / _INTENSIFICATION_TRIES_ + (_INTENSIFICATION_TRIES_ - i) * global_score / _INTENSIFICATION_TRIES_); - - if (m_mpz_manager.is_one(m_tracker.get_value(q))) - return 1; - } - - return 0; - } - - // main search loop - lbool search(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - unsigned plateau_cnt = 0; - - score = rescore(g); - unsigned sz = g->size(); -#if _PERC_STICKY_ - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - -#if _RESTARTS_ == 1 - while (check_restart(m_stats.m_moves) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 2 - while (check_restart(plateau_cnt) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#elif _RESTARTS_ == 3 - while (check_restart((unsigned)m_stats.m_stopwatch.get_current_seconds()) && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#endif - checkpoint(); - m_stats.m_moves++; - -#if _UCT_FORGET_ - if (m_stats.m_moves % _UCT_FORGET_ == 0) - m_tracker.uct_forget(g); -#endif - -#if _REAL_RS_ || _REAL_PBFS_ - //m_tracker.debug_real(g, m_stats.m_moves); -#endif - -#if _FOCUS_ -#if _PERC_STICKY_ - if (m_tracker.get_random_uint(16) % 100 >= _PERC_STICKY_ || m_mpz_manager.eq(m_tracker.get_value(e), m_one)) - e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#else - expr * e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); -#endif - if (!e) - { - res = l_true; - goto bailout; - } - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else - ptr_vector & to_evaluate = m_tracker.get_unsat_constants_gsat(g, sz); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(to_evaluate); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(to_evaluate); -#endif -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } - continue; -#endif - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - old_score = score; - new_const = (unsigned)-1; - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - - if (new_const == static_cast(-1)) { - score = old_score; - plateau_cnt++; -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); - //e = m_tracker.get_unsat_assertion(g, m_stats.m_moves); - //to_evaluate = m_tracker.get_unsat_constants_walksat(e); -#else -#if _PERC_PLATEAU_MOVES_ - if (m_tracker.get_random_uint(8) % 100 < _PERC_PLATEAU_MOVES_) - mk_random_move(to_evaluate); - else -#endif -#if _REPICK_ - m_evaluator.randomize_local(g, m_stats.m_moves); -#else - m_evaluator.randomize_local(to_evaluate); -#endif -#endif - -#if _CACHE_TOP_SCORE_ - score = m_tracker.get_top_sum() / g->size(); -#else - score = top_score(g); -#endif - } else { - func_decl * fd = to_evaluate[new_const]; -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - // main search loop - lbool search_old(goal_ref const & g) { - lbool res = l_undef; - double score = 0.0, old_score = 0.0; - unsigned new_const = (unsigned)-1, new_bit = 0; - mpz new_value; - move_type move; - - score = rescore(g); - TRACE("sls", tout << "Starting search, initial score = " << std::setprecision(32) << score << std::endl; - tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - - unsigned plateau_cnt = 0; - - // Andreas: Why do we only allow so few plateaus? -#if _RESTARTS_ - while (m_stats.m_stopwatch.get_current_seconds() < 200 * (m_stats.m_restarts + 1) * 0.2) { - //while (plateau_cnt < m_plateau_limit && m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_) { -#else - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && (_RESTARTS_ == 0 || m_stats.m_moves < _RESTARTS_)) { -#endif - do { - checkpoint(); - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif - -#if _TYPE_RSTEP_ - if (m_tracker.get_random_uint(16) % 1000 < _PERM_RSTEP_) - { -#if _TYPE_RSTEP_ == 1 - m_evaluator.randomize_local(g, m_stats.m_moves); -#elif _TYPE_RSTEP_ == 2 - mk_random_move(g); -#endif - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } -#endif - old_score = score; - new_const = (unsigned)-1; - - ptr_vector & to_evaluate = m_tracker.get_unsat_constants(g, m_stats.m_moves); - if (!to_evaluate.size()) - { - res = l_true; - goto bailout; - } - TRACE("sls_constants", tout << "Evaluating these constants: " << std::endl; - for (unsigned i = 0 ; i < to_evaluate.size(); i++) - tout << to_evaluate[i]->get_name() << std::endl; ); - -#if _VNS_ - score = find_best_move_vns(g, to_evaluate, score, new_const, new_value, new_bit, move); -#else - score = find_best_move(g, to_evaluate, score, new_const, new_value, new_bit, move); -#endif - if (new_const == static_cast(-1)) { - TRACE("sls", tout << "Local maximum reached; unsatisfied constraints: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) { - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - tout << mk_ismt2_pp(g->form(i), m_manager) << std::endl; - }); - - TRACE("sls_max", m_tracker.show_model(tout); - tout << "Scores: " << std::endl; - for (unsigned i = 0; i < g->size(); i++) - tout << mk_ismt2_pp(g->form(i), m_manager) << " ---> " << - m_tracker.get_score(g->form(i)) << std::endl; ); - // Andreas: If new_const == -1, shouldn't score = old_score anyway? - score = old_score; - } - else { - // Andreas: Why does randomizing not count as a move? (Now it does.) - m_stats.m_moves++; - func_decl * fd = to_evaluate[new_const]; - - TRACE("sls", tout << "Setting " << fd->get_name() << " to " << m_mpz_manager.to_string(new_value) << " (Move: "; - switch (move) { - case MV_FLIP: - tout << "Flip"; - if (!m_manager.is_bool(fd->get_range())) tout << " #" << new_bit; - break; - case MV_INC: - tout << "+1"; - break; - case MV_DEC: - tout << "-1"; - break; - case MV_INV: - tout << "NEG"; - break; - }; - tout << ") ; new score = " << std::setprecision(32) << score << std::endl; ); - - switch (move) { - case MV_FLIP: m_stats.m_flips++; break; - case MV_INC: m_stats.m_incs++; break; - case MV_DEC: m_stats.m_decs++; break; - case MV_INV: m_stats.m_invs++; break; - case MV_UMIN: m_stats.m_umins++; break; - case MV_MUL2: m_stats.m_mul2s++; break; - case MV_MUL3: m_stats.m_mul3s++; break; - case MV_DIV2: m_stats.m_div2s++; break; - } - -#if _REAL_RS_ || _REAL_PBFS_ - score = serious_score(g, fd, new_value); -#else - score = incremental_score(g, fd, new_value); -#endif - - TRACE("sls", tout << "Score distribution:"; - for (unsigned i = 0; i < g->size(); i++) - tout << " " << std::setprecision(3) << m_tracker.get_score(g->form(i)); - tout << " TOP: " << score << std::endl; ); - } - - if (score >= 0.99999) { -// if (score >= 1.0) { - // score could theoretically be imprecise. - // Andreas: it seems using top level score caching can make the score unprecise also in the other direction! - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - /* - if (m_stats.m_moves % 100 == 0) - { - verbose_stream() << "(" << std::fixed << std::setprecision(10) << score << ")" << std::endl; - verbose_stream() << "(" << std::fixed << std::setprecision(2) << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - }*/ - } - while (score > old_score && res == l_undef); - - // Andreas: Why do you check for old_score? This should always be equal due to the loop invariant. - if (score != old_score) { - report_tactic_progress("This should not happen I guess.", plateau_cnt); - plateau_cnt = 0; - } else { - m_stats.m_moves++; - plateau_cnt++; - //report_tactic_progress("Plateau.", plateau_cnt); - // Andreas: Right now, a useless assignment is created in case of a restart. But we don't want to use restarts anyway. - //if (plateau_cnt < m_plateau_limit) { - TRACE("sls", tout << "In a plateau (" << plateau_cnt << "/" << m_plateau_limit << "); randomizing locally." << std::endl; ); -#if _INTENSIFICATION_ - handle_plateau(g, score); - //handle_plateau(g); -#else - m_evaluator.randomize_local(g, m_stats.m_moves); -#endif - //mk_random_move(g); - score = top_score(g); - - if (score >= 1.0) { - bool all_true = true; - for (unsigned i = 0; i < g->size() && all_true; i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - all_true=false; - if (all_true) { - res = l_true; // sat - goto bailout; - } else - TRACE("sls", tout << "Imprecise 1.0 score" << std::endl;); - } - } - } - - bailout: - m_mpz_manager.del(new_value); - - return res; - } - - void operator()(goal_ref const & g, model_converter_ref & mc) { - if (g->inconsistent()) { - mc = 0; - return; - } - - verbose_stream() << "_BFS_ " << _BFS_ << std::endl; - verbose_stream() << "_FOCUS_ " << _FOCUS_ << std::endl; - verbose_stream() << "_DIRTY_UP_ " << _DIRTY_UP_ << std::endl; - verbose_stream() << "_PERC_STICKY_ " << _PERC_STICKY_ << std::endl; - verbose_stream() << "_RESTARTS_ " << _RESTARTS_ << std::endl; - verbose_stream() << "_RESTART_LIMIT_ " << _RESTART_LIMIT_ << std::endl; - verbose_stream() << "_RESTART_INIT_ " << _RESTART_INIT_ << std::endl; - verbose_stream() << "_RESTART_SCHEME_ " << _RESTART_SCHEME_ << std::endl; - verbose_stream() << "_RESTART_CONST_ARMIN_ " << std::fixed << std::setprecision(2) << _RESTART_CONST_ARMIN_ << std::endl; - verbose_stream() << "_TIMELIMIT_ " << _TIMELIMIT_ << std::endl; - verbose_stream() << "_SCORE_AND_AVG_ " << _SCORE_AND_AVG_ << std::endl; - verbose_stream() << "_SCORE_OR_MUL_ " << _SCORE_OR_MUL_ << std::endl; - verbose_stream() << "_VNS_ " << _VNS_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_ " << _WEIGHT_DIST_ << std::endl; - verbose_stream() << "_WEIGHT_DIST_FACTOR_ " << std::fixed << std::setprecision(2) << _WEIGHT_DIST_FACTOR_ << std::endl; - verbose_stream() << "_INTENSIFICATION_ " << _INTENSIFICATION_ << std::endl; - verbose_stream() << "_INTENSIFICATION_TRIES_ " << _INTENSIFICATION_TRIES_ << std::endl; - verbose_stream() << "_PERC_PLATEAU_MOVES_ " << _PERC_PLATEAU_MOVES_ << std::endl; - verbose_stream() << "_REPICK_ " << _REPICK_ << std::endl; - verbose_stream() << "_UCT_ " << _UCT_ << std::endl; - verbose_stream() << "_UCT_CONSTANT_ " << std::fixed << std::setprecision(2) << _UCT_CONSTANT_ << std::endl; - verbose_stream() << "_UCT_RESET_ " << _UCT_RESET_ << std::endl; - verbose_stream() << "_UCT_INIT_ " << _UCT_INIT_ << std::endl; - verbose_stream() << "_UCT_FORGET_ " << _UCT_FORGET_ << std::endl; - verbose_stream() << "_UCT_FORGET_FACTOR_ " << std::fixed << std::setprecision(2) << _UCT_FORGET_FACTOR_ << std::endl; - verbose_stream() << "_PROBABILISTIC_UCT_ " << _PROBABILISTIC_UCT_ << std::endl; - verbose_stream() << "_UCT_EPS_ " << std::fixed << std::setprecision(4) << _UCT_EPS_ << std::endl; - verbose_stream() << "_USE_ADDSUB_ " << _USE_ADDSUB_ << std::endl; - verbose_stream() << "_USE_MUL2DIV2_ " << _USE_MUL2DIV2_ << std::endl; - verbose_stream() << "_USE_MUL3_ " << _USE_MUL3_ << std::endl; - verbose_stream() << "_USE_UNARY_MINUS_ " << _USE_UNARY_MINUS_ << std::endl; - verbose_stream() << "_UNIFORM_RANDOM_ " << _UNIFORM_RANDOM_ << std::endl; - verbose_stream() << "_REAL_RS_ " << _REAL_RS_ << std::endl; - verbose_stream() << "_REAL_PBFS_ " << _REAL_PBFS_ << std::endl; - verbose_stream() << "_SKIP_BITS_ " << _SKIP_BITS_ << std::endl; - verbose_stream() << "_PERC_CHANGE_ " << _PERC_CHANGE_ << std::endl; - verbose_stream() << "_TYPE_RSTEP_ " << _TYPE_RSTEP_ << std::endl; - verbose_stream() << "_PERM_RSTEP_ " << _PERM_RSTEP_ << std::endl; - verbose_stream() << "_EARLY_PRUNE_ " << _EARLY_PRUNE_ << std::endl; - verbose_stream() << "_CACHE_TOP_SCORE_ " << _CACHE_TOP_SCORE_ << std::endl; - -#if _WEIGHT_DIST_ == 4 - m_tracker.set_weight_dist_factor(m_stats.m_stopwatch.get_current_seconds() / _TIMELIMIT_); -#endif -#if _WEIGHT_TOGGLE_ - m_tracker.set_weight_dist_factor(_WEIGHT_DIST_FACTOR_); -#endif - m_tracker.initialize(g); - lbool res = l_undef; - - m_restart_limit = _RESTART_LIMIT_; - - do { - checkpoint(); - - report_tactic_progress("Searching... restarts left:", m_max_restarts - m_stats.m_restarts); - res = search(g); - - if (res == l_undef) - { -#if _RESTART_INIT_ - m_tracker.randomize(g); -#else - m_tracker.reset(g); -#endif - } - } - while (m_stats.m_stopwatch.get_current_seconds() < _TIMELIMIT_ && res != l_true && m_stats.m_restarts++ < m_max_restarts); - - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; - - if (res == l_true) { - report_tactic_progress("Number of flips:", m_stats.m_moves); - for (unsigned i = 0; i < g->size(); i++) - if (!m_mpz_manager.is_one(m_tracker.get_value(g->form(i)))) - { - verbose_stream() << "Terminated before all assertions were SAT!" << std::endl; - NOT_IMPLEMENTED_YET(); - } - - if (m_produce_models) { - model_ref mdl = m_tracker.get_model(); - mc = model2model_converter(mdl.get()); - TRACE("sls_model", mc->display(tout); ); - } - g->reset(); - } - else - mc = 0; - } - }; - +class sls_tactic : public tactic { ast_manager & m; params_ref m_params; - imp * m_imp; - stats m_stats; + sls_engine * m_engine; public: sls_tactic(ast_manager & _m, params_ref const & p): m(_m), m_params(p) { - m_imp = alloc(imp, m, p, m_stats); + m_engine = alloc(sls_engine, m, p); } virtual tactic * translate(ast_manager & m) { @@ -1395,16 +47,16 @@ public: } virtual ~sls_tactic() { - dealloc(m_imp); + dealloc(m_engine); } virtual void updt_params(params_ref const & p) { m_params = p; - m_imp->updt_params(p); + m_engine->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { - imp::collect_param_descrs(r); + sls_params::collect_param_descrs(r); } virtual void operator()(goal_ref const & g, @@ -1412,14 +64,13 @@ public: model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) { - SASSERT(g->is_well_sorted()); - m_imp->m_produce_models = g->models_enabled(); + SASSERT(g->is_well_sorted()); mc = 0; pc = 0; core = 0; result.reset(); TRACE("sls", g->display(tout);); tactic_report report("sls", *g); - m_imp->operator()(g, mc); + m_engine->operator()(g, mc); g->inc_depth(); result.push_back(g.get()); @@ -1428,40 +79,36 @@ public: } virtual void cleanup() { - imp * d = m_imp; + sls_engine * d = alloc(sls_engine, m, m_params); #pragma omp critical (tactic_cancel) { - d = m_imp; + std::swap(d, m_engine); } dealloc(d); - d = alloc(imp, m, m_params, m_stats); - #pragma omp critical (tactic_cancel) - { - m_imp = d; - } } virtual void collect_statistics(statistics & st) const { - double seconds = m_stats.m_stopwatch.get_current_seconds(); - st.update("sls restarts", m_stats.m_restarts); - st.update("sls full evals", m_stats.m_full_evals); - st.update("sls incr evals", m_stats.m_incr_evals); - st.update("sls incr evals/sec", m_stats.m_incr_evals/ seconds); - st.update("sls FLIP moves", m_stats.m_flips); - st.update("sls INC moves", m_stats.m_incs); - st.update("sls DEC moves", m_stats.m_decs); - st.update("sls INV moves", m_stats.m_invs); - st.update("sls moves", m_stats.m_moves); - st.update("sls moves/sec", m_stats.m_moves / seconds); + sls_engine::stats const & stats = m_engine->get_stats(); + double seconds = stats.m_stopwatch.get_current_seconds(); + st.update("sls restarts", stats.m_restarts); + st.update("sls full evals", stats.m_full_evals); + st.update("sls incr evals", stats.m_incr_evals); + st.update("sls incr evals/sec", stats.m_incr_evals / seconds); + st.update("sls FLIP moves", stats.m_flips); + st.update("sls INC moves", stats.m_incs); + st.update("sls DEC moves", stats.m_decs); + st.update("sls INV moves", stats.m_invs); + st.update("sls moves", stats.m_moves); + st.update("sls moves/sec", stats.m_moves / seconds); } virtual void reset_statistics() { - m_stats.reset(); + m_engine->reset_statistics(); } virtual void set_cancel(bool f) { - if (m_imp) - m_imp->set_cancel(f); + if (m_engine) + m_engine->set_cancel(f); } }; From 168c3eb363e89b245cd4d36b3a7e744b3e979748 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 19 Dec 2014 12:32:57 +0000 Subject: [PATCH 209/507] BV-SLS optimization Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 73355197a..89ef57871 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -89,6 +89,7 @@ private: unsigned m_track_unsat; obj_map m_weights; double m_top_sum; + obj_hashtable m_temp_seen; public: sls_tracker(ast_manager & m, bv_util & bvu, unsynch_mpz_manager & mm, powers & p) : @@ -440,6 +441,7 @@ public: } } + m_temp_seen.reset(); for (unsigned i = 0; i < sz; i++) { expr * e = as[i]; @@ -630,7 +632,14 @@ public: app * a = to_app(n); expr * const * args = a->get_args(); for (unsigned i = 0; i < a->get_num_args(); i++) - setup_occs(args[i]); + { + expr * child = args[i]; + if (!m_temp_seen.contains(child)) + { + setup_occs(child, false); + m_temp_seen.insert(child); + } + } } else if (m_manager.is_not(n)) { @@ -638,8 +647,7 @@ public: app * a = to_app(n); SASSERT(a->get_num_args() == 1); expr * child = a->get_arg(0); - if (m_manager.is_and(child) || m_manager.is_or(child)) - NOT_IMPLEMENTED_YET(); + SASSERT(!m_manager.is_and(child) && !m_manager.is_or(child)); setup_occs(child, true); } else From 916ef815fabe999205a858cf27063a859b1b3dd9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 12 Jan 2015 15:59:20 +0000 Subject: [PATCH 210/507] Disabled BV-SLS as default tactic in anticipation for integration with the unstable branch. Signed-off-by: Christoph M. Wintersteiger --- src/tactic/portfolio/default_tactic.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 53da9a159..5a5cbcf94 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -32,8 +32,7 @@ Notes: tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), mk_qfbv_sls_tactic(m), - // cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), From 58bf80f1138ffe356e603a76ebff8f8c8de6686b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 12 Jan 2015 17:03:56 +0000 Subject: [PATCH 211/507] Cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/tactic/smtlogics/qfbv_tactic.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index a7870176d..3b4da2f2d 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -28,8 +28,6 @@ Notes: #include"bv_size_reduction_tactic.h" #include"aig_tactic.h" #include"sat_tactic.h" -//#include"nnf_tactic.h" -//#include"sls_tactic.h" #define MEMLIMIT 300 From f1a00da401ccd42155e3753bc83320e81b89b1bb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 12 Jan 2015 17:43:56 +0000 Subject: [PATCH 212/507] BV-SLS Cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/sat/tactic/sat_tactic.cpp | 2 -- src/tactic/portfolio/default_tactic.cpp | 1 - src/tactic/portfolio/smt_strategic_solver.cpp | 5 +--- src/tactic/smtlogics/qfbv_tactic.cpp | 26 ------------------- 4 files changed, 1 insertion(+), 33 deletions(-) diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index 717bf7007..677540991 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -66,8 +66,6 @@ class sat_tactic : public tactic { CASSERT("sat_solver", m_solver.check_invariant()); IF_VERBOSE(TACTIC_VERBOSITY_LVL, m_solver.display_status(verbose_stream());); TRACE("sat_dimacs", m_solver.display_dimacs(tout);); - //m_solver.display_dimacs(std::cerr); - //exit(0); lbool r = m_solver.check(); if (r == l_false) { diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 5a5cbcf94..9ecc16ecf 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -28,7 +28,6 @@ Notes: #include"probe_arith.h" #include"quant_tactics.h" #include"qffpa_tactic.h" -#include"sls_tactic.h" tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index f63b4fd8c..ae79446e3 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -37,14 +37,11 @@ Notes: #include"horn_tactic.h" #include"smt_solver.h" -#include"sls_tactic.h" - tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") - // return mk_qfbv_tactic(m, p); - return mk_qfbv_sls_tactic(m, p); + return mk_qfbv_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); else if (logic=="QF_LIA") diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index 3b4da2f2d..ac53ca0c8 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -93,32 +93,6 @@ tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) { mk_sat_tactic(m)); #endif - /* use full sls - tactic * st = using_params(and_then(preamble_st, - cond(mk_is_qfbv_probe(), - cond(mk_is_qfbv_eq_probe(), - and_then(mk_bv1_blaster_tactic(m), - using_params(mk_smt_tactic(), solver_p)), - and_then(mk_nnf_tactic(m, p), mk_sls_tactic(m))), - mk_smt_tactic())), - main_p);*/ - - /* use pure dpll - tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), - and_then(mk_bit_blaster_tactic(m), - when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)), - and_then(using_params(and_then(mk_simplify_tactic(m), - mk_solve_eqs_tactic(m)), - local_ctx_p), - if_no_proofs(cond(mk_produce_unsat_cores_probe(), - mk_aig_tactic(), - using_params(mk_aig_tactic(), - big_aig_p))))), - new_sat), - mk_smt_tactic())), - main_p);*/ - tactic * st = using_params(and_then(preamble_st, // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function // symbols. In this case, we should not use From dbc9bebd189bc168218b3cef30e203bb888c50d3 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Thu, 15 Jan 2015 16:47:10 +0530 Subject: [PATCH 213/507] fix instance test Signed-off-by: Nikolaj Bjorner --- src/api/python/z3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index db629cd2d..1414201b2 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -6183,7 +6183,7 @@ class Fixedpoint(Z3PPObject): """ query = _get_args(query) sz = len(query) - if sz >= 1 and isinstance(query[0], FuncDecl): + if sz >= 1 and isinstance(query[0], FuncDeclRef): _decls = (FuncDecl * sz)() i = 0 for q in query: From caafee0033bf3df860dff3c53694f42075c9978a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 15 Jan 2015 19:18:18 +0000 Subject: [PATCH 214/507] Added simplifier plugin for FP --- src/ast/simplifier/fpa_simplifier_plugin.cpp | 43 ++++++++++++++++++++ src/ast/simplifier/fpa_simplifier_plugin.h | 40 ++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 src/ast/simplifier/fpa_simplifier_plugin.cpp create mode 100644 src/ast/simplifier/fpa_simplifier_plugin.h diff --git a/src/ast/simplifier/fpa_simplifier_plugin.cpp b/src/ast/simplifier/fpa_simplifier_plugin.cpp new file mode 100644 index 000000000..d2f7a3e58 --- /dev/null +++ b/src/ast/simplifier/fpa_simplifier_plugin.cpp @@ -0,0 +1,43 @@ +/*++ +Copyright (c) 2015 Microsoft Corporation + +Module Name: + + fpa_simplifier_plugin.cpp + +Abstract: + + Simplifier for the floating-point theory + +Author: + + Christoph (cwinter) 2015-01-14 + +--*/ +#include"fpa_simplifier_plugin.h" + +fpa_simplifier_plugin::fpa_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b) : +simplifier_plugin(symbol("fpa"), m), +m_util(m), +m_bsimp(b), +m_rw(m) {} + +fpa_simplifier_plugin::~fpa_simplifier_plugin() {} + +bool fpa_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { + set_reduce_invoked(); + + SASSERT(f->get_family_id() == get_family_id()); + /*switch (f->get_decl_kind()) { + case OP_FPA_FP: break; + }*/ + + return m_rw.mk_app_core(f, num_args, args, result) == BR_DONE; +} + +bool fpa_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) { + set_reduce_invoked(); + + return m_rw.mk_eq_core(lhs, rhs, result) == BR_DONE; +} + diff --git a/src/ast/simplifier/fpa_simplifier_plugin.h b/src/ast/simplifier/fpa_simplifier_plugin.h new file mode 100644 index 000000000..36e315737 --- /dev/null +++ b/src/ast/simplifier/fpa_simplifier_plugin.h @@ -0,0 +1,40 @@ +/*++ +Copyright (c) 2015 Microsoft Corporation + +Module Name: + + fpa_simplifier_plugin.h + +Abstract: + + Simplifier for the floating-point theory + +Author: + + Christoph (cwinter) 2015-01-14 + +--*/ +#ifndef _FPA_SIMPLIFIER_PLUGIN_H_ +#define _FPA_SIMPLIFIER_PLUGIN_H_ + +#include"basic_simplifier_plugin.h" +#include"fpa_decl_plugin.h" +#include"fpa_rewriter.h" + +class fpa_simplifier_plugin : public simplifier_plugin { + fpa_util m_util; + basic_simplifier_plugin & m_bsimp; + fpa_rewriter m_rw; + +public: + fpa_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b); + ~fpa_simplifier_plugin(); + + + virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); + + virtual bool reduce_eq(expr * lhs, expr * rhs, expr_ref & result); + +}; + +#endif /* _FPA_SIMPLIFIER_PLUGIN_H_ */ From 5344d6f3c02f02aa980f916eb8ae09acba7ae81b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 15 Jan 2015 19:25:49 +0000 Subject: [PATCH 215/507] various bugfixes and extensions for FPA Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 237 ++++++------- src/ast/fpa/fpa2bv_converter.h | 16 +- src/ast/fpa/fpa2bv_rewriter.h | 10 +- src/ast/fpa_decl_plugin.cpp | 12 +- src/ast/fpa_decl_plugin.h | 7 +- src/ast/rewriter/fpa_rewriter.cpp | 10 +- src/smt/asserted_formulas.cpp | 4 +- src/smt/theory_fpa.cpp | 412 +++++++++++++--------- src/tactic/fpa/fpa2bv_model_converter.cpp | 2 +- src/tactic/fpa/qffp_tactic.cpp | 27 +- 10 files changed, 396 insertions(+), 341 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f6ce259f2..4cdb64d8d 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -44,8 +44,8 @@ fpa2bv_converter::~fpa2bv_converter() { } void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { - SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_TO_FP)); - SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_FP)); + SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_FP)); expr_ref sgn(m), s(m), e(m); m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), sgn); @@ -64,20 +64,20 @@ void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) { } void fpa2bv_converter::mk_ite(expr * c, expr * t, expr * f, expr_ref & result) { - SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_FPA_TO_FP)); - SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(t, m_plugin->get_family_id(), OP_FPA_FP)); + SASSERT(is_app_of(f, m_plugin->get_family_id(), OP_FPA_FP)); expr *t_sgn, *t_sig, *t_exp; expr *f_sgn, *f_sig, *f_exp; - split_triple(t, t_sgn, t_sig, t_exp); - split_triple(f, f_sgn, f_sig, f_exp); + split_fp(t, t_sgn, t_exp, t_sig); + split_fp(f, f_sgn, f_exp, f_sig); expr_ref sgn(m), s(m), e(m); m_simp.mk_ite(c, t_sgn, f_sgn, sgn); m_simp.mk_ite(c, t_sig, f_sig, s); m_simp.mk_ite(c, t_exp, f_exp, e); - mk_triple(sgn, s, e, result); + mk_fp(sgn, e, s, result); } void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -111,7 +111,7 @@ void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * ar mk_bias(e, biased_exp); - mk_triple(bv_sgn, bv_sig, biased_exp, result); + mk_fp(bv_sgn, biased_exp, bv_sig, result); TRACE("fpa2bv_dbg", tout << "value of [" << sign << " " << m_mpz_manager.to_string(sig) << " " << exp << "] is " << mk_ismt2_pp(result, m) << std::endl;); @@ -158,7 +158,7 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) { SASSERT(m_bv_util.get_bv_size(e) == ebits); #endif - mk_triple(sgn, s, e, result); + mk_fp(sgn, e, s, result); m_const2bv.insert(f, result); m.inc_ref(f); @@ -177,7 +177,7 @@ void fpa2bv_converter::mk_var(unsigned base_inx, sort * srt, expr_ref & result) s = m.mk_var(base_inx + 1, m_bv_util.mk_sort(sbits-1)); e = m.mk_var(base_inx + 2, m_bv_util.mk_sort(ebits)); - mk_triple(sgn, s, e, result); + mk_fp(sgn, e, s, result); } void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, expr * const * args, expr_ref & result) @@ -191,7 +191,7 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex if (is_float(args[i])) { expr * sgn, * sig, * exp; - split_triple(args[i], sgn, sig, exp); + split_fp(args[i], sgn, exp, sig); new_args.push_back(sgn); new_args.push_back(sig); new_args.push_back(exp); @@ -210,7 +210,7 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex a_sgn = m.mk_app(fd3.f_sgn, new_args.size(), new_args.c_ptr()); a_sig = m.mk_app(fd3.f_sig, new_args.size(), new_args.c_ptr()); a_exp = m.mk_app(fd3.f_exp, new_args.size(), new_args.c_ptr()); - mk_triple(a_sgn, a_sig, a_exp, result); + mk_fp(a_sgn, a_exp, a_sig, result); } else { sort_ref_buffer new_domain(m); @@ -256,7 +256,7 @@ void fpa2bv_converter::mk_uninterpreted_function(func_decl * f, unsigned num, ex m.inc_ref(f_sgn); m.inc_ref(f_sig); m.inc_ref(f_exp); - mk_triple(a_sgn, a_sig, a_exp, result); + mk_fp(a_sgn, a_exp, a_sig, result); } } @@ -300,10 +300,10 @@ void fpa2bv_converter::mk_pinf(func_decl * f, expr_ref & result) { unsigned ebits = m_util.get_ebits(srt); expr_ref top_exp(m); mk_top_exp(ebits, top_exp); - mk_triple(m_bv_util.mk_numeral(0, 1), - m_bv_util.mk_numeral(0, sbits-1), - top_exp, - result); + mk_fp(m_bv_util.mk_numeral(0, 1), + top_exp, + m_bv_util.mk_numeral(0, sbits-1), + result); } void fpa2bv_converter::mk_ninf(func_decl * f, expr_ref & result) { @@ -313,10 +313,10 @@ void fpa2bv_converter::mk_ninf(func_decl * f, expr_ref & result) { unsigned ebits = m_util.get_ebits(srt); expr_ref top_exp(m); mk_top_exp(ebits, top_exp); - mk_triple(m_bv_util.mk_numeral(1, 1), - m_bv_util.mk_numeral(0, sbits-1), - top_exp, - result); + mk_fp(m_bv_util.mk_numeral(1, 1), + top_exp, + m_bv_util.mk_numeral(0, sbits-1), + result); } void fpa2bv_converter::mk_nan(func_decl * f, expr_ref & result) { @@ -326,10 +326,10 @@ void fpa2bv_converter::mk_nan(func_decl * f, expr_ref & result) { unsigned ebits = m_util.get_ebits(srt); expr_ref top_exp(m); mk_top_exp(ebits, top_exp); - mk_triple(m_bv_util.mk_numeral(0, 1), - m_bv_util.mk_numeral(1, sbits-1), - top_exp, - result); + mk_fp(m_bv_util.mk_numeral(0, 1), + top_exp, + m_bv_util.mk_numeral(1, sbits-1), + result); } void fpa2bv_converter::mk_nzero(func_decl *f, expr_ref & result) { @@ -339,10 +339,10 @@ void fpa2bv_converter::mk_nzero(func_decl *f, expr_ref & result) { unsigned ebits = m_util.get_ebits(srt); expr_ref bot_exp(m); mk_bot_exp(ebits, bot_exp); - mk_triple(m_bv_util.mk_numeral(1, 1), - m_bv_util.mk_numeral(0, sbits-1), - bot_exp, - result); + mk_fp(m_bv_util.mk_numeral(1, 1), + bot_exp, + m_bv_util.mk_numeral(0, sbits - 1), + result); } void fpa2bv_converter::mk_pzero(func_decl *f, expr_ref & result) { @@ -352,10 +352,10 @@ void fpa2bv_converter::mk_pzero(func_decl *f, expr_ref & result) { unsigned ebits = m_util.get_ebits(srt); expr_ref bot_exp(m); mk_bot_exp(ebits, bot_exp); - mk_triple(m_bv_util.mk_numeral(0, 1), - m_bv_util.mk_numeral(0, sbits-1), - bot_exp, - result); + mk_fp(m_bv_util.mk_numeral(0, 1), + bot_exp, + m_bv_util.mk_numeral(0, sbits-1), + result); } void fpa2bv_converter::add_core(unsigned sbits, unsigned ebits, expr_ref & rm, @@ -607,13 +607,13 @@ void fpa2bv_converter::mk_sub(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_neg(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; - split_triple(args[0], sgn, s, e); + split_fp(args[0], sgn, e, s); expr_ref c(m), nsgn(m); mk_is_nan(args[0], c); nsgn = m_bv_util.mk_bv_not(sgn); expr_ref r_sgn(m); m_simp.mk_ite(c, sgn, nsgn, r_sgn); - mk_triple(r_sgn, s, e, result); + mk_fp(r_sgn, e, s, result); } void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -1027,8 +1027,8 @@ void fpa2bv_converter::mk_rem(func_decl * f, unsigned num, expr * const * args, void fpa2bv_converter::mk_abs(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; - split_triple(args[0], sgn, s, e); - mk_triple(m_bv_util.mk_numeral(0, 1), s, e, result); + split_fp(args[0], sgn, e, s); + mk_fp(m_bv_util.mk_numeral(0, 1), e, s, result); } void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -1038,8 +1038,8 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split_triple(x, x_sgn, x_sig, x_exp); - split_triple(y, y_sgn, y_sig, y_exp); + split_fp(x, x_sgn, x_exp, x_sig); + split_fp(y, y_sgn, y_exp, y_sig); expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), x_is_zero(m), y_is_zero(m), c1_and(m); mk_is_zero(x, x_is_zero); @@ -1071,7 +1071,7 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args, m_simp.mk_ite(c2, x_exp, c3xy_exp, c2c3_exp); m_simp.mk_ite(c1, y_exp, c2c3_exp, r_exp); - mk_triple(r_sgn, r_sig, r_exp, result); + mk_fp(r_sgn, r_exp, r_sig, result); } void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -1081,8 +1081,8 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split_triple(x, x_sgn, x_sig, x_exp); - split_triple(y, y_sgn, y_sig, y_exp); + split_fp(x, x_sgn, x_exp, x_sig); + split_fp(y, y_sgn, y_exp, y_sig); expr_ref c1(m), c2(m), x_is_nan(m), y_is_nan(m), y_is_zero(m), x_is_zero(m), c1_and(m); mk_is_zero(y, y_is_zero); @@ -1114,7 +1114,7 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args, m_simp.mk_ite(c2, x_exp, c3xy_exp, c2c3_exp); m_simp.mk_ite(c1, y_exp, c2c3_exp, r_exp); - mk_triple(r_sgn, r_sig, r_exp, result); + mk_fp(r_sgn, r_exp, r_sig, result); } void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { @@ -1689,8 +1689,8 @@ void fpa2bv_converter::mk_float_eq(func_decl * f, unsigned num, expr * const * a expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split_triple(x, x_sgn, x_sig, x_exp); - split_triple(y, y_sgn, y_sig, y_exp); + split_fp(x, x_sgn, x_exp, x_sig); + split_fp(y, y_sgn, y_exp, y_sig); expr_ref x_eq_y_sgn(m), x_eq_y_exp(m), x_eq_y_sig(m); m_simp.mk_eq(x_sgn, y_sgn, x_eq_y_sgn); @@ -1725,8 +1725,8 @@ void fpa2bv_converter::mk_float_lt(func_decl * f, unsigned num, expr * const * a expr * x_sgn, * x_sig, * x_exp; expr * y_sgn, * y_sig, * y_exp; - split_triple(x, x_sgn, x_sig, x_exp); - split_triple(y, y_sgn, y_sig, y_exp); + split_fp(x, x_sgn, x_exp, x_sig); + split_fp(y, y_sgn, y_exp, y_sig); expr_ref c3(m), t3(m), t4(m), one_1(m), nil_1(m); one_1 = m_bv_util.mk_numeral(1, 1); @@ -1863,10 +1863,10 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args int sz = m_bv_util.get_bv_size(bv); SASSERT((unsigned)sz == to_sbits + to_ebits); - mk_triple(m_bv_util.mk_extract(sz - 1, sz - 1, bv), - m_bv_util.mk_extract(sz - to_ebits - 2, 0, bv), - m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), - result); + mk_fp(m_bv_util.mk_extract(sz - 1, sz - 1, bv), + m_bv_util.mk_extract(sz - 2, sz - to_ebits - 1, bv), + m_bv_util.mk_extract(sz - to_ebits - 2, 0, bv), + result); } else if (num == 2 && m_bv_util.is_bv(args[0]) && @@ -1895,7 +1895,7 @@ void fpa2bv_converter::mk_to_fp(func_decl * f, unsigned num, expr * const * args SASSERT(m_bv_util.get_bv_size(args[0]) == 1); SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); - mk_triple(args[0], args[2], args[1], result); + mk_fp(args[0], args[1], args[2], result); } else if (num == 3 && m_bv_util.is_bv(args[0]) && @@ -2061,6 +2061,8 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * TRACE("fpa2bv_to_fp_real", tout << "rm: " << mk_ismt2_pp(rm, m) << std::endl << "x: " << mk_ismt2_pp(x, m) << std::endl;); SASSERT(m_util.is_float(s)); + SASSERT(au().is_real(x)); + unsigned ebits = m_util.get_ebits(s); unsigned sbits = m_util.get_sbits(s); @@ -2093,11 +2095,9 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits); mk_bias(unbiased_exp, e); - mk_triple(sgn, s, e, result); + mk_fp(sgn, e, s, result); } - else { - NOT_IMPLEMENTED_YET(); - + else { mpf_manager & fm = fu().fm(); bv_util & bu = m_bv_util; arith_util & au = m_arith_util; @@ -2109,44 +2109,15 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * two = au.mk_numeral(rational(2), false); expr_ref sgn(m), sig(m), exp(m); - sgn = m.mk_ite(au.mk_lt(x, zero), bv1, bv0); - sig = bu.mk_numeral(0, sbits + 4); - mpz const & max_normal_exponent = fm.m_powers2.m1(ebits-1); - exp = bu.mk_numeral(max_normal_exponent, ebits); - - //expr_ref cur_s(m), cur_d(m), cur_r(m), cur_s2(m), bv1_s4(m); - //bv1_s4 = bu.mk_numeral(1, sbits + 4); - //cur_s = x; - //std::string trace_name; - //for (unsigned i = 0; i < sbits + 3; i++) { - // std::stringstream dbg_name; - // dbg_name << "fpa2bv_to_float_real_sig_" << i; - // dbg_decouple(dbg_name.str().c_str(), sig); + sgn = mk_fresh_const("fpa2bv_to_fp_real_sgn", 1); + sig = mk_fresh_const("fpa2bv_to_fp_real_sig", sbits + 4); + exp = mk_fresh_const("fpa2bv_to_fp_real_exp", ebits + 2); - // cur_s = au.mk_div(cur_s, two); - // // cur_r = au.mk_rem(cur_s, two); - // cur_r = au.mk_mod(cur_s, two); - // cur_s2 = bu.mk_bv_shl(sig, bv1_s4); - // sig = m.mk_ite(au.mk_eq(cur_r, zero), - // cur_s2, - // bu.mk_bv_add(cur_s2, bv1_s4)); - //} - //dbg_decouple("fpa2bv_to_float_real_last_cur_s", cur_s); - //expr_ref inc(m); - //inc = m.mk_not(m.mk_eq(cur_s, zero)); - //dbg_decouple("fpa2bv_to_float_real_inc", inc); - //sig = m.mk_ite(inc, bu.mk_bv_add(sig, bv1_s4), sig); - - //SASSERT(bu.get_bv_size(sgn) == 1); - //SASSERT(bu.get_bv_size(sig) == sbits + 4); - //SASSERT(bu.get_bv_size(exp) == ebits + 2); + expr_ref rme(rm, m); + round(s, rme, sgn, sig, exp, result); - //dbg_decouple("fpa2bv_to_float_real_sgn", sgn); - //dbg_decouple("fpa2bv_to_float_real_sig", sig); - //dbg_decouple("fpa2bv_to_float_real_exp", exp); - - //expr_ref rmr(rm, m); - //round(s, rmr, sgn, sig, exp, result); + expr * e = m.mk_eq(m_util.mk_to_real(result), x); + m_extra_assertions.push_back(e); } SASSERT(is_well_sorted(m, result)); @@ -2208,7 +2179,7 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); SASSERT(num == 1); SASSERT(f->get_num_parameters() == 0); - SASSERT(is_app_of(args[0], m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(args[0], m_plugin->get_family_id(), OP_FPA_FP)); expr * x = args[0]; sort * s = m.get_sort(x); @@ -2565,19 +2536,10 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { SASSERT(num == 1); expr * sgn, * s, * e; - split_triple(args[0], sgn, s, e); + split_fp(args[0], sgn, e, s); result = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s); } -void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { - SASSERT(num == 3); - SASSERT(m_bv_util.get_bv_size(args[0]) == 1); - SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2])+1); - SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); - mk_triple(args[0], args[2], args[1], result); - TRACE("fpa2bv_mk_fp", tout << "mk_fp result = " << mk_ismt2_pp(result, m) << std::endl;); -} - void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { TRACE("fpa2bv_to_ubv", for (unsigned i = 0; i < num; i++) tout << "arg" << i << " = " << mk_ismt2_pp(args[i], m) << std::endl;); @@ -2753,6 +2715,10 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg expr_ref sgn(m), sig(m), exp(m), lz(m); unpack(x, sgn, sig, exp, lz, true); + dbg_decouple("fpa2bv_to_sbv_sgn", sgn); + dbg_decouple("fpa2bv_to_sbv_sig", sig); + dbg_decouple("fpa2bv_to_sbv_exp", exp); + // x is of the form +- [1].[sig] * 2^(exp-lz) SASSERT(m_bv_util.get_bv_size(sgn) == 1); SASSERT(m_bv_util.get_bv_size(sig) == sbits); @@ -2777,8 +2743,8 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2); SASSERT(m_bv_util.get_bv_size(shift_neg) == ebits + 2); SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2); - dbg_decouple("fpa2bv_to_ubv_shift", shift); - dbg_decouple("fpa2bv_to_ubv_shift_abs", shift_abs); + dbg_decouple("fpa2bv_to_sbv_shift", shift); + dbg_decouple("fpa2bv_to_sbv_shift_abs", shift_abs); // sig is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long // [1][ ... sig ... ][r][g][ ... s ...] @@ -2861,28 +2827,43 @@ expr_ref fpa2bv_converter::mk_to_real_unspecified() { return expr_ref(m_util.mk_internal_to_real_unspecified(), m); } -void fpa2bv_converter::split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); - SASSERT(to_app(e)->get_num_args() == 3); - +void fpa2bv_converter::mk_fp(expr * sign, expr * exponent, expr * significand, expr_ref & result) { + SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); + SASSERT(m_bv_util.is_bv(significand)); + SASSERT(m_bv_util.is_bv(exponent)); + result = m.mk_app(m_util.get_family_id(), OP_FPA_FP, sign, exponent, significand); +} + +void fpa2bv_converter::mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + SASSERT(num == 3); + SASSERT(m_bv_util.get_bv_size(args[0]) == 1); + SASSERT(m_util.get_sbits(f->get_range()) == m_bv_util.get_bv_size(args[2]) + 1); + SASSERT(m_util.get_ebits(f->get_range()) == m_bv_util.get_bv_size(args[1])); + mk_fp(args[0], args[1], args[2], result); + TRACE("fpa2bv_mk_fp", tout << "mk_fp result = " << mk_ismt2_pp(result, m) << std::endl;); +} + +void fpa2bv_converter::split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const { + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_FP)); + SASSERT(to_app(e)->get_num_args() == 3); sgn = to_app(e)->get_arg(0); exp = to_app(e)->get_arg(1); sig = to_app(e)->get_arg(2); } -void fpa2bv_converter::split_triple(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp) const { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); +void fpa2bv_converter::split_fp(expr * e, expr_ref & sgn, expr_ref & exp, expr_ref & sig) const { + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr *e_sgn, *e_sig, *e_exp; - split_triple(e, e_sgn, e_sig, e_exp); + split_fp(e, e_sgn, e_exp, e_sig); sgn = e_sgn; - sig = e_sig; exp = e_exp; + sig = e_sig; } void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); // exp == 1^n , sig != 0 expr_ref sig_is_zero(m), sig_is_not_zero(m), exp_is_top(m), top_exp(m), zero(m); @@ -2897,7 +2878,7 @@ void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_inf(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); expr_ref eq1(m), eq2(m), top_exp(m), zero(m); mk_top_exp(m_bv_util.get_bv_size(exp), top_exp); zero = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(sig)); @@ -2921,7 +2902,7 @@ void fpa2bv_converter::mk_is_ninf(expr * e, expr_ref & result) { } void fpa2bv_converter::mk_is_pos(expr * e, expr_ref & result) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr * a0 = to_app(e)->get_arg(0); expr_ref zero(m); @@ -2930,7 +2911,7 @@ void fpa2bv_converter::mk_is_pos(expr * e, expr_ref & result) { } void fpa2bv_converter::mk_is_neg(expr * e, expr_ref & result) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_FP)); SASSERT(to_app(e)->get_num_args() == 3); expr * a0 = to_app(e)->get_arg(0); expr_ref one(m); @@ -2940,7 +2921,7 @@ void fpa2bv_converter::mk_is_neg(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_zero(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); expr_ref eq1(m), eq2(m), bot_exp(m), zero(m); mk_bot_exp(m_bv_util.get_bv_size(exp), bot_exp); zero = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(sig)); @@ -2951,7 +2932,7 @@ void fpa2bv_converter::mk_is_zero(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_nzero(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); expr_ref e_is_zero(m), eq(m), one_1(m); mk_is_zero(e, e_is_zero); one_1 = m_bv_util.mk_numeral(1, 1); @@ -2961,7 +2942,7 @@ void fpa2bv_converter::mk_is_nzero(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_pzero(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); expr_ref e_is_zero(m), eq(m), nil_1(m); mk_is_zero(e, e_is_zero); nil_1 = m_bv_util.mk_numeral(0, 1); @@ -2971,7 +2952,7 @@ void fpa2bv_converter::mk_is_pzero(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_denormal(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); expr_ref zero(m); zero = m_bv_util.mk_numeral(0, m_bv_util.get_bv_size(exp)); m_simp.mk_eq(exp, zero, result); @@ -2979,7 +2960,7 @@ void fpa2bv_converter::mk_is_denormal(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_normal(expr * e, expr_ref & result) { expr * sgn, * sig, * exp; - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); expr_ref is_special(m), is_denormal(m), p(m); mk_is_denormal(e, is_denormal); @@ -3093,7 +3074,7 @@ void fpa2bv_converter::mk_unbias(expr * e, expr_ref & result) { } void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp, expr_ref & lz, bool normalize) { - SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_TO_FP)); + SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_FPA_FP)); SASSERT(to_app(e)->get_num_args() == 3); sort * srt = to_app(e)->get_decl()->get_range(); @@ -3101,7 +3082,11 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref unsigned sbits = m_util.get_sbits(srt); unsigned ebits = m_util.get_ebits(srt); - split_triple(e, sgn, sig, exp); + split_fp(e, sgn, exp, sig); + + SASSERT(m_bv_util.get_bv_size(sgn) == 1); + SASSERT(m_bv_util.get_bv_size(exp) == ebits); + SASSERT(m_bv_util.get_bv_size(sig) == sbits-1); expr_ref is_normal(m); mk_is_normal(e, is_normal); @@ -3134,7 +3119,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref expr_ref shift(m); m_simp.mk_ite(is_sig_zero, zero_e, lz, shift); dbg_decouple("fpa2bv_unpack_shift", shift); - SASSERT(is_well_sorted(m, is_sig_zero)); + SASSERT(is_well_sorted(m, is_sig_zero)); SASSERT(is_well_sorted(m, shift)); SASSERT(m_bv_util.get_bv_size(shift) == ebits); if (ebits <= sbits) { @@ -3545,7 +3530,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & SASSERT(m_bv_util.get_bv_size(res_exp) == ebits); SASSERT(is_well_sorted(m, res_exp)); - mk_triple(res_sgn, res_sig, res_exp, result); + mk_fp(res_sgn, res_exp, res_sig, result); TRACE("fpa2bv_round", tout << "ROUND = " << mk_ismt2_pp(result, m) << std::endl; ); } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 062c56ef2..82fad6ff9 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -72,15 +72,11 @@ public: bool is_rm(sort * s) { return m_util.is_rm(s); } bool is_float_family(func_decl * f) { return f->get_family_id() == m_util.get_family_id(); } - void mk_triple(expr * sign, expr * significand, expr * exponent, expr_ref & result) { - SASSERT(m_bv_util.is_bv(sign) && m_bv_util.get_bv_size(sign) == 1); - SASSERT(m_bv_util.is_bv(significand)); - SASSERT(m_bv_util.is_bv(exponent)); - result = m.mk_app(m_util.get_family_id(), OP_FPA_TO_FP, sign, exponent, significand); - } + void mk_fp(expr * sign, expr * exponent, expr * significand, expr_ref & result); + void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void split_triple(expr * e, expr * & sgn, expr * & sig, expr * & exp) const; - void split_triple(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref & exp) const; + void split_fp(expr * e, expr * & sgn, expr * & exp, expr * & sig) const; + void split_fp(expr * e, expr_ref & sgn, expr_ref & exp, expr_ref & sig) const; void mk_eq(expr * a, expr * b, expr_ref & result); void mk_ite(expr * c, expr * t, expr * f, expr_ref & result); @@ -125,9 +121,7 @@ public: void mk_is_nan(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_inf(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_is_normal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - void mk_is_subnormal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); - - void mk_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_is_subnormal(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_fp(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * x, expr_ref & result); diff --git a/src/ast/fpa/fpa2bv_rewriter.h b/src/ast/fpa/fpa2bv_rewriter.h index 75176c9c4..ed885a4cc 100644 --- a/src/ast/fpa/fpa2bv_rewriter.h +++ b/src/ast/fpa/fpa2bv_rewriter.h @@ -259,13 +259,13 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { unsigned ebits = m_conv.fu().get_ebits(s); unsigned sbits = m_conv.fu().get_sbits(s); new_var = m().mk_var(t->get_idx(), m_conv.bu().mk_sort(sbits+ebits)); - m_conv.mk_triple(m_conv.bu().mk_extract(sbits+ebits-1, sbits+ebits-1, new_var), - m_conv.bu().mk_extract(sbits+ebits-2, ebits, new_var), - m_conv.bu().mk_extract(ebits-1, 0, new_var), - new_exp); + m_conv.mk_fp(m_conv.bu().mk_extract(sbits+ebits-1, sbits+ebits-1, new_var), + m_conv.bu().mk_extract(ebits - 1, 0, new_var), + m_conv.bu().mk_extract(sbits+ebits-2, ebits, new_var), + new_exp); } else - new_exp = m().mk_var(t->get_idx(), s); + new_exp = m().mk_var(t->get_idx(), s); result = new_exp; result_pr = 0; diff --git a/src/ast/fpa_decl_plugin.cpp b/src/ast/fpa_decl_plugin.cpp index 9900812dd..8cf158604 100644 --- a/src/ast/fpa_decl_plugin.cpp +++ b/src/ast/fpa_decl_plugin.cpp @@ -72,7 +72,7 @@ func_decl * fpa_decl_plugin::mk_numeral_decl(mpf const & v) { parameter p(mk_id(v), true); SASSERT(p.is_external()); sort * s = mk_float_sort(v.get_ebits(), v.get_sbits()); - return m_manager->mk_const_decl(symbol("fpa"), s, func_decl_info(m_family_id, OP_FPA_NUM, 1, &p)); + return m_manager->mk_const_decl(symbol("fp.numeral"), s, func_decl_info(m_family_id, OP_FPA_NUM, 1, &p)); } app * fpa_decl_plugin::mk_numeral(mpf const & v) { @@ -131,6 +131,11 @@ bool fpa_decl_plugin::is_numeral(expr * n, mpf & val) { return false; } +bool fpa_decl_plugin::is_numeral(expr * n) { + scoped_mpf v(m_fm); + return is_numeral(n, v); +} + bool fpa_decl_plugin::is_rm_numeral(expr * n, mpf_rounding_mode & val) { if (is_app_of(n, m_family_id, OP_FPA_RM_NEAREST_TIES_TO_AWAY)) { val = MPF_ROUND_NEAREST_TAWAY; @@ -156,6 +161,11 @@ bool fpa_decl_plugin::is_rm_numeral(expr * n, mpf_rounding_mode & val) { return 0; } +bool fpa_decl_plugin::is_rm_numeral(expr * n) { + mpf_rounding_mode t; + return is_rm_numeral(n, t); +} + void fpa_decl_plugin::del(parameter const & p) { SASSERT(p.is_external()); recycled_id(p.get_ext_id()); diff --git a/src/ast/fpa_decl_plugin.h b/src/ast/fpa_decl_plugin.h index 24481d348..fc1521456 100644 --- a/src/ast/fpa_decl_plugin.h +++ b/src/ast/fpa_decl_plugin.h @@ -191,10 +191,10 @@ public: mpf_manager & fm() { return m_fm; } func_decl * mk_numeral_decl(mpf const & v); app * mk_numeral(mpf const & v); - bool is_numeral(expr * n) { return is_app_of(n, m_family_id, OP_FPA_NUM); } + bool is_numeral(expr * n); bool is_numeral(expr * n, mpf & val); bool is_rm_numeral(expr * n, mpf_rounding_mode & val); - bool is_rm_numeral(expr * n) { mpf_rounding_mode t; return is_rm_numeral(n, t); } + bool is_rm_numeral(expr * n); mpf const & get_value(unsigned id) const { SASSERT(m_value_table.contains(id)); @@ -322,8 +322,7 @@ public: app * mk_is_inf(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_INF, arg1); } app * mk_is_zero(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_ZERO, arg1); } app * mk_is_normal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NORMAL, arg1); } - app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_SUBNORMAL, arg1); } - app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NEGATIVE, arg1); } + app * mk_is_subnormal(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_SUBNORMAL, arg1); } app * mk_is_positive(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_POSITIVE, arg1); } app * mk_is_negative(expr * arg1) { return m().mk_app(m_fid, OP_FPA_IS_NEGATIVE, arg1); } diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 915d25e50..ce7fe5ed6 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -131,7 +131,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const scoped_mpf v(m_util.fm()); m_util.fm().set(v, ebits, sbits, rm, q.to_mpq(), e.to_mpq().numerator()); result = m_util.mk_value(v); - m_util.fm().del(v); + m_util.fm().del(v); return BR_DONE; } else if (bu.is_numeral(args[0], r1, bvs1) && @@ -268,10 +268,8 @@ br_status fpa_rewriter::mk_abs(expr * arg1, expr_ref & result) { result = arg1; return BR_DONE; } - result = m().mk_ite(m_util.mk_is_sign_minus(arg1), - m_util.mk_neg(arg1), - arg1); - return BR_REWRITE2; + + return BR_FAILED; } br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) { @@ -565,7 +563,7 @@ br_status fpa_rewriter::mk_fp(expr * arg1, expr * arg2, expr * arg3, expr_ref & r1.is_one(), r3.to_mpq().numerator(), m_util.fm().unbias_exp(bvs2, biased_exp)); - TRACE("fp_rewriter", tout << "v = " << m_util.fm().to_string(v) << std::endl;); + TRACE("fp_rewriter", tout << "simplified (fp ...) to " << m_util.fm().to_string(v) << std::endl;); result = m_util.mk_value(v); return BR_DONE; } diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index 4775e44a4..1acfcdf57 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -22,6 +22,7 @@ Revision History: #include"arith_simplifier_plugin.h" #include"array_simplifier_plugin.h" #include"datatype_simplifier_plugin.h" +#include"fpa_simplifier_plugin.h" #include"bv_simplifier_plugin.h" #include"for_each_expr.h" #include"well_sorted.h" @@ -96,7 +97,8 @@ void asserted_formulas::setup_simplifier_plugins(simplifier & s, basic_simplifie s.register_plugin(alloc(array_simplifier_plugin, m_manager, *bsimp, s, m_params)); bvsimp = alloc(bv_simplifier_plugin, m_manager, *bsimp, m_params); s.register_plugin(bvsimp); - s.register_plugin(alloc(datatype_simplifier_plugin, m_manager, *bsimp)); + s.register_plugin(alloc(datatype_simplifier_plugin, m_manager, *bsimp)); + s.register_plugin(alloc(fpa_simplifier_plugin, m_manager, *bsimp)); } void asserted_formulas::init(unsigned num_formulas, expr * const * formulas, proof * const * prs) { diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index 158622428..ac9bd5141 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -54,11 +54,11 @@ namespace smt { unsigned ebits = m_th.m_fpa_util.get_ebits(s); unsigned sbits = m_th.m_fpa_util.get_sbits(s); SASSERT(bv_sz == ebits + sbits); - m_th.m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), - m_bv_util.mk_extract(sbits - 2, 0, bv), - m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), - result); - + m_th.m_converter.mk_fp(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), + m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), + m_bv_util.mk_extract(sbits - 2, 0, bv), + result); + SASSERT(m_th.m_fpa_util.is_float(result)); m_const2bv.insert(f, result); m.inc_ref(f); m.inc_ref(result); @@ -97,62 +97,86 @@ namespace smt { } theory_fpa::~theory_fpa() - { + { ast_manager & m = get_manager(); dec_ref_map_values(m, m_conversions); dec_ref_map_values(m, m_wraps); - dec_ref_map_values(m, m_unwraps); + dec_ref_map_values(m, m_unwraps); } app * theory_fpa::fpa_value_proc::mk_value(model_generator & mg, ptr_vector & values) { - SASSERT(values.size() == 1); ast_manager & m = m_th.get_manager(); + TRACE("t_fpa_detail", for (unsigned i = 0; i < values.size(); i++) + tout << "value[" << i << "] = " << mk_ismt2_pp(values[i], m) << std::endl;); + mpf_manager & mpfm = m_fu.fm(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); - unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); - - SASSERT(m_bu.get_bv_size(values[0]) == (m_ebits + m_sbits)); - + unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); app * result; - + scoped_mpz bias(mpzm); mpzm.power(mpz(2), m_ebits - 1, bias); mpzm.dec(bias); - rational all_rat(0); - scoped_mpz all_bits(mpzm); + scoped_mpz sgn_z(mpzm), sig_z(mpzm), exp_z(mpzm); unsigned bv_sz; - bool r = m_bu.is_numeral(values[0], all_rat, bv_sz); - SASSERT(r); - SASSERT(bv_sz == (m_ebits+m_sbits)); - SASSERT(all_rat.is_int()); - mpzm.set(all_bits, all_rat.to_mpq().numerator()); - - scoped_mpz sgn_z(mpzm), sig_z(mpzm), exp_z(mpzm); - mpzm.machine_div2k(all_bits, m_ebits + m_sbits - 1, sgn_z); - mpzm.mod(all_bits, mpfm.m_powers2(m_ebits + m_sbits - 1), all_bits); + if (values.size() == 1) { + SASSERT(m_bu.is_bv(values[0])); + SASSERT(m_bu.get_bv_size(values[0]) == (m_ebits + m_sbits)); - mpzm.machine_div2k(all_bits, m_sbits - 1, exp_z); - mpzm.mod(all_bits, mpfm.m_powers2(m_sbits - 1), all_bits); - - mpzm.set(sig_z, all_bits); + rational all_r(0); + scoped_mpz all_z(mpzm); - TRACE("t_fpa_detail", tout << "sgn=" << mpzm.to_string(sgn_z) << " ; " << - "sig=" << mpzm.to_string(sig_z) << " ; " << - "exp=" << mpzm.to_string(exp_z) << std::endl;); + bool r = m_bu.is_numeral(values[0], all_r, bv_sz); + SASSERT(r); + SASSERT(bv_sz == (m_ebits + m_sbits)); + SASSERT(all_r.is_int()); + mpzm.set(all_z, all_r.to_mpq().numerator()); + + mpzm.machine_div2k(all_z, m_ebits + m_sbits - 1, sgn_z); + mpzm.mod(all_z, mpfm.m_powers2(m_ebits + m_sbits - 1), all_z); + + mpzm.machine_div2k(all_z, m_sbits - 1, exp_z); + mpzm.mod(all_z, mpfm.m_powers2(m_sbits - 1), all_z); + + mpzm.set(sig_z, all_z); + } + else if (values.size() == 3) { + rational sgn_r(0), exp_r(0), sig_r(0); + + bool r = m_bu.is_numeral(values[0], sgn_r, bv_sz); + SASSERT(r && bv_sz == 1); + r = m_bu.is_numeral(values[1], exp_r, bv_sz); + SASSERT(r && bv_sz == m_ebits); + r = m_bu.is_numeral(values[2], sig_r, bv_sz); + SASSERT(r && bv_sz == m_sbits - 1); + + SASSERT(sgn_r.to_mpq().denominator() == mpz(1)); + SASSERT(exp_r.to_mpq().denominator() == mpz(1)); + SASSERT(sig_r.to_mpq().denominator() == mpz(1)); + + mpzm.set(sgn_z, sgn_r.to_mpq().numerator()); + mpzm.set(exp_z, exp_r.to_mpq().numerator()); + mpzm.set(sig_z, sig_r.to_mpq().numerator()); + } + else + UNREACHABLE(); scoped_mpz exp_u = exp_z - bias; SASSERT(mpzm.is_int64(exp_u)); - scoped_mpf f(mpfm); + scoped_mpf f(mpfm); mpfm.set(f, m_ebits, m_sbits, mpzm.is_one(sgn_z), sig_z, mpzm.get_int64(exp_u)); result = m_fu.mk_value(f); TRACE("t_fpa", tout << "fpa_value_proc::mk_value [" << - mk_ismt2_pp(values[0], m) << "] --> " << - mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + mpzm.to_string(sgn_z) << "," << + mpzm.to_string(exp_z) << "," << + mpzm.to_string(sig_z) << "] --> " << + mk_ismt2_pp(result, m_th.get_manager()) << "\n";); + return result; } @@ -160,8 +184,8 @@ namespace smt { SASSERT(values.size() == 1); ast_manager & m = m_th.get_manager(); - TRACE("t_fpa", tout << "fpa_rm_value_proc::mk_value for: [" << - mk_ismt2_pp(values[0], m) << "]" << std::endl;); + TRACE("t_fpa_detail", for (unsigned i = 0; i < values.size(); i++) + tout << "value[" << i << "] = " << mk_ismt2_pp(values[i], m) << std::endl;); app * result = 0; sort * s = m.get_sort(values[0]); @@ -199,42 +223,44 @@ namespace smt { if (!m_wraps.find(e_srt, w)) { SASSERT(!m_wraps.contains(e_srt)); - sort * bv_srt = 0; - + sort * bv_srt; if (m_converter.is_rm(e_srt)) bv_srt = m_bv_util.mk_sort(3); else { SASSERT(m_converter.is_float(e_srt)); unsigned ebits = m_fpa_util.get_ebits(e_srt); unsigned sbits = m_fpa_util.get_sbits(e_srt); - bv_srt = m_bv_util.mk_sort(ebits + sbits); + bv_srt = m_bv_util.mk_sort(ebits + sbits); } - w = m.mk_func_decl(get_family_id(), OP_FPA_INTERNAL_BVWRAP, 0, 0, 1, &e_srt, bv_srt); + w = m.mk_func_decl(get_family_id(), OP_FPA_INTERNAL_BVWRAP, 0, 0, 1, &e_srt, bv_srt); m_wraps.insert(e_srt, w); - m.inc_ref(w); + m.inc_ref(w); } - return app_ref(m.mk_app(w, e), m); + app_ref res(m); + res = m.mk_app(w, e); + return res; } app_ref theory_fpa::unwrap(expr * e, sort * s) { SASSERT(!m_fpa_util.is_unwrap(e)); ast_manager & m = get_manager(); context & ctx = get_context(); - sort * e_srt = m.get_sort(e); + sort * bv_srt = m.get_sort(e); func_decl *u; - if (!m_unwraps.find(e_srt, u)) { - SASSERT(!m_unwraps.contains(e_srt)); - sort * bv_srt = m.get_sort(e); + if (!m_unwraps.find(bv_srt, u)) { + SASSERT(!m_unwraps.contains(bv_srt)); u = m.mk_func_decl(get_family_id(), OP_FPA_INTERNAL_BVUNWRAP, 0, 0, 1, &bv_srt, s); - m_unwraps.insert(s, u); + m_unwraps.insert(bv_srt, u); m.inc_ref(u); } - return app_ref(m.mk_app(u, e), m); + app_ref res(m); + res = m.mk_app(u, e); + return res; } expr_ref theory_fpa::convert_atom(expr * e) { @@ -244,55 +270,30 @@ namespace smt { m_rw(e, res); m_th_rw(res, res); SASSERT(is_app(res)); - SASSERT(m.is_bool(res)); + SASSERT(m.is_bool(res)); return res; } expr_ref theory_fpa::convert_term(expr * e) { - ast_manager & m = get_manager(); - TRACE("t_fpa_detail", tout << "converting: " << mk_ismt2_pp(e, m) << " sort is: " << mk_ismt2_pp(m.get_sort(e), m) << std::endl;); + ast_manager & m = get_manager(); context & ctx = get_context(); - expr_ref ec(m), res(m); + expr_ref e_conv(m), res(m); proof_ref pr(m); - m_rw(e, ec); + m_rw(e, e_conv); - SASSERT(is_app(ec)); - app_ref eca(to_app(ec), m); - TRACE("t_fpa_detail", tout << "eca = " << mk_ismt2_pp(eca, m) << " sort is: " << mk_ismt2_pp(m.get_sort(eca), m) << std::endl;); - - if (m_fpa_util.is_rm(e)) { - expr_ref bv_rm(m); - bv_rm = eca; - TRACE("t_fpa_detail", tout << "bvrm = " << mk_ismt2_pp(bv_rm, m) << " sort is: " << mk_ismt2_pp(m.get_sort(bv_rm), m) << std::endl;); - SASSERT(is_sort_of(m.get_sort(bv_rm), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(m_bv_util.get_bv_size(bv_rm) == 3); - m_th_rw(bv_rm, res); + if (m_fpa_util.is_rm(e)) { + SASSERT(is_sort_of(m.get_sort(e_conv), m_bv_util.get_family_id(), BV_SORT)); + SASSERT(m_bv_util.get_bv_size(e_conv) == 3); + m_th_rw(e_conv, res); } else if (m_fpa_util.is_float(e)) { - SASSERT(eca->get_family_id() == get_family_id()); - fpa_op_kind k = (fpa_op_kind)(eca->get_decl_kind()); - SASSERT(k == OP_FPA_TO_FP || k == OP_FPA_INTERNAL_BVUNWRAP); - switch (k) { - case OP_FPA_TO_FP: { - SASSERT(eca->get_num_args() == 3); - SASSERT(is_sort_of(m.get_sort(eca->get_arg(0)), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(is_sort_of(m.get_sort(eca->get_arg(1)), m_bv_util.get_family_id(), BV_SORT)); - SASSERT(is_sort_of(m.get_sort(eca->get_arg(2)), m_bv_util.get_family_id(), BV_SORT)); - - expr *sgn, *sig, *exp; - expr_ref s_sgn(m), s_sig(m), s_exp(m); - m_converter.split_triple(eca, sgn, sig, exp); - m_th_rw(sgn, s_sgn); - m_th_rw(sig, s_sig); - m_th_rw(exp, s_exp); - - m_converter.mk_triple(s_sgn, s_sig, s_exp, res); - break; - } - default: - res = eca; - } + expr_ref sgn(m), sig(m), exp(m); + m_converter.split_fp(e_conv, sgn, exp, sig); + m_th_rw(sgn); + m_th_rw(exp); + m_th_rw(sig); + m_converter.mk_fp(sgn, exp, sig, res); } else UNREACHABLE(); @@ -310,7 +311,7 @@ namespace smt { SASSERT(m_arith_util.is_real(e) || m_bv_util.is_bv(e)); - m_rw(e, res); + m_rw(e, res); m_th_rw(res, res); return res; } @@ -327,12 +328,13 @@ namespace smt { SASSERT(m_fpa_util.is_float(srt)); unsigned ebits = m_fpa_util.get_ebits(srt); unsigned sbits = m_fpa_util.get_sbits(srt); - expr * bv = to_app(e)->get_arg(0); - unsigned bv_sz = m_bv_util.get_bv_size(bv); - m_converter.mk_triple(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), - m_bv_util.mk_extract(sbits - 2, 0, bv), - m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), - res); + expr_ref bv(m); + bv = to_app(e)->get_arg(0); + unsigned bv_sz = m_bv_util.get_bv_size(bv); + m_converter.mk_fp(m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, bv), + m_bv_util.mk_extract(bv_sz - 2, sbits - 1, bv), + m_bv_util.mk_extract(sbits - 2, 0, bv), + res); } return res; } @@ -342,7 +344,7 @@ namespace smt { ast_manager & m = get_manager(); context & ctx = get_context(); expr_ref res(m); - + if (m_conversions.contains(e)) { res = m_conversions.find(e); TRACE("t_fpa_detail", tout << "cached:" << std::endl; @@ -401,11 +403,12 @@ namespace smt { void theory_fpa::assert_cnstr(expr * e) { if (get_manager().is_true(e)) return; TRACE("t_fpa_detail", tout << "asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); - context& ctx = get_context(); + context & ctx = get_context(); ctx.internalize(e, false); literal lit(ctx.get_literal(e)); ctx.mark_as_relevant(lit); - ctx.mk_th_axiom(get_id(), 1, &lit); + ctx.mk_th_axiom(get_id(), 1, &lit); + TRACE("t_fpa_detail", tout << "done asserting " << mk_ismt2_pp(e, get_manager()) << "\n";); } void theory_fpa::attach_new_th_var(enode * n) { @@ -433,11 +436,10 @@ namespace smt { ctx.set_var_theory(l.var(), get_id()); expr_ref bv_atom(m); - bv_atom = convert(atom); + bv_atom = convert_atom(atom); SASSERT(is_app(bv_atom) && m.is_bool(bv_atom)); bv_atom = m.mk_and(bv_atom, mk_side_conditions()); - expr_ref atom_iff(m); assert_cnstr(m.mk_iff(atom, bv_atom)); return true; } @@ -447,7 +449,7 @@ namespace smt { context & ctx = get_context(); TRACE("t_fpa", tout << "internalizing term: " << mk_ismt2_pp(term, get_manager()) << "\n";); SASSERT(term->get_family_id() == get_family_id()); - SASSERT(!ctx.e_internalized(term)); + SASSERT(!ctx.e_internalized(term)); unsigned num_args = term->get_num_args(); for (unsigned i = 0; i < num_args; i++) @@ -455,7 +457,7 @@ namespace smt { enode * e = (ctx.e_internalized(term)) ? ctx.get_enode(term) : ctx.mk_enode(term, false, false, true); - + if (is_attached_to_var(e)) return false; @@ -476,9 +478,9 @@ namespace smt { assert_cnstr(mk_side_conditions()); break; } - default: /* ignore */; + default: /* ignore */; } - + return true; } @@ -486,33 +488,33 @@ namespace smt { TRACE("t_fpa", tout << "apply sort cnstr for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); SASSERT(n->get_owner()->get_family_id() == get_family_id() || n->get_owner()->get_family_id() == null_theory_id); - SASSERT(s->get_family_id() == get_family_id()); + SASSERT(s->get_family_id() == get_family_id()); - if (!is_attached_to_var(n)) + if (!is_attached_to_var(n)) { attach_new_th_var(n); - ast_manager & m = get_manager(); - context & ctx = get_context(); + ast_manager & m = get_manager(); + context & ctx = get_context(); - app_ref owner(m); - sort_ref owner_sort(m); - owner = n->get_owner(); - owner_sort = m.get_sort(owner); + app_ref owner(m); + sort_ref owner_sort(m); + owner = n->get_owner(); + owner_sort = m.get_sort(owner); - if (m_fpa_util.is_rm(owner_sort)) { - // For every RM term, we need to make sure that it's - // associated bit-vector is within the valid range. - if (!m_fpa_util.is_unwrap(owner)) - { - expr_ref valid(m), limit(m); - limit = m_bv_util.mk_numeral(4, 3); - valid = m_bv_util.mk_ule(wrap(owner), limit); - assert_cnstr(valid); + if (m_fpa_util.is_rm(owner_sort)) { + // For every RM term, we need to make sure that it's + // associated bit-vector is within the valid range. + if (!m_fpa_util.is_unwrap(owner)) { + expr_ref valid(m), limit(m); + limit = m_bv_util.mk_numeral(4, 3); + valid = m_bv_util.mk_ule(wrap(owner), limit); + assert_cnstr(valid); + } } + + if (!ctx.relevancy() && !m_fpa_util.is_unwrap(owner)) + assert_cnstr(m.mk_eq(unwrap(wrap(owner), owner_sort), owner)); } - - if (!ctx.relevancy() && !m_fpa_util.is_unwrap(owner)) - assert_cnstr(m.mk_eq(unwrap(wrap(owner), owner_sort), owner)); } void theory_fpa::new_eq_eh(theory_var x, theory_var y) { @@ -527,36 +529,40 @@ namespace smt { bv_util & bu = m_bv_util; mpf_manager & mpfm = fu.fm(); - app * xe = get_enode(x)->get_owner(); - app * ye = get_enode(y)->get_owner(); + expr_ref xe(m), ye(m); + xe = get_enode(x)->get_owner(); + ye = get_enode(y)->get_owner(); if ((m.is_bool(xe) && m.is_bool(ye)) || (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye))) { - SASSERT(xe->get_decl()->get_family_id() == get_family_id()); + SASSERT(to_app(xe)->get_decl()->get_family_id() == get_family_id()); return; } - + expr_ref xc(m), yc(m); xc = convert(xe); yc = convert(ye); - + + TRACE("t_fpa_detail", tout << "xc=" << mk_ismt2_pp(xc, m) << std::endl; + tout << "yc=" << mk_ismt2_pp(yc, m) << std::endl;); + expr_ref c(m); - + if (fu.is_float(xe) && fu.is_float(ye)) { expr *x_sgn, *x_sig, *x_exp; - m_converter.split_triple(xc, x_sgn, x_sig, x_exp); + m_converter.split_fp(xc, x_sgn, x_exp, x_sig); expr *y_sgn, *y_sig, *y_exp; - m_converter.split_triple(yc, y_sgn, y_sig, y_exp); + m_converter.split_fp(yc, y_sgn, y_exp, y_sig); - c = m.mk_and(m.mk_eq(x_sgn, y_sgn), - m.mk_eq(x_sig, y_sig), - m.mk_eq(x_exp, y_exp)); + c = m.mk_eq(m_bv_util.mk_concat(m_bv_util.mk_concat(x_sgn, x_exp), x_sig), + m_bv_util.mk_concat(m_bv_util.mk_concat(y_sgn, y_exp), y_sig)); } else c = m.mk_eq(xc, yc); - - assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); + + m_th_rw(c); + assert_cnstr(m.mk_iff(m.mk_eq(xe, ye), c)); assert_cnstr(mk_side_conditions()); return; @@ -572,12 +578,13 @@ namespace smt { context & ctx = get_context(); mpf_manager & mpfm = m_fpa_util.fm(); - app * xe = get_enode(x)->get_owner(); - app * ye = get_enode(y)->get_owner(); + expr_ref xe(m), ye(m); + xe = get_enode(x)->get_owner(); + ye = get_enode(y)->get_owner(); if ((m.is_bool(xe) && m.is_bool(ye)) || (m_bv_util.is_bv(xe) && m_bv_util.is_bv(ye))) { - SASSERT(xe->get_decl()->get_family_id() == get_family_id()); + SASSERT(to_app(xe)->get_decl()->get_family_id() == get_family_id()); return; } @@ -590,18 +597,18 @@ namespace smt { if (m_fpa_util.is_float(xe) && m_fpa_util.is_float(ye)) { expr *x_sgn, *x_sig, *x_exp; - m_converter.split_triple(xc, x_sgn, x_sig, x_exp); + m_converter.split_fp(xc, x_sgn, x_exp, x_sig); expr *y_sgn, *y_sig, *y_exp; - m_converter.split_triple(yc, y_sgn, y_sig, y_exp); - - c = m.mk_or(m.mk_not(m.mk_eq(x_sgn, y_sgn)), - m.mk_not(m.mk_eq(x_sig, y_sig)), - m.mk_not(m.mk_eq(x_exp, y_exp))); + m_converter.split_fp(yc, y_sgn, y_exp, y_sig); + + c = m.mk_not(m.mk_eq(m_bv_util.mk_concat(m_bv_util.mk_concat(x_sgn, x_exp), x_sig), + m_bv_util.mk_concat(m_bv_util.mk_concat(y_sgn, y_exp), y_sig))); } else c = m.mk_not(m.mk_eq(xc, yc)); - assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); + m_th_rw(c); + assert_cnstr(m.mk_iff(m.mk_not(m.mk_eq(xe, ye)), c)); assert_cnstr(mk_side_conditions()); return; @@ -609,7 +616,7 @@ namespace smt { void theory_fpa::push_scope_eh() { theory::push_scope_eh(); - m_trail_stack.push_scope(); + m_trail_stack.push_scope(); } void theory_fpa::pop_scope_eh(unsigned num_scopes) { @@ -628,8 +635,10 @@ namespace smt { expr_ref converted(m); converted = m.mk_and(convert(e), mk_side_conditions()); - if (!is_true) converted = m.mk_not(converted); - assert_cnstr(converted); + if (is_true) + assert_cnstr(m.mk_implies(e, converted)); + else + assert_cnstr(m.mk_implies(m.mk_not(e), m.mk_not(converted))); } void theory_fpa::relevant_eh(app * n) { @@ -664,18 +673,17 @@ namespace smt { assert_cnstr(c); } else { - c = m.mk_eq(unwrap(wrapped, m.get_sort(n)), n); + c = m.mk_eq(unwrap(wrapped, m.get_sort(n)), n); assert_cnstr(c); } } } else if (n->get_family_id() == get_family_id()) { - SASSERT(!m_fpa_util.is_float(n) && !m_fpa_util.is_rm(n)); // These are the conversion functions fp.to_* */ + SASSERT(!m_fpa_util.is_float(n) && !m_fpa_util.is_rm(n)); } else UNREACHABLE(); - } void theory_fpa::reset_eh() { @@ -695,6 +703,7 @@ namespace smt { final_check_status theory_fpa::final_check_eh() { TRACE("t_fpa", tout << "final_check_eh\n";); + SASSERT(m_converter.m_extra_assertions.empty()); return FC_DONE; } @@ -705,45 +714,75 @@ namespace smt { } model_value_proc * theory_fpa::mk_value(enode * n, model_generator & mg) { - TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << "\n";); + TRACE("t_fpa", tout << "mk_value for: " << mk_ismt2_pp(n->get_owner(), get_manager()) << + " (sort " << mk_ismt2_pp(get_manager().get_sort(n->get_owner()), get_manager()) << ")\n";); ast_manager & m = get_manager(); context & ctx = get_context(); - app * owner = n->get_owner(); + app_ref owner(m); + owner = n->get_owner(); // If the owner is not internalized, it doesn't have an enode associated. SASSERT(ctx.e_internalized(owner)); if (m_fpa_util.is_rm_numeral(owner) || - m_fpa_util.is_numeral(owner)) + m_fpa_util.is_numeral(owner)) { return alloc(expr_wrapper_proc, owner); + } model_value_proc * res = 0; app_ref wrapped(m); wrapped = wrap(owner); - - CTRACE("t_fpa", !ctx.e_internalized(wrapped), - tout << "Model dependency not internalized: " << - mk_ismt2_pp(wrapped, m) << - " (owner " << (!ctx.e_internalized(owner) ? "not" : "is") << - " internalized)" << std::endl;); - - if (m_fpa_util.is_rm(owner)) { - fpa_rm_value_proc * vp = alloc(fpa_rm_value_proc, this); - vp->add_dependency(ctx.get_enode(wrapped)); - res = vp; - } - else if (m_fpa_util.is_float(owner)) { + SASSERT(m_bv_util.is_bv(wrapped)); + + CTRACE("t_fpa_detail", !ctx.e_internalized(wrapped), + tout << "Model dependency not internalized: " << + mk_ismt2_pp(wrapped, m) << + " (owner " << (!ctx.e_internalized(owner) ? "not" : "is") << + " internalized)" << std::endl;); + + if (is_app_of(owner, get_family_id(), OP_FPA_FP)) { + SASSERT(to_app(owner)->get_num_args() == 3); + app_ref a0(m), a1(m), a2(m); + a0 = to_app(owner->get_arg(0)); + a1 = to_app(owner->get_arg(1)); + a2 = to_app(owner->get_arg(2)); unsigned ebits = m_fpa_util.get_ebits(m.get_sort(owner)); unsigned sbits = m_fpa_util.get_sbits(m.get_sort(owner)); - fpa_value_proc * vp = alloc(fpa_value_proc, this, ebits, sbits); - vp->add_dependency(ctx.get_enode(wrapped)); + fpa_value_proc * vp = alloc(fpa_value_proc, this, ebits, sbits); + vp->add_dependency(ctx.get_enode(a0)); + vp->add_dependency(ctx.get_enode(a1)); + vp->add_dependency(ctx.get_enode(a2)); + TRACE("t_fpa_detail", tout << "Depends on: " << + mk_ismt2_pp(a0, m) << " eq. cls. #" << get_enode(a0)->get_root()->get_owner()->get_id() << std::endl << + mk_ismt2_pp(a1, m) << " eq. cls. #" << get_enode(a1)->get_root()->get_owner()->get_id() << std::endl << + mk_ismt2_pp(a2, m) << " eq. cls. #" << get_enode(a2)->get_root()->get_owner()->get_id() << std::endl;); res = vp; } - else - UNREACHABLE(); + else if (ctx.e_internalized(wrapped)) { + if (m_fpa_util.is_rm(owner)) { + fpa_rm_value_proc * vp = alloc(fpa_rm_value_proc, this); + vp->add_dependency(ctx.get_enode(wrapped)); + res = vp; + } + else if (m_fpa_util.is_float(owner)) { + unsigned ebits = m_fpa_util.get_ebits(m.get_sort(owner)); + unsigned sbits = m_fpa_util.get_sbits(m.get_sort(owner)); + fpa_value_proc * vp = alloc(fpa_value_proc, this, ebits, sbits); + enode * en = ctx.get_enode(wrapped); + vp->add_dependency(en); + TRACE("t_fpa_detail", tout << "Depends on: " << mk_ismt2_pp(wrapped, m) << " eq. cls. #" << en->get_root()->get_owner()->get_id() << std::endl;); + res = vp; + } + } + else { + unsigned ebits = m_fpa_util.get_ebits(m.get_sort(owner)); + unsigned sbits = m_fpa_util.get_sbits(m.get_sort(owner)); + return alloc(expr_wrapper_proc, m_fpa_util.mk_pzero(ebits, sbits)); + } + SASSERT(res != 0); return res; } @@ -754,7 +793,7 @@ namespace smt { ast_manager & m = get_manager(); context & ctx = get_context(); - out << "theory variables:" << std::endl; + out << "fpa theory variables:" << std::endl; ptr_vector::const_iterator it = ctx.begin_enodes(); ptr_vector::const_iterator end = ctx.end_enodes(); for (; it != end; it++) { @@ -762,5 +801,32 @@ namespace smt { if (v != -1) out << v << " -> " << mk_ismt2_pp((*it)->get_owner(), m) << std::endl; } + + out << "bv theory variables:" << std::endl; + it = ctx.begin_enodes(); + end = ctx.end_enodes(); + for (; it != end; it++) { + theory_var v = (*it)->get_th_var(m_bv_util.get_family_id()); + if (v != -1) out << v << " -> " << + mk_ismt2_pp((*it)->get_owner(), m) << std::endl; + } + + out << "arith theory variables:" << std::endl; + it = ctx.begin_enodes(); + end = ctx.end_enodes(); + for (; it != end; it++) { + theory_var v = (*it)->get_th_var(m_arith_util.get_family_id()); + if (v != -1) out << v << " -> " << + mk_ismt2_pp((*it)->get_owner(), m) << std::endl; + } + + out << "equivalence classes:\n"; + it = ctx.begin_enodes(); + end = ctx.end_enodes(); + for (; it != end; ++it) { + expr * n = (*it)->get_owner(); + expr * r = (*it)->get_root()->get_owner(); + out << r->get_id() << " --> " << mk_ismt2_pp(n, m) << std::endl; + } } }; diff --git a/src/tactic/fpa/fpa2bv_model_converter.cpp b/src/tactic/fpa/fpa2bv_model_converter.cpp index dfddfd12f..5c12cbd8f 100644 --- a/src/tactic/fpa/fpa2bv_model_converter.cpp +++ b/src/tactic/fpa/fpa2bv_model_converter.cpp @@ -116,7 +116,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { bv_mdl->eval(a->get_arg(1), exp, true); bv_mdl->eval(a->get_arg(2), sig, true); - SASSERT(a->is_app_of(fu.get_family_id(), OP_FPA_TO_FP)); + SASSERT(a->is_app_of(fu.get_family_id(), OP_FPA_FP)); #ifdef Z3DEBUG SASSERT(to_app(a->get_arg(0))->get_decl()->get_arity() == 0); diff --git a/src/tactic/fpa/qffp_tactic.cpp b/src/tactic/fpa/qffp_tactic.cpp index 5bc006f00..6b081f0a5 100644 --- a/src/tactic/fpa/qffp_tactic.cpp +++ b/src/tactic/fpa/qffp_tactic.cpp @@ -22,6 +22,7 @@ Notes: #include"sat_tactic.h" #include"fpa2bv_tactic.h" #include"smt_tactic.h" +#include"propagate_values_tactic.h" #include"qffp_tactic.h" @@ -30,19 +31,19 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { simp_p.set_bool("arith_lhs", true); simp_p.set_bool("elim_and", true); - tactic * st = cond( mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), - and_then(mk_simplify_tactic(m, simp_p), - mk_smt_tactic()), - and_then( - mk_simplify_tactic(m, p), - mk_fpa2bv_tactic(m, p), - using_params(mk_simplify_tactic(m, p), simp_p), - mk_bit_blaster_tactic(m, p), - using_params(mk_simplify_tactic(m, p), simp_p), - cond(mk_is_propositional_probe(), - mk_sat_tactic(m, p), - mk_smt_tactic(p)), - mk_fail_if_undecided_tactic())); + tactic * st = and_then(mk_simplify_tactic(m, simp_p), + mk_propagate_values_tactic(m, p), + cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), + mk_smt_tactic(), + and_then( + mk_fpa2bv_tactic(m, p), + using_params(mk_simplify_tactic(m, p), simp_p), + mk_bit_blaster_tactic(m, p), + using_params(mk_simplify_tactic(m, p), simp_p), + cond(mk_is_propositional_probe(), + mk_sat_tactic(m, p), + mk_smt_tactic(p)), + mk_fail_if_undecided_tactic()))); st->updt_params(p); return st; From b9bbfbdbb7bcf67a9489eab3c8ef535b6d324825 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 16 Jan 2015 12:05:12 +0530 Subject: [PATCH 216/507] fix interval dependencies bug. Codeplex issue 163 Signed-off-by: Nikolaj Bjorner --- src/duality/duality_rpfp.cpp | 2 +- src/smt/old_interval.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/duality/duality_rpfp.cpp b/src/duality/duality_rpfp.cpp index cdc8fb3b2..304e41168 100755 --- a/src/duality/duality_rpfp.cpp +++ b/src/duality/duality_rpfp.cpp @@ -3147,7 +3147,7 @@ namespace Duality { } if(node->Annotation.IsEmpty() || eq(node->Annotation.Formula,prev_annot) || (repeated_case_count > 0 && !axioms_added) || (repeated_case_count >= 10)){ - looks_bad: + //looks_bad: if(!axioms_added){ // add the axioms in the off chance they are useful const std::vector &theory = ls->get_axioms(); diff --git a/src/smt/old_interval.cpp b/src/smt/old_interval.cpp index ffc3331be..9dd8e0955 100644 --- a/src/smt/old_interval.cpp +++ b/src/smt/old_interval.cpp @@ -295,6 +295,8 @@ interval & interval::operator*=(interval const & other) { } if (other.is_zero()) { *this = other; + m_lower_dep = m_manager.mk_join(m_lower_dep, m_upper_dep); + m_upper_dep = m_lower_dep; return *this; } From bb722b24c12354640718e444ced8468b8f4dc43a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 16 Jan 2015 17:34:01 +0000 Subject: [PATCH 217/507] Added call to memory::finalize() to ease memory leak debugging Signed-off-by: Christoph M. Wintersteiger --- src/shell/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 0eb612f35..8239871a3 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -337,6 +337,7 @@ int main(int argc, char ** argv) { default: UNREACHABLE(); } + memory::finalize(); #ifdef _WINDOWS _CrtDumpMemoryLeaks(); #endif From 67e04c5dfba23718167b68dd8cd417d6480bc3f7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 16 Jan 2015 17:40:28 +0000 Subject: [PATCH 218/507] Python example: removed function that has no body. Signed-off-by: Christoph M. Wintersteiger --- examples/python/complex/complex.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/python/complex/complex.py b/examples/python/complex/complex.py index d90c01e93..a2de4a6cc 100644 --- a/examples/python/complex/complex.py +++ b/examples/python/complex/complex.py @@ -65,9 +65,6 @@ class ComplexExpr: def __neq__(self, other): return Not(self.__eq__(other)) - def __pow__(self, k): - - def simplify(self): return ComplexExpr(simplify(self.r), simplify(self.i)) From c3247d75988d0a3f0c7f4808acb881c1d60621ed Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 17 Jan 2015 16:36:33 +0000 Subject: [PATCH 219/507] FPA: bugfix for rounding mode bv translation Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 6 +++--- src/ast/fpa/fpa2bv_converter.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 4cdb64d8d..1f7ea1186 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3170,11 +3170,11 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) { switch(f->get_decl_kind()) - { - case OP_FPA_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; + { case OP_FPA_RM_NEAREST_TIES_TO_EVEN: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3); break; - case OP_FPA_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; + case OP_FPA_RM_NEAREST_TIES_TO_AWAY: result = m_bv_util.mk_numeral(BV_RM_TIES_TO_AWAY, 3); break; case OP_FPA_RM_TOWARD_POSITIVE: result = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); break; + case OP_FPA_RM_TOWARD_NEGATIVE: result = m_bv_util.mk_numeral(BV_RM_TO_NEGATIVE, 3); break; case OP_FPA_RM_TOWARD_ZERO: result = m_bv_util.mk_numeral(BV_RM_TO_ZERO, 3); break; default: UNREACHABLE(); } diff --git a/src/ast/fpa/fpa2bv_converter.h b/src/ast/fpa/fpa2bv_converter.h index 82fad6ff9..fa797b610 100644 --- a/src/ast/fpa/fpa2bv_converter.h +++ b/src/ast/fpa/fpa2bv_converter.h @@ -26,7 +26,7 @@ Notes: #include"bv_decl_plugin.h" #include"basic_simplifier_plugin.h" -typedef enum { BV_RM_TIES_TO_AWAY=0, BV_RM_TIES_TO_EVEN=1, BV_RM_TO_NEGATIVE=2, BV_RM_TO_POSITIVE=3, BV_RM_TO_ZERO=4 } BV_RM_VAL; +typedef enum { BV_RM_TIES_TO_EVEN, BV_RM_TIES_TO_AWAY, BV_RM_TO_POSITIVE, BV_RM_TO_NEGATIVE, BV_RM_TO_ZERO = 4 } BV_RM_VAL; struct func_decl_triple { func_decl_triple () { f_sgn = 0; f_sig = 0; f_exp = 0; } From 6af978292703e4f7ceefa0399e07d002de34a7c5 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sun, 18 Jan 2015 04:50:00 +0530 Subject: [PATCH 220/507] set default file format to smt2 Signed-off-by: Nikolaj Bjorner --- src/shell/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 0eb612f35..d84c88366 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -297,7 +297,7 @@ int main(int argc, char ** argv) { } if (g_input_kind == IN_UNSPECIFIED) { - g_input_kind = IN_SMTLIB; + g_input_kind = IN_SMTLIB_2; char const * ext = get_extension(g_input_file); if (ext) { if (strcmp(ext, "datalog") == 0 || strcmp(ext, "dl") == 0) { From 5619f6b583147b5bdb0218001a05c0f3a47ecf1a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Jan 2015 15:18:12 +0000 Subject: [PATCH 221/507] FPA Python API bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/python/z3.py | 19 ++++++-------- src/api/python/z3printer.py | 52 ++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index ee33fbe51..82002c4f7 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -904,12 +904,8 @@ def _to_expr_ref(a, ctx): if sk == Z3_DATATYPE_SORT: return DatatypeRef(a, ctx) if sk == Z3_FLOATING_POINT_SORT: - if k == Z3_APP_AST: - e = ExprRef(a, ctx) - if e.decl().kind() == Z3_OP_FPA_NUM: - return FPNumRef(a, ctx) - else: - return FPRef(a, ctx) + if k == Z3_APP_AST and _is_numeral(ctx, a): + return FPNumRef(a, ctx) else: return FPRef(a, ctx) if sk == Z3_ROUNDING_MODE_SORT: @@ -7817,7 +7813,8 @@ class FPNumRef(FPRef): return self.decl().kind() == Z3_OP_FPA_PLUS_ZERO or self.decl().kind() == Z3_OP_FPA_MINUS_ZERO def isNegative(self): - return (self.num_args() == 0 and (Z3_OP_FPA_MINUS_INF or Z3_OP_FPA_MINUS_ZERO)) or (self.num_args() == 3 and self.arg(0) == BitVecVal(1)) + k = self.decl().kind() + return (self.num_args() == 0 and (k == Z3_OP_FPA_MINUS_INF or k == Z3_OP_FPA_MINUS_ZERO)) or (self.num_args() == 3 and self.arg(0) == BitVecVal(1)) def _to_fpnum(num, ctx=None): if isinstance(num, FPNum): @@ -7851,7 +7848,7 @@ def is_fp_value(a): True """ return is_fp(a) and _is_numeral(a.ctx, a.ast) - + def FPSort(ebits, sbits, ctx=None): """Return a Z3 floating-point sort of the given sizes. If `ctx=None`, then the global context is used. @@ -7989,7 +7986,7 @@ def fpAbs(a): FloatingPoint(8, 24) """ if __debug__: - _z3_assert(is_fp(a), "First argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a), "First argument must be Z3 floating-point expression") return FPRef(Z3_mk_fpa_abs(a.ctx_ref(), a.as_ast()), a.ctx) def fpNeg(a): @@ -8004,7 +8001,7 @@ def fpNeg(a): FloatingPoint(8, 24) """ if __debug__: - _z3_assert(is_fp(a), "First argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a), "First argument must be Z3 floating-point expression") return FPRef(Z3_mk_fpa_neg(a.ctx_ref(), a.as_ast()), a.ctx) def fpAdd(rm, a, b): @@ -8069,7 +8066,7 @@ def fpDiv(rm, a, b): if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") - return FPRef(Z3_mk_fpa_mul(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) + return FPRef(Z3_mk_fpa_div(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) def fpRem(a, b): """Create a Z3 floating-point remainder expression. diff --git a/src/api/python/z3printer.py b/src/api/python/z3printer.py index a74a67fa8..da49f1719 100644 --- a/src/api/python/z3printer.py +++ b/src/api/python/z3printer.py @@ -71,7 +71,7 @@ _z3_op_to_fpa_normal_str = { Z3_OP_FPA_NAN : 'NaN', Z3_OP_FPA_PLUS_ZERO : 'PZero', Z3_OP_FPA_MINUS_ZERO : 'NZero', Z3_OP_FPA_ADD : 'fpAdd', Z3_OP_FPA_SUB : 'fpSub', Z3_OP_FPA_NEG : 'fpNeg', Z3_OP_FPA_MUL : 'fpMul', Z3_OP_FPA_DIV : 'fpDiv', Z3_OP_FPA_REM : 'fpRem', Z3_OP_FPA_ABS : 'fpAbs', - Z3_OP_FPA_NEG : 'fpNeg', Z3_OP_FPA_MIN : 'fpMin', Z3_OP_FPA_MAX : 'fpMax', + Z3_OP_FPA_MIN : 'fpMin', Z3_OP_FPA_MAX : 'fpMax', Z3_OP_FPA_FMA : 'fpFMA', Z3_OP_FPA_SQRT : 'fpSqrt', Z3_OP_FPA_ROUND_TO_INTEGRAL : 'fpRoundToIntegral', Z3_OP_FPA_EQ : 'fpEQ', Z3_OP_FPA_LT : 'fpLT', Z3_OP_FPA_GT : 'fpGT', Z3_OP_FPA_LE : 'fpLEQ', @@ -93,9 +93,8 @@ _z3_op_to_fpa_pretty_str = { Z3_OP_FPA_PLUS_INF : '+oo', Z3_OP_FPA_MINUS_INF : '-oo', Z3_OP_FPA_NAN : 'NaN', Z3_OP_FPA_PLUS_ZERO : '+0.0', Z3_OP_FPA_MINUS_ZERO : '-0.0', - Z3_OP_FPA_ADD : '+', Z3_OP_FPA_SUB : '-', Z3_OP_FPA_NEG : '-', Z3_OP_FPA_MUL : '*', - Z3_OP_FPA_DIV : '/', Z3_OP_FPA_REM : '%', - Z3_OP_FPA_NEG: '-', + Z3_OP_FPA_ADD : '+', Z3_OP_FPA_SUB : '-', Z3_OP_FPA_MUL : '*', Z3_OP_FPA_DIV : '/', + Z3_OP_FPA_REM : '%', Z3_OP_FPA_NEG : '-', Z3_OP_FPA_EQ : 'fpEQ', Z3_OP_FPA_LT : '<', Z3_OP_FPA_GT : '>', Z3_OP_FPA_LE : '<=', Z3_OP_FPA_GE : '>=' } @@ -578,7 +577,7 @@ class Formatter: def pp_fprm_value(self, a): z3._z3_assert(z3.is_fprm_value(a), 'expected FPRMNumRef') - if self.fpa_pretty and _z3_op_to_fpa_pretty_str.has_key(a.decl().kind()): + if self.fpa_pretty and a.decl().kind() in _z3_op_to_fpa_pretty_str: return to_format(_z3_op_to_fpa_pretty_str.get(a.decl().kind())) else: return to_format(a.as_string()) @@ -617,7 +616,7 @@ class Formatter: return compose(r) else: if (a.isNaN()): - return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_NAN]) + return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_FPA_NAN]) elif (a.isInf()): if (a.isNegative()): return to_format(_z3_op_to_fpa_pretty_str[Z3_OP_FPA_MINUS_INF]) @@ -649,28 +648,33 @@ class Formatter: z3._z3_assert(isinstance(a, z3.FPRef), "type mismatch") k = a.decl().kind() op = '?' - if self.fpa_pretty: - op = _z3_op_to_fpa_pretty_str.get(k, None) - if (op == None): - op = _z3_op_to_str.get(k, None) + if (self.fpa_pretty and k in _z3_op_to_fpa_pretty_str): + op = _z3_op_to_fpa_pretty_str[k] + elif k in _z3_op_to_fpa_normal_str: + op = _z3_op_to_fpa_normal_str[k] + elif k in _z3_op_to_str: + op = _z3_op_to_str[k] n = a.num_args() - if self.fpa_pretty and self.is_infix(k) and n >= 3: - rm = a.arg(0) - if z3.is_fprm_value(rm) and z3._dflt_rm(a.ctx).eq(rm): - arg1 = to_format(self.pp_expr(a.arg(1), d+1, xs)) - arg2 = to_format(self.pp_expr(a.arg(2), d+1, xs)) - r = [] - r.append(arg1) - r.append(to_format(' ')) - r.append(to_format(op)) - r.append(to_format(' ')) - r.append(arg2) - return compose(r) + if self.fpa_pretty: + if self.is_infix(k) and n >= 3: + rm = a.arg(0) + if z3.is_fprm_value(rm) and z3._dflt_rm(a.ctx).eq(rm): + arg1 = to_format(self.pp_expr(a.arg(1), d+1, xs)) + arg2 = to_format(self.pp_expr(a.arg(2), d+1, xs)) + r = [] + r.append(arg1) + r.append(to_format(' ')) + r.append(to_format(op)) + r.append(to_format(' ')) + r.append(arg2) + return compose(r) + elif k == Z3_OP_FPA_NEG: + return compose([to_format('-') , to_format(self.pp_expr(a.arg(0), d+1, xs))]) - if _z3_op_to_fpa_normal_str.has_key(k): - op = _z3_op_to_fpa_normal_str.get(k, None) + if k in _z3_op_to_fpa_normal_str: + op = _z3_op_to_fpa_normal_str[k] r = [] r.append(to_format(op)) From 70f0d2f423f32d6a7ef23e6d9b202d3355d2ddd4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 13:37:02 +0000 Subject: [PATCH 222/507] Beginnings of a new ML API Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_project.py | 1 + scripts/mk_util.py | 36 +- scripts/update_api.py | 207 ++++++++++ src/api/ml/README | 3 + .../ml/{ => old}/add_error_checking.V3.sed | 0 src/api/ml/{ => old}/add_error_checking.sed | 0 src/api/ml/{ => old}/build-lib.cmd | 0 src/api/ml/{ => old}/build-lib.sh | 0 src/api/ml/{ => old}/build-test.cmd | 0 src/api/ml/{ => old}/build-test.sh | 0 src/api/ml/{ => old}/build.cmd | 0 src/api/ml/{ => old}/clean.cmd | 0 src/api/ml/{ => old}/cleantmp.cmd | 0 src/api/ml/{ => old}/compile_mlapi.cmd | 0 src/api/ml/{ => old}/error_handling.idl | 0 src/api/ml/{ => old}/exec.cmd | 0 src/api/ml/{ => old}/exec.sh | 0 src/api/ml/{ => old}/generate_mlapi.cmd | 0 src/api/ml/{ => old}/generate_mlapi.sh | 0 src/api/ml/{ => old}/import.cmd | 0 src/api/ml/{ => old}/mlx_get_app_args.idl | 0 src/api/ml/{ => old}/mlx_get_array_sort.idl | 0 .../ml/{ => old}/mlx_get_datatype_sort.idl | 0 src/api/ml/{ => old}/mlx_get_domains.idl | 0 src/api/ml/{ => old}/mlx_get_error_msg.idl | 0 .../ml/{ => old}/mlx_get_pattern_terms.idl | 0 src/api/ml/{ => old}/mlx_get_tuple_sort.idl | 0 src/api/ml/{ => old}/mlx_mk_context_x.idl | 0 src/api/ml/{ => old}/mlx_mk_datatypes.idl | 0 src/api/ml/{ => old}/mlx_mk_numeral.idl | 0 src/api/ml/{ => old}/mlx_mk_sort.idl | 0 src/api/ml/{ => old}/mlx_mk_symbol.idl | 0 src/api/ml/{ => old}/mlx_model.idl | 0 src/api/ml/{ => old}/mlx_numeral_refine.idl | 0 src/api/ml/{ => old}/mlx_parse_smtlib.idl | 0 src/api/ml/{ => old}/mlx_sort_refine.idl | 0 src/api/ml/{ => old}/mlx_statistics.idl | 0 src/api/ml/{ => old}/mlx_symbol_refine.idl | 0 src/api/ml/{ => old}/mlx_term_refine.idl | 0 src/api/ml/{ => old}/postprocess.sed | 0 src/api/ml/{ => old}/preprocess.sed | 0 src/api/ml/{ => old}/queen.ml | 0 src/api/ml/{ => old}/queen.regress.err | 0 src/api/ml/{ => old}/queen.regress.out | 0 src/api/ml/{ => old}/reverse.sed | 0 src/api/ml/{ => old}/test_mlapi.cmd | 0 src/api/ml/{ => old}/test_theory.ml | 0 src/api/ml/{ => old}/update-ml-doc.cmd | 0 src/api/ml/{ => old}/x3V3.ml | 0 src/api/ml/{ => old}/x3V3.mli | 0 src/api/ml/{ => old}/z3.0.idl | 0 src/api/ml/test_capi.regress.err | 5 - src/api/ml/test_capi.regress.out | 386 ------------------ src/api/ml/test_mlapi.regress.err | 0 src/api/ml/test_mlapi.regress.out | 32 -- src/api/ml/test_mlapiV3.regress.err | 5 - src/api/ml/test_mlapiV3.regress.out | 315 -------------- 57 files changed, 245 insertions(+), 745 deletions(-) create mode 100644 src/api/ml/README rename src/api/ml/{ => old}/add_error_checking.V3.sed (100%) rename src/api/ml/{ => old}/add_error_checking.sed (100%) rename src/api/ml/{ => old}/build-lib.cmd (100%) rename src/api/ml/{ => old}/build-lib.sh (100%) rename src/api/ml/{ => old}/build-test.cmd (100%) rename src/api/ml/{ => old}/build-test.sh (100%) rename src/api/ml/{ => old}/build.cmd (100%) rename src/api/ml/{ => old}/clean.cmd (100%) rename src/api/ml/{ => old}/cleantmp.cmd (100%) rename src/api/ml/{ => old}/compile_mlapi.cmd (100%) rename src/api/ml/{ => old}/error_handling.idl (100%) rename src/api/ml/{ => old}/exec.cmd (100%) rename src/api/ml/{ => old}/exec.sh (100%) rename src/api/ml/{ => old}/generate_mlapi.cmd (100%) rename src/api/ml/{ => old}/generate_mlapi.sh (100%) rename src/api/ml/{ => old}/import.cmd (100%) rename src/api/ml/{ => old}/mlx_get_app_args.idl (100%) rename src/api/ml/{ => old}/mlx_get_array_sort.idl (100%) rename src/api/ml/{ => old}/mlx_get_datatype_sort.idl (100%) rename src/api/ml/{ => old}/mlx_get_domains.idl (100%) rename src/api/ml/{ => old}/mlx_get_error_msg.idl (100%) rename src/api/ml/{ => old}/mlx_get_pattern_terms.idl (100%) rename src/api/ml/{ => old}/mlx_get_tuple_sort.idl (100%) rename src/api/ml/{ => old}/mlx_mk_context_x.idl (100%) rename src/api/ml/{ => old}/mlx_mk_datatypes.idl (100%) rename src/api/ml/{ => old}/mlx_mk_numeral.idl (100%) rename src/api/ml/{ => old}/mlx_mk_sort.idl (100%) rename src/api/ml/{ => old}/mlx_mk_symbol.idl (100%) rename src/api/ml/{ => old}/mlx_model.idl (100%) rename src/api/ml/{ => old}/mlx_numeral_refine.idl (100%) rename src/api/ml/{ => old}/mlx_parse_smtlib.idl (100%) rename src/api/ml/{ => old}/mlx_sort_refine.idl (100%) rename src/api/ml/{ => old}/mlx_statistics.idl (100%) rename src/api/ml/{ => old}/mlx_symbol_refine.idl (100%) rename src/api/ml/{ => old}/mlx_term_refine.idl (100%) rename src/api/ml/{ => old}/postprocess.sed (100%) rename src/api/ml/{ => old}/preprocess.sed (100%) rename src/api/ml/{ => old}/queen.ml (100%) rename src/api/ml/{ => old}/queen.regress.err (100%) rename src/api/ml/{ => old}/queen.regress.out (100%) rename src/api/ml/{ => old}/reverse.sed (100%) rename src/api/ml/{ => old}/test_mlapi.cmd (100%) rename src/api/ml/{ => old}/test_theory.ml (100%) rename src/api/ml/{ => old}/update-ml-doc.cmd (100%) rename src/api/ml/{ => old}/x3V3.ml (100%) rename src/api/ml/{ => old}/x3V3.mli (100%) rename src/api/ml/{ => old}/z3.0.idl (100%) delete mode 100644 src/api/ml/test_capi.regress.err delete mode 100644 src/api/ml/test_capi.regress.out delete mode 100644 src/api/ml/test_mlapi.regress.err delete mode 100644 src/api/ml/test_mlapi.regress.out delete mode 100644 src/api/ml/test_mlapiV3.regress.err delete mode 100644 src/api/ml/test_mlapiV3.regress.out diff --git a/scripts/mk_project.py b/scripts/mk_project.py index b30bba609..e2b003d21 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -87,6 +87,7 @@ def init_project_def(): export_files=API_files) add_dot_net_dll('dotnet', ['api_dll'], 'api/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties') add_java_dll('java', ['api_dll'], 'api/java', dll_name='libz3java', package_name="com.microsoft.z3", manifest_file='manifest') + add_ml_lib('ml', ['api_dll'], 'api/ml', lib_name='libz3ml') add_hlib('cpp', 'api/c++', includes2install=['z3++.h']) set_z3py_dir('api/python') # Examples diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4641a7b1b..cb6b17cce 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -65,6 +65,7 @@ VS_PROJ = False TRACE = False DOTNET_ENABLED=False JAVA_ENABLED=False +ML_ENABLED=False STATIC_LIB=False VER_MAJOR=None VER_MINOR=None @@ -476,13 +477,13 @@ def display_help(exit_code): # Parse configuration option for mk_make script def parse_options(): global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM - global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH + global DOTNET_ENABLED, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH try: options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:df:sxhmcvtnp:gj', ['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof', - 'githash=']) + 'githash=', 'ml']) except: print("ERROR: Invalid command line option") display_help(1) @@ -535,6 +536,8 @@ def parse_options(): GPROF = True elif opt == '--githash': GIT_HASH=arg + elif opt in ('', '--ml'): + ML_ENABLED = True else: print("ERROR: Invalid command line option '%s'" % opt) display_help(1) @@ -621,6 +624,9 @@ def is_verbose(): def is_java_enabled(): return JAVA_ENABLED +def is_ml_enabled(): + return ML_ENABLED + def is_compiler(given, expected): """ Return True if the 'given' compiler is the expected one. @@ -1268,6 +1274,26 @@ class JavaDLLComponent(Component): shutil.copy(os.path.join(build_path, 'libz3java.%s' % so), os.path.join(dist_path, 'bin', 'libz3java.%s' % so)) +class MLComponent(Component): + def __init__(self, name, lib_name, path, deps): + Component.__init__(self, name, path, deps) + if lib_name == None: + lib_name = name + self.lib_name = lib_name + + def mk_makefile(self, out): + if is_ml_enabled(): + mk_dir(os.path.join(BUILD_DIR, 'api', 'ml')) + libfile = '%s$(LIB_EXT)' % self.lib_name + out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'z3_native.c'))) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) %s/z3_native.c\n' % self.to_src_dir) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'z3_native')) + out.write('ml: %s\n' % libfile) + out.write('\n') + + def main_component(self): + return is_ml_enabled() + class ExampleComponent(Component): def __init__(self, name, path): Component.__init__(self, name, path, []) @@ -1430,6 +1456,10 @@ def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None, man c = JavaDLLComponent(name, dll_name, package_name, manifest_file, path, deps) reg_component(name, c) +def add_ml_lib(name, deps=[], path=None, lib_name=None): + c = MLComponent(name, lib_name, path, deps) + reg_component(name, c) + def add_cpp_example(name, path=None): c = CppExampleComponent(name, path) reg_component(name, c) @@ -1513,6 +1543,7 @@ def mk_config(): # End of Windows VS config.mk if is_verbose(): print('64-bit: %s' % is64()) + print('ML API: %s' % is_ml_enabled()) if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) @@ -1631,6 +1662,7 @@ def mk_config(): if GPROF: print('gprof: enabled') print('Python version: %s' % distutils.sysconfig.get_python_version()) + print('ML API: %s' % is_ml_enabled()) if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) diff --git a/scripts/update_api.py b/scripts/update_api.py index 2fbf42cca..9ef0ce9a2 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -155,6 +155,10 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I STRING : 'jstring', STRING_PTR : 'jobject', BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint'} +# Mapping to ML types +Type2ML = { VOID : 'void', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', + STRING : 'char*', STRING_PTR : 'char**', + BOOL : 'boolean', SYMBOL : 'long', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -205,6 +209,13 @@ def type2javaw(ty): else: return Type2JavaW[ty] +def type2ml(ty): + global Type2ML + if (ty >= FIRST_OBJ_ID): + return 'long' + else: + return Type2ML[ty] + def _in(ty): return (IN, ty); @@ -313,6 +324,24 @@ def param2pystr(p): else: return type2pystr(param_type(p)) +def param2ml(p): + k = param_kind(p) + if k == OUT: + if param_type(p) == INT or param_type(p) == UINT: + return "int*" + elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: + return "long*" + elif param_type(p) == STRING: + return "char*" + else: + print "ERROR: unreachable code" + assert(False) + exit(1) + if k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: + return "%s[]" % type2ml(param_type(p)) + else: + return type2ml(param_type(p)) + # Save name, result, params to generate wrapper _API2PY = [] @@ -1039,6 +1068,183 @@ def mk_bindings(): exe_c.write(" in.register_cmd(%s, exec_%s);\n" % (key, val)) exe_c.write("}\n") +def ml_method_name(name): + result = '' + name = name[3:] # Remove Z3_ + return result + +def mk_ml(): + if not is_ml_enabled(): + return + ml_dir = get_component('ml').src_dir + ml_nativef = os.path.join(ml_dir, 'z3_native.ml') + ml_wrapperf = os.path.join(ml_dir, 'z3_native.c') + ml_native = open(ml_nativef, 'w') + ml_native.write('// Automatically generated file\n') + ml_native.write('\n') + for name, result, params in _dotnet_decls: + ml_native.write(' external %s : (' % ml_method_name(name)) + first = True + i = 0; + for param in params: + if first: + first = False + else: + ml_native.write(', ') + ml_native.write('%s a%d' % (param2ml(param), i)) + i = i + 1 + ml_native.write('%s)\n' % (type2ml(result))) + # ml_native.write(' = "NATIVE_%s"' % ml_method_name(name)) + # ml_native.write('\n\n') + # # Exception wrappers + # for name, result, params in _dotnet_decls: + # java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) + # first = True + # i = 0; + # for param in params: + # if first: + # first = False + # else: + # java_native.write(', ') + # java_native.write('%s a%d' % (param2java(param), i)) + # i = i + 1 + # java_native.write(')') + # if len(params) > 0 and param_type(params[0]) == CONTEXT: + # java_native.write(' throws Z3Exception') + # java_native.write('\n') + # java_native.write(' {\n') + # java_native.write(' ') + # if result != VOID: + # java_native.write('%s res = ' % type2java(result)) + # java_native.write('INTERNAL%s(' % (java_method_name(name))) + # first = True + # i = 0; + # for param in params: + # if first: + # first = False + # else: + # java_native.write(', ') + # java_native.write('a%d' % i) + # i = i + 1 + # java_native.write(');\n') + # if len(params) > 0 and param_type(params[0]) == CONTEXT: + # java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') + # java_native.write(' if (err != Z3_error_code.Z3_OK)\n') + # java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') + # if result != VOID: + # java_native.write(' return res;\n') + # java_native.write(' }\n\n') + # java_native.write('}\n') + ml_wrapper = open(ml_wrapperf, 'w') + ml_wrapper.write('// Automatically generated file\n\n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#ifdef Custom_tag\n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n') + ml_wrapper.write('#endif\n') + # for name, result, params in _dotnet_decls: + # java_wrapper.write('JNIEXPORT %s JNICALL Java_%s_Native_INTERNAL%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), pkg_str, java_method_name(name))) + # i = 0; + # for param in params: + # java_wrapper.write(', ') + # java_wrapper.write('%s a%d' % (param2javaw(param), i)) + # i = i + 1 + # java_wrapper.write(') {\n') + # # preprocess arrays, strings, in/out arguments + # i = 0 + # for param in params: + # k = param_kind(param) + # if k == OUT or k == INOUT: + # java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) + # elif k == IN_ARRAY or k == INOUT_ARRAY: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) + # else: + # java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) + # elif k == OUT_ARRAY: + # java_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), + # i, + # type2str(param_type(param)), + # param_array_capacity_pos(param), + # type2str(param_type(param)))) + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + # else: + # java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) + # elif k == IN and param_type(param) == STRING: + # java_wrapper.write(' Z3_string _a%s = (Z3_string) jenv->GetStringUTFChars(a%s, NULL);\n' % (i, i)) + # i = i + 1 + # # invoke procedure + # java_wrapper.write(' ') + # if result != VOID: + # java_wrapper.write('%s result = ' % type2str(result)) + # java_wrapper.write('%s(' % name) + # i = 0 + # first = True + # for param in params: + # if first: + # first = False + # else: + # java_wrapper.write(', ') + # k = param_kind(param) + # if k == OUT or k == INOUT: + # java_wrapper.write('&_a%s' % i) + # elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: + # java_wrapper.write('_a%s' % i) + # elif k == IN and param_type(param) == STRING: + # java_wrapper.write('_a%s' % i) + # else: + # java_wrapper.write('(%s)a%i' % (param2str(param), i)) + # i = i + 1 + # java_wrapper.write(');\n') + # # cleanup + # i = 0 + # for param in params: + # k = param_kind(param) + # if k == OUT_ARRAY: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + # else: + # java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) + # java_wrapper.write(' free(_a%s);\n' % i) + # elif k == IN_ARRAY or k == OUT_ARRAY: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) + # else: + # java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) + + # elif k == OUT or k == INOUT: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' {\n') + # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') + # java_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) + # java_wrapper.write(' }\n') + # else: + # java_wrapper.write(' {\n') + # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') + # java_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) + # java_wrapper.write(' }\n') + # i = i + 1 + # # return + # if result == STRING: + # java_wrapper.write(' return jenv->NewStringUTF(result);\n') + # elif result != VOID: + # java_wrapper.write(' return (%s) result;\n' % type2javaw(result)) + # java_wrapper.write('}\n') + # java_wrapper.write('#ifdef __cplusplus\n') + # java_wrapper.write('}\n') + # java_wrapper.write('#endif\n') + if is_verbose(): + print "Generated '%s'" % ml_nativef + # Collect API(...) commands from def def_APIs(): pat1 = re.compile(" *def_API.*") @@ -1063,6 +1269,7 @@ mk_py_wrappers() mk_dotnet() mk_dotnet_wrappers() mk_java() +mk_ml() log_h.close() log_c.close() diff --git a/src/api/ml/README b/src/api/ml/README new file mode 100644 index 000000000..925fced59 --- /dev/null +++ b/src/api/ml/README @@ -0,0 +1,3 @@ +This directory is work in progress. + +We are currently working on a brand new ML API. diff --git a/src/api/ml/add_error_checking.V3.sed b/src/api/ml/old/add_error_checking.V3.sed similarity index 100% rename from src/api/ml/add_error_checking.V3.sed rename to src/api/ml/old/add_error_checking.V3.sed diff --git a/src/api/ml/add_error_checking.sed b/src/api/ml/old/add_error_checking.sed similarity index 100% rename from src/api/ml/add_error_checking.sed rename to src/api/ml/old/add_error_checking.sed diff --git a/src/api/ml/build-lib.cmd b/src/api/ml/old/build-lib.cmd similarity index 100% rename from src/api/ml/build-lib.cmd rename to src/api/ml/old/build-lib.cmd diff --git a/src/api/ml/build-lib.sh b/src/api/ml/old/build-lib.sh similarity index 100% rename from src/api/ml/build-lib.sh rename to src/api/ml/old/build-lib.sh diff --git a/src/api/ml/build-test.cmd b/src/api/ml/old/build-test.cmd similarity index 100% rename from src/api/ml/build-test.cmd rename to src/api/ml/old/build-test.cmd diff --git a/src/api/ml/build-test.sh b/src/api/ml/old/build-test.sh similarity index 100% rename from src/api/ml/build-test.sh rename to src/api/ml/old/build-test.sh diff --git a/src/api/ml/build.cmd b/src/api/ml/old/build.cmd similarity index 100% rename from src/api/ml/build.cmd rename to src/api/ml/old/build.cmd diff --git a/src/api/ml/clean.cmd b/src/api/ml/old/clean.cmd similarity index 100% rename from src/api/ml/clean.cmd rename to src/api/ml/old/clean.cmd diff --git a/src/api/ml/cleantmp.cmd b/src/api/ml/old/cleantmp.cmd similarity index 100% rename from src/api/ml/cleantmp.cmd rename to src/api/ml/old/cleantmp.cmd diff --git a/src/api/ml/compile_mlapi.cmd b/src/api/ml/old/compile_mlapi.cmd similarity index 100% rename from src/api/ml/compile_mlapi.cmd rename to src/api/ml/old/compile_mlapi.cmd diff --git a/src/api/ml/error_handling.idl b/src/api/ml/old/error_handling.idl similarity index 100% rename from src/api/ml/error_handling.idl rename to src/api/ml/old/error_handling.idl diff --git a/src/api/ml/exec.cmd b/src/api/ml/old/exec.cmd similarity index 100% rename from src/api/ml/exec.cmd rename to src/api/ml/old/exec.cmd diff --git a/src/api/ml/exec.sh b/src/api/ml/old/exec.sh similarity index 100% rename from src/api/ml/exec.sh rename to src/api/ml/old/exec.sh diff --git a/src/api/ml/generate_mlapi.cmd b/src/api/ml/old/generate_mlapi.cmd similarity index 100% rename from src/api/ml/generate_mlapi.cmd rename to src/api/ml/old/generate_mlapi.cmd diff --git a/src/api/ml/generate_mlapi.sh b/src/api/ml/old/generate_mlapi.sh similarity index 100% rename from src/api/ml/generate_mlapi.sh rename to src/api/ml/old/generate_mlapi.sh diff --git a/src/api/ml/import.cmd b/src/api/ml/old/import.cmd similarity index 100% rename from src/api/ml/import.cmd rename to src/api/ml/old/import.cmd diff --git a/src/api/ml/mlx_get_app_args.idl b/src/api/ml/old/mlx_get_app_args.idl similarity index 100% rename from src/api/ml/mlx_get_app_args.idl rename to src/api/ml/old/mlx_get_app_args.idl diff --git a/src/api/ml/mlx_get_array_sort.idl b/src/api/ml/old/mlx_get_array_sort.idl similarity index 100% rename from src/api/ml/mlx_get_array_sort.idl rename to src/api/ml/old/mlx_get_array_sort.idl diff --git a/src/api/ml/mlx_get_datatype_sort.idl b/src/api/ml/old/mlx_get_datatype_sort.idl similarity index 100% rename from src/api/ml/mlx_get_datatype_sort.idl rename to src/api/ml/old/mlx_get_datatype_sort.idl diff --git a/src/api/ml/mlx_get_domains.idl b/src/api/ml/old/mlx_get_domains.idl similarity index 100% rename from src/api/ml/mlx_get_domains.idl rename to src/api/ml/old/mlx_get_domains.idl diff --git a/src/api/ml/mlx_get_error_msg.idl b/src/api/ml/old/mlx_get_error_msg.idl similarity index 100% rename from src/api/ml/mlx_get_error_msg.idl rename to src/api/ml/old/mlx_get_error_msg.idl diff --git a/src/api/ml/mlx_get_pattern_terms.idl b/src/api/ml/old/mlx_get_pattern_terms.idl similarity index 100% rename from src/api/ml/mlx_get_pattern_terms.idl rename to src/api/ml/old/mlx_get_pattern_terms.idl diff --git a/src/api/ml/mlx_get_tuple_sort.idl b/src/api/ml/old/mlx_get_tuple_sort.idl similarity index 100% rename from src/api/ml/mlx_get_tuple_sort.idl rename to src/api/ml/old/mlx_get_tuple_sort.idl diff --git a/src/api/ml/mlx_mk_context_x.idl b/src/api/ml/old/mlx_mk_context_x.idl similarity index 100% rename from src/api/ml/mlx_mk_context_x.idl rename to src/api/ml/old/mlx_mk_context_x.idl diff --git a/src/api/ml/mlx_mk_datatypes.idl b/src/api/ml/old/mlx_mk_datatypes.idl similarity index 100% rename from src/api/ml/mlx_mk_datatypes.idl rename to src/api/ml/old/mlx_mk_datatypes.idl diff --git a/src/api/ml/mlx_mk_numeral.idl b/src/api/ml/old/mlx_mk_numeral.idl similarity index 100% rename from src/api/ml/mlx_mk_numeral.idl rename to src/api/ml/old/mlx_mk_numeral.idl diff --git a/src/api/ml/mlx_mk_sort.idl b/src/api/ml/old/mlx_mk_sort.idl similarity index 100% rename from src/api/ml/mlx_mk_sort.idl rename to src/api/ml/old/mlx_mk_sort.idl diff --git a/src/api/ml/mlx_mk_symbol.idl b/src/api/ml/old/mlx_mk_symbol.idl similarity index 100% rename from src/api/ml/mlx_mk_symbol.idl rename to src/api/ml/old/mlx_mk_symbol.idl diff --git a/src/api/ml/mlx_model.idl b/src/api/ml/old/mlx_model.idl similarity index 100% rename from src/api/ml/mlx_model.idl rename to src/api/ml/old/mlx_model.idl diff --git a/src/api/ml/mlx_numeral_refine.idl b/src/api/ml/old/mlx_numeral_refine.idl similarity index 100% rename from src/api/ml/mlx_numeral_refine.idl rename to src/api/ml/old/mlx_numeral_refine.idl diff --git a/src/api/ml/mlx_parse_smtlib.idl b/src/api/ml/old/mlx_parse_smtlib.idl similarity index 100% rename from src/api/ml/mlx_parse_smtlib.idl rename to src/api/ml/old/mlx_parse_smtlib.idl diff --git a/src/api/ml/mlx_sort_refine.idl b/src/api/ml/old/mlx_sort_refine.idl similarity index 100% rename from src/api/ml/mlx_sort_refine.idl rename to src/api/ml/old/mlx_sort_refine.idl diff --git a/src/api/ml/mlx_statistics.idl b/src/api/ml/old/mlx_statistics.idl similarity index 100% rename from src/api/ml/mlx_statistics.idl rename to src/api/ml/old/mlx_statistics.idl diff --git a/src/api/ml/mlx_symbol_refine.idl b/src/api/ml/old/mlx_symbol_refine.idl similarity index 100% rename from src/api/ml/mlx_symbol_refine.idl rename to src/api/ml/old/mlx_symbol_refine.idl diff --git a/src/api/ml/mlx_term_refine.idl b/src/api/ml/old/mlx_term_refine.idl similarity index 100% rename from src/api/ml/mlx_term_refine.idl rename to src/api/ml/old/mlx_term_refine.idl diff --git a/src/api/ml/postprocess.sed b/src/api/ml/old/postprocess.sed similarity index 100% rename from src/api/ml/postprocess.sed rename to src/api/ml/old/postprocess.sed diff --git a/src/api/ml/preprocess.sed b/src/api/ml/old/preprocess.sed similarity index 100% rename from src/api/ml/preprocess.sed rename to src/api/ml/old/preprocess.sed diff --git a/src/api/ml/queen.ml b/src/api/ml/old/queen.ml similarity index 100% rename from src/api/ml/queen.ml rename to src/api/ml/old/queen.ml diff --git a/src/api/ml/queen.regress.err b/src/api/ml/old/queen.regress.err similarity index 100% rename from src/api/ml/queen.regress.err rename to src/api/ml/old/queen.regress.err diff --git a/src/api/ml/queen.regress.out b/src/api/ml/old/queen.regress.out similarity index 100% rename from src/api/ml/queen.regress.out rename to src/api/ml/old/queen.regress.out diff --git a/src/api/ml/reverse.sed b/src/api/ml/old/reverse.sed similarity index 100% rename from src/api/ml/reverse.sed rename to src/api/ml/old/reverse.sed diff --git a/src/api/ml/test_mlapi.cmd b/src/api/ml/old/test_mlapi.cmd similarity index 100% rename from src/api/ml/test_mlapi.cmd rename to src/api/ml/old/test_mlapi.cmd diff --git a/src/api/ml/test_theory.ml b/src/api/ml/old/test_theory.ml similarity index 100% rename from src/api/ml/test_theory.ml rename to src/api/ml/old/test_theory.ml diff --git a/src/api/ml/update-ml-doc.cmd b/src/api/ml/old/update-ml-doc.cmd similarity index 100% rename from src/api/ml/update-ml-doc.cmd rename to src/api/ml/old/update-ml-doc.cmd diff --git a/src/api/ml/x3V3.ml b/src/api/ml/old/x3V3.ml similarity index 100% rename from src/api/ml/x3V3.ml rename to src/api/ml/old/x3V3.ml diff --git a/src/api/ml/x3V3.mli b/src/api/ml/old/x3V3.mli similarity index 100% rename from src/api/ml/x3V3.mli rename to src/api/ml/old/x3V3.mli diff --git a/src/api/ml/z3.0.idl b/src/api/ml/old/z3.0.idl similarity index 100% rename from src/api/ml/z3.0.idl rename to src/api/ml/old/z3.0.idl diff --git a/src/api/ml/test_capi.regress.err b/src/api/ml/test_capi.regress.err deleted file mode 100644 index 0c383b409..000000000 --- a/src/api/ml/test_capi.regress.err +++ /dev/null @@ -1,5 +0,0 @@ -WARNING: invalid function application, sort mismatch on argument at position 1 -WARNING: (define iff Bool Bool Bool) applied to: -x of sort Int -y of sort Bool - diff --git a/src/api/ml/test_capi.regress.out b/src/api/ml/test_capi.regress.out deleted file mode 100644 index 48870057c..000000000 --- a/src/api/ml/test_capi.regress.out +++ /dev/null @@ -1,386 +0,0 @@ -Z3 4.2.0.0 - -simple_example -CONTEXT: -(solver)END OF CONTEXT - -DeMorgan -DeMorgan is valid - -find_model_example1 -model for: x xor y -sat -y -> false -x -> true - - -find_model_example2 -model for: x < y + 1, x > 2 -sat -y -> 3 -x -> 3 - -model for: x < y + 1, x > 2, not(x = y) -sat -y -> 4 -x -> 3 - - -prove_example1 -prove: x = y implies g(x) = g(y) -valid -disprove: x = y implies g(g(x)) = g(y) -invalid -counterexample: -y -> U!val!0 -x -> U!val!0 -g -> { - U!val!0 -> U!val!1 - U!val!1 -> U!val!2 - else -> U!val!1 -} - - -prove_example2 -prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 -valid -disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1 -invalid -counterexample: -z -> (- 1) -y -> (- 7719) -x -> (- 7719) -g -> { - (- 7719) -> 0 - 0 -> 2 - (- 1) -> 3 - else -> 0 -} - - -push_pop_example1 -assert: x >= 'big number' -push -number of scopes: 1 -assert: x <= 3 -unsat -pop -number of scopes: 0 -sat -x = 1000000000000000000000000000000000000000000000000000000:int -function interpretations: -assert: y > x -sat -y = 1000000000000000000000000000000000000000000000000000001:int -x = 1000000000000000000000000000000000000000000000000000000:int -function interpretations: - -quantifier_example1 -pattern: {(f #0 #1)} - -assert axiom: -(forall (k!0 Int) (k!1 Int) (= (inv!0 (f k!1 k!0)) k!0) :pat {(f k!1 k!0)}) -prove: f(x, y) = f(w, v) implies y = v -valid -disprove: f(x, y) = f(w, v) implies x = w -that is: not(f(x, y) = f(w, v) implies x = w) is satisfiable -unknown -potential model: -w = 2:int -v = 1:int -y = 1:int -x = 0:int -function interpretations: -f = {(else|->(define f!52 Int Int Int)[(define k!50 Int Int)[#unknown], (define k!51 Int Int)[#unknown]])} -#51 = {(2:int|->2:int), (1:int|->1:int), (15:int|->15:int), (11:int|->11:int), (0:int|->0:int), (19:int|->19:int), (else|->2:int)} -f!52 = {(0:int, 1:int|->3:int), (2:int, 1:int|->3:int), (0:int, 0:int|->4:int), (2:int, 0:int|->5:int), (6:int, 2:int|->7:int), (2:int, 2:int|->8:int), (0:int, 2:int|->9:int), (6:int, 0:int|->10:int), (0:int, 11:int|->12:int), (2:int, 11:int|->13:int), (6:int, 11:int|->14:int), (0:int, 15:int|->16:int), (2:int, 15:int|->17:int), (6:int, 15:int|->18:int), (0:int, 19:int|->20:int), (6:int, 19:int|->21:int), (2:int, 19:int|->22:int), (else|->3:int)} -inv!0 = {(3:int|->1:int), (4:int|->0:int), (5:int|->0:int), (7:int|->2:int), (8:int|->2:int), (9:int|->2:int), (10:int|->0:int), (12:int|->11:int), (13:int|->11:int), (14:int|->11:int), (16:int|->15:int), (17:int|->15:int), (18:int|->15:int), (20:int|->19:int), (21:int|->19:int), (22:int|->19:int), (else|->2:int)} -#50 = {(2:int|->2:int), (6:int|->6:int), (0:int|->0:int), (else|->2:int)} -reason for last failure: 7 (7 = quantifiers) - -array_example1 -prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) -(=> (= (store a1 i1 v1) (store a2 i2 v2)) - (or (= i1 i3) (= i2 i3) (= (select a1 i3) (select a2 i3)))) -valid - -array_example2 -n = 2 -(distinct k!0 k!1) -sat -#0 = (define as-array[k!0] (Array Bool Bool)) -#1 = (define as-array[k!1] (Array Bool Bool)) -function interpretations: -#0 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))} -#1 = {((define false Bool)|->(define false Bool)), (else|->(define false Bool))} -n = 3 -(distinct k!0 k!1 k!2) -sat -#0 = (define as-array[k!0] (Array Bool Bool)) -#1 = (define as-array[k!1] (Array Bool Bool)) -#2 = (define as-array[k!2] (Array Bool Bool)) -function interpretations: -#0 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))} -#1 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))} -#2 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))} -n = 4 -(distinct k!0 k!1 k!2 k!3) -sat -#0 = (define as-array[k!0] (Array Bool Bool)) -#1 = (define as-array[k!1] (Array Bool Bool)) -#2 = (define as-array[k!2] (Array Bool Bool)) -#3 = (define as-array[k!3] (Array Bool Bool)) -function interpretations: -#0 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define true Bool)), (else|->(define false Bool))} -#1 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))} -#2 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define true Bool)), (else|->(define true Bool))} -#3 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))} -n = 5 -(distinct k!0 k!1 k!2 k!3 k!4) -unsat - -array_example3 -domain: int -range: bool - -tuple_example1 -tuple_sort: (real, real) -prove: get_x(mk_pair(x, y)) = 1 implies x = 1 -valid -disprove: get_x(mk_pair(x, y)) = 1 implies y = 1 -invalid -counterexample: -y -> 0 -x -> 1 - -prove: get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2 -valid -disprove: get_x(p1) = get_x(p2) implies p1 = p2 -invalid -counterexample: -p1 -> (mk_pair 1 0) -p2 -> (mk_pair 1 2) - -prove: p2 = update(p1, 0, 10) implies get_x(p2) = 10 -valid -disprove: p2 = update(p1, 0, 10) implies get_y(p2) = 10 -invalid -counterexample: -p2 -> (mk_pair 10 1) -p1 -> (mk_pair 0 1) - - -bitvector_example1 -disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers -invalid -counterexample: -x -> bv2147483656[32] - - -bitvector_example2 -find values of x and y, such that x ^ y - 103 == x * y -sat -y -> bv3905735879[32] -x -> bv3787456528[32] - - -eval_example1 -MODEL: -y -> 4 -x -> 3 - -evaluating x+y -result = 7:int - -two_contexts_example1 -k!0 - -error_code_example1 -last call succeeded. -last call failed. - -error_code_example2 -before Z3_mk_iff -Z3 error: type error. - -parser_example1 -formula 0: (> x y) -formula 1: (> x 0) -sat -y -> 0 -x -> 1 - - -parser_example2 -formula: (> x y) -sat -y -> (- 1) -x -> 0 - - -parser_example3 -assert axiom: -(forall (x Int) (y Int) (= (g x y) (g y x)) :qid {k!1}) -formula: (forall (x Int) (y Int) (=> (= x y) (= (g x 0) (g 0 y))) :qid {k!1}) -valid - -parser_example4 -declaration 0: (define y Int) -declaration 1: (define sk_hack Bool Bool) -declaration 2: (define x Int) -assumption 0: (= x 20) -formula 0: (> x y) -formula 1: (> x 0) - -parser_example5 -Z3 error: parser error. -Error message: 'ERROR: line 1 column 41: could not find sort symbol 'y'. -'. - -numeral_example -Numerals n1:1/2 n2:1/2 -valid -Numerals n1:(- 1/3) n2:(- 33333333333333333333333333333333333333333333333333/100000000000000000000000000000000000000000000000000) -valid - -ite_example -term: (if false 1 0) - -list_example -valid -valid -valid -valid -valid -valid -valid -Formula (=> (is_cons u) (= u (cons (head u) (tail u)))) -valid -invalid -counterexample: -u -> nil - - -tree_example -valid -valid -valid -valid -valid -Formula (=> (is_cons u) (= u (cons (car u) (cdr u)))) -valid -invalid -counterexample: -u -> nil - - -forest_example -valid -valid -valid -valid -valid -valid - -binary_tree_example -valid -valid -valid -valid -valid - -enum_example -(define apple[fruit:0] fruit) -(define banana[fruit:1] fruit) -(define orange[fruit:2] fruit) -(define is_apple[fruit:0] fruit Bool) -(define is_banana[fruit:1] fruit Bool) -(define is_orange[fruit:2] fruit Bool) -valid -valid -invalid -counterexample: - -valid -valid - -unsat_core_and_proof_example -unsat -proof: [unit-resolution - [def-axiom (or (or (not PredA) PredB (not PredC)) (not PredB))] - [unit-resolution - [def-axiom (or (or (not PredA) (not PredB) (not PredC)) PredB)] - [unit-resolution - [mp - [asserted (or (and PredA PredB PredC) P1)] - [monotonicity - [rewrite - (iff (and PredA PredB PredC) - (not (or (not PredA) (not PredB) (not PredC))))] - (iff (or (and PredA PredB PredC) P1) - (or (not (or (not PredA) (not PredB) (not PredC))) P1))] - (or (not (or (not PredA) (not PredB) (not PredC))) P1)] - [asserted (not P1)] - (not (or (not PredA) (not PredB) (not PredC)))] - PredB] - [unit-resolution - [mp - [asserted (or (and PredA (not PredB) PredC) P2)] - [monotonicity - [rewrite - (iff (and PredA (not PredB) PredC) - (not (or (not PredA) PredB (not PredC))))] - (iff (or (and PredA (not PredB) PredC) P2) - (or (not (or (not PredA) PredB (not PredC))) P2))] - (or (not (or (not PredA) PredB (not PredC))) P2)] - [asserted (not P2)] - (not (or (not PredA) PredB (not PredC)))] - false] - -core: -(not P1) -(not P2) - - -get_implied_equalities example -Class a |-> 0 -Class b |-> 0 -Class c |-> 0 -Class d |-> 3 -Class (f a) |-> 0 -Class (f b) |-> 0 -Class (f c) |-> 0 -asserting f(a) <= b -Class a |-> 0 -Class b |-> 0 -Class c |-> 0 -Class d |-> 3 -Class (f a) |-> 0 -Class (f b) |-> 0 -Class (f c) |-> 0 - -incremental_example1 -unsat core: 0 2 3 -unsat -sat -unsat core: 0 2 3 -unsat -unsat core: 0 2 3 -unsat -sat - -reference_counter_example -model for: x xor y -sat -y -> false -x -> true - - -smt2parser_example -formulas: (and (bvuge a bv16[8]) (bvule a bv240[8])) - -substitute_example -substitution result: (f (f a 0) 1) - -substitute_vars_example -substitution result: (f (f a (g b)) a) diff --git a/src/api/ml/test_mlapi.regress.err b/src/api/ml/test_mlapi.regress.err deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/api/ml/test_mlapi.regress.out b/src/api/ml/test_mlapi.regress.out deleted file mode 100644 index 1fb6289c7..000000000 --- a/src/api/ml/test_mlapi.regress.out +++ /dev/null @@ -1,32 +0,0 @@ -datatype created: -sort: tree -constructor: (define leaf[tree:0] Int tree) recognizer: (define is_leaf[tree:0] tree Bool) accessors: (define data[tree:0:0] tree Int) -constructor: (define node[tree:1] forest tree) recognizer: (define is_node[tree:1] tree Bool) accessors: (define children[tree:1:0] tree forest) -sort: forest -constructor: (define nil[forest:0] forest) recognizer: (define is_nil[forest:0] forest Bool) accessors: -constructor: (define cons[forest:1] tree forest forest) recognizer: (define is_cons[forest:1] forest Bool) accessors: (define hd[forest:1:0] forest tree) (define tl[forest:1:1] forest forest) - -t1: (node (cons (leaf 1) (cons (leaf 2) nil))) -t2: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 3) nil))) -t3: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil))) - (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil))) -t4: (node (cons (leaf 4) (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil))) -f1: (cons (leaf 0) nil) -f2: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil) -f3: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 0) nil)) -t1: (node (cons (leaf 1) (cons (leaf 2) nil))) -t2: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 3) nil))) -t3: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil))) - (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil))) -t4: (node (cons (leaf 4) (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil))) -f1: (cons (leaf 0) nil) -f2: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil) -f3: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 0) nil)) -valid -valid -l1: (cons x u) -l2: (cons y v) -valid -valid -valid -valid diff --git a/src/api/ml/test_mlapiV3.regress.err b/src/api/ml/test_mlapiV3.regress.err deleted file mode 100644 index 0c383b409..000000000 --- a/src/api/ml/test_mlapiV3.regress.err +++ /dev/null @@ -1,5 +0,0 @@ -WARNING: invalid function application, sort mismatch on argument at position 1 -WARNING: (define iff Bool Bool Bool) applied to: -x of sort Int -y of sort Bool - diff --git a/src/api/ml/test_mlapiV3.regress.out b/src/api/ml/test_mlapiV3.regress.out deleted file mode 100644 index efcc4388d..000000000 --- a/src/api/ml/test_mlapiV3.regress.out +++ /dev/null @@ -1,315 +0,0 @@ -Z3 4.2.0.0 - -simple_example -CONTEXT: -(solver)END OF CONTEXT - -DeMorgan -DeMorgan is valid - -find_model_example1 -model for: x xor y -sat -y -> false -x -> true - - -find_model_example2 -model for: x < y + 1, x > 2 -sat -y -> 3 -x -> 3 - -model for: x < y + 1, x > 2, not(x = y) -sat -y -> 4 -x -> 3 - - -prove_example1 -prove: x = y implies g(x) = g(y) -valid -disprove: x = y implies g(g(x)) = g(y) -invalid -counterexample: -y -> U!val!0 -x -> U!val!0 -g -> { - U!val!0 -> U!val!1 - U!val!1 -> U!val!2 - else -> U!val!1 -} - - -prove_example2 -prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 -valid -disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1 -invalid -counterexample: -z -> (- 1) -y -> (- 7719) -x -> (- 7719) -g -> { - (- 7719) -> 0 - 0 -> 2 - (- 1) -> 3 - else -> 0 -} - - -push_pop_example1 -assert: x >= 'big number' -push -number of scopes: 1 -assert: x <= 3 -unsat -pop -number of scopes: 0 -sat -x = 1000000000000000000000000000000000000000000000000000000:int -function interpretations: -assert: y > x -sat -y = 1000000000000000000000000000000000000000000000000000001:int -x = 1000000000000000000000000000000000000000000000000000000:int -function interpretations: - -quantifier_example1 -pattern: {(f #0 #1)} - -assert axiom: -(forall (k!0 Int) (k!1 Int) (= (inv!0 (f k!1 k!0)) k!0) :pat {(f k!1 k!0)}) -prove: f(x, y) = f(w, v) implies y = v -valid -disprove: f(x, y) = f(w, v) implies x = w -that is: not(f(x, y) = f(w, v) implies x = w) is satisfiable -unknown -potential model: -w = 2:int -v = 1:int -y = 1:int -x = 0:int -function interpretations: -f = {(else|->(define f!52 Int Int Int)[(define k!50 Int Int)[#unknown], (define k!51 Int Int)[#unknown]])} -#51 = {(2:int|->2:int), (1:int|->1:int), (15:int|->15:int), (11:int|->11:int), (0:int|->0:int), (19:int|->19:int), (else|->2:int)} -f!52 = {(0:int, 1:int|->3:int), (2:int, 1:int|->3:int), (0:int, 0:int|->4:int), (2:int, 0:int|->5:int), (6:int, 2:int|->7:int), (2:int, 2:int|->8:int), (0:int, 2:int|->9:int), (6:int, 0:int|->10:int), (0:int, 11:int|->12:int), (2:int, 11:int|->13:int), (6:int, 11:int|->14:int), (0:int, 15:int|->16:int), (2:int, 15:int|->17:int), (6:int, 15:int|->18:int), (0:int, 19:int|->20:int), (6:int, 19:int|->21:int), (2:int, 19:int|->22:int), (else|->3:int)} -inv!0 = {(3:int|->1:int), (4:int|->0:int), (5:int|->0:int), (7:int|->2:int), (8:int|->2:int), (9:int|->2:int), (10:int|->0:int), (12:int|->11:int), (13:int|->11:int), (14:int|->11:int), (16:int|->15:int), (17:int|->15:int), (18:int|->15:int), (20:int|->19:int), (21:int|->19:int), (22:int|->19:int), (else|->2:int)} -#50 = {(2:int|->2:int), (6:int|->6:int), (0:int|->0:int), (else|->2:int)} -reason for last failure: 7 (7 = quantifiers) - -array_example1 -prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) -(=> (= (store a1 i1 v1) (store a2 i2 v2)) - (or (= i1 i3) (= i2 i3) (= (select a1 i3) (select a2 i3)))) -valid - -array_example2 -n = 2 -(distinct k!0 k!1) -sat -#0 = (define as-array[k!0] (Array Bool Bool)) -#1 = (define as-array[k!1] (Array Bool Bool)) -function interpretations: -#0 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))} -#1 = {((define false Bool)|->(define false Bool)), (else|->(define false Bool))} -n = 3 -(distinct k!0 k!1 k!2) -sat -#0 = (define as-array[k!0] (Array Bool Bool)) -#1 = (define as-array[k!1] (Array Bool Bool)) -#2 = (define as-array[k!2] (Array Bool Bool)) -function interpretations: -#0 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))} -#1 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))} -#2 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))} -n = 4 -(distinct k!0 k!1 k!2 k!3) -sat -#0 = (define as-array[k!0] (Array Bool Bool)) -#1 = (define as-array[k!1] (Array Bool Bool)) -#2 = (define as-array[k!2] (Array Bool Bool)) -#3 = (define as-array[k!3] (Array Bool Bool)) -function interpretations: -#0 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define true Bool)), (else|->(define false Bool))} -#1 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))} -#2 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define true Bool)), (else|->(define true Bool))} -#3 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))} -n = 5 -(distinct k!0 k!1 k!2 k!3 k!4) -unsat - -array_example3 -domain: int -range: bool - -tuple_example1 -tuple_sort: (real, real) -prove: get_x(mk_pair(x, y)) = 1 implies x = 1 -valid -disprove: get_x(mk_pair(x, y)) = 1 implies y = 1 -invalid -counterexample: -y -> 0 -x -> 1 - -prove: get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2 -valid -disprove: get_x(p1) = get_x(p2) implies p1 = p2 -invalid -counterexample: -p1 -> (mk_pair 1 0) -p2 -> (mk_pair 1 2) - -prove: p2 = update(p1, 0, 10) implies get_x(p2) = 10 -valid -disprove: p2 = update(p1, 0, 10) implies get_y(p2) = 10 -invalid -counterexample: -p2 -> (mk_pair 10 1) -p1 -> (mk_pair 0 1) - - -bitvector_example1 -disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers -invalid -counterexample: -x -> bv2147483656[32] - - -bitvector_example2 -find values of x and y, such that x ^ y - 103 == x * y -sat -y -> bv3905735879[32] -x -> bv3787456528[32] - - -eval_example1 -MODEL: -y -> 4 -x -> 3 - -evaluating x+y -result = 7:int - -two_contexts_example1 -k!0 - -error_code_example1 -last call succeeded. -last call failed. - -error_code_example2 -before Z3_mk_iff -Z3 error: type error. - -parser_example1 -formula 0: (> x y) -formula 1: (> x 0) -sat -y -> 0 -x -> 1 - - -parser_example2 -formula: (> x y) -sat -y -> (- 1) -x -> 0 - - -parser_example3 -assert axiom: -(forall (x Int) (y Int) (= (g x y) (g y x)) :qid {k!1}) -formula: (forall (x Int) (y Int) (=> (= x y) (= (g x 0) (g 0 y))) :qid {k!1}) -valid - -parser_example4 -declaration 0: (define y Int) -declaration 1: (define sk_hack Bool Bool) -declaration 2: (define x Int) -assumption 0: (= x 20) -formula 0: (> x y) -formula 1: (> x 0) - -parser_example5 -Z3 error: parser error. -Error message: 'ERROR: line 1 column 41: could not find sort symbol 'y'. -'. - -ite_example -term: (if false 1 0) - -enum_example -(define apple[fruit:0] fruit) -(define banana[fruit:1] fruit) -(define orange[fruit:2] fruit) -(define is_apple[fruit:0] fruit Bool) -(define is_banana[fruit:1] fruit Bool) -(define is_orange[fruit:2] fruit Bool) -valid -valid -invalid -counterexample: - -valid -valid - -unsat_core_and_proof_example -unsat -proof: [unit-resolution - [def-axiom (or (or (not PredA) PredC (not PredB)) (not PredC))] - [unit-resolution - [def-axiom (or (or (not PredA) (not PredB) (not PredC)) PredC)] - [unit-resolution - [mp - [asserted (or (and PredA PredB PredC) P1)] - [monotonicity - [rewrite - (iff (and PredA PredB PredC) - (not (or (not PredA) (not PredB) (not PredC))))] - (iff (or (and PredA PredB PredC) P1) - (or (not (or (not PredA) (not PredB) (not PredC))) P1))] - (or (not (or (not PredA) (not PredB) (not PredC))) P1)] - [asserted (not P1)] - (not (or (not PredA) (not PredB) (not PredC)))] - PredC] - [unit-resolution - [mp - [asserted (or (and PredA (not PredC) PredB) P2)] - [monotonicity - [rewrite - (iff (and PredA (not PredC) PredB) - (not (or (not PredA) PredC (not PredB))))] - (iff (or (and PredA (not PredC) PredB) P2) - (or (not (or (not PredA) PredC (not PredB))) P2))] - (or (not (or (not PredA) PredC (not PredB))) P2)] - [asserted (not P2)] - (not (or (not PredA) PredC (not PredB)))] - false] - -core: -(not P2) -(not P1) - - -abstract_example -formula: (> x y) -abstracted formula: (> #0 y) - -get_implied_equalities example -Class a |-> 0 -Class b |-> 0 -Class c |-> 0 -Class d |-> 3 -Class (f a) |-> 0 -Class (f b) |-> 0 -Class (f c) |-> 0 -asserting f(a) <= b -Class a |-> 0 -Class b |-> 0 -Class c |-> 0 -Class d |-> 3 -Class (f a) |-> 0 -Class (f b) |-> 0 -Class (f c) |-> 0 From 03a5c88dedfc148308c04be596adc56ed251d674 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 15:07:33 +0000 Subject: [PATCH 223/507] More new ML API Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 3 + scripts/mk_util.py | 89 ++++++++++++++++++++++++++++++ scripts/update_api.py | 125 ++++++++++++++++++++++++------------------ 3 files changed, 164 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 65a69bf51..3c4fb1218 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,6 @@ src/api/java/enumerations/*.java *.bak doc/api doc/code +src/api/ml/z3_native.c +src/api/ml/z3_native.ml +src/api/ml/z3_enums.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index cb6b17cce..8543f1ffa 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -49,6 +49,7 @@ UTIL_COMPONENT='util' API_COMPONENT='api' DOTNET_COMPONENT='dotnet' JAVA_COMPONENT='java' +ML_COMPONENT='ml' CPP_COMPONENT='cpp' ##################### IS_WINDOWS=False @@ -2230,6 +2231,8 @@ def mk_bindings(api_files): if is_java_enabled(): check_java() mk_z3consts_java(api_files) + if is_ml_enabled(): + mk_z3consts_ml(api_files) _execfile(os.path.join('scripts', 'update_api.py'), g) # HACK cp_z3py_to_build() @@ -2503,6 +2506,92 @@ def mk_z3consts_java(api_files): if VERBOSE: print("Generated '%s'" % ('%s' % gendir)) +# Extract enumeration types from z3_api.h, and add ML definitions +def mk_z3consts_ml(api_files): + blank_pat = re.compile("^ *$") + comment_pat = re.compile("^ *//.*$") + typedef_pat = re.compile("typedef enum *") + typedef2_pat = re.compile("typedef enum { *") + openbrace_pat = re.compile("{ *") + closebrace_pat = re.compile("}.*;") + + ml = get_component(ML_COMPONENT) + + DeprecatedEnums = [ 'Z3_search_failure' ] + gendir = ml.src_dir + if not os.path.exists(gendir): + os.mkdir(gendir) + + efile = open('%s.ml' % os.path.join(gendir, "z3_enums"), 'w') + efile.write('(* Automatically generated file *)\n\n') + # efile.write('module z3_enums = struct\n\n'); + + + for api_file in api_files: + api_file_c = ml.find_file(api_file, ml.name) + api_file = os.path.join(api_file_c.src_dir, api_file) + + api = open(api_file, 'r') + + SEARCHING = 0 + FOUND_ENUM = 1 + IN_ENUM = 2 + + mode = SEARCHING + decls = {} + idx = 0 + + linenum = 1 + for line in api: + m1 = blank_pat.match(line) + m2 = comment_pat.match(line) + if m1 or m2: + # skip blank lines and comments + linenum = linenum + 1 + elif mode == SEARCHING: + m = typedef_pat.match(line) + if m: + mode = FOUND_ENUM + m = typedef2_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + elif mode == FOUND_ENUM: + m = openbrace_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + else: + assert False, "Invalid %s, line: %s" % (api_file, linenum) + else: + assert mode == IN_ENUM + words = re.split('[^\-a-zA-Z0-9_]+', line) + m = closebrace_pat.match(line) + if m: + name = words[1] + if name not in DeprecatedEnums: + efile.write('\n(* %s *)\n' % name) + efile.write('type %s =\n' % name[3:]) # strip Z3_ + efile.write + for k, i in decls.iteritems(): + efile.write(' | %s \n' % k[3:]) # strip Z3_ + mode = SEARCHING + else: + if words[2] != '': + if len(words[2]) > 1 and words[2][1] == 'x': + idx = int(words[2], 16) + else: + idx = int(words[2]) + decls[words[1]] = idx + idx = idx + 1 + linenum = linenum + 1 + efile.write('\n') + # efile.write'end\n'); + if VERBOSE: + print "Generated '%s/z3_enums.ml'" % ('%s' % gendir) + def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 9ef0ce9a2..1e86dc0ef 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -156,9 +156,9 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint'} # Mapping to ML types -Type2ML = { VOID : 'void', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', - STRING : 'char*', STRING_PTR : 'char**', - BOOL : 'boolean', SYMBOL : 'long', PRINT_MODE : 'int', ERROR_CODE : 'int' } +Type2ML = { VOID : 'unit', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', + STRING : 'string', STRING_PTR : 'char**', + BOOL : 'lbool', SYMBOL : 'symbol', PRINT_MODE : 'ast_print_mode', ERROR_CODE : 'error_code' } next_type_id = FIRST_OBJ_ID @@ -332,13 +332,13 @@ def param2ml(p): elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: return "long*" elif param_type(p) == STRING: - return "char*" + return "string" else: print "ERROR: unreachable code" assert(False) exit(1) if k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: - return "%s[]" % type2ml(param_type(p)) + return "%s array" % type2ml(param_type(p)) else: return type2ml(param_type(p)) @@ -1069,9 +1069,7 @@ def mk_bindings(): exe_c.write("}\n") def ml_method_name(name): - result = '' - name = name[3:] # Remove Z3_ - return result + return name[3:] # Remove Z3_ def mk_ml(): if not is_ml_enabled(): @@ -1080,10 +1078,57 @@ def mk_ml(): ml_nativef = os.path.join(ml_dir, 'z3_native.ml') ml_wrapperf = os.path.join(ml_dir, 'z3_native.c') ml_native = open(ml_nativef, 'w') - ml_native.write('// Automatically generated file\n') + ml_native.write('(* Automatically generated file *)\n') ml_native.write('\n') + ml_native.write('module Z3 = struct\n\n') + ml_native.write('type context\n') + ml_native.write('and symbol\n') + ml_native.write('and ast\n') + ml_native.write('and sort = private ast\n') + ml_native.write('and func_decl = private ast\n') + ml_native.write('and app = private ast\n') + ml_native.write('and pattern = private ast\n') + ml_native.write('and params\n') + ml_native.write('and param_descrs\n') + ml_native.write('and model\n') + ml_native.write('and func_interp\n') + ml_native.write('and func_entry\n') + ml_native.write('and fixedpoint\n') + ml_native.write('and ast_vector\n') + ml_native.write('and ast_map\n') + ml_native.write('and goal\n') + ml_native.write('and tactic\n') + ml_native.write('and probe\n') + ml_native.write('and apply_result\n') + ml_native.write('and solver\n') + ml_native.write('and stats\n') + ml_native.write('\n') + ml_native.write(' exception Z3Exception of string\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external %s : (' % ml_method_name(name)) + ml_native.write(' external native_%s : ' % ml_method_name(name)) + i = 0; + for param in params: + ml_native.write('%s -> ' % param2ml(param)) + i = i + 1 + ml_native.write('%s\n' % (type2ml(result))) + ml_native.write(' = "Native_Z3_%s"\n\n' % ml_method_name(name)) + # Exception wrappers + for name, result, params in _dotnet_decls: + ml_native.write(' let %s ' % ml_method_name(name)) + first = True + i = 0; + for param in params: + if first: + first = False; + else: + ml_native.write(' ') + ml_native.write('a%d' % i) + i = i + 1 + ml_native.write(' = \n') + ml_native.write(' ') + if result != VOID: + ml_native.write('let res = ') + ml_native.write('n_%s(' % (ml_method_name(name))) first = True i = 0; for param in params: @@ -1091,50 +1136,24 @@ def mk_ml(): first = False else: ml_native.write(', ') - ml_native.write('%s a%d' % (param2ml(param), i)) + ml_native.write('a%d' % i) i = i + 1 - ml_native.write('%s)\n' % (type2ml(result))) - # ml_native.write(' = "NATIVE_%s"' % ml_method_name(name)) - # ml_native.write('\n\n') - # # Exception wrappers - # for name, result, params in _dotnet_decls: - # java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) - # first = True - # i = 0; - # for param in params: - # if first: - # first = False - # else: - # java_native.write(', ') - # java_native.write('%s a%d' % (param2java(param), i)) - # i = i + 1 - # java_native.write(')') - # if len(params) > 0 and param_type(params[0]) == CONTEXT: - # java_native.write(' throws Z3Exception') - # java_native.write('\n') - # java_native.write(' {\n') - # java_native.write(' ') - # if result != VOID: - # java_native.write('%s res = ' % type2java(result)) - # java_native.write('INTERNAL%s(' % (java_method_name(name))) - # first = True - # i = 0; - # for param in params: - # if first: - # first = False - # else: - # java_native.write(', ') - # java_native.write('a%d' % i) - # i = i + 1 - # java_native.write(');\n') - # if len(params) > 0 and param_type(params[0]) == CONTEXT: - # java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') - # java_native.write(' if (err != Z3_error_code.Z3_OK)\n') - # java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') - # if result != VOID: - # java_native.write(' return res;\n') - # java_native.write(' }\n\n') - # java_native.write('}\n') + ml_native.write(')') + if result != VOID: + ml_native.write(' in\n') + else: + ml_native.write(';\n') + if len(params) > 0 and param_type(params[0]) == CONTEXT: + ml_native.write(' let err = error_code.fromInt(n_get_error_code(a0)) in \n') + ml_native.write(' if err <> Z3_enums.OK then\n') + ml_native.write(' raise (z3_exception n_get_error_msg_ex(a0, err.toInt()))\n') + ml_native.write(' else\n') + if result == VOID: + ml_native.write(' ()\n') + else: + ml_native.write(' res\n') + ml_native.write('\n') + ml_native.write('\nend\n') ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') ml_wrapper.write('#include \n') From f5a0520b838fa04ba5336daf35ffa268b670c6db Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 16:35:39 +0000 Subject: [PATCH 224/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 3 + scripts/mk_util.py | 6 +- scripts/update_api.py | 211 +++++++++++++------------ src/api/ml/{ => old}/Makefile | 0 src/api/ml/{ => old}/Makefile.build | 0 src/api/ml/{ => old}/test_mlapi.ml | 0 src/api/ml/{ => old}/test_mlapiV3.ml | 0 src/api/ml/{ => old}/x3.ml | 0 src/api/ml/{ => old}/z3_stubs.c | 0 src/api/ml/{ => old}/z3_theory_stubs.c | 0 10 files changed, 120 insertions(+), 100 deletions(-) rename src/api/ml/{ => old}/Makefile (100%) rename src/api/ml/{ => old}/Makefile.build (100%) rename src/api/ml/{ => old}/test_mlapi.ml (100%) rename src/api/ml/{ => old}/test_mlapiV3.ml (100%) rename src/api/ml/{ => old}/x3.ml (100%) rename src/api/ml/{ => old}/z3_stubs.c (100%) rename src/api/ml/{ => old}/z3_theory_stubs.c (100%) diff --git a/.gitignore b/.gitignore index 3c4fb1218..f2a31c21e 100644 --- a/.gitignore +++ b/.gitignore @@ -64,9 +64,12 @@ src/util/version.h src/api/java/Native.cpp src/api/java/Native.java src/api/java/enumerations/*.java + *.bak doc/api doc/code src/api/ml/z3_native.c src/api/ml/z3_native.ml +src/api/ml/native.c +src/api/ml/Z3.ml src/api/ml/z3_enums.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8543f1ffa..4249a04b0 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1286,9 +1286,9 @@ class MLComponent(Component): if is_ml_enabled(): mk_dir(os.path.join(BUILD_DIR, 'api', 'ml')) libfile = '%s$(LIB_EXT)' % self.lib_name - out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'z3_native.c'))) - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) %s/z3_native.c\n' % self.to_src_dir) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'z3_native')) + out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) -I%s %s/native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'native')) out.write('ml: %s\n' % libfile) out.write('\n') diff --git a/scripts/update_api.py b/scripts/update_api.py index 1e86dc0ef..9acdf1040 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1075,12 +1075,12 @@ def mk_ml(): if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'z3_native.ml') - ml_wrapperf = os.path.join(ml_dir, 'z3_native.c') + ml_nativef = os.path.join(ml_dir, 'Z3.ml') + ml_wrapperf = os.path.join(ml_dir, 'native.c') ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n') ml_native.write('\n') - ml_native.write('module Z3 = struct\n\n') + ml_native.write('module Z3Native = struct\n\n') ml_native.write('type context\n') ml_native.write('and symbol\n') ml_native.write('and ast\n') @@ -1166,101 +1166,118 @@ def mk_ml(): ml_wrapper.write('#ifdef Custom_tag\n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') - ml_wrapper.write('#endif\n') - # for name, result, params in _dotnet_decls: - # java_wrapper.write('JNIEXPORT %s JNICALL Java_%s_Native_INTERNAL%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), pkg_str, java_method_name(name))) - # i = 0; - # for param in params: - # java_wrapper.write(', ') - # java_wrapper.write('%s a%d' % (param2javaw(param), i)) - # i = i + 1 - # java_wrapper.write(') {\n') - # # preprocess arrays, strings, in/out arguments - # i = 0 - # for param in params: - # k = param_kind(param) - # if k == OUT or k == INOUT: - # java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) - # elif k == IN_ARRAY or k == INOUT_ARRAY: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) - # else: - # java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) - # elif k == OUT_ARRAY: - # java_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), - # i, - # type2str(param_type(param)), - # param_array_capacity_pos(param), - # type2str(param_type(param)))) - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - # else: - # java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) - # elif k == IN and param_type(param) == STRING: - # java_wrapper.write(' Z3_string _a%s = (Z3_string) jenv->GetStringUTFChars(a%s, NULL);\n' % (i, i)) - # i = i + 1 - # # invoke procedure - # java_wrapper.write(' ') - # if result != VOID: - # java_wrapper.write('%s result = ' % type2str(result)) - # java_wrapper.write('%s(' % name) - # i = 0 - # first = True - # for param in params: - # if first: - # first = False - # else: - # java_wrapper.write(', ') - # k = param_kind(param) - # if k == OUT or k == INOUT: - # java_wrapper.write('&_a%s' % i) - # elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: - # java_wrapper.write('_a%s' % i) - # elif k == IN and param_type(param) == STRING: - # java_wrapper.write('_a%s' % i) - # else: - # java_wrapper.write('(%s)a%i' % (param2str(param), i)) - # i = i + 1 - # java_wrapper.write(');\n') - # # cleanup - # i = 0 - # for param in params: - # k = param_kind(param) - # if k == OUT_ARRAY: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - # else: - # java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) - # java_wrapper.write(' free(_a%s);\n' % i) - # elif k == IN_ARRAY or k == OUT_ARRAY: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) - # else: - # java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) + ml_wrapper.write('#endif\n\n') + ml_wrapper.write('#include \n\n') + for name, result, params in _dotnet_decls: + #return type = type2ml(result) + ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) + first = True + i = 0 + for param in params: + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('value a%d' % i) + # param type = param2ml(param) + i = i + 1 + ml_wrapper.write(') {\n') + ml_wrapper.write(' CAMLparam%d(' % len(params)) + i = 0 + first = True + for param in params: + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('a%d' % i) + i = i + 1 + ml_wrapper.write(');\n') + # preprocess arrays, strings, in/out arguments + i = 0 + for param in params: + k = param_kind(param) + if k == OUT or k == INOUT: + ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) + elif k == IN_ARRAY or k == INOUT_ARRAY: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) + else: + ml_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) + elif k == OUT_ARRAY: + ml_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), + i, + type2str(param_type(param)), + param_array_capacity_pos(param), + type2str(param_type(param)))) + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + else: + ml_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) + elif k == IN and param_type(param) == STRING: + ml_wrapper.write(' Z3_string _a%s = (Z3_string) String_val(a%s);\n' % (i, i)) + i = i + 1 + # invoke procedure + ml_wrapper.write(' ') + if result != VOID: + ml_wrapper.write('%s result = ' % type2str(result)) + ml_wrapper.write('%s(' % name) + i = 0 + first = True + for param in params: + if first: + first = False + else: + ml_wrapper.write(', ') + k = param_kind(param) + if k == OUT or k == INOUT: + ml_wrapper.write('&_a%s' % i) + elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: + ml_wrapper.write('_a%s' % i) + elif k == IN and param_type(param) == STRING: + ml_wrapper.write('_a%s' % i) + else: + ml_wrapper.write('(%s)a%i' % (param2str(param), i)) + i = i + 1 + ml_wrapper.write(');\n') + # cleanup + i = 0 + for param in params: + k = param_kind(param) + if k == OUT_ARRAY: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + else: + ml_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) + ml_wrapper.write(' free(_a%s);\n' % i) + elif k == IN_ARRAY or k == OUT_ARRAY: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) + else: + ml_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) - # elif k == OUT or k == INOUT: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' {\n') - # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') - # java_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) - # java_wrapper.write(' }\n') - # else: - # java_wrapper.write(' {\n') - # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') - # java_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) - # java_wrapper.write(' }\n') - # i = i + 1 - # # return - # if result == STRING: - # java_wrapper.write(' return jenv->NewStringUTF(result);\n') - # elif result != VOID: - # java_wrapper.write(' return (%s) result;\n' % type2javaw(result)) - # java_wrapper.write('}\n') - # java_wrapper.write('#ifdef __cplusplus\n') - # java_wrapper.write('}\n') - # java_wrapper.write('#endif\n') + elif k == OUT or k == INOUT: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' {\n') + ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') + ml_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) + ml_wrapper.write(' }\n') + else: + ml_wrapper.write(' {\n') + ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') + ml_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) + ml_wrapper.write(' }\n') + i = i + 1 + # return + if result == STRING: + ml_wrapper.write(' return caml_copy_string(result);\n') + elif result == VOID: + ml_wrapper.write(' CAMLreturn(Val_unit);\n') + elif result != VOID: + ml_wrapper.write(' return (value) result;\n') + ml_wrapper.write('}\n\n') if is_verbose(): print "Generated '%s'" % ml_nativef diff --git a/src/api/ml/Makefile b/src/api/ml/old/Makefile similarity index 100% rename from src/api/ml/Makefile rename to src/api/ml/old/Makefile diff --git a/src/api/ml/Makefile.build b/src/api/ml/old/Makefile.build similarity index 100% rename from src/api/ml/Makefile.build rename to src/api/ml/old/Makefile.build diff --git a/src/api/ml/test_mlapi.ml b/src/api/ml/old/test_mlapi.ml similarity index 100% rename from src/api/ml/test_mlapi.ml rename to src/api/ml/old/test_mlapi.ml diff --git a/src/api/ml/test_mlapiV3.ml b/src/api/ml/old/test_mlapiV3.ml similarity index 100% rename from src/api/ml/test_mlapiV3.ml rename to src/api/ml/old/test_mlapiV3.ml diff --git a/src/api/ml/x3.ml b/src/api/ml/old/x3.ml similarity index 100% rename from src/api/ml/x3.ml rename to src/api/ml/old/x3.ml diff --git a/src/api/ml/z3_stubs.c b/src/api/ml/old/z3_stubs.c similarity index 100% rename from src/api/ml/z3_stubs.c rename to src/api/ml/old/z3_stubs.c diff --git a/src/api/ml/z3_theory_stubs.c b/src/api/ml/old/z3_theory_stubs.c similarity index 100% rename from src/api/ml/z3_theory_stubs.c rename to src/api/ml/old/z3_theory_stubs.c From 65ddf2be491719af481c93c6140a17271fa201e4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 21:39:52 +0000 Subject: [PATCH 225/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 5 ++-- scripts/mk_util.py | 42 +++++++++++++++++++++--------- scripts/update_api.py | 59 +++++++++++++++++++++++-------------------- 3 files changed, 65 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index f2a31c21e..95c44e557 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ callgrind.out.* # OCaml generated files *.a *.cma +*.cmo *.cmi *.cmxa ocamlz3 @@ -71,5 +72,5 @@ doc/code src/api/ml/z3_native.c src/api/ml/z3_native.ml src/api/ml/native.c -src/api/ml/Z3.ml -src/api/ml/z3_enums.ml +src/api/ml/z3.ml +src/api/ml/enumerations.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4249a04b0..31e64b10e 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -672,6 +672,9 @@ def get_cs_files(path): def get_java_files(path): return filter(lambda f: f.endswith('.java'), os.listdir(path)) +def get_ml_files(path): + return filter(lambda f: f.endswith('.ml'), os.listdir(path)) + def find_all_deps(name, deps): new_deps = [] for dep in deps: @@ -1284,9 +1287,17 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): - mk_dir(os.path.join(BUILD_DIR, 'api', 'ml')) + bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') + mk_dir(bld_dir) libfile = '%s$(LIB_EXT)' % self.lib_name - out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) + for mlfile in get_ml_files(self.src_dir): + out.write('%si: %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) + out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) + out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) + out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) + for mlfile in get_ml_files(self.src_dir): + out.write(' %si' % os.path.join('api','ml', mlfile)) + out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) -I%s %s/native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'native')) out.write('ml: %s\n' % libfile) @@ -2522,11 +2533,9 @@ def mk_z3consts_ml(api_files): if not os.path.exists(gendir): os.mkdir(gendir) - efile = open('%s.ml' % os.path.join(gendir, "z3_enums"), 'w') + efile = open('%s.ml' % os.path.join(gendir, "enumerations"), 'w') efile.write('(* Automatically generated file *)\n\n') - # efile.write('module z3_enums = struct\n\n'); - - + efile.write('module Enumerations = struct\n') for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) @@ -2572,11 +2581,21 @@ def mk_z3consts_ml(api_files): if m: name = words[1] if name not in DeprecatedEnums: - efile.write('\n(* %s *)\n' % name) efile.write('type %s =\n' % name[3:]) # strip Z3_ - efile.write for k, i in decls.iteritems(): - efile.write(' | %s \n' % k[3:]) # strip Z3_ + efile.write(' | %s \n' % k[3:]) # strip Z3_ + efile.write('\n') + efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ + efile.write(' match x with\n') + for k, i in decls.iteritems(): + efile.write(' | %s -> %d\n' % (k[3:], i)) + efile.write('\n') + efile.write('let int2%s x : %s =\n' % (name[3:],name[3:])) # strip Z3_ + efile.write(' match x with\n') + for k, i in decls.iteritems(): + efile.write(' | %d -> %s\n' % (i, k[3:])) + # use Z3.Exception? + efile.write(' | _ -> raise (Failure "undefined enum value")\n\n') mode = SEARCHING else: if words[2] != '': @@ -2587,10 +2606,9 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 - efile.write('\n') - # efile.write'end\n'); + efile.write('end\n') if VERBOSE: - print "Generated '%s/z3_enums.ml'" % ('%s' % gendir) + print "Generated '%s/enumerations.ml'" % ('%s' % gendir) def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 9acdf1040..b8295405e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -156,9 +156,9 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint'} # Mapping to ML types -Type2ML = { VOID : 'unit', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', - STRING : 'string', STRING_PTR : 'char**', - BOOL : 'lbool', SYMBOL : 'symbol', PRINT_MODE : 'ast_print_mode', ERROR_CODE : 'error_code' } +Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', + STRING : 'string', STRING_PTR : 'char**', + BOOL : 'int', SYMBOL : 'symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -212,7 +212,7 @@ def type2javaw(ty): def type2ml(ty): global Type2ML if (ty >= FIRST_OBJ_ID): - return 'long' + return 'int' else: return Type2ML[ty] @@ -328,9 +328,9 @@ def param2ml(p): k = param_kind(p) if k == OUT: if param_type(p) == INT or param_type(p) == UINT: - return "int*" + return "int" elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: - return "long*" + return "int" elif param_type(p) == STRING: return "string" else: @@ -1075,12 +1075,12 @@ def mk_ml(): if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'Z3.ml') + ml_nativef = os.path.join(ml_dir, 'z3.ml') ml_wrapperf = os.path.join(ml_dir, 'native.c') ml_native = open(ml_nativef, 'w') - ml_native.write('(* Automatically generated file *)\n') - ml_native.write('\n') - ml_native.write('module Z3Native = struct\n\n') + ml_native.write('(* Automatically generated file *)\n\n') + ml_native.write('open Enumerations\n\n') + ml_native.write('module Z3 = struct\n\n') ml_native.write('type context\n') ml_native.write('and symbol\n') ml_native.write('and ast\n') @@ -1103,15 +1103,17 @@ def mk_ml(): ml_native.write('and solver\n') ml_native.write('and stats\n') ml_native.write('\n') - ml_native.write(' exception Z3Exception of string\n\n') + ml_native.write(' exception Exception of string\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external native_%s : ' % ml_method_name(name)) + ml_native.write(' external n_%s : ' % ml_method_name(name)) i = 0; for param in params: ml_native.write('%s -> ' % param2ml(param)) i = i + 1 + if len(params) == 0: + ml_native.write(' unit -> ') ml_native.write('%s\n' % (type2ml(result))) - ml_native.write(' = "Native_Z3_%s"\n\n' % ml_method_name(name)) + ml_native.write(' = "n_%s"\n\n' % ml_method_name(name)) # Exception wrappers for name, result, params in _dotnet_decls: ml_native.write(' let %s ' % ml_method_name(name)) @@ -1128,25 +1130,28 @@ def mk_ml(): ml_native.write(' ') if result != VOID: ml_native.write('let res = ') - ml_native.write('n_%s(' % (ml_method_name(name))) - first = True - i = 0; - for param in params: - if first: - first = False - else: - ml_native.write(', ') - ml_native.write('a%d' % i) - i = i + 1 - ml_native.write(')') + if len(params) == 0: + ml_native.write('n_%s()' % (ml_method_name(name))) + else: + ml_native.write('(n_%s ' % (ml_method_name(name))) + first = True + i = 0; + for param in params: + if first: + first = False + else: + ml_native.write(' ') + ml_native.write('a%d' % i) + i = i + 1 + ml_native.write(')') if result != VOID: ml_native.write(' in\n') else: ml_native.write(';\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = error_code.fromInt(n_get_error_code(a0)) in \n') - ml_native.write(' if err <> Z3_enums.OK then\n') - ml_native.write(' raise (z3_exception n_get_error_msg_ex(a0, err.toInt()))\n') + ml_native.write(' let err = (Enumerations.int2error_code (n_get_error_code a0)) in \n') + ml_native.write(' if err <> Enumerations.OK then\n') + ml_native.write(' raise (Exception (n_get_error_msg_ex a0 (error_code2int err)))\n') ml_native.write(' else\n') if result == VOID: ml_native.write(' ()\n') From 8d30fabc0a556ba3ef239958fcf37feb096a257e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 04:34:36 +0000 Subject: [PATCH 226/507] New native ML API layer. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 35 ++-- scripts/update_api.py | 400 +++++++++++++++++++++++++++--------------- 2 files changed, 286 insertions(+), 149 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 31e64b10e..962f15670 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1287,20 +1287,31 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): + deffile = open('%s.mllib' % os.path.join(self.src_dir, "z3"), 'w') + for mlfile in get_ml_files(self.src_dir): + deffile.write('%s\n' % (string.upper(mlfile[0]) + mlfile[1:-3])) + deffile.close() + bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') mk_dir(bld_dir) - libfile = '%s$(LIB_EXT)' % self.lib_name + libfile = '%s$(SO_EXT)' % self.lib_name + # for mlfile in get_ml_files(self.src_dir): + # out.write('%si: libz3$(SO_EXT) %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) + # out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) + # out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) + out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) for mlfile in get_ml_files(self.src_dir): - out.write('%si: %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) - out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) - out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) - out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) - for mlfile in get_ml_files(self.src_dir): - out.write(' %si' % os.path.join('api','ml', mlfile)) + out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) -I%s %s/native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'native')) - out.write('ml: %s\n' % libfile) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + out.write('z3.cmxa: %s\n' % libfile) + out.write('\tcd %s && ocamlbuild -lflags -cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cmxa && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) + out.write('\tcp api/ml/z3.cmxa .\n') + out.write('z3.cma: %s\n' % libfile) + out.write('\tcd %s && ocamlbuild -lflags -custom,-cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) + out.write('\tcp api/ml/z3.cma .\n') + out.write('ml: z3.cmxa z3.cma\n') out.write('\n') def main_component(self): @@ -2533,9 +2544,9 @@ def mk_z3consts_ml(api_files): if not os.path.exists(gendir): os.mkdir(gendir) - efile = open('%s.ml' % os.path.join(gendir, "enumerations"), 'w') + efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') - efile.write('module Enumerations = struct\n') + efile.write('module Z3enums = struct\n') for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) diff --git a/scripts/update_api.py b/scripts/update_api.py index b8295405e..b613ce79d 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1071,98 +1071,145 @@ def mk_bindings(): def ml_method_name(name): return name[3:] # Remove Z3_ +def is_out_param(p): + if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: + return True + else: + return False + +def outparams(params): + op = [] + for param in params: + if is_out_param(param): + op.append(param) + return op + +def is_in_param(p): + if param_kind(p) == IN or param_kind(p) == INOUT or param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY: + return True + else: + return False + +def inparams(params): + ip = [] + for param in params: + if is_in_param(param): + ip.append(param) + return ip + +def is_array_param(p): + if param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_ARRAY: + return True + else: + return False + def mk_ml(): if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'z3.ml') - ml_wrapperf = os.path.join(ml_dir, 'native.c') + ml_nativef = os.path.join(ml_dir, 'z3native.ml') + ml_wrapperf = os.path.join(ml_dir, 'z3native.c') ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n\n') - ml_native.write('open Enumerations\n\n') - ml_native.write('module Z3 = struct\n\n') - ml_native.write('type context\n') - ml_native.write('and symbol\n') - ml_native.write('and ast\n') - ml_native.write('and sort = private ast\n') - ml_native.write('and func_decl = private ast\n') - ml_native.write('and app = private ast\n') - ml_native.write('and pattern = private ast\n') - ml_native.write('and params\n') - ml_native.write('and param_descrs\n') - ml_native.write('and model\n') - ml_native.write('and func_interp\n') - ml_native.write('and func_entry\n') - ml_native.write('and fixedpoint\n') - ml_native.write('and ast_vector\n') - ml_native.write('and ast_map\n') - ml_native.write('and goal\n') - ml_native.write('and tactic\n') - ml_native.write('and probe\n') - ml_native.write('and apply_result\n') - ml_native.write('and solver\n') - ml_native.write('and stats\n') - ml_native.write('\n') + ml_native.write('open Z3enums\n\n') + ml_native.write('module Z3native = struct\n\n') + ml_native.write(' type context\n') + ml_native.write(' and symbol\n') + ml_native.write(' and ast\n') + ml_native.write(' and sort = private ast\n') + ml_native.write(' and func_decl = private ast\n') + ml_native.write(' and app = private ast\n') + ml_native.write(' and pattern = private ast\n') + ml_native.write(' and params\n') + ml_native.write(' and param_descrs\n') + ml_native.write(' and model\n') + ml_native.write(' and func_interp\n') + ml_native.write(' and func_entry\n') + ml_native.write(' and fixedpoint\n') + ml_native.write(' and ast_vector\n') + ml_native.write(' and ast_map\n') + ml_native.write(' and goal\n') + ml_native.write(' and tactic\n') + ml_native.write(' and probe\n') + ml_native.write(' and apply_result\n') + ml_native.write(' and solver\n') + ml_native.write(' and stats\n\n') ml_native.write(' exception Exception of string\n\n') + + # ML declarations + ml_native.write(' module ML2C = struct\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external n_%s : ' % ml_method_name(name)) - i = 0; - for param in params: - ml_native.write('%s -> ' % param2ml(param)) - i = i + 1 - if len(params) == 0: + ml_native.write(' external n_%s : ' % ml_method_name(name)) + ip = inparams(params) + op = outparams(params) + if len(ip) == 0: ml_native.write(' unit -> ') - ml_native.write('%s\n' % (type2ml(result))) - ml_native.write(' = "n_%s"\n\n' % ml_method_name(name)) + for p in ip: + ml_native.write('%s -> ' % param2ml(p)) + if len(op) > 0: + ml_native.write('(') + ml_native.write('%s' % type2ml(result)) + for p in op: + ml_native.write(' * %s' % param2ml(p)) + if len(op) > 0: + ml_native.write(')') + ml_native.write('\n') + ml_native.write(' = "n_%s"\n' % ml_method_name(name)) + if len(ip) > 5: + ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) + ml_native.write('\n') + ml_native.write(' end\n\n') + # Exception wrappers for name, result, params in _dotnet_decls: - ml_native.write(' let %s ' % ml_method_name(name)) + ip = inparams(params) + op = outparams(params) + ml_native.write(' let %s ' % ml_method_name(name)) first = True i = 0; - for param in params: - if first: - first = False; - else: - ml_native.write(' ') - ml_native.write('a%d' % i) - i = i + 1 - ml_native.write(' = \n') - ml_native.write(' ') - if result != VOID: - ml_native.write('let res = ') - if len(params) == 0: - ml_native.write('n_%s()' % (ml_method_name(name))) - else: - ml_native.write('(n_%s ' % (ml_method_name(name))) - first = True - i = 0; - for param in params: + for p in params: + if is_in_param(p): if first: - first = False + first = False; else: ml_native.write(' ') ml_native.write('a%d' % i) - i = i + 1 - ml_native.write(')') - if result != VOID: - ml_native.write(' in\n') + i = i + 1 + ml_native.write(' = \n') + ml_native.write(' ') + if result == VOID: + ml_native.write('let _ = ') else: - ml_native.write(';\n') + ml_native.write('let res = ') + ml_native.write('(ML2C.n_%s' % (ml_method_name(name))) + first = True + i = 0; + for p in params: + if is_in_param(p): + ml_native.write(' a%d' % i) + i = i + 1 + ml_native.write(') in\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (Enumerations.int2error_code (n_get_error_code a0)) in \n') - ml_native.write(' if err <> Enumerations.OK then\n') - ml_native.write(' raise (Exception (n_get_error_msg_ex a0 (error_code2int err)))\n') + ml_native.write(' let err = (Z3enums.int2error_code (ML2C.n_get_error_code a0)) in \n') + ml_native.write(' if err <> Z3enums.OK then\n') + ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (Z3enums.error_code2int err)))\n') ml_native.write(' else\n') if result == VOID: ml_native.write(' ()\n') else: ml_native.write(' res\n') ml_native.write('\n') - ml_native.write('\nend\n') + + ml_native.write('end\n') + + # C interface ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') ml_wrapper.write('#include \n') - ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('extern "C" {\n') + ml_wrapper.write('#endif\n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') @@ -1171,61 +1218,119 @@ def mk_ml(): ml_wrapper.write('#ifdef Custom_tag\n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') + ml_wrapper.write('#endif\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('}\n') ml_wrapper.write('#endif\n\n') ml_wrapper.write('#include \n\n') + ml_wrapper.write('#define CAMLlocal6(X1,X2,X3,X4,X5,X6) \\\n') + ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLlocal1(X6); \n') + ml_wrapper.write('#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \\\n') + ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLlocal2(X6,X7); \n') + ml_wrapper.write('#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') + ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLlocal3(X6,X7,X8); \n') + ml_wrapper.write('\n') + ml_wrapper.write('#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam2(X6,X7); \n') + ml_wrapper.write('#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam3(X6,X7,X8); \n') + ml_wrapper.write('#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9); \n') + ml_wrapper.write('#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') + ml_wrapper.write(' CAMLxparam2(X11,X12); \n') + ml_wrapper.write('#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') + ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') + ml_wrapper.write('\n\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('extern "C" {\n') + ml_wrapper.write('#endif\n\n') for name, result, params in _dotnet_decls: - #return type = type2ml(result) + ip = inparams(params) + op = outparams(params) + ret_size = len(op) + if result != VOID: + ret_size = ret_size + 1 + + # Setup frame + n_locals = 0 + for p in params: + if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): + n_locals = n_locals + 1 ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) first = True i = 0 - for param in params: - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('value a%d' % i) - # param type = param2ml(param) + for p in params: + if is_in_param(p): + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('value a%d' % i) i = i + 1 ml_wrapper.write(') {\n') - ml_wrapper.write(' CAMLparam%d(' % len(params)) + ml_wrapper.write(' CAMLparam%d(' % len(ip)) i = 0 first = True - for param in params: - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('a%d' % i) + for p in params: + if is_in_param(p): + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('a%d' % i) i = i + 1 ml_wrapper.write(');\n') + i = 0 + first = True + if result != VOID: + n_locals = n_locals + 1 + if ret_size > 1: + n_locals = n_locals + 1 + if n_locals > 0: + ml_wrapper.write(' CAMLlocal%s(' % (n_locals)) + if ret_size > 1: + if result != VOID: + ml_wrapper.write('result, ') + ml_wrapper.write('result_tuple') + first = False + elif result != VOID: + ml_wrapper.write('result') + first = False + for p in params: + if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('_a%s' % i) + i = i + 1 + ml_wrapper.write(');\n') + # preprocess arrays, strings, in/out arguments i = 0 for param in params: - k = param_kind(param) - if k == OUT or k == INOUT: - ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) - elif k == IN_ARRAY or k == INOUT_ARRAY: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) - else: - ml_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) - elif k == OUT_ARRAY: - ml_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), - i, - type2str(param_type(param)), - param_array_capacity_pos(param), - type2str(param_type(param)))) - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - else: - ml_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) - elif k == IN and param_type(param) == STRING: - ml_wrapper.write(' Z3_string _a%s = (Z3_string) String_val(a%s);\n' % (i, i)) + if param_kind(param) == OUT_ARRAY: + ml_wrapper.write(' _a%s = (long) malloc(sizeof(%s) * ((long)a%s));\n' % (i, + type2str(param_type(param)), + param_array_capacity_pos(param))) + elif param_kind(param) == IN and param_type(param) == STRING: + ml_wrapper.write(' _a%s = (value) String_val(a%s);\n' % (i, i)) i = i + 1 + # invoke procedure ml_wrapper.write(' ') if result != VOID: - ml_wrapper.write('%s result = ' % type2str(result)) + ml_wrapper.write('result = (value) ') ml_wrapper.write('%s(' % name) i = 0 first = True @@ -1236,53 +1341,74 @@ def mk_ml(): ml_wrapper.write(', ') k = param_kind(param) if k == OUT or k == INOUT: - ml_wrapper.write('&_a%s' % i) - elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: - ml_wrapper.write('_a%s' % i) + ml_wrapper.write('(%s)&_a%s' % (param2str(param), i)) + elif k == INOUT_ARRAY or k == IN_ARRAY: + ml_wrapper.write('(%s*)a%s' % (type2str(param_type(param)), i)) + elif k == OUT_ARRAY: + ml_wrapper.write('(%s*)_a%s' % (type2str(param_type(param)), i)) elif k == IN and param_type(param) == STRING: - ml_wrapper.write('_a%s' % i) + ml_wrapper.write('(Z3_string) _a%s' % i) else: ml_wrapper.write('(%s)a%i' % (param2str(param), i)) i = i + 1 ml_wrapper.write(');\n') - # cleanup - i = 0 - for param in params: - k = param_kind(param) - if k == OUT_ARRAY: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - else: - ml_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) - ml_wrapper.write(' free(_a%s);\n' % i) - elif k == IN_ARRAY or k == OUT_ARRAY: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) - else: - ml_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) - elif k == OUT or k == INOUT: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' {\n') - ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') - ml_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) - ml_wrapper.write(' }\n') + # return tuples + if len(op) > 0: + ml_wrapper.write(' result_tuple = caml_alloc(%s, 0);\n' % ret_size) + i = j = 0 + if result != VOID: + if result == STRING: + ml_wrapper.write(' Store_field(result_tuple, 0, caml_copy_string(result));\n') else: - ml_wrapper.write(' {\n') - ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') - ml_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) - ml_wrapper.write(' }\n') + ml_wrapper.write(' Store_field(result_tuple, 0, result);\n') + j = j + 1 + for p in params: + if param_kind(p) == OUT_ARRAY or param_kind(p) == OUT: + ml_wrapper.write(' Store_field(result_tuple, %s, _a%s);\n' % (j, i)) + j = j + 1; + elif is_out_param(p): + if param_type(p) == STRING: + ml_wrapper.write(' Store_field(result_tuple, %s, caml_copy_string((const char *)_a%s));\n' % (j, i)) + else: + ml_wrapper.write(' Store_field(result_tuple, %s, a%s);\n' % (j, i)) + j = j + 1; + i = i + 1 + + # local array cleanup + i = 0 + for p in params: + if param_kind(p) == OUT_ARRAY: + ml_wrapper.write(' free((long*)_a%s);\n' % i) i = i + 1 + # return - if result == STRING: - ml_wrapper.write(' return caml_copy_string(result);\n') - elif result == VOID: - ml_wrapper.write(' CAMLreturn(Val_unit);\n') - elif result != VOID: - ml_wrapper.write(' return (value) result;\n') + if len(op) > 0: + ml_wrapper.write(' CAMLreturn(result_tuple);\n') + else: + if result == STRING: + ml_wrapper.write(' CAMLreturn(caml_copy_string((const char*) result));\n') + elif result == VOID: + ml_wrapper.write(' CAMLreturn(Val_unit);\n') + elif result != VOID: + ml_wrapper.write(' CAMLreturn(result);\n') + ml_wrapper.write('}\n\n') + if len(ip) > 5: + ml_wrapper.write('CAMLprim value n_%s_bytecode(value * argv, int argn) {\n' % ml_method_name(name)) + ml_wrapper.write(' return n_%s(' % ml_method_name(name)) + i = 0 + while i < len(ip): + if i == 0: + ml_wrapper.write('argv[0]') + else: + ml_wrapper.write(', argv[%s]' % i) + i = i + 1 + ml_wrapper.write(');\n}\n') + ml_wrapper.write('\n\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('}\n') + ml_wrapper.write('#endif\n') if is_verbose(): print "Generated '%s'" % ml_nativef From d5f135c4325772297fd49e24b22a0984044c6eb4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 04:37:32 +0000 Subject: [PATCH 227/507] More new ML API. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 705f9a3e7..61ac503a0 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,3 +1,4 @@ +<<<<<<< HEAD (* File generated from z3.idl *) type context @@ -3383,3 +3384,16 @@ let set_new_relevant_callback th cb = end +======= +(* + Author: CM Wintersteiger + (C) Microsoft Research, 2012 +*) + +open Z3enums +open Z3native + +module Z3 = struct + +end +>>>>>>> More new ML API. From a965d65901ba6698f3ac13a8dbcb69d23f8b2610 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 04:37:46 +0000 Subject: [PATCH 228/507] ML API temp files added to .gitignore Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 95c44e557..fccf9424d 100644 --- a/.gitignore +++ b/.gitignore @@ -65,7 +65,6 @@ src/util/version.h src/api/java/Native.cpp src/api/java/Native.java src/api/java/enumerations/*.java - *.bak doc/api doc/code @@ -74,3 +73,7 @@ src/api/ml/z3_native.ml src/api/ml/native.c src/api/ml/z3.ml src/api/ml/enumerations.ml +src/api/ml/z3native.c +src/api/ml/z3native.ml +src/api/ml/z3enums.ml +src/api/ml/z3.mllib From 2dde851ed7ec60719efb3290999d0fb41a45e3c8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 08:06:10 +0000 Subject: [PATCH 229/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 ++- scripts/update_api.py | 58 +++++++++---------------------- src/api/ml/z3.ml | 80 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 96 insertions(+), 47 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 962f15670..c17df82e6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -458,7 +458,8 @@ def display_help(exit_code): if IS_WINDOWS: print(" -n, --nodotnet do not generate Microsoft.Z3.dll make rules.") print(" -j, --java generate Java bindings.") - print(" --staticlib build Z3 static library.") + print(" --ml generate Ocaml bindinds.") + print(" --staticlib build Z3 static library.") if not IS_WINDOWS: print(" -g, --gmp use GMP.") print(" --gprof enable gprof") @@ -2546,7 +2547,6 @@ def mk_z3consts_ml(api_files): efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') - efile.write('module Z3enums = struct\n') for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) @@ -2617,7 +2617,6 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 - efile.write('end\n') if VERBOSE: print "Generated '%s/enumerations.ml'" % ('%s' % gendir) diff --git a/scripts/update_api.py b/scripts/update_api.py index b613ce79d..9eb7d1405 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -158,7 +158,7 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I # Mapping to ML types Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', STRING : 'string', STRING_PTR : 'char**', - BOOL : 'int', SYMBOL : 'symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } + BOOL : 'int', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -182,6 +182,7 @@ def def_Types(): v = Type2Str[k] if is_obj(k): Type2Dotnet[k] = v + Type2ML[k] = v.lower() def type2str(ty): global Type2Str @@ -211,10 +212,7 @@ def type2javaw(ty): def type2ml(ty): global Type2ML - if (ty >= FIRST_OBJ_ID): - return 'int' - else: - return Type2ML[ty] + return Type2ML[ty] def _in(ty): return (IN, ty); @@ -327,17 +325,11 @@ def param2pystr(p): def param2ml(p): k = param_kind(p) if k == OUT: - if param_type(p) == INT or param_type(p) == UINT: - return "int" - elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: - return "int" - elif param_type(p) == STRING: + if param_type(p) == STRING: return "string" else: - print "ERROR: unreachable code" - assert(False) - exit(1) - if k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: + return "ptr" + elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: return "%s array" % type2ml(param_type(p)) else: return type2ml(param_type(p)) @@ -1104,6 +1096,7 @@ def is_array_param(p): return False def mk_ml(): + global Type2Str if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir @@ -1112,29 +1105,12 @@ def mk_ml(): ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n\n') ml_native.write('open Z3enums\n\n') - ml_native.write('module Z3native = struct\n\n') - ml_native.write(' type context\n') - ml_native.write(' and symbol\n') - ml_native.write(' and ast\n') - ml_native.write(' and sort = private ast\n') - ml_native.write(' and func_decl = private ast\n') - ml_native.write(' and app = private ast\n') - ml_native.write(' and pattern = private ast\n') - ml_native.write(' and params\n') - ml_native.write(' and param_descrs\n') - ml_native.write(' and model\n') - ml_native.write(' and func_interp\n') - ml_native.write(' and func_entry\n') - ml_native.write(' and fixedpoint\n') - ml_native.write(' and ast_vector\n') - ml_native.write(' and ast_map\n') - ml_native.write(' and goal\n') - ml_native.write(' and tactic\n') - ml_native.write(' and probe\n') - ml_native.write(' and apply_result\n') - ml_native.write(' and solver\n') - ml_native.write(' and stats\n\n') - ml_native.write(' exception Exception of string\n\n') + ml_native.write('type ptr\n') + ml_native.write('and z3_symbol = ptr\n') + for k, v in Type2Str.iteritems(): + if is_obj(k): + ml_native.write('and %s = ptr\n' % v.lower()) + ml_native.write('\nexception Exception of string\n\n') # ML declarations ml_native.write(' module ML2C = struct\n\n') @@ -1190,9 +1166,9 @@ def mk_ml(): i = i + 1 ml_native.write(') in\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (Z3enums.int2error_code (ML2C.n_get_error_code a0)) in \n') - ml_native.write(' if err <> Z3enums.OK then\n') - ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (Z3enums.error_code2int err)))\n') + ml_native.write(' let err = (int2error_code (ML2C.n_get_error_code a0)) in \n') + ml_native.write(' if err <> OK then\n') + ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (error_code2int err)))\n') ml_native.write(' else\n') if result == VOID: ml_native.write(' ()\n') @@ -1200,8 +1176,6 @@ def mk_ml(): ml_native.write(' res\n') ml_native.write('\n') - ml_native.write('end\n') - # C interface ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 61ac503a0..b00569da1 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -3388,12 +3388,88 @@ end (* Author: CM Wintersteiger (C) Microsoft Research, 2012 -*) + *) open Z3enums open Z3native -module Z3 = struct +class context = + object (self) + val m_n_ctx : Z3native.z3_context option = None + val mutable m_refCount : int = 0 + initializer Gc.finalise (fun self -> self#dispose ()) self + method dispose () = + Printf.printf "Disposing %d \n" (Oo.id self) ; + match m_n_ctx with + | Some(x) -> (del_context x) + | None -> () + method sub_one_ctx_obj = m_refCount <- m_refCount - 1 + method add_one_ctx_obj = m_refCount <- m_refCount + 1 + end +class virtual z3object ctx_init obj_init = + object (self) + val mutable m_ctx : context option = ctx_init + val mutable m_n_obj : Z3native.ptr option = obj_init + + initializer + (match m_n_obj with + | Some (x) -> self#incref x; + (match m_ctx with + | Some(x) -> x#add_one_ctx_obj + | None -> () + ) + | None -> () + ); + Gc.finalise (fun self -> self#dispose ()) self + + method virtual incref : Z3native.ptr -> unit + method virtual decref : Z3native.ptr -> unit + + (* + Disposes of the underlying native Z3 object. + *) + method dispose () = + Printf.printf "Disposing %d \n" (Oo.id self) ; + (match m_n_obj with + | Some (x) -> self#decref x; m_n_obj <- None + | None -> () + ); + (match m_ctx with + | Some (x) -> x#sub_one_ctx_obj + | None -> () + ); + m_ctx <- None + + + method get_native_object = m_n_obj + + method set_native_object x = + (match x with + | Some(x) -> self#incref x + | None -> () + ); + (match m_n_obj with + | Some(x) -> self#decref x + | None -> () + ); + m_n_obj <- x + + method get_context = m_ctx + + method array_to_native a = + let f e = e#get_native_object in + (Array.map f a) + + method array_length a = + match a with + | Some(x) -> (Array.length x) + | None -> 0 + + end + +<<<<<<< HEAD end >>>>>>> More new ML API. +======= +>>>>>>> More ML API From bea09539cfe19f58bf4c09dc33747fad3d5f2d23 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 16:33:51 +0000 Subject: [PATCH 230/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- examples/ml/MLExample.ml | 12 ++++++++ examples/ml/README | 14 ++++++++++ scripts/mk_project.py | 1 + scripts/mk_util.py | 22 +++++++++++++++ src/api/ml/z3.ml | 59 ++++++++++++++++++++++++++++++++-------- 5 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 examples/ml/MLExample.ml create mode 100644 examples/ml/README diff --git a/examples/ml/MLExample.ml b/examples/ml/MLExample.ml new file mode 100644 index 000000000..8cc248206 --- /dev/null +++ b/examples/ml/MLExample.ml @@ -0,0 +1,12 @@ +(* + Copyright (C) 2012 Microsoft Corporation + Author: CM Wintersteiger (cwinter) 2012-12-17 + *) + + open Z3 + + let _ = ignore(Log.open_ "z3.log") ; +let cfg = Some [("model", "true"); ("proof", "false")] in +let ctx = (new context cfg) in +ctx#dispose +;; diff --git a/examples/ml/README b/examples/ml/README new file mode 100644 index 000000000..a83400e99 --- /dev/null +++ b/examples/ml/README @@ -0,0 +1,14 @@ +### This is work-in-progress and does not work yet. + +Small example using the Z3 ML bindings. +To build the example execute + make examples +in the build directory. + +It will create MLExample in the build directory, +which can be run on Windows via +ocaml -I . MLExample + +On Linux and FreeBSD, we must use +?? + diff --git a/scripts/mk_project.py b/scripts/mk_project.py index e2b003d21..5bbc42da8 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -98,6 +98,7 @@ def init_project_def(): add_c_example('maxsat') add_dotnet_example('dotnet_example', 'dotnet') add_java_example('java_example', 'java') + add_ml_example('ml_example', 'ml') add_z3py_example('py_example', 'python') return API_files diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c17df82e6..27913ab62 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1427,6 +1427,24 @@ class JavaExampleComponent(ExampleComponent): out.write(' -d .\n') out.write('_ex_%s: JavaExample.class\n\n' % (self.name)) +class MLExampleComponent(ExampleComponent): + def __init__(self, name, path): + ExampleComponent.__init__(self, name, path) + + def is_example(self): + return ML_ENABLED + + def mk_makefile(self, out): + if ML_ENABLED: + out.write('_ex_%s: z3.cmxa' % self.name) + deps = '' + for mlfile in get_ml_files(self.ex_dir): + out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) + if IS_WINDOWS: + deps = deps.replace('/', '\\') + out.write('%s\n' % deps) + out.write('\tcd %s && ocamlbuild -build-dir ../../%s -lib z3 MLExample.native && cd -\n\n' % (self.to_src_dir, BUILD_DIR)) + class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): ExampleComponent.__init__(self, name, path) @@ -1500,6 +1518,10 @@ def add_java_example(name, path=None): c = JavaExampleComponent(name, path) reg_component(name, c) +def add_ml_example(name, path=None): + c = MLExampleComponent(name, path) + reg_component(name, c) + def add_z3py_example(name, path=None): c = PythonExampleComponent(name, path) reg_component(name, c) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b00569da1..31c5aa342 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -3386,29 +3386,62 @@ end ======= (* - Author: CM Wintersteiger - (C) Microsoft Research, 2012 + Copyright (C) 2012 Microsoft Corporation + Author: CM Wintersteiger (cwinter) 2012-12-17 *) open Z3enums open Z3native -class context = +module Log = + struct + let m_is_open = false +(* CMW: "open" seems to be an invalid function name*) + let open_ fn = int2lbool(open_log fn) == L_TRUE + let close = (close_log) + let append s = (append_log s) + end + +class virtual idisposable = + object + method virtual dispose : unit + end + +class context settings = object (self) - val m_n_ctx : Z3native.z3_context option = None + inherit idisposable + val mutable m_n_ctx : Z3native.z3_context option = None val mutable m_refCount : int = 0 - initializer Gc.finalise (fun self -> self#dispose ()) self - method dispose () = - Printf.printf "Disposing %d \n" (Oo.id self) ; - match m_n_ctx with - | Some(x) -> (del_context x) - | None -> () + + initializer + let cfg = mk_config() in + (match settings with + | Some(x) -> + let f e = (set_param_value cfg (fst e) (snd e)) in + (List.iter f x) + | _ -> () + ) ; + m_n_ctx <- Some (mk_context_rc cfg) ; + del_config(cfg) ; + Gc.finalise (fun self -> self#dispose) self + + method dispose : unit = + if m_refCount == 0 then ( + Printf.printf "Disposing %d \n" (Oo.id self) ; + match m_n_ctx with + | Some(x) -> (del_context x) + | None -> () + ) else ( + (* re-queue for finalization? *) + ) + method sub_one_ctx_obj = m_refCount <- m_refCount - 1 method add_one_ctx_obj = m_refCount <- m_refCount + 1 end class virtual z3object ctx_init obj_init = object (self) + inherit idisposable val mutable m_ctx : context option = ctx_init val mutable m_n_obj : Z3native.ptr option = obj_init @@ -3421,7 +3454,7 @@ class virtual z3object ctx_init obj_init = ) | None -> () ); - Gc.finalise (fun self -> self#dispose ()) self + Gc.finalise (fun self -> self#dispose) self method virtual incref : Z3native.ptr -> unit method virtual decref : Z3native.ptr -> unit @@ -3429,7 +3462,7 @@ class virtual z3object ctx_init obj_init = (* Disposes of the underlying native Z3 object. *) - method dispose () = + method dispose = Printf.printf "Disposing %d \n" (Oo.id self) ; (match m_n_obj with | Some (x) -> self#decref x; m_n_obj <- None @@ -3457,6 +3490,7 @@ class virtual z3object ctx_init obj_init = method get_context = m_ctx +(* method array_to_native a = let f e = e#get_native_object in (Array.map f a) @@ -3465,6 +3499,7 @@ class virtual z3object ctx_init obj_init = match a with | Some(x) -> (Array.length x) | None -> 0 +*) end From 01dc79fcd44a03710c5b6e43284cdebd23b0aaa7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 17:26:28 +0000 Subject: [PATCH 231/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 158 +++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 31c5aa342..fb8121c79 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -3388,120 +3388,120 @@ end (* Copyright (C) 2012 Microsoft Corporation Author: CM Wintersteiger (cwinter) 2012-12-17 - *) +*) open Z3enums open Z3native module Log = - struct - let m_is_open = false -(* CMW: "open" seems to be an invalid function name*) - let open_ fn = int2lbool(open_log fn) == L_TRUE - let close = (close_log) - let append s = (append_log s) - end - +struct + let m_is_open = false + (* CMW: "open" seems to be an invalid function name*) + let open_ fn = int2lbool(open_log fn) == L_TRUE + let close = (close_log) + let append s = (append_log s) +end + class virtual idisposable = - object - method virtual dispose : unit - end +object + method virtual dispose : unit +end class context settings = - object (self) - inherit idisposable - val mutable m_n_ctx : Z3native.z3_context option = None - val mutable m_refCount : int = 0 - - initializer - let cfg = mk_config() in - (match settings with - | Some(x) -> - let f e = (set_param_value cfg (fst e) (snd e)) in - (List.iter f x) - | _ -> () - ) ; - m_n_ctx <- Some (mk_context_rc cfg) ; - del_config(cfg) ; - Gc.finalise (fun self -> self#dispose) self - - method dispose : unit = - if m_refCount == 0 then ( - Printf.printf "Disposing %d \n" (Oo.id self) ; - match m_n_ctx with +object (self) + inherit idisposable + val mutable m_n_ctx : Z3native.z3_context option = None + val mutable m_refCount : int = 0 + + initializer + let cfg = mk_config() in + (match settings with + | Some(x) -> + let f e = (set_param_value cfg (fst e) (snd e)) in + (List.iter f x) + | _ -> () + ) ; + m_n_ctx <- Some (mk_context_rc cfg) ; + del_config(cfg) ; + Gc.finalise (fun self -> self#dispose) self + + method dispose : unit = + if m_refCount == 0 then ( + Printf.printf "Disposing %d \n" (Oo.id self) ; + match m_n_ctx with | Some(x) -> (del_context x) | None -> () - ) else ( - (* re-queue for finalization? *) - ) + ) else ( + (* re-queue for finalization? *) + ) - method sub_one_ctx_obj = m_refCount <- m_refCount - 1 - method add_one_ctx_obj = m_refCount <- m_refCount + 1 - end + method sub_one_ctx_obj = m_refCount <- m_refCount - 1 + method add_one_ctx_obj = m_refCount <- m_refCount + 1 +end class virtual z3object ctx_init obj_init = - object (self) - inherit idisposable - val mutable m_ctx : context option = ctx_init - val mutable m_n_obj : Z3native.ptr option = obj_init - - initializer - (match m_n_obj with +object (self) + inherit idisposable + val mutable m_ctx : context option = ctx_init + val mutable m_n_obj : Z3native.ptr option = obj_init + + initializer + (match m_n_obj with | Some (x) -> self#incref x; - (match m_ctx with + (match m_ctx with | Some(x) -> x#add_one_ctx_obj | None -> () - ) + ) | None -> () - ); - Gc.finalise (fun self -> self#dispose) self + ); + Gc.finalise (fun self -> self#dispose) self - method virtual incref : Z3native.ptr -> unit - method virtual decref : Z3native.ptr -> unit - - (* - Disposes of the underlying native Z3 object. - *) - method dispose = - Printf.printf "Disposing %d \n" (Oo.id self) ; - (match m_n_obj with + method virtual incref : Z3native.ptr -> unit + method virtual decref : Z3native.ptr -> unit + + (* + Disposes of the underlying native Z3 object. + *) + method dispose = + Printf.printf "Disposing %d \n" (Oo.id self) ; + (match m_n_obj with | Some (x) -> self#decref x; m_n_obj <- None | None -> () - ); - (match m_ctx with + ); + (match m_ctx with | Some (x) -> x#sub_one_ctx_obj | None -> () - ); - m_ctx <- None + ); + m_ctx <- None - method get_native_object = m_n_obj + method get_native_object = m_n_obj - method set_native_object x = - (match x with + method set_native_object x = + (match x with | Some(x) -> self#incref x | None -> () - ); - (match m_n_obj with + ); + (match m_n_obj with | Some(x) -> self#decref x | None -> () - ); - m_n_obj <- x + ); + m_n_obj <- x - method get_context = m_ctx + method get_context = m_ctx -(* + (* method array_to_native a = - let f e = e#get_native_object in - (Array.map f a) + let f e = e#get_native_object in + (Array.map f a) method array_length a = - match a with - | Some(x) -> (Array.length x) - | None -> 0 -*) + match a with + | Some(x) -> (Array.length x) + | None -> 0 + *) - end +end <<<<<<< HEAD end From e7e85dc7b4892f6a08c9f4ad56f55f342b0913f7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 20:18:53 +0000 Subject: [PATCH 232/507] File renamed Signed-off-by: Christoph M. Wintersteiger --- examples/ml/{MLExample.ml => mlexample.ml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/ml/{MLExample.ml => mlexample.ml} (100%) diff --git a/examples/ml/MLExample.ml b/examples/ml/mlexample.ml similarity index 100% rename from examples/ml/MLExample.ml rename to examples/ml/mlexample.ml From c001da618826339103136692b90996f3b047dd4f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 22:25:16 +0000 Subject: [PATCH 233/507] ML API and example compilation. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 12 ++++++------ examples/ml/ml_example.ml | 14 ++++++++++++++ examples/ml/mlexample.ml | 12 ------------ scripts/mk_util.py | 33 ++++++++++++++++++--------------- src/api/ml/z3.ml | 2 +- 5 files changed, 39 insertions(+), 34 deletions(-) create mode 100644 examples/ml/ml_example.ml delete mode 100644 examples/ml/mlexample.ml diff --git a/examples/ml/README b/examples/ml/README index a83400e99..3e1eb0d1c 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -5,10 +5,10 @@ To build the example execute make examples in the build directory. -It will create MLExample in the build directory, -which can be run on Windows via -ocaml -I . MLExample +It will create ml_example in the build directory, +which can be run in the build directory via +LD_LIBRARY_PATH=. ./ml_example +or +LD_LIBRARY_PATH=. ./ml_example.byte +for the byte-code version. -On Linux and FreeBSD, we must use -?? - diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml new file mode 100644 index 000000000..9c704e4d0 --- /dev/null +++ b/examples/ml/ml_example.ml @@ -0,0 +1,14 @@ +(* + Copyright (C) 2012 Microsoft Corporation + Author: CM Wintersteiger (cwinter) 2012-12-17 +*) + +open Z3 + +let _ = ignore(Log.open_ "z3.log") ; + let cfg = Some [("model", "true"); ("proof", "false")] in + let ctx = (new context cfg) in + Printf.printf "Disposing...\n"; + ctx#dispose ; + Printf.printf "Exiting.\n"; +;; diff --git a/examples/ml/mlexample.ml b/examples/ml/mlexample.ml deleted file mode 100644 index 8cc248206..000000000 --- a/examples/ml/mlexample.ml +++ /dev/null @@ -1,12 +0,0 @@ -(* - Copyright (C) 2012 Microsoft Corporation - Author: CM Wintersteiger (cwinter) 2012-12-17 - *) - - open Z3 - - let _ = ignore(Log.open_ "z3.log") ; -let cfg = Some [("model", "true"); ("proof", "false")] in -let ctx = (new context cfg) in -ctx#dispose -;; diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 27913ab62..da7d22d54 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1296,10 +1296,6 @@ class MLComponent(Component): bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') mk_dir(bld_dir) libfile = '%s$(SO_EXT)' % self.lib_name - # for mlfile in get_ml_files(self.src_dir): - # out.write('%si: libz3$(SO_EXT) %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) - # out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) - # out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) @@ -1307,11 +1303,9 @@ class MLComponent(Component): out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) out.write('z3.cmxa: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -lflags -cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cmxa && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) - out.write('\tcp api/ml/z3.cmxa .\n') + out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('z3.cma: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -lflags -custom,-cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) - out.write('\tcp api/ml/z3.cma .\n') + out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -custom,-cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3native$(OBJ_EXT) z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('ml: z3.cmxa z3.cma\n') out.write('\n') @@ -1436,14 +1430,23 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('_ex_%s: z3.cmxa' % self.name) - deps = '' + out.write('ml_example.byte: z3.cma ') for mlfile in get_ml_files(self.ex_dir): - out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) - if IS_WINDOWS: - deps = deps.replace('/', '\\') - out.write('%s\n' % deps) - out.write('\tcd %s && ocamlbuild -build-dir ../../%s -lib z3 MLExample.native && cd -\n\n' % (self.to_src_dir, BUILD_DIR)) + out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) + out.write('\n') + out.write('\tocamlc -g -o ml_example.byte -I . z3.cma -I api/ml') + for mlfile in get_ml_files(self.ex_dir): + out.write(' %s/%s' % (self.to_ex_dir, mlfile)) + out.write('\n') + out.write('ml_example($EXE_EXT): z3.cmxa ') + for mlfile in get_ml_files(self.ex_dir): + out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) + out.write('\n') + out.write('\tocamlopt -g -o ml_example -I . z3.cmxa -I api/ml') + for mlfile in get_ml_files(self.ex_dir): + out.write(' %s/%s' % (self.to_ex_dir, mlfile)) + out.write('\n') + out.write('_ex_%s: ml_example.byte ml_example($EXE_EXT)\n\n' % self.name) class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index fb8121c79..71e16898e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -3463,7 +3463,7 @@ object (self) Disposes of the underlying native Z3 object. *) method dispose = - Printf.printf "Disposing %d \n" (Oo.id self) ; + Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with | Some (x) -> self#decref x; m_n_obj <- None | None -> () From 0fad5abd199091ebbb7eb719d291aa359d547f32 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 23:31:42 +0000 Subject: [PATCH 234/507] more ML API Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 3486 +--------------------------------------------- 1 file changed, 68 insertions(+), 3418 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 71e16898e..55ffd91e8 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,3390 +1,3 @@ -<<<<<<< HEAD -(* File generated from z3.idl *) - -type context -and symbol -and ast -and sort = private ast -and func_decl = private ast -and app = private ast -and pattern = private ast -and params -and param_descrs -and model -and func_interp -and func_entry -and fixedpoint -and ast_vector -and ast_map -and goal -and tactic -and probe -and apply_result -and solver -and stats - - - -and constructor -and constructor_list - -and lbool = - | L_FALSE - | L_UNDEF - | L_TRUE - -and symbol_kind = - | INT_SYMBOL - | STRING_SYMBOL - -and parameter_kind = - | PARAMETER_INT - | PARAMETER_DOUBLE - | PARAMETER_RATIONAL - | PARAMETER_SYMBOL - | PARAMETER_SORT - | PARAMETER_AST - | PARAMETER_FUNC_DECL - -and sort_kind = - | UNINTERPRETED_SORT - | BOOL_SORT - | INT_SORT - | REAL_SORT - | BV_SORT - | ARRAY_SORT - | DATATYPE_SORT - | RELATION_SORT - | FINITE_DOMAIN_SORT - | UNKNOWN_SORT - -and ast_kind = - | NUMERAL_AST - | APP_AST - | VAR_AST - | QUANTIFIER_AST - | SORT_AST - | FUNC_DECL_AST - | UNKNOWN_AST - -and decl_kind = - | OP_TRUE - | OP_FALSE - | OP_EQ - | OP_DISTINCT - | OP_ITE - | OP_AND - | OP_OR - | OP_IFF - | OP_XOR - | OP_NOT - | OP_IMPLIES - | OP_OEQ - | OP_ANUM - | OP_AGNUM - | OP_LE - | OP_GE - | OP_LT - | OP_GT - | OP_ADD - | OP_SUB - | OP_UMINUS - | OP_MUL - | OP_DIV - | OP_IDIV - | OP_REM - | OP_MOD - | OP_TO_REAL - | OP_TO_INT - | OP_IS_INT - | OP_POWER - | OP_STORE - | OP_SELECT - | OP_CONST_ARRAY - | OP_ARRAY_MAP - | OP_ARRAY_DEFAULT - | OP_SET_UNION - | OP_SET_INTERSECT - | OP_SET_DIFFERENCE - | OP_SET_COMPLEMENT - | OP_SET_SUBSET - | OP_AS_ARRAY - | OP_BNUM - | OP_BIT1 - | OP_BIT0 - | OP_BNEG - | OP_BADD - | OP_BSUB - | OP_BMUL - | OP_BSDIV - | OP_BUDIV - | OP_BSREM - | OP_BUREM - | OP_BSMOD - | OP_BSDIV0 - | OP_BUDIV0 - | OP_BSREM0 - | OP_BUREM0 - | OP_BSMOD0 - | OP_ULEQ - | OP_SLEQ - | OP_UGEQ - | OP_SGEQ - | OP_ULT - | OP_SLT - | OP_UGT - | OP_SGT - | OP_BAND - | OP_BOR - | OP_BNOT - | OP_BXOR - | OP_BNAND - | OP_BNOR - | OP_BXNOR - | OP_CONCAT - | OP_SIGN_EXT - | OP_ZERO_EXT - | OP_EXTRACT - | OP_REPEAT - | OP_BREDOR - | OP_BREDAND - | OP_BCOMP - | OP_BSHL - | OP_BLSHR - | OP_BASHR - | OP_ROTATE_LEFT - | OP_ROTATE_RIGHT - | OP_EXT_ROTATE_LEFT - | OP_EXT_ROTATE_RIGHT - | OP_INT2BV - | OP_BV2INT - | OP_CARRY - | OP_XOR3 - | OP_PR_UNDEF - | OP_PR_TRUE - | OP_PR_ASSERTED - | OP_PR_GOAL - | OP_PR_MODUS_PONENS - | OP_PR_REFLEXIVITY - | OP_PR_SYMMETRY - | OP_PR_TRANSITIVITY - | OP_PR_TRANSITIVITY_STAR - | OP_PR_MONOTONICITY - | OP_PR_QUANT_INTRO - | OP_PR_DISTRIBUTIVITY - | OP_PR_AND_ELIM - | OP_PR_NOT_OR_ELIM - | OP_PR_REWRITE - | OP_PR_REWRITE_STAR - | OP_PR_PULL_QUANT - | OP_PR_PULL_QUANT_STAR - | OP_PR_PUSH_QUANT - | OP_PR_ELIM_UNUSED_VARS - | OP_PR_DER - | OP_PR_QUANT_INST - | OP_PR_HYPOTHESIS - | OP_PR_LEMMA - | OP_PR_UNIT_RESOLUTION - | OP_PR_IFF_TRUE - | OP_PR_IFF_FALSE - | OP_PR_COMMUTATIVITY - | OP_PR_DEF_AXIOM - | OP_PR_DEF_INTRO - | OP_PR_APPLY_DEF - | OP_PR_IFF_OEQ - | OP_PR_NNF_POS - | OP_PR_NNF_NEG - | OP_PR_NNF_STAR - | OP_PR_CNF_STAR - | OP_PR_SKOLEMIZE - | OP_PR_MODUS_PONENS_OEQ - | OP_PR_TH_LEMMA - | OP_PR_HYPER_RESOLVE - | OP_RA_STORE - | OP_RA_EMPTY - | OP_RA_IS_EMPTY - | OP_RA_JOIN - | OP_RA_UNION - | OP_RA_WIDEN - | OP_RA_PROJECT - | OP_RA_FILTER - | OP_RA_NEGATION_FILTER - | OP_RA_RENAME - | OP_RA_COMPLEMENT - | OP_RA_SELECT - | OP_RA_CLONE - | OP_FD_LT - | OP_LABEL - | OP_LABEL_LIT - | OP_DT_CONSTRUCTOR - | OP_DT_RECOGNISER - | OP_DT_ACCESSOR - | OP_UNINTERPRETED - -and param_kind = - | PK_UINT - | PK_BOOL - | PK_DOUBLE - | PK_SYMBOL - | PK_STRING - | PK_OTHER - | PK_INVALID - -and ast_print_mode = - | PRINT_SMTLIB_FULL - | PRINT_LOW_LEVEL - | PRINT_SMTLIB_COMPLIANT - | PRINT_SMTLIB2_COMPLIANT - -and error_code = - | OK - | SORT_ERROR - | IOB - | INVALID_ARG - | PARSER_ERROR - | NO_PARSER - | INVALID_PATTERN - | MEMOUT_FAIL - | FILE_ACCESS_ERROR - | INTERNAL_FATAL - | INVALID_USAGE - | DEC_REF_ERROR - | EXCEPTION - -and goal_prec = - | GOAL_PRECISE - | GOAL_UNDER - | GOAL_OVER - | GOAL_UNDER_OVER - - -external finalize_Z3_context : context -> unit = "finalize_Z3_context";; let _ = Callback.register "finalize_Z3_context" finalize_Z3_context -external finalize_Z3_ast : ast -> unit = "finalize_Z3_ast";; let _ = Callback.register "finalize_Z3_ast" finalize_Z3_ast -external finalize_Z3_params : params -> unit = "finalize_Z3_params";; let _ = Callback.register "finalize_Z3_params" finalize_Z3_params -external finalize_Z3_param_descrs : param_descrs -> unit = "finalize_Z3_param_descrs";; let _ = Callback.register "finalize_Z3_param_descrs" finalize_Z3_param_descrs -external finalize_Z3_model : model -> unit = "finalize_Z3_model";; let _ = Callback.register "finalize_Z3_model" finalize_Z3_model -external finalize_Z3_func_interp : func_interp -> unit = "finalize_Z3_func_interp";; let _ = Callback.register "finalize_Z3_func_interp" finalize_Z3_func_interp -external finalize_Z3_func_entry : func_entry -> unit = "finalize_Z3_func_entry";; let _ = Callback.register "finalize_Z3_func_entry" finalize_Z3_func_entry -external finalize_Z3_fixedpoint : fixedpoint -> unit = "finalize_Z3_fixedpoint";; let _ = Callback.register "finalize_Z3_fixedpoint" finalize_Z3_fixedpoint -external finalize_Z3_ast_vector : ast_vector -> unit = "finalize_Z3_ast_vector";; let _ = Callback.register "finalize_Z3_ast_vector" finalize_Z3_ast_vector -external finalize_Z3_ast_map : ast_map -> unit = "finalize_Z3_ast_map";; let _ = Callback.register "finalize_Z3_ast_map" finalize_Z3_ast_map -external finalize_Z3_goal : goal -> unit = "finalize_Z3_goal";; let _ = Callback.register "finalize_Z3_goal" finalize_Z3_goal -external finalize_Z3_tactic : tactic -> unit = "finalize_Z3_tactic";; let _ = Callback.register "finalize_Z3_tactic" finalize_Z3_tactic -external finalize_Z3_probe : probe -> unit = "finalize_Z3_probe";; let _ = Callback.register "finalize_Z3_probe" finalize_Z3_probe -external finalize_Z3_apply_result : apply_result -> unit = "finalize_Z3_apply_result";; let _ = Callback.register "finalize_Z3_apply_result" finalize_Z3_apply_result -external finalize_Z3_solver : solver -> unit = "finalize_Z3_solver";; let _ = Callback.register "finalize_Z3_solver" finalize_Z3_solver -external finalize_Z3_stats : stats -> unit = "finalize_Z3_stats";; let _ = Callback.register "finalize_Z3_stats" finalize_Z3_stats - -let del_constructor _ _ = () -let del_constructor_list _ _ = () -let del_model _ _ = () -let del_context _ = () -let reset_memory () = () - - -(** Exceptions raised by Z3. It is safe to continue interacting with Z3 after - catching [Error] exceptions. - - {b See also}: {!get_error_msg} -*) -exception Error of context * error_code - - -(* Register dynamically-generated exception tag for use from C *) -let _ = Callback.register_exception "Z3.Error" (Error (Obj.magic None, OK)) - -external mk_context: (string * string) list -> context = "caml_z3_mk_context" - -external update_param_value : context -> string -> string -> unit - = "camlidl_z3_Z3_update_param_value" - -external get_param_value : context -> string -> string option - = "camlidl_z3_Z3_get_param_value" - -external interrupt : context -> unit - = "camlidl_z3_Z3_interrupt" - -external mk_params : context -> params - = "camlidl_z3_Z3_mk_params" - -external params_set_bool : context -> params -> symbol -> bool -> unit - = "camlidl_z3_Z3_params_set_bool" - -external params_set_uint : context -> params -> symbol -> int -> unit - = "camlidl_z3_Z3_params_set_uint" - -external params_set_double : context -> params -> symbol -> float -> unit - = "camlidl_z3_Z3_params_set_double" - -external params_set_symbol : context -> params -> symbol -> symbol -> unit - = "camlidl_z3_Z3_params_set_symbol" - -external params_to_string : context -> params -> string - = "camlidl_z3_Z3_params_to_string" - -external params_validate : context -> params -> param_descrs -> unit - = "camlidl_z3_Z3_params_validate" - -external param_descrs_get_kind : context -> param_descrs -> symbol -> param_kind - = "camlidl_z3_Z3_param_descrs_get_kind" - -external param_descrs_size : context -> param_descrs -> int - = "camlidl_z3_Z3_param_descrs_size" - -external param_descrs_get_name : context -> param_descrs -> int -> symbol - = "camlidl_z3_Z3_param_descrs_get_name" - -external param_descrs_to_string : context -> param_descrs -> string - = "camlidl_z3_Z3_param_descrs_to_string" - - -(** - Refined view of a {!symbol}. - - {b See also}: {!mk_symbol} - - {b See also}: {!symbol_refine} -*) -type symbol_refined = - | Symbol_int of int - | Symbol_string of string - -external mk_int_symbol : context -> int -> symbol - = "camlidl_z3_Z3_mk_int_symbol" - -external mk_string_symbol : context -> string -> symbol - = "camlidl_z3_Z3_mk_string_symbol" - - -(** - A datatype constructor descriptor. -*) -type datatype_constructor_desc = { - constructor_desc : symbol; (** name of the constructor function *) - recognizer_desc : symbol; (** name of the recognizer function *) - accessor_descs : (symbol * sort) array; (** names and sorts of the fields *) -} -(** - A datatype is described by a name and constructor descriptors. -*) -type datatype_desc = symbol * datatype_constructor_desc array -(** - A datatype constructor representation. -*) -type datatype_constructor = { - constructor : func_decl; (** constructor function *) - recognizer : func_decl; (** recognizer function *) - accessors : func_decl array; (** field accessor functions *) -} -(** - A datatype is represented by a sort and constructors. -*) -type datatype = sort * datatype_constructor array -(** - Refined view of a {!sort}. - - {b See also}: {!mk_sort} - - {b See also}: {!sort_refine} -*) -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_bv of int - | Sort_finite_domain of symbol * int64 - | Sort_real - | Sort_array of sort * sort - | Sort_datatype of datatype_constructor array - | Sort_relation of sort array - | Sort_unknown - -external mk_uninterpreted_sort : context -> symbol -> sort - = "camlidl_z3_Z3_mk_uninterpreted_sort" - -external mk_bool_sort : context -> sort - = "camlidl_z3_Z3_mk_bool_sort" - -external mk_int_sort : context -> sort - = "camlidl_z3_Z3_mk_int_sort" - -external mk_real_sort : context -> sort - = "camlidl_z3_Z3_mk_real_sort" - -external mk_bv_sort : context -> int -> sort - = "camlidl_z3_Z3_mk_bv_sort" - -external mk_finite_domain_sort : context -> symbol -> int64 -> sort - = "camlidl_z3_Z3_mk_finite_domain_sort" - -external mk_array_sort : context -> sort -> sort -> sort - = "camlidl_z3_Z3_mk_array_sort" - -external mk_tuple_sort : context -> symbol -> symbol array -> sort array -> sort * func_decl * func_decl array - = "camlidl_z3_Z3_mk_tuple_sort" - -external mk_enumeration_sort : context -> symbol -> symbol array -> sort * func_decl array * func_decl array - = "camlidl_z3_Z3_mk_enumeration_sort" - -external mk_list_sort : context -> symbol -> sort -> sort * func_decl * func_decl * func_decl * func_decl * func_decl * func_decl - = "camlidl_z3_Z3_mk_list_sort" - -external mk_constructor : context -> symbol -> symbol -> symbol array -> sort option array -> int array -> constructor - = "camlidl_z3_Z3_mk_constructor_bytecode" "camlidl_z3_Z3_mk_constructor" - -external del_constructor : context -> constructor -> unit - = "camlidl_z3_Z3_del_constructor" - -external mk_datatype : context -> symbol -> constructor array -> sort * constructor array - = "camlidl_z3_Z3_mk_datatype" - -external mk_constructor_list : context -> constructor array -> constructor_list - = "camlidl_z3_Z3_mk_constructor_list" - -external del_constructor_list : context -> constructor_list -> unit - = "camlidl_z3_Z3_del_constructor_list" - -external mk_datatypes : context -> symbol array -> constructor_list array -> sort array * constructor_list array - = "camlidl_z3_Z3_mk_datatypes" - -external query_constructor : context -> constructor -> int -> func_decl * func_decl * func_decl array - = "camlidl_z3_Z3_query_constructor" - -external mk_func_decl : context -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3_Z3_mk_func_decl" - -external mk_app : context -> func_decl -> ast array -> ast - = "camlidl_z3_Z3_mk_app" - -external mk_const : context -> symbol -> sort -> ast - = "camlidl_z3_Z3_mk_const" - -external mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl - = "camlidl_z3_Z3_mk_fresh_func_decl" - -external mk_fresh_const : context -> string -> sort -> ast - = "camlidl_z3_Z3_mk_fresh_const" - -external mk_true : context -> ast - = "camlidl_z3_Z3_mk_true" - -external mk_false : context -> ast - = "camlidl_z3_Z3_mk_false" - -external mk_eq : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_eq" - -external mk_distinct : context -> ast array -> ast - = "camlidl_z3_Z3_mk_distinct" - -external mk_not : context -> ast -> ast - = "camlidl_z3_Z3_mk_not" - -external mk_ite : context -> ast -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ite" - -external mk_iff : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_iff" - -external mk_implies : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_implies" - -external mk_xor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_xor" - -external mk_and : context -> ast array -> ast - = "camlidl_z3_Z3_mk_and" - -external mk_or : context -> ast array -> ast - = "camlidl_z3_Z3_mk_or" - -external mk_add : context -> ast array -> ast - = "camlidl_z3_Z3_mk_add" - -external mk_mul : context -> ast array -> ast - = "camlidl_z3_Z3_mk_mul" - -external mk_sub : context -> ast array -> ast - = "camlidl_z3_Z3_mk_sub" - -external mk_unary_minus : context -> ast -> ast - = "camlidl_z3_Z3_mk_unary_minus" - -external mk_div : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_div" - -external mk_mod : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_mod" - -external mk_rem : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_rem" - -external mk_power : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_power" - -external mk_lt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_lt" - -external mk_le : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_le" - -external mk_gt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_gt" - -external mk_ge : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ge" - -external mk_int2real : context -> ast -> ast - = "camlidl_z3_Z3_mk_int2real" - -external mk_real2int : context -> ast -> ast - = "camlidl_z3_Z3_mk_real2int" - -external mk_is_int : context -> ast -> ast - = "camlidl_z3_Z3_mk_is_int" - -external mk_bvnot : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvnot" - -external mk_bvredand : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvredand" - -external mk_bvredor : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvredor" - -external mk_bvand : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvand" - -external mk_bvor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvor" - -external mk_bvxor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvxor" - -external mk_bvnand : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvnand" - -external mk_bvnor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvnor" - -external mk_bvxnor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvxnor" - -external mk_bvneg : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvneg" - -external mk_bvadd : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvadd" - -external mk_bvsub : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsub" - -external mk_bvmul : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvmul" - -external mk_bvudiv : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvudiv" - -external mk_bvsdiv : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsdiv" - -external mk_bvurem : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvurem" - -external mk_bvsrem : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsrem" - -external mk_bvsmod : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsmod" - -external mk_bvult : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvult" - -external mk_bvslt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvslt" - -external mk_bvule : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvule" - -external mk_bvsle : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsle" - -external mk_bvuge : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvuge" - -external mk_bvsge : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsge" - -external mk_bvugt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvugt" - -external mk_bvsgt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsgt" - -external mk_concat : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_concat" - -external mk_extract : context -> int -> int -> ast -> ast - = "camlidl_z3_Z3_mk_extract" - -external mk_sign_ext : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_sign_ext" - -external mk_zero_ext : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_zero_ext" - -external mk_repeat : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_repeat" - -external mk_bvshl : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvshl" - -external mk_bvlshr : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvlshr" - -external mk_bvashr : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvashr" - -external mk_rotate_left : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_rotate_left" - -external mk_rotate_right : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_rotate_right" - -external mk_ext_rotate_left : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ext_rotate_left" - -external mk_ext_rotate_right : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ext_rotate_right" - -external mk_int2bv : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_int2bv" - -external mk_bv2int : context -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bv2int" - -external mk_bvadd_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bvadd_no_overflow" - -external mk_bvadd_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvadd_no_underflow" - -external mk_bvsub_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsub_no_overflow" - -external mk_bvsub_no_underflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bvsub_no_underflow" - -external mk_bvsdiv_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsdiv_no_overflow" - -external mk_bvneg_no_overflow : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvneg_no_overflow" - -external mk_bvmul_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bvmul_no_overflow" - -external mk_bvmul_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvmul_no_underflow" - -external mk_select : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_select" - -external mk_store : context -> ast -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_store" - -external mk_const_array : context -> sort -> ast -> ast - = "camlidl_z3_Z3_mk_const_array" - -external mk_map : context -> func_decl -> int -> ast -> ast - = "camlidl_z3_Z3_mk_map" - -external mk_array_default : context -> ast -> ast - = "camlidl_z3_Z3_mk_array_default" - -external mk_set_sort : context -> sort -> sort - = "camlidl_z3_Z3_mk_set_sort" - -external mk_empty_set : context -> sort -> ast - = "camlidl_z3_Z3_mk_empty_set" - -external mk_full_set : context -> sort -> ast - = "camlidl_z3_Z3_mk_full_set" - -external mk_set_add : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_add" - -external mk_set_del : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_del" - -external mk_set_union : context -> ast array -> ast - = "camlidl_z3_Z3_mk_set_union" - -external mk_set_intersect : context -> ast array -> ast - = "camlidl_z3_Z3_mk_set_intersect" - -external mk_set_difference : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_difference" - -external mk_set_complement : context -> ast -> ast - = "camlidl_z3_Z3_mk_set_complement" - -external mk_set_member : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_member" - -external mk_set_subset : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_subset" - - -(** - Summary: \[ [ numeral_refined ] \] is the refined view of a numeral . -*) -type numeral_refined = - | Numeral_int of int * sort - | Numeral_int64 of int64 * sort - | Numeral_large of string * sort - | Numeral_rational of numeral_refined * numeral_refined - -external mk_numeral : context -> string -> sort -> ast - = "camlidl_z3_Z3_mk_numeral" - -external mk_real : context -> int -> int -> ast - = "camlidl_z3_Z3_mk_real" - -external mk_int : context -> int -> sort -> ast - = "camlidl_z3_Z3_mk_int" - -external mk_int64 : context -> int64 -> sort -> ast - = "camlidl_z3_Z3_mk_int64" - -external mk_pattern : context -> ast array -> pattern - = "camlidl_z3_Z3_mk_pattern" - -external mk_bound : context -> int -> sort -> ast - = "camlidl_z3_Z3_mk_bound" - -external mk_forall : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_forall_bytecode" "camlidl_z3_Z3_mk_forall" - -external mk_exists : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_exists_bytecode" "camlidl_z3_Z3_mk_exists" - -external mk_quantifier : context -> bool -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_bytecode" "camlidl_z3_Z3_mk_quantifier" - -external mk_quantifier_ex : context -> bool -> int -> symbol -> symbol -> pattern array -> ast array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_ex_bytecode" "camlidl_z3_Z3_mk_quantifier_ex" - -external mk_forall_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3_Z3_mk_forall_const" - -external mk_exists_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3_Z3_mk_exists_const" - -external mk_quantifier_const : context -> bool -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_const_bytecode" "camlidl_z3_Z3_mk_quantifier_const" - -external mk_quantifier_const_ex : context -> bool -> int -> symbol -> symbol -> app array -> pattern array -> ast array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_const_ex_bytecode" "camlidl_z3_Z3_mk_quantifier_const_ex" - -external get_symbol_kind : context -> symbol -> symbol_kind - = "camlidl_z3_Z3_get_symbol_kind" - -external get_symbol_int : context -> symbol -> int - = "camlidl_z3_Z3_get_symbol_int" - -external get_symbol_string : context -> symbol -> string - = "camlidl_z3_Z3_get_symbol_string" - -external get_sort_name : context -> sort -> symbol - = "camlidl_z3_Z3_get_sort_name" - -external get_sort_id : context -> sort -> int - = "camlidl_z3_Z3_get_sort_id" - -external sort_to_ast : context -> sort -> ast - = "camlidl_z3_Z3_sort_to_ast" - -external is_eq_sort : context -> sort -> sort -> bool - = "camlidl_z3_Z3_is_eq_sort" - -external get_sort_kind : context -> sort -> sort_kind - = "camlidl_z3_Z3_get_sort_kind" - -external get_bv_sort_size : context -> sort -> int - = "camlidl_z3_Z3_get_bv_sort_size" - -external get_finite_domain_sort_size : context -> sort -> int64 option - = "camlidl_z3_Z3_get_finite_domain_sort_size" - -external get_array_sort_domain : context -> sort -> sort - = "camlidl_z3_Z3_get_array_sort_domain" - -external get_array_sort_range : context -> sort -> sort - = "camlidl_z3_Z3_get_array_sort_range" - -external get_tuple_sort_mk_decl : context -> sort -> func_decl - = "camlidl_z3_Z3_get_tuple_sort_mk_decl" - -external get_tuple_sort_num_fields : context -> sort -> int - = "camlidl_z3_Z3_get_tuple_sort_num_fields" - -external get_tuple_sort_field_decl : context -> sort -> int -> func_decl - = "camlidl_z3_Z3_get_tuple_sort_field_decl" - -external get_datatype_sort_num_constructors : context -> sort -> int - = "camlidl_z3_Z3_get_datatype_sort_num_constructors" - -external get_datatype_sort_constructor : context -> sort -> int -> func_decl - = "camlidl_z3_Z3_get_datatype_sort_constructor" - -external get_datatype_sort_recognizer : context -> sort -> int -> func_decl - = "camlidl_z3_Z3_get_datatype_sort_recognizer" - -external get_datatype_sort_constructor_accessor : context -> sort -> int -> int -> func_decl - = "camlidl_z3_Z3_get_datatype_sort_constructor_accessor" - -external get_relation_arity : context -> sort -> int - = "camlidl_z3_Z3_get_relation_arity" - -external get_relation_column : context -> sort -> int -> sort - = "camlidl_z3_Z3_get_relation_column" - -external func_decl_to_ast : context -> func_decl -> ast - = "camlidl_z3_Z3_func_decl_to_ast" - -external is_eq_func_decl : context -> func_decl -> func_decl -> bool - = "camlidl_z3_Z3_is_eq_func_decl" - -external get_func_decl_id : context -> func_decl -> int - = "camlidl_z3_Z3_get_func_decl_id" - -external get_decl_name : context -> func_decl -> symbol - = "camlidl_z3_Z3_get_decl_name" - -external get_decl_kind : context -> func_decl -> decl_kind - = "camlidl_z3_Z3_get_decl_kind" - -external get_domain_size : context -> func_decl -> int - = "camlidl_z3_Z3_get_domain_size" - -external get_arity : context -> func_decl -> int - = "camlidl_z3_Z3_get_arity" - -external get_domain : context -> func_decl -> int -> sort - = "camlidl_z3_Z3_get_domain" - -external get_range : context -> func_decl -> sort - = "camlidl_z3_Z3_get_range" - -external get_decl_num_parameters : context -> func_decl -> int - = "camlidl_z3_Z3_get_decl_num_parameters" - -external get_decl_parameter_kind : context -> func_decl -> int -> parameter_kind - = "camlidl_z3_Z3_get_decl_parameter_kind" - -external get_decl_int_parameter : context -> func_decl -> int -> int - = "camlidl_z3_Z3_get_decl_int_parameter" - -external get_decl_double_parameter : context -> func_decl -> int -> float - = "camlidl_z3_Z3_get_decl_double_parameter" - -external get_decl_symbol_parameter : context -> func_decl -> int -> symbol - = "camlidl_z3_Z3_get_decl_symbol_parameter" - -external get_decl_sort_parameter : context -> func_decl -> int -> sort - = "camlidl_z3_Z3_get_decl_sort_parameter" - -external get_decl_ast_parameter : context -> func_decl -> int -> ast - = "camlidl_z3_Z3_get_decl_ast_parameter" - -external get_decl_func_decl_parameter : context -> func_decl -> int -> func_decl - = "camlidl_z3_Z3_get_decl_func_decl_parameter" - -external get_decl_rational_parameter : context -> func_decl -> int -> string - = "camlidl_z3_Z3_get_decl_rational_parameter" - -external app_to_ast : context -> app -> ast - = "camlidl_z3_Z3_app_to_ast" - -external get_app_decl : context -> app -> func_decl - = "camlidl_z3_Z3_get_app_decl" - -external get_app_num_args : context -> app -> int - = "camlidl_z3_Z3_get_app_num_args" - -external get_app_arg : context -> app -> int -> ast - = "camlidl_z3_Z3_get_app_arg" - - -(** - Summary: \[ [ binder_type ] \] is a universal or existential quantifier. - - {b See also}: {!term_refined} -*) -type binder_type = Forall | Exists -(** - Summary: \[ [ term_refined ] \] is the refinement of a {!ast} . - - {b See also}: {!term_refine} -*) -type term_refined = - | Term_numeral of numeral_refined - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast - | Term_var of int * sort - -external is_eq_ast : context -> ast -> ast -> bool - = "camlidl_z3_Z3_is_eq_ast" - -external get_ast_id : context -> ast -> int - = "camlidl_z3_Z3_get_ast_id" - -external get_ast_hash : context -> ast -> int - = "camlidl_z3_Z3_get_ast_hash" - -external get_sort : context -> ast -> sort - = "camlidl_z3_Z3_get_sort" - -external is_well_sorted : context -> ast -> bool - = "camlidl_z3_Z3_is_well_sorted" - -external get_bool_value : context -> ast -> lbool - = "camlidl_z3_Z3_get_bool_value" - -external get_ast_kind : context -> ast -> ast_kind - = "camlidl_z3_Z3_get_ast_kind" - -external is_app : context -> ast -> bool - = "camlidl_z3_Z3_is_app" - -external is_numeral_ast : context -> ast -> bool - = "camlidl_z3_Z3_is_numeral_ast" - -external is_algebraic_number : context -> ast -> bool - = "camlidl_z3_Z3_is_algebraic_number" - -external to_app : context -> ast -> app - = "camlidl_z3_Z3_to_app" - -external to_func_decl : context -> ast -> func_decl - = "camlidl_z3_Z3_to_func_decl" - -external get_numeral_string : context -> ast -> string - = "camlidl_z3_Z3_get_numeral_string" - -external get_numeral_decimal_string : context -> ast -> int -> string - = "camlidl_z3_Z3_get_numeral_decimal_string" - -external get_numerator : context -> ast -> ast - = "camlidl_z3_Z3_get_numerator" - -external get_denominator : context -> ast -> ast - = "camlidl_z3_Z3_get_denominator" - -external get_numeral_small : context -> ast -> bool * int64 * int64 - = "camlidl_z3_Z3_get_numeral_small" - -external get_numeral_int : context -> ast -> bool * int - = "camlidl_z3_Z3_get_numeral_int" - -external get_numeral_int64 : context -> ast -> bool * int64 - = "camlidl_z3_Z3_get_numeral_int64" - -external get_numeral_rational_int64 : context -> ast -> bool * int64 * int64 - = "camlidl_z3_Z3_get_numeral_rational_int64" - -external get_algebraic_number_lower : context -> ast -> int -> ast - = "camlidl_z3_Z3_get_algebraic_number_lower" - -external get_algebraic_number_upper : context -> ast -> int -> ast - = "camlidl_z3_Z3_get_algebraic_number_upper" - -external pattern_to_ast : context -> pattern -> ast - = "camlidl_z3_Z3_pattern_to_ast" - -external get_pattern_num_terms : context -> pattern -> int - = "camlidl_z3_Z3_get_pattern_num_terms" - -external get_pattern : context -> pattern -> int -> ast - = "camlidl_z3_Z3_get_pattern" - -external get_index_value : context -> ast -> int - = "camlidl_z3_Z3_get_index_value" - -external is_quantifier_forall : context -> ast -> bool - = "camlidl_z3_Z3_is_quantifier_forall" - -external get_quantifier_weight : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_weight" - -external get_quantifier_num_patterns : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_num_patterns" - -external get_quantifier_pattern_ast : context -> ast -> int -> pattern - = "camlidl_z3_Z3_get_quantifier_pattern_ast" - -external get_quantifier_num_no_patterns : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_num_no_patterns" - -external get_quantifier_no_pattern_ast : context -> ast -> int -> ast - = "camlidl_z3_Z3_get_quantifier_no_pattern_ast" - -external get_quantifier_num_bound : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_num_bound" - -external get_quantifier_bound_name : context -> ast -> int -> symbol - = "camlidl_z3_Z3_get_quantifier_bound_name" - -external get_quantifier_bound_sort : context -> ast -> int -> sort - = "camlidl_z3_Z3_get_quantifier_bound_sort" - -external get_quantifier_body : context -> ast -> ast - = "camlidl_z3_Z3_get_quantifier_body" - -external simplify : context -> ast -> ast - = "camlidl_z3_Z3_simplify" - -external simplify_ex : context -> ast -> params -> ast - = "camlidl_z3_Z3_simplify_ex" - -external simplify_get_help : context -> string - = "camlidl_z3_Z3_simplify_get_help" - -external simplify_get_param_descrs : context -> param_descrs - = "camlidl_z3_Z3_simplify_get_param_descrs" - -external update_term : context -> ast -> ast array -> ast - = "camlidl_z3_Z3_update_term" - -external substitute : context -> ast -> ast array -> ast array -> ast - = "camlidl_z3_Z3_substitute" - -external substitute_vars : context -> ast -> ast array -> ast - = "camlidl_z3_Z3_substitute_vars" - -external translate : context -> ast -> context -> ast - = "camlidl_z3_Z3_translate" - - -(** - A model assigns uninterpreted sorts to finite universes of distinct values, constants to values, - and arrays and functions to finite maps from argument values to result values plus a default - value for all other arguments. -*) -type model_refined = { - sorts : (sort, ast_vector) Hashtbl.t; - consts : (func_decl, ast) Hashtbl.t; - arrays : (func_decl, (ast, ast) Hashtbl.t * ast) Hashtbl.t; - funcs : (func_decl, (ast array, ast) Hashtbl.t * ast) Hashtbl.t; -} - -external model_eval : context -> model -> ast -> bool -> ast option - = "camlidl_z3_Z3_model_eval" - -external model_get_const_interp : context -> model -> func_decl -> ast option - = "camlidl_z3_Z3_model_get_const_interp" - -external model_get_func_interp : context -> model -> func_decl -> func_interp option - = "camlidl_z3_Z3_model_get_func_interp" - -external model_get_num_consts : context -> model -> int - = "camlidl_z3_Z3_model_get_num_consts" - -external model_get_const_decl : context -> model -> int -> func_decl - = "camlidl_z3_Z3_model_get_const_decl" - -external model_get_num_funcs : context -> model -> int - = "camlidl_z3_Z3_model_get_num_funcs" - -external model_get_func_decl : context -> model -> int -> func_decl - = "camlidl_z3_Z3_model_get_func_decl" - -external model_get_num_sorts : context -> model -> int - = "camlidl_z3_Z3_model_get_num_sorts" - -external model_get_sort : context -> model -> int -> sort - = "camlidl_z3_Z3_model_get_sort" - -external model_get_sort_universe : context -> model -> sort -> ast_vector - = "camlidl_z3_Z3_model_get_sort_universe" - -external is_as_array : context -> ast -> bool - = "camlidl_z3_Z3_is_as_array" - -external get_as_array_func_decl : context -> ast -> func_decl - = "camlidl_z3_Z3_get_as_array_func_decl" - -external func_interp_get_num_entries : context -> func_interp -> int - = "camlidl_z3_Z3_func_interp_get_num_entries" - -external func_interp_get_entry : context -> func_interp -> int -> func_entry - = "camlidl_z3_Z3_func_interp_get_entry" - -external func_interp_get_else : context -> func_interp -> ast - = "camlidl_z3_Z3_func_interp_get_else" - -external func_interp_get_arity : context -> func_interp -> int - = "camlidl_z3_Z3_func_interp_get_arity" - -external func_entry_get_value : context -> func_entry -> ast - = "camlidl_z3_Z3_func_entry_get_value" - -external func_entry_get_num_args : context -> func_entry -> int - = "camlidl_z3_Z3_func_entry_get_num_args" - -external func_entry_get_arg : context -> func_entry -> int -> ast - = "camlidl_z3_Z3_func_entry_get_arg" - -external open_log : string -> bool - = "camlidl_z3_Z3_open_log" - -external append_log : string -> unit - = "camlidl_z3_Z3_append_log" - -external close_log : unit -> unit - = "camlidl_z3_Z3_close_log" - -external toggle_warning_messages : bool -> unit - = "camlidl_z3_Z3_toggle_warning_messages" - -external set_ast_print_mode : context -> ast_print_mode -> unit - = "camlidl_z3_Z3_set_ast_print_mode" - -external ast_to_string : context -> ast -> string - = "camlidl_z3_Z3_ast_to_string" - -external pattern_to_string : context -> pattern -> string - = "camlidl_z3_Z3_pattern_to_string" - -external sort_to_string : context -> sort -> string - = "camlidl_z3_Z3_sort_to_string" - -external func_decl_to_string : context -> func_decl -> string - = "camlidl_z3_Z3_func_decl_to_string" - -external model_to_string : context -> model -> string - = "camlidl_z3_Z3_model_to_string" - -external benchmark_to_smtlib_string : context -> string -> string -> string -> string -> ast array -> ast -> string - = "camlidl_z3_Z3_benchmark_to_smtlib_string_bytecode" "camlidl_z3_Z3_benchmark_to_smtlib_string" - -external parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3_Z3_parse_smtlib2_string_bytecode" "camlidl_z3_Z3_parse_smtlib2_string" - -external parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3_Z3_parse_smtlib2_file_bytecode" "camlidl_z3_Z3_parse_smtlib2_file" - -external parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3_Z3_parse_smtlib_string_bytecode" "camlidl_z3_Z3_parse_smtlib_string" - -external parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3_Z3_parse_smtlib_file_bytecode" "camlidl_z3_Z3_parse_smtlib_file" - -external get_smtlib_num_formulas : context -> int - = "camlidl_z3_Z3_get_smtlib_num_formulas" - -external get_smtlib_formula : context -> int -> ast - = "camlidl_z3_Z3_get_smtlib_formula" - -external get_smtlib_num_assumptions : context -> int - = "camlidl_z3_Z3_get_smtlib_num_assumptions" - -external get_smtlib_assumption : context -> int -> ast - = "camlidl_z3_Z3_get_smtlib_assumption" - -external get_smtlib_num_decls : context -> int - = "camlidl_z3_Z3_get_smtlib_num_decls" - -external get_smtlib_decl : context -> int -> func_decl - = "camlidl_z3_Z3_get_smtlib_decl" - -external get_smtlib_num_sorts : context -> int - = "camlidl_z3_Z3_get_smtlib_num_sorts" - -external get_smtlib_sort : context -> int -> sort - = "camlidl_z3_Z3_get_smtlib_sort" - -external get_smtlib_error : context -> string - = "camlidl_z3_Z3_get_smtlib_error" - -external set_error : context -> error_code -> unit - = "camlidl_z3_Z3_set_error" - -external get_error_msg_ex : context -> error_code -> string - = "camlidl_z3_Z3_get_error_msg_ex" - -external get_version : unit -> int * int * int * int - = "camlidl_z3_Z3_get_version" - -external enable_trace : string -> unit - = "camlidl_z3_Z3_enable_trace" - -external disable_trace : string -> unit - = "camlidl_z3_Z3_disable_trace" - -external mk_fixedpoint : context -> fixedpoint - = "camlidl_z3_Z3_mk_fixedpoint" - -external fixedpoint_add_rule : context -> fixedpoint -> ast -> symbol -> unit - = "camlidl_z3_Z3_fixedpoint_add_rule" - -external fixedpoint_add_fact : context -> fixedpoint -> func_decl -> int array -> unit - = "camlidl_z3_Z3_fixedpoint_add_fact" - -external fixedpoint_assert : context -> fixedpoint -> ast -> unit - = "camlidl_z3_Z3_fixedpoint_assert" - -external fixedpoint_query : context -> fixedpoint -> ast -> lbool - = "camlidl_z3_Z3_fixedpoint_query" - -external fixedpoint_query_relations : context -> fixedpoint -> func_decl array -> lbool - = "camlidl_z3_Z3_fixedpoint_query_relations" - -external fixedpoint_get_answer : context -> fixedpoint -> ast - = "camlidl_z3_Z3_fixedpoint_get_answer" - -external fixedpoint_get_reason_unknown : context -> fixedpoint -> string - = "camlidl_z3_Z3_fixedpoint_get_reason_unknown" - -external fixedpoint_update_rule : context -> fixedpoint -> ast -> symbol -> unit - = "camlidl_z3_Z3_fixedpoint_update_rule" - -external fixedpoint_get_num_levels : context -> fixedpoint -> func_decl -> int - = "camlidl_z3_Z3_fixedpoint_get_num_levels" - -external fixedpoint_get_cover_delta : context -> fixedpoint -> int -> func_decl -> ast - = "camlidl_z3_Z3_fixedpoint_get_cover_delta" - -external fixedpoint_add_cover : context -> fixedpoint -> int -> func_decl -> ast -> unit - = "camlidl_z3_Z3_fixedpoint_add_cover" - -external fixedpoint_get_statistics : context -> fixedpoint -> stats - = "camlidl_z3_Z3_fixedpoint_get_statistics" - -external fixedpoint_register_relation : context -> fixedpoint -> func_decl -> unit - = "camlidl_z3_Z3_fixedpoint_register_relation" - -external fixedpoint_set_predicate_representation : context -> fixedpoint -> func_decl -> symbol array -> unit - = "camlidl_z3_Z3_fixedpoint_set_predicate_representation" - -external fixedpoint_get_rules : context -> fixedpoint -> ast_vector - = "camlidl_z3_Z3_fixedpoint_get_rules" - -external fixedpoint_get_assertions : context -> fixedpoint -> ast_vector - = "camlidl_z3_Z3_fixedpoint_get_assertions" - -external fixedpoint_set_params : context -> fixedpoint -> params -> unit - = "camlidl_z3_Z3_fixedpoint_set_params" - -external fixedpoint_get_help : context -> fixedpoint -> string - = "camlidl_z3_Z3_fixedpoint_get_help" - -external fixedpoint_get_param_descrs : context -> fixedpoint -> param_descrs - = "camlidl_z3_Z3_fixedpoint_get_param_descrs" - -external fixedpoint_to_string : context -> fixedpoint -> ast array -> string - = "camlidl_z3_Z3_fixedpoint_to_string" - -external fixedpoint_from_string : context -> fixedpoint -> string -> ast_vector - = "camlidl_z3_Z3_fixedpoint_from_string" - -external fixedpoint_from_file : context -> fixedpoint -> string -> ast_vector - = "camlidl_z3_Z3_fixedpoint_from_file" - -external fixedpoint_push : context -> fixedpoint -> unit - = "camlidl_z3_Z3_fixedpoint_push" - -external fixedpoint_pop : context -> fixedpoint -> unit - = "camlidl_z3_Z3_fixedpoint_pop" - -external mk_ast_vector : context -> ast_vector - = "camlidl_z3_Z3_mk_ast_vector" - -external ast_vector_size : context -> ast_vector -> int - = "camlidl_z3_Z3_ast_vector_size" - -external ast_vector_get : context -> ast_vector -> int -> ast - = "camlidl_z3_Z3_ast_vector_get" - -external ast_vector_set : context -> ast_vector -> int -> ast -> unit - = "camlidl_z3_Z3_ast_vector_set" - -external ast_vector_resize : context -> ast_vector -> int -> unit - = "camlidl_z3_Z3_ast_vector_resize" - -external ast_vector_push : context -> ast_vector -> ast -> unit - = "camlidl_z3_Z3_ast_vector_push" - -external ast_vector_translate : context -> ast_vector -> context -> ast_vector - = "camlidl_z3_Z3_ast_vector_translate" - -external ast_vector_to_string : context -> ast_vector -> string - = "camlidl_z3_Z3_ast_vector_to_string" - -external mk_ast_map : context -> ast_map - = "camlidl_z3_Z3_mk_ast_map" - -external ast_map_contains : context -> ast_map -> ast -> bool - = "camlidl_z3_Z3_ast_map_contains" - -external ast_map_find : context -> ast_map -> ast -> ast - = "camlidl_z3_Z3_ast_map_find" - -external ast_map_insert : context -> ast_map -> ast -> ast -> unit - = "camlidl_z3_Z3_ast_map_insert" - -external ast_map_erase : context -> ast_map -> ast -> unit - = "camlidl_z3_Z3_ast_map_erase" - -external ast_map_reset : context -> ast_map -> unit - = "camlidl_z3_Z3_ast_map_reset" - -external ast_map_size : context -> ast_map -> int - = "camlidl_z3_Z3_ast_map_size" - -external ast_map_keys : context -> ast_map -> ast_vector - = "camlidl_z3_Z3_ast_map_keys" - -external ast_map_to_string : context -> ast_map -> string - = "camlidl_z3_Z3_ast_map_to_string" - -external mk_goal : context -> bool -> bool -> bool -> goal - = "camlidl_z3_Z3_mk_goal" - -external goal_precision : context -> goal -> goal_prec - = "camlidl_z3_Z3_goal_precision" - -external goal_assert : context -> goal -> ast -> unit - = "camlidl_z3_Z3_goal_assert" - -external goal_inconsistent : context -> goal -> bool - = "camlidl_z3_Z3_goal_inconsistent" - -external goal_depth : context -> goal -> int - = "camlidl_z3_Z3_goal_depth" - -external goal_reset : context -> goal -> unit - = "camlidl_z3_Z3_goal_reset" - -external goal_size : context -> goal -> int - = "camlidl_z3_Z3_goal_size" - -external goal_formula : context -> goal -> int -> ast - = "camlidl_z3_Z3_goal_formula" - -external goal_num_exprs : context -> goal -> int - = "camlidl_z3_Z3_goal_num_exprs" - -external goal_is_decided_sat : context -> goal -> bool - = "camlidl_z3_Z3_goal_is_decided_sat" - -external goal_is_decided_unsat : context -> goal -> bool - = "camlidl_z3_Z3_goal_is_decided_unsat" - -external goal_translate : context -> goal -> context -> goal - = "camlidl_z3_Z3_goal_translate" - -external goal_to_string : context -> goal -> string - = "camlidl_z3_Z3_goal_to_string" - -external mk_tactic : context -> string -> tactic - = "camlidl_z3_Z3_mk_tactic" - -external mk_probe : context -> string -> probe - = "camlidl_z3_Z3_mk_probe" - -external tactic_and_then : context -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_and_then" - -external tactic_or_else : context -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_or_else" - -external tactic_par_or : context -> tactic array -> tactic - = "camlidl_z3_Z3_tactic_par_or" - -external tactic_par_and_then : context -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_par_and_then" - -external tactic_try_for : context -> tactic -> int -> tactic - = "camlidl_z3_Z3_tactic_try_for" - -external tactic_when : context -> probe -> tactic -> tactic - = "camlidl_z3_Z3_tactic_when" - -external tactic_cond : context -> probe -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_cond" - -external tactic_repeat : context -> tactic -> int -> tactic - = "camlidl_z3_Z3_tactic_repeat" - -external tactic_skip : context -> tactic - = "camlidl_z3_Z3_tactic_skip" - -external tactic_fail : context -> tactic - = "camlidl_z3_Z3_tactic_fail" - -external tactic_fail_if : context -> probe -> tactic - = "camlidl_z3_Z3_tactic_fail_if" - -external tactic_fail_if_not_decided : context -> tactic - = "camlidl_z3_Z3_tactic_fail_if_not_decided" - -external tactic_using_params : context -> tactic -> params -> tactic - = "camlidl_z3_Z3_tactic_using_params" - -external probe_const : context -> float -> probe - = "camlidl_z3_Z3_probe_const" - -external probe_lt : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_lt" - -external probe_gt : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_gt" - -external probe_le : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_le" - -external probe_ge : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_ge" - -external probe_eq : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_eq" - -external probe_and : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_and" - -external probe_or : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_or" - -external probe_not : context -> probe -> probe - = "camlidl_z3_Z3_probe_not" - -external get_num_tactics : context -> int - = "camlidl_z3_Z3_get_num_tactics" - -external get_tactic_name : context -> int -> string - = "camlidl_z3_Z3_get_tactic_name" - -external get_num_probes : context -> int - = "camlidl_z3_Z3_get_num_probes" - -external get_probe_name : context -> int -> string - = "camlidl_z3_Z3_get_probe_name" - -external tactic_get_help : context -> tactic -> string - = "camlidl_z3_Z3_tactic_get_help" - -external tactic_get_param_descrs : context -> tactic -> param_descrs - = "camlidl_z3_Z3_tactic_get_param_descrs" - -external tactic_get_descr : context -> string -> string - = "camlidl_z3_Z3_tactic_get_descr" - -external probe_get_descr : context -> string -> string - = "camlidl_z3_Z3_probe_get_descr" - -external probe_apply : context -> probe -> goal -> float - = "camlidl_z3_Z3_probe_apply" - -external tactic_apply : context -> tactic -> goal -> apply_result - = "camlidl_z3_Z3_tactic_apply" - -external tactic_apply_ex : context -> tactic -> goal -> params -> apply_result - = "camlidl_z3_Z3_tactic_apply_ex" - -external apply_result_to_string : context -> apply_result -> string - = "camlidl_z3_Z3_apply_result_to_string" - -external apply_result_get_num_subgoals : context -> apply_result -> int - = "camlidl_z3_Z3_apply_result_get_num_subgoals" - -external apply_result_get_subgoal : context -> apply_result -> int -> goal - = "camlidl_z3_Z3_apply_result_get_subgoal" - -external apply_result_convert_model : context -> apply_result -> int -> model -> model - = "camlidl_z3_Z3_apply_result_convert_model" - -external mk_solver : context -> solver - = "camlidl_z3_Z3_mk_solver" - -external mk_simple_solver : context -> solver - = "camlidl_z3_Z3_mk_simple_solver" - -external mk_solver_for_logic : context -> symbol -> solver - = "camlidl_z3_Z3_mk_solver_for_logic" - -external mk_solver_from_tactic : context -> tactic -> solver - = "camlidl_z3_Z3_mk_solver_from_tactic" - -external solver_get_help : context -> solver -> string - = "camlidl_z3_Z3_solver_get_help" - -external solver_get_param_descrs : context -> solver -> param_descrs - = "camlidl_z3_Z3_solver_get_param_descrs" - -external solver_set_params : context -> solver -> params -> unit - = "camlidl_z3_Z3_solver_set_params" - -external solver_push : context -> solver -> unit - = "camlidl_z3_Z3_solver_push" - -external solver_pop : context -> solver -> int -> unit - = "camlidl_z3_Z3_solver_pop" - -external solver_reset : context -> solver -> unit - = "camlidl_z3_Z3_solver_reset" - -external solver_get_num_scopes : context -> solver -> int - = "camlidl_z3_Z3_solver_get_num_scopes" - -external solver_assert : context -> solver -> ast -> unit - = "camlidl_z3_Z3_solver_assert" - -external solver_assert_and_track : context -> solver -> ast -> ast -> unit - = "camlidl_z3_Z3_solver_assert_and_track" - -external solver_get_assertions : context -> solver -> ast_vector - = "camlidl_z3_Z3_solver_get_assertions" - -external solver_check : context -> solver -> lbool - = "camlidl_z3_Z3_solver_check" - -external solver_check_assumptions : context -> solver -> ast array -> lbool - = "camlidl_z3_Z3_solver_check_assumptions" - -external solver_get_model : context -> solver -> model - = "camlidl_z3_Z3_solver_get_model" - -external solver_get_proof : context -> solver -> ast - = "camlidl_z3_Z3_solver_get_proof" - -external solver_get_unsat_core : context -> solver -> ast_vector - = "camlidl_z3_Z3_solver_get_unsat_core" - -external solver_get_reason_unknown : context -> solver -> string - = "camlidl_z3_Z3_solver_get_reason_unknown" - -external solver_get_statistics : context -> solver -> stats - = "camlidl_z3_Z3_solver_get_statistics" - -external solver_to_string : context -> solver -> string - = "camlidl_z3_Z3_solver_to_string" - - -type stat_datum = Stat_int of int | Stat_float of float -type stats_refined = (string, stat_datum) Hashtbl.t - -external stats_to_string : context -> stats -> string - = "camlidl_z3_Z3_stats_to_string" - -external stats_size : context -> stats -> int - = "camlidl_z3_Z3_stats_size" - -external stats_get_key : context -> stats -> int -> string - = "camlidl_z3_Z3_stats_get_key" - -external stats_is_uint : context -> stats -> int -> bool - = "camlidl_z3_Z3_stats_is_uint" - -external stats_is_double : context -> stats -> int -> bool - = "camlidl_z3_Z3_stats_is_double" - -external stats_get_uint_value : context -> stats -> int -> int - = "camlidl_z3_Z3_stats_get_uint_value" - -external stats_get_double_value : context -> stats -> int -> float - = "camlidl_z3_Z3_stats_get_double_value" - -external get_implied_equalities : context -> solver -> ast array -> lbool * int array - = "camlidl_z3_Z3_get_implied_equalities" - - -(* Internal auxiliary functions: *) -(* -(* Transform a pair of arrays into an array of pairs *) -let array_combine a b = - if Array.length a <> Array.length b then raise (Invalid_argument "array_combine"); - Array.init (Array.length a) (fun i -> (a.(i), b.(i))) -(* [a |> b] is the pipeline operator for [b(a)] *) -let ( |> ) x f = f x -*) -(* Find the index of an element in an array, raises Not_found is missing *) -let find equal x a = - let len = Array.length a in - let rec find_ i = - if i >= len then - raise Not_found - else - if equal x a.(i) then - i - else - find_ (i+1) - in - find_ 0 -(* Symbols *) -let symbol_refine c s = - match get_symbol_kind c s with - | INT_SYMBOL -> Symbol_int (get_symbol_int c s) - | STRING_SYMBOL -> Symbol_string (get_symbol_string c s) -let mk_symbol c = function - | Symbol_int(i) -> mk_int_symbol c i - | Symbol_string(s) -> mk_string_symbol c s -(* Sorts *) -let get_datatype_sort c s = - Array.init (get_datatype_sort_num_constructors c s) (fun i -> - let constructor = get_datatype_sort_constructor c s i in - let recognizer = get_datatype_sort_recognizer c s i in - let accessors = - Array.init (get_domain_size c constructor) (fun j -> - get_datatype_sort_constructor_accessor c s i j - ) in - {constructor; recognizer; accessors} - ) -let sort_refine c s = - match get_sort_kind c s with - | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c s) - | BOOL_SORT -> Sort_bool - | INT_SORT -> Sort_int - | BV_SORT -> Sort_bv (get_bv_sort_size c s) - | FINITE_DOMAIN_SORT -> - (match get_finite_domain_sort_size c s with - | Some(sz) -> Sort_finite_domain (get_sort_name c s, sz) - | None -> failwith "Z3.sort_refine: failed to get size of finite-domain sort" - ) - | REAL_SORT -> Sort_real - | ARRAY_SORT -> Sort_array (get_array_sort_domain c s, get_array_sort_range c s) - | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c s) - | RELATION_SORT -> Sort_relation (Array.init (get_relation_arity c s) (fun i -> get_relation_column c s i)) - | UNKNOWN_SORT -> Sort_unknown -let mk_sort c = function - | Sort_uninterpreted(s) -> mk_uninterpreted_sort c s - | Sort_bool -> mk_bool_sort c - | Sort_int -> mk_int_sort c - | Sort_bv(size) -> mk_bv_sort c size - | Sort_finite_domain(name,size) -> mk_finite_domain_sort c name size - | Sort_real -> mk_real_sort c - | Sort_array(domain,range) -> mk_array_sort c domain range - | Sort_datatype(constructors) -> get_range c constructors.(0).constructor - | Sort_relation(_) -> invalid_arg "Z3.mk_sort: cannot construct relation sorts" - | Sort_unknown(_) -> invalid_arg "Z3.mk_sort: cannot construct unknown sorts" -(* Replacement datatypes creation API *) -let mk_datatypes ctx generator = - let usort0 = mk_uninterpreted_sort ctx (mk_int_symbol ctx 0) - in - let rec find_num_sorts i = - if i = max_int then invalid_arg "mk_datatypes: too many sorts" - else - match generator (Array.make i usort0) with - | None -> find_num_sorts (i+1) - | Some(a) when Array.length a = i -> i - | Some _ -> invalid_arg "mk_datatypes: number of sorts and datatype descriptors must be equal" - in - let num_sorts = find_num_sorts 0 - in - let sorts0 = Array.init num_sorts (fun i -> mk_uninterpreted_sort ctx (mk_int_symbol ctx i)) - in - let ctorss_descriptors = - match generator sorts0 with - | Some(ctorss_descriptors) -> ctorss_descriptors - | None -> invalid_arg "mk_datatypes: generator failed" - in - let names = Array.map fst ctorss_descriptors - in - let ctorss = - Array.map (fun (_, ctors_descriptor) -> - Array.map (fun {constructor_desc; recognizer_desc; accessor_descs} -> - let field_names = Array.map fst accessor_descs - in - let sort_refs = Array.make (Array.length accessor_descs) 0 - in - let field_sorts = - Array.mapi (fun i (_, sort) -> - try - let j = find (fun s t -> is_eq_sort ctx s t) sort sorts0 in - sort_refs.(i) <- j ; - None - with Not_found -> - Some(sort) - ) accessor_descs - in - mk_constructor ctx constructor_desc recognizer_desc field_names field_sorts sort_refs - ) ctors_descriptor - ) ctorss_descriptors - in - let constructor_lists = Array.map (mk_constructor_list ctx) ctorss - in - let sorts,_ = mk_datatypes ctx names constructor_lists - in - let datatypes = - Array.mapi (fun i sort -> - (sort, - Array.mapi (fun j ctor -> - let num_fields = Array.length (snd ctorss_descriptors.(i)).(j).accessor_descs in - let constructor, recognizer, accessors = query_constructor ctx ctor num_fields in - {constructor; recognizer; accessors} - ) ctorss.(i)) - ) sorts - in - Array.iter (fun ctor_list -> - del_constructor_list ctx ctor_list - ) constructor_lists - ; - Array.iter (fun ctors -> - Array.iter (fun ctor -> - del_constructor ctx ctor - ) ctors - ) ctorss - ; - datatypes -(* Numerals *) -let rec numeral_refine c t = - assert( get_ast_kind c t = NUMERAL_AST ); - let sort = get_sort c t in - let is_int, i = get_numeral_int c t in - if is_int then - Numeral_int (i, sort) - else - let is_int64, i = get_numeral_int64 c t in - if is_int64 then - Numeral_int64 (i, sort) - else - if get_sort_kind c sort <> REAL_SORT then - Numeral_large (get_numeral_string c t, sort) - else - let n = numeral_refine c (get_numerator c t) in - let d = numeral_refine c (get_denominator c t) in - Numeral_rational (n, d) -let to_real c x = - if get_sort_kind c (get_sort c x) = REAL_SORT then - x - else - mk_int2real c x -let rec embed_numeral c = function - | Numeral_int (i, s) -> mk_int c i s - | Numeral_int64 (i, s) -> mk_int64 c i s - | Numeral_large (l, s) -> mk_numeral c l s - | Numeral_rational (Numeral_int(n,_), Numeral_int(d,_)) -> mk_real c n d - | Numeral_rational (n, d) -> - mk_div c (to_real c (embed_numeral c n)) (to_real c (embed_numeral c d)) - (* Or should the following be used instead? - let n_str = get_numeral_string c (embed_numeral c n) in - let d_str = get_numeral_string c (embed_numeral c d) in - mk_numeral c (n_str ^ " / " ^ d_str) (mk_real_sort c) - *) -(* Terms *) -let get_app_args c a = - Array.init (get_app_num_args c a) (get_app_arg c a);; -let get_domains c d = - Array.init (get_domain_size c d) (get_domain c d);; -let get_pattern_terms c p = - Array.init (get_pattern_num_terms c p) (get_pattern c p) -let term_refine c t = - match get_ast_kind c t with - | NUMERAL_AST -> - Term_numeral (numeral_refine c t) - | APP_AST -> - let t' = to_app c t in - let f = get_app_decl c t' in - let num_args = get_app_num_args c t' in - let args = Array.init num_args (get_app_arg c t') in - let k = get_decl_kind c f in - Term_app (k, f, args) - | QUANTIFIER_AST -> - let bt = if is_quantifier_forall c t then Forall else Exists in - let w = get_quantifier_weight c t in - let np = get_quantifier_num_patterns c t in - let pats = Array.init np (get_quantifier_pattern_ast c t) in - let pats = Array.map (get_pattern_terms c) pats in - let nb = get_quantifier_num_bound c t in - let bound = - Array.init nb (fun i -> - (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i) - ) in - let body = get_quantifier_body c t in - Term_quantifier (bt, w, pats, bound, body) - | VAR_AST -> - Term_var (get_index_value c t, get_sort c t) - | _ -> - assert false -(* let mk_term c = function *) -(* | Term_numeral (numeral, sort) -> mk_numeral c numeral sort *) -(* | Term_app (kind, decl, args) -> *) -(* | Term_quantifier (strength, weight, pats, bound, body) -> *) -(* | Term_var (index, sort) -> *) -(* Refined model API *) -let model_refine c m = - let num_sorts = model_get_num_sorts c m in - let sorts = Hashtbl.create num_sorts in - for i = 0 to num_sorts - 1 do - let sort = model_get_sort c m i in - let universe = model_get_sort_universe c m sort in - Hashtbl.add sorts sort universe - done; - let num_consts = model_get_num_consts c m in - let consts = Hashtbl.create num_consts in - let arrays = Hashtbl.create 0 in - for i = 0 to num_consts - 1 do - let const_decl = model_get_const_decl c m i in - match model_get_const_interp c m const_decl with - | Some(const_interp) -> - if is_as_array c const_interp then - let array_decl = get_as_array_func_decl c const_interp in - match model_get_func_interp c m array_decl with - | Some(array_interp) -> - let num_entries = func_interp_get_num_entries c array_interp in - let tbl = Hashtbl.create num_entries in - for i = 0 to num_entries - 1 do - let entry = func_interp_get_entry c array_interp i in - assert( func_entry_get_num_args c entry = 1 ); - let arg = func_entry_get_arg c entry 0 in - let value = func_entry_get_value c entry in - Hashtbl.add tbl arg value - done; - let default = func_interp_get_else c array_interp in - Hashtbl.add arrays const_decl (tbl, default) - | None -> - () - else - Hashtbl.add consts const_decl const_interp - | None -> - () - done; - let num_funcs = model_get_num_funcs c m in - let funcs = Hashtbl.create num_funcs in - for i = 0 to num_funcs - 1 do - let func_decl = model_get_func_decl c m i in - if not (Hashtbl.mem arrays func_decl) then - match model_get_func_interp c m func_decl with - | Some(func_interp) -> - let num_entries = func_interp_get_num_entries c func_interp in - let tbl = Hashtbl.create num_entries in - for i = 0 to num_entries - 1 do - let entry = func_interp_get_entry c func_interp i in - let num_args = func_entry_get_num_args c entry in - let args = Array.init num_args (fun i -> func_entry_get_arg c entry i) in - let value = func_entry_get_value c entry in - Hashtbl.add tbl args value - done; - let default = func_interp_get_else c func_interp in - Hashtbl.add funcs func_decl (tbl, default) - | None -> - () - done; - {sorts; consts; arrays; funcs} -(* Extended parser API *) -let get_smtlib_formulas c = - Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c) -let get_smtlib_assumptions c = - Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c) -let get_smtlib_decls c = - Array.init (get_smtlib_num_decls c) (get_smtlib_decl c) -let get_smtlib_parse_results c = - (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c) -let parse_smtlib_string_x c a1 a2 a3 a4 a5 = - parse_smtlib_string c a1 a2 a3 a4 a5 ; - get_smtlib_parse_results c -let parse_smtlib_file_x c a1 a2 a3 a4 a5 = - parse_smtlib_file c a1 a2 a3 a4 a5 ; - get_smtlib_parse_results c -let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = - parse_smtlib_string c a1 a2 a3 a4 a5 ; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith "Z3: parse_smtlib_string_formula" -let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = - parse_smtlib_file c a1 a2 a3 a4 a5 ; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith "Z3: parse_smtlib_file_formula" -(* Error handling *) -let get_error_msg c e = - match e with - | PARSER_ERROR -> (get_error_msg_ex c e) ^ ": " ^ (get_smtlib_error c) - | _ -> get_error_msg_ex c e -(* Refined stats API *) -let stats_refine c s = - let num_stats = stats_size c s in - let tbl = Hashtbl.create num_stats in - for i = 0 to num_stats - 1 do - let key = stats_get_key c s i in - let datum = - if stats_is_uint c s i then - Stat_int(stats_get_uint_value c s i) - else - Stat_float(stats_get_double_value c s i) in - Hashtbl.add tbl key datum - done; - tbl - - -let _ = - Printexc.register_printer (function - | Error(c,e) -> Some ("Z3 "^(get_error_msg c e)) - | _ -> None - ) - - -module V3 = struct - -(* File generated from z3V3.idl *) - -type symbol -and literals -and theory -and config -and context -and sort -and func_decl -and ast -and app -and pattern -and model -and constructor -and constructor_list - -and lbool = - | L_FALSE - | L_UNDEF - | L_TRUE - -and symbol_kind = - | INT_SYMBOL - | STRING_SYMBOL - -and parameter_kind = - | PARAMETER_INT - | PARAMETER_DOUBLE - | PARAMETER_RATIONAL - | PARAMETER_SYMBOL - | PARAMETER_SORT - | PARAMETER_AST - | PARAMETER_FUNC_DECL - -and sort_kind = - | UNINTERPRETED_SORT - | BOOL_SORT - | INT_SORT - | REAL_SORT - | BV_SORT - | ARRAY_SORT - | DATATYPE_SORT - | RELATION_SORT - | FINITE_DOMAIN_SORT - | UNKNOWN_SORT - -and ast_kind = - | NUMERAL_AST - | APP_AST - | VAR_AST - | QUANTIFIER_AST - | SORT_AST - | FUNC_DECL_AST - | UNKNOWN_AST - -and decl_kind = - | OP_TRUE - | OP_FALSE - | OP_EQ - | OP_DISTINCT - | OP_ITE - | OP_AND - | OP_OR - | OP_IFF - | OP_XOR - | OP_NOT - | OP_IMPLIES - | OP_OEQ - | OP_ANUM - | OP_AGNUM - | OP_LE - | OP_GE - | OP_LT - | OP_GT - | OP_ADD - | OP_SUB - | OP_UMINUS - | OP_MUL - | OP_DIV - | OP_IDIV - | OP_REM - | OP_MOD - | OP_TO_REAL - | OP_TO_INT - | OP_IS_INT - | OP_POWER - | OP_STORE - | OP_SELECT - | OP_CONST_ARRAY - | OP_ARRAY_MAP - | OP_ARRAY_DEFAULT - | OP_SET_UNION - | OP_SET_INTERSECT - | OP_SET_DIFFERENCE - | OP_SET_COMPLEMENT - | OP_SET_SUBSET - | OP_AS_ARRAY - | OP_BNUM - | OP_BIT1 - | OP_BIT0 - | OP_BNEG - | OP_BADD - | OP_BSUB - | OP_BMUL - | OP_BSDIV - | OP_BUDIV - | OP_BSREM - | OP_BUREM - | OP_BSMOD - | OP_BSDIV0 - | OP_BUDIV0 - | OP_BSREM0 - | OP_BUREM0 - | OP_BSMOD0 - | OP_ULEQ - | OP_SLEQ - | OP_UGEQ - | OP_SGEQ - | OP_ULT - | OP_SLT - | OP_UGT - | OP_SGT - | OP_BAND - | OP_BOR - | OP_BNOT - | OP_BXOR - | OP_BNAND - | OP_BNOR - | OP_BXNOR - | OP_CONCAT - | OP_SIGN_EXT - | OP_ZERO_EXT - | OP_EXTRACT - | OP_REPEAT - | OP_BREDOR - | OP_BREDAND - | OP_BCOMP - | OP_BSHL - | OP_BLSHR - | OP_BASHR - | OP_ROTATE_LEFT - | OP_ROTATE_RIGHT - | OP_EXT_ROTATE_LEFT - | OP_EXT_ROTATE_RIGHT - | OP_INT2BV - | OP_BV2INT - | OP_CARRY - | OP_XOR3 - | OP_PR_UNDEF - | OP_PR_TRUE - | OP_PR_ASSERTED - | OP_PR_GOAL - | OP_PR_MODUS_PONENS - | OP_PR_REFLEXIVITY - | OP_PR_SYMMETRY - | OP_PR_TRANSITIVITY - | OP_PR_TRANSITIVITY_STAR - | OP_PR_MONOTONICITY - | OP_PR_QUANT_INTRO - | OP_PR_DISTRIBUTIVITY - | OP_PR_AND_ELIM - | OP_PR_NOT_OR_ELIM - | OP_PR_REWRITE - | OP_PR_REWRITE_STAR - | OP_PR_PULL_QUANT - | OP_PR_PULL_QUANT_STAR - | OP_PR_PUSH_QUANT - | OP_PR_ELIM_UNUSED_VARS - | OP_PR_DER - | OP_PR_QUANT_INST - | OP_PR_HYPOTHESIS - | OP_PR_LEMMA - | OP_PR_UNIT_RESOLUTION - | OP_PR_IFF_TRUE - | OP_PR_IFF_FALSE - | OP_PR_COMMUTATIVITY - | OP_PR_DEF_AXIOM - | OP_PR_DEF_INTRO - | OP_PR_APPLY_DEF - | OP_PR_IFF_OEQ - | OP_PR_NNF_POS - | OP_PR_NNF_NEG - | OP_PR_NNF_STAR - | OP_PR_CNF_STAR - | OP_PR_SKOLEMIZE - | OP_PR_MODUS_PONENS_OEQ - | OP_PR_TH_LEMMA - | OP_PR_HYPER_RESOLVE - | OP_RA_STORE - | OP_RA_EMPTY - | OP_RA_IS_EMPTY - | OP_RA_JOIN - | OP_RA_UNION - | OP_RA_WIDEN - | OP_RA_PROJECT - | OP_RA_FILTER - | OP_RA_NEGATION_FILTER - | OP_RA_RENAME - | OP_RA_COMPLEMENT - | OP_RA_SELECT - | OP_RA_CLONE - | OP_FD_LT - | OP_LABEL - | OP_LABEL_LIT - | OP_DT_CONSTRUCTOR - | OP_DT_RECOGNISER - | OP_DT_ACCESSOR - | OP_UNINTERPRETED - -and param_kind = - | PK_UINT - | PK_BOOL - | PK_DOUBLE - | PK_SYMBOL - | PK_STRING - | PK_OTHER - | PK_INVALID - -and search_failure = - | NO_FAILURE - | UNKNOWN - | TIMEOUT - | MEMOUT_WATERMARK - | CANCELED - | NUM_CONFLICTS - | THEORY - | QUANTIFIERS - -and ast_print_mode = - | PRINT_SMTLIB_FULL - | PRINT_LOW_LEVEL - | PRINT_SMTLIB_COMPLIANT - | PRINT_SMTLIB2_COMPLIANT - - -external global_param_set : string -> string -> unit - = "camlidl_z3V3_Z3_global_param_set" - -external global_param_reset_all : unit -> unit - = "camlidl_z3V3_Z3_global_param_reset_all" - -external global_param_get : string -> string option - = "camlidl_z3V3_Z3_global_param_get" - -external mk_config : unit -> config - = "camlidl_z3V3_Z3_mk_config" - -external del_config : config -> unit - = "camlidl_z3V3_Z3_del_config" - -external set_param_value : config -> string -> string -> unit - = "camlidl_z3V3_Z3_set_param_value" - -external mk_context : config -> context - = "camlidl_z3V3_Z3_mk_context" - -external del_context : context -> unit - = "camlidl_z3V3_Z3_del_context" - -external update_param_value : context -> string -> string -> unit - = "camlidl_z3V3_Z3_update_param_value" - -external get_param_value : context -> string -> string option - = "camlidl_z3V3_Z3_get_param_value" - -external mk_int_symbol : context -> int -> symbol - = "camlidl_z3V3_Z3_mk_int_symbol" - -external mk_string_symbol : context -> string -> symbol - = "camlidl_z3V3_Z3_mk_string_symbol" - -external mk_uninterpreted_sort : context -> symbol -> sort - = "camlidl_z3V3_Z3_mk_uninterpreted_sort" - -external mk_bool_sort : context -> sort - = "camlidl_z3V3_Z3_mk_bool_sort" - -external mk_int_sort : context -> sort - = "camlidl_z3V3_Z3_mk_int_sort" - -external mk_real_sort : context -> sort - = "camlidl_z3V3_Z3_mk_real_sort" - -external mk_bv_sort : context -> int -> sort - = "camlidl_z3V3_Z3_mk_bv_sort" - -external mk_finite_domain_sort : context -> symbol -> int64 -> sort - = "camlidl_z3V3_Z3_mk_finite_domain_sort" - -external mk_array_sort : context -> sort -> sort -> sort - = "camlidl_z3V3_Z3_mk_array_sort" - -external mk_tuple_sort : context -> symbol -> symbol array -> sort array -> sort * func_decl * func_decl array - = "camlidl_z3V3_Z3_mk_tuple_sort" - -external mk_enumeration_sort : context -> symbol -> symbol array -> sort * func_decl array * func_decl array - = "camlidl_z3V3_Z3_mk_enumeration_sort" - -external mk_list_sort : context -> symbol -> sort -> sort * func_decl * func_decl * func_decl * func_decl * func_decl * func_decl - = "camlidl_z3V3_Z3_mk_list_sort" - -external mk_constructor : context -> symbol -> symbol -> symbol array -> sort array -> int array -> constructor - = "camlidl_z3V3_Z3_mk_constructor_bytecode" "camlidl_z3V3_Z3_mk_constructor" - -external del_constructor : context -> constructor -> unit - = "camlidl_z3V3_Z3_del_constructor" - -external mk_datatype : context -> symbol -> constructor array -> sort * constructor array - = "camlidl_z3V3_Z3_mk_datatype" - -external mk_constructor_list : context -> constructor array -> constructor_list - = "camlidl_z3V3_Z3_mk_constructor_list" - -external del_constructor_list : context -> constructor_list -> unit - = "camlidl_z3V3_Z3_del_constructor_list" - -external mk_datatypes : context -> symbol array -> constructor_list array -> sort array * constructor_list array - = "camlidl_z3V3_Z3_mk_datatypes" - -external query_constructor : context -> constructor -> int -> func_decl * func_decl * func_decl array - = "camlidl_z3V3_Z3_query_constructor" - -external mk_func_decl : context -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_mk_func_decl" - -external mk_app : context -> func_decl -> ast array -> ast - = "camlidl_z3V3_Z3_mk_app" - -external mk_const : context -> symbol -> sort -> ast - = "camlidl_z3V3_Z3_mk_const" - -external mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_mk_fresh_func_decl" - -external mk_fresh_const : context -> string -> sort -> ast - = "camlidl_z3V3_Z3_mk_fresh_const" - -external mk_true : context -> ast - = "camlidl_z3V3_Z3_mk_true" - -external mk_false : context -> ast - = "camlidl_z3V3_Z3_mk_false" - -external mk_eq : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_eq" - -external mk_distinct : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_distinct" - -external mk_not : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_not" - -external mk_ite : context -> ast -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ite" - -external mk_iff : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_iff" - -external mk_implies : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_implies" - -external mk_xor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_xor" - -external mk_and : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_and" - -external mk_or : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_or" - -external mk_add : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_add" - -external mk_mul : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_mul" - -external mk_sub : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_sub" - -external mk_unary_minus : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_unary_minus" - -external mk_div : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_div" - -external mk_mod : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_mod" - -external mk_rem : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_rem" - -external mk_power : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_power" - -external mk_lt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_lt" - -external mk_le : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_le" - -external mk_gt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_gt" - -external mk_ge : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ge" - -external mk_int2real : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_int2real" - -external mk_real2int : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_real2int" - -external mk_is_int : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_is_int" - -external mk_bvnot : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvnot" - -external mk_bvredand : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvredand" - -external mk_bvredor : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvredor" - -external mk_bvand : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvand" - -external mk_bvor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvor" - -external mk_bvxor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvxor" - -external mk_bvnand : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvnand" - -external mk_bvnor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvnor" - -external mk_bvxnor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvxnor" - -external mk_bvneg : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvneg" - -external mk_bvadd : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvadd" - -external mk_bvsub : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsub" - -external mk_bvmul : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvmul" - -external mk_bvudiv : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvudiv" - -external mk_bvsdiv : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsdiv" - -external mk_bvurem : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvurem" - -external mk_bvsrem : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsrem" - -external mk_bvsmod : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsmod" - -external mk_bvult : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvult" - -external mk_bvslt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvslt" - -external mk_bvule : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvule" - -external mk_bvsle : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsle" - -external mk_bvuge : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvuge" - -external mk_bvsge : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsge" - -external mk_bvugt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvugt" - -external mk_bvsgt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsgt" - -external mk_concat : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_concat" - -external mk_extract : context -> int -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_extract" - -external mk_sign_ext : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_sign_ext" - -external mk_zero_ext : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_zero_ext" - -external mk_repeat : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_repeat" - -external mk_bvshl : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvshl" - -external mk_bvlshr : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvlshr" - -external mk_bvashr : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvashr" - -external mk_rotate_left : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_rotate_left" - -external mk_rotate_right : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_rotate_right" - -external mk_ext_rotate_left : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ext_rotate_left" - -external mk_ext_rotate_right : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ext_rotate_right" - -external mk_int2bv : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_int2bv" - -external mk_bv2int : context -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bv2int" - -external mk_bvadd_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bvadd_no_overflow" - -external mk_bvadd_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvadd_no_underflow" - -external mk_bvsub_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsub_no_overflow" - -external mk_bvsub_no_underflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bvsub_no_underflow" - -external mk_bvsdiv_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsdiv_no_overflow" - -external mk_bvneg_no_overflow : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvneg_no_overflow" - -external mk_bvmul_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bvmul_no_overflow" - -external mk_bvmul_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvmul_no_underflow" - -external mk_select : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_select" - -external mk_store : context -> ast -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_store" - -external mk_const_array : context -> sort -> ast -> ast - = "camlidl_z3V3_Z3_mk_const_array" - -external mk_map : context -> func_decl -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_map" - -external mk_array_default : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_array_default" - -external mk_set_sort : context -> sort -> sort - = "camlidl_z3V3_Z3_mk_set_sort" - -external mk_empty_set : context -> sort -> ast - = "camlidl_z3V3_Z3_mk_empty_set" - -external mk_full_set : context -> sort -> ast - = "camlidl_z3V3_Z3_mk_full_set" - -external mk_set_add : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_add" - -external mk_set_del : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_del" - -external mk_set_union : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_set_union" - -external mk_set_intersect : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_set_intersect" - -external mk_set_difference : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_difference" - -external mk_set_complement : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_complement" - -external mk_set_member : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_member" - -external mk_set_subset : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_subset" - -external mk_numeral : context -> string -> sort -> ast - = "camlidl_z3V3_Z3_mk_numeral" - -external mk_real : context -> int -> int -> ast - = "camlidl_z3V3_Z3_mk_real" - -external mk_int : context -> int -> sort -> ast - = "camlidl_z3V3_Z3_mk_int" - -external mk_int64 : context -> int64 -> sort -> ast - = "camlidl_z3V3_Z3_mk_int64" - -external mk_pattern : context -> ast array -> pattern - = "camlidl_z3V3_Z3_mk_pattern" - -external mk_bound : context -> int -> sort -> ast - = "camlidl_z3V3_Z3_mk_bound" - -external mk_forall : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_forall_bytecode" "camlidl_z3V3_Z3_mk_forall" - -external mk_exists : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_exists_bytecode" "camlidl_z3V3_Z3_mk_exists" - -external mk_quantifier : context -> bool -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_bytecode" "camlidl_z3V3_Z3_mk_quantifier" - -external mk_quantifier_ex : context -> bool -> int -> symbol -> symbol -> pattern array -> ast array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_ex_bytecode" "camlidl_z3V3_Z3_mk_quantifier_ex" - -external mk_forall_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3V3_Z3_mk_forall_const" - -external mk_exists_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3V3_Z3_mk_exists_const" - -external mk_quantifier_const : context -> bool -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_const_bytecode" "camlidl_z3V3_Z3_mk_quantifier_const" - -external mk_quantifier_const_ex : context -> bool -> int -> symbol -> symbol -> app array -> pattern array -> ast array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_const_ex_bytecode" "camlidl_z3V3_Z3_mk_quantifier_const_ex" - -external get_symbol_kind : context -> symbol -> symbol_kind - = "camlidl_z3V3_Z3_get_symbol_kind" - -external get_symbol_int : context -> symbol -> int - = "camlidl_z3V3_Z3_get_symbol_int" - -external get_symbol_string : context -> symbol -> string - = "camlidl_z3V3_Z3_get_symbol_string" - -external get_sort_name : context -> sort -> symbol - = "camlidl_z3V3_Z3_get_sort_name" - -external get_sort_id : context -> sort -> int - = "camlidl_z3V3_Z3_get_sort_id" - -external sort_to_ast : context -> sort -> ast - = "camlidl_z3V3_Z3_sort_to_ast" - -external is_eq_sort : context -> sort -> sort -> bool - = "camlidl_z3V3_Z3_is_eq_sort" - -external get_sort_kind : context -> sort -> sort_kind - = "camlidl_z3V3_Z3_get_sort_kind" - -external get_bv_sort_size : context -> sort -> int - = "camlidl_z3V3_Z3_get_bv_sort_size" - -external get_finite_domain_sort_size : context -> sort -> int64 option - = "camlidl_z3V3_Z3_get_finite_domain_sort_size" - -external get_array_sort_domain : context -> sort -> sort - = "camlidl_z3V3_Z3_get_array_sort_domain" - -external get_array_sort_range : context -> sort -> sort - = "camlidl_z3V3_Z3_get_array_sort_range" - -external get_tuple_sort_mk_decl : context -> sort -> func_decl - = "camlidl_z3V3_Z3_get_tuple_sort_mk_decl" - -external get_tuple_sort_num_fields : context -> sort -> int - = "camlidl_z3V3_Z3_get_tuple_sort_num_fields" - -external get_tuple_sort_field_decl : context -> sort -> int -> func_decl - = "camlidl_z3V3_Z3_get_tuple_sort_field_decl" - -external get_datatype_sort_num_constructors : context -> sort -> int - = "camlidl_z3V3_Z3_get_datatype_sort_num_constructors" - -external get_datatype_sort_constructor : context -> sort -> int -> func_decl - = "camlidl_z3V3_Z3_get_datatype_sort_constructor" - -external get_datatype_sort_recognizer : context -> sort -> int -> func_decl - = "camlidl_z3V3_Z3_get_datatype_sort_recognizer" - -external get_datatype_sort_constructor_accessor : context -> sort -> int -> int -> func_decl - = "camlidl_z3V3_Z3_get_datatype_sort_constructor_accessor" - -external get_relation_arity : context -> sort -> int - = "camlidl_z3V3_Z3_get_relation_arity" - -external get_relation_column : context -> sort -> int -> sort - = "camlidl_z3V3_Z3_get_relation_column" - -external func_decl_to_ast : context -> func_decl -> ast - = "camlidl_z3V3_Z3_func_decl_to_ast" - -external is_eq_func_decl : context -> func_decl -> func_decl -> bool - = "camlidl_z3V3_Z3_is_eq_func_decl" - -external get_func_decl_id : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_func_decl_id" - -external get_decl_name : context -> func_decl -> symbol - = "camlidl_z3V3_Z3_get_decl_name" - -external get_decl_kind : context -> func_decl -> decl_kind - = "camlidl_z3V3_Z3_get_decl_kind" - -external get_domain_size : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_domain_size" - -external get_arity : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_arity" - -external get_domain : context -> func_decl -> int -> sort - = "camlidl_z3V3_Z3_get_domain" - -external get_range : context -> func_decl -> sort - = "camlidl_z3V3_Z3_get_range" - -external get_decl_num_parameters : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_decl_num_parameters" - -external get_decl_parameter_kind : context -> func_decl -> int -> parameter_kind - = "camlidl_z3V3_Z3_get_decl_parameter_kind" - -external get_decl_int_parameter : context -> func_decl -> int -> int - = "camlidl_z3V3_Z3_get_decl_int_parameter" - -external get_decl_double_parameter : context -> func_decl -> int -> float - = "camlidl_z3V3_Z3_get_decl_double_parameter" - -external get_decl_symbol_parameter : context -> func_decl -> int -> symbol - = "camlidl_z3V3_Z3_get_decl_symbol_parameter" - -external get_decl_sort_parameter : context -> func_decl -> int -> sort - = "camlidl_z3V3_Z3_get_decl_sort_parameter" - -external get_decl_ast_parameter : context -> func_decl -> int -> ast - = "camlidl_z3V3_Z3_get_decl_ast_parameter" - -external get_decl_func_decl_parameter : context -> func_decl -> int -> func_decl - = "camlidl_z3V3_Z3_get_decl_func_decl_parameter" - -external get_decl_rational_parameter : context -> func_decl -> int -> string - = "camlidl_z3V3_Z3_get_decl_rational_parameter" - -external app_to_ast : context -> app -> ast - = "camlidl_z3V3_Z3_app_to_ast" - -external get_app_decl : context -> app -> func_decl - = "camlidl_z3V3_Z3_get_app_decl" - -external get_app_num_args : context -> app -> int - = "camlidl_z3V3_Z3_get_app_num_args" - -external get_app_arg : context -> app -> int -> ast - = "camlidl_z3V3_Z3_get_app_arg" - -external is_eq_ast : context -> ast -> ast -> bool - = "camlidl_z3V3_Z3_is_eq_ast" - -external get_ast_id : context -> ast -> int - = "camlidl_z3V3_Z3_get_ast_id" - -external get_ast_hash : context -> ast -> int - = "camlidl_z3V3_Z3_get_ast_hash" - -external get_sort : context -> ast -> sort - = "camlidl_z3V3_Z3_get_sort" - -external is_well_sorted : context -> ast -> bool - = "camlidl_z3V3_Z3_is_well_sorted" - -external get_bool_value : context -> ast -> lbool - = "camlidl_z3V3_Z3_get_bool_value" - -external get_ast_kind : context -> ast -> ast_kind - = "camlidl_z3V3_Z3_get_ast_kind" - -external is_app : context -> ast -> bool - = "camlidl_z3V3_Z3_is_app" - -external is_numeral_ast : context -> ast -> bool - = "camlidl_z3V3_Z3_is_numeral_ast" - -external is_algebraic_number : context -> ast -> bool - = "camlidl_z3V3_Z3_is_algebraic_number" - -external to_app : context -> ast -> app - = "camlidl_z3V3_Z3_to_app" - -external to_func_decl : context -> ast -> func_decl - = "camlidl_z3V3_Z3_to_func_decl" - -external get_numeral_string : context -> ast -> string - = "camlidl_z3V3_Z3_get_numeral_string" - -external get_numeral_decimal_string : context -> ast -> int -> string - = "camlidl_z3V3_Z3_get_numeral_decimal_string" - -external get_numerator : context -> ast -> ast - = "camlidl_z3V3_Z3_get_numerator" - -external get_denominator : context -> ast -> ast - = "camlidl_z3V3_Z3_get_denominator" - -external get_numeral_small : context -> ast -> bool * int64 * int64 - = "camlidl_z3V3_Z3_get_numeral_small" - -external get_numeral_int : context -> ast -> bool * int - = "camlidl_z3V3_Z3_get_numeral_int" - -external get_numeral_int64 : context -> ast -> bool * int64 - = "camlidl_z3V3_Z3_get_numeral_int64" - -external get_numeral_rational_int64 : context -> ast -> bool * int64 * int64 - = "camlidl_z3V3_Z3_get_numeral_rational_int64" - -external get_algebraic_number_lower : context -> ast -> int -> ast - = "camlidl_z3V3_Z3_get_algebraic_number_lower" - -external get_algebraic_number_upper : context -> ast -> int -> ast - = "camlidl_z3V3_Z3_get_algebraic_number_upper" - -external pattern_to_ast : context -> pattern -> ast - = "camlidl_z3V3_Z3_pattern_to_ast" - -external get_pattern_num_terms : context -> pattern -> int - = "camlidl_z3V3_Z3_get_pattern_num_terms" - -external get_pattern : context -> pattern -> int -> ast - = "camlidl_z3V3_Z3_get_pattern" - -external get_index_value : context -> ast -> int - = "camlidl_z3V3_Z3_get_index_value" - -external is_quantifier_forall : context -> ast -> bool - = "camlidl_z3V3_Z3_is_quantifier_forall" - -external get_quantifier_weight : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_weight" - -external get_quantifier_num_patterns : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_num_patterns" - -external get_quantifier_pattern_ast : context -> ast -> int -> pattern - = "camlidl_z3V3_Z3_get_quantifier_pattern_ast" - -external get_quantifier_num_no_patterns : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_num_no_patterns" - -external get_quantifier_no_pattern_ast : context -> ast -> int -> ast - = "camlidl_z3V3_Z3_get_quantifier_no_pattern_ast" - -external get_quantifier_num_bound : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_num_bound" - -external get_quantifier_bound_name : context -> ast -> int -> symbol - = "camlidl_z3V3_Z3_get_quantifier_bound_name" - -external get_quantifier_bound_sort : context -> ast -> int -> sort - = "camlidl_z3V3_Z3_get_quantifier_bound_sort" - -external get_quantifier_body : context -> ast -> ast - = "camlidl_z3V3_Z3_get_quantifier_body" - -external simplify : context -> ast -> ast - = "camlidl_z3V3_Z3_simplify" - -external update_term : context -> ast -> ast array -> ast - = "camlidl_z3V3_Z3_update_term" - -external substitute : context -> ast -> ast array -> ast array -> ast - = "camlidl_z3V3_Z3_substitute" - -external substitute_vars : context -> ast -> ast array -> ast - = "camlidl_z3V3_Z3_substitute_vars" - -external open_log : string -> bool - = "camlidl_z3V3_Z3_open_log" - -external append_log : string -> unit - = "camlidl_z3V3_Z3_append_log" - -external close_log : unit -> unit - = "camlidl_z3V3_Z3_close_log" - -external toggle_warning_messages : bool -> unit - = "camlidl_z3V3_Z3_toggle_warning_messages" - -external set_ast_print_mode : context -> ast_print_mode -> unit - = "camlidl_z3V3_Z3_set_ast_print_mode" - -external ast_to_string : context -> ast -> string - = "camlidl_z3V3_Z3_ast_to_string" - -external pattern_to_string : context -> pattern -> string - = "camlidl_z3V3_Z3_pattern_to_string" - -external sort_to_string : context -> sort -> string - = "camlidl_z3V3_Z3_sort_to_string" - -external func_decl_to_string : context -> func_decl -> string - = "camlidl_z3V3_Z3_func_decl_to_string" - -external model_to_string : context -> model -> string - = "camlidl_z3V3_Z3_model_to_string" - -external benchmark_to_smtlib_string : context -> string -> string -> string -> string -> ast array -> ast -> string - = "camlidl_z3V3_Z3_benchmark_to_smtlib_string_bytecode" "camlidl_z3V3_Z3_benchmark_to_smtlib_string" - -external parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3V3_Z3_parse_smtlib2_string_bytecode" "camlidl_z3V3_Z3_parse_smtlib2_string" - -external parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3V3_Z3_parse_smtlib2_file_bytecode" "camlidl_z3V3_Z3_parse_smtlib2_file" - -external parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3V3_Z3_parse_smtlib_string_bytecode" "camlidl_z3V3_Z3_parse_smtlib_string" - -external parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3V3_Z3_parse_smtlib_file_bytecode" "camlidl_z3V3_Z3_parse_smtlib_file" - -external get_smtlib_num_formulas : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_formulas" - -external get_smtlib_formula : context -> int -> ast - = "camlidl_z3V3_Z3_get_smtlib_formula" - -external get_smtlib_num_assumptions : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_assumptions" - -external get_smtlib_assumption : context -> int -> ast - = "camlidl_z3V3_Z3_get_smtlib_assumption" - -external get_smtlib_num_decls : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_decls" - -external get_smtlib_decl : context -> int -> func_decl - = "camlidl_z3V3_Z3_get_smtlib_decl" - -external get_smtlib_num_sorts : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_sorts" - -external get_smtlib_sort : context -> int -> sort - = "camlidl_z3V3_Z3_get_smtlib_sort" - -external get_smtlib_error : context -> string - = "camlidl_z3V3_Z3_get_smtlib_error" - -external get_version : unit -> int * int * int * int - = "camlidl_z3V3_Z3_get_version" - -external enable_trace : string -> unit - = "camlidl_z3V3_Z3_enable_trace" - -external disable_trace : string -> unit - = "camlidl_z3V3_Z3_disable_trace" - -external reset_memory : unit -> unit - = "camlidl_z3V3_Z3_reset_memory" - -external theory_mk_sort : context -> theory -> symbol -> sort - = "camlidl_z3V3_Z3_theory_mk_sort" - -external theory_mk_value : context -> theory -> symbol -> sort -> ast - = "camlidl_z3V3_Z3_theory_mk_value" - -external theory_mk_constant : context -> theory -> symbol -> sort -> ast - = "camlidl_z3V3_Z3_theory_mk_constant" - -external theory_mk_func_decl : context -> theory -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_theory_mk_func_decl" - -external theory_get_context : theory -> context - = "camlidl_z3V3_Z3_theory_get_context" - -external theory_assert_axiom : theory -> ast -> unit - = "camlidl_z3V3_Z3_theory_assert_axiom" - -external theory_assume_eq : theory -> ast -> ast -> unit - = "camlidl_z3V3_Z3_theory_assume_eq" - -external theory_enable_axiom_simplification : theory -> bool -> unit - = "camlidl_z3V3_Z3_theory_enable_axiom_simplification" - -external theory_get_eqc_root : theory -> ast -> ast - = "camlidl_z3V3_Z3_theory_get_eqc_root" - -external theory_get_eqc_next : theory -> ast -> ast - = "camlidl_z3V3_Z3_theory_get_eqc_next" - -external theory_get_num_parents : theory -> ast -> int - = "camlidl_z3V3_Z3_theory_get_num_parents" - -external theory_get_parent : theory -> ast -> int -> ast - = "camlidl_z3V3_Z3_theory_get_parent" - -external theory_is_value : theory -> ast -> bool - = "camlidl_z3V3_Z3_theory_is_value" - -external theory_is_decl : theory -> func_decl -> bool - = "camlidl_z3V3_Z3_theory_is_decl" - -external theory_get_num_elems : theory -> int - = "camlidl_z3V3_Z3_theory_get_num_elems" - -external theory_get_elem : theory -> int -> ast - = "camlidl_z3V3_Z3_theory_get_elem" - -external theory_get_num_apps : theory -> int - = "camlidl_z3V3_Z3_theory_get_num_apps" - -external theory_get_app : theory -> int -> ast - = "camlidl_z3V3_Z3_theory_get_app" - -external mk_injective_function : context -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_mk_injective_function" - -external set_logic : context -> string -> bool - = "camlidl_z3V3_Z3_set_logic" - -external push : context -> unit - = "camlidl_z3V3_Z3_push" - -external pop : context -> int -> unit - = "camlidl_z3V3_Z3_pop" - -external get_num_scopes : context -> int - = "camlidl_z3V3_Z3_get_num_scopes" - -external persist_ast : context -> ast -> int -> unit - = "camlidl_z3V3_Z3_persist_ast" - -external assert_cnstr : context -> ast -> unit - = "camlidl_z3V3_Z3_assert_cnstr" - -external check_and_get_model : context -> lbool * model - = "camlidl_z3V3_Z3_check_and_get_model" - -external check : context -> lbool - = "camlidl_z3V3_Z3_check" - -external check_assumptions : context -> ast array -> int -> ast array -> lbool * model * ast * int * ast array - = "camlidl_z3V3_Z3_check_assumptions" - -external del_model : context -> model -> unit - = "camlidl_z3V3_Z3_del_model" - -external soft_check_cancel : context -> unit - = "camlidl_z3V3_Z3_soft_check_cancel" - -external get_search_failure : context -> search_failure - = "camlidl_z3V3_Z3_get_search_failure" - -external mk_label : context -> symbol -> bool -> ast -> ast - = "camlidl_z3V3_Z3_mk_label" - -external get_relevant_labels : context -> literals - = "camlidl_z3V3_Z3_get_relevant_labels" - -external get_relevant_literals : context -> literals - = "camlidl_z3V3_Z3_get_relevant_literals" - -external get_guessed_literals : context -> literals - = "camlidl_z3V3_Z3_get_guessed_literals" - -external del_literals : context -> literals -> unit - = "camlidl_z3V3_Z3_del_literals" - -external get_num_literals : context -> literals -> int - = "camlidl_z3V3_Z3_get_num_literals" - -external get_label_symbol : context -> literals -> int -> symbol - = "camlidl_z3V3_Z3_get_label_symbol" - -external get_literal : context -> literals -> int -> ast - = "camlidl_z3V3_Z3_get_literal" - -external disable_literal : context -> literals -> int -> unit - = "camlidl_z3V3_Z3_disable_literal" - -external block_literals : context -> literals -> unit - = "camlidl_z3V3_Z3_block_literals" - -external get_model_num_constants : context -> model -> int - = "camlidl_z3V3_Z3_get_model_num_constants" - -external get_model_constant : context -> model -> int -> func_decl - = "camlidl_z3V3_Z3_get_model_constant" - -external get_model_num_funcs : context -> model -> int - = "camlidl_z3V3_Z3_get_model_num_funcs" - -external get_model_func_decl : context -> model -> int -> func_decl - = "camlidl_z3V3_Z3_get_model_func_decl" - -external eval_func_decl : context -> model -> func_decl -> bool * ast - = "camlidl_z3V3_Z3_eval_func_decl" - -external is_array_value : context -> model -> ast -> bool * int - = "camlidl_z3V3_Z3_is_array_value" - -external get_array_value : context -> model -> ast -> ast array -> ast array -> ast array * ast array * ast - = "camlidl_z3V3_Z3_get_array_value" - -external get_model_func_else : context -> model -> int -> ast - = "camlidl_z3V3_Z3_get_model_func_else" - -external get_model_func_num_entries : context -> model -> int -> int - = "camlidl_z3V3_Z3_get_model_func_num_entries" - -external get_model_func_entry_num_args : context -> model -> int -> int -> int - = "camlidl_z3V3_Z3_get_model_func_entry_num_args" - -external get_model_func_entry_arg : context -> model -> int -> int -> int -> ast - = "camlidl_z3V3_Z3_get_model_func_entry_arg" - -external get_model_func_entry_value : context -> model -> int -> int -> ast - = "camlidl_z3V3_Z3_get_model_func_entry_value" - -external eval : context -> model -> ast -> bool * ast - = "camlidl_z3V3_Z3_eval" - -external eval_decl : context -> model -> func_decl -> ast array -> bool * ast - = "camlidl_z3V3_Z3_eval_decl" - -external context_to_string : context -> string - = "camlidl_z3V3_Z3_context_to_string" - -external statistics_to_string : context -> string - = "camlidl_z3V3_Z3_statistics_to_string" - -external get_context_assignment : context -> ast - = "camlidl_z3V3_Z3_get_context_assignment" - - -(* Internal auxillary functions: *) -(* Transform a pair of arrays into an array of pairs *) -let array_combine a b = - if Array.length a <> Array.length b then raise (Invalid_argument "array_combine"); - Array.init (Array.length a) (fun i->(a.(i),b.(i)));; -(* [a |> b] is the pipeline operator for [b(a)] *) -let ( |> ) x f = f x;; -(* Extensions, except for refinement: *) -let mk_context_x configs = - let config = mk_config() in - let f(param_id,param_value) = set_param_value config param_id param_value in - Array.iter f configs; - let context = mk_context config in - del_config config; - context;; -let get_app_args c a = - Array.init (get_app_num_args c a) (get_app_arg c a);; -let get_domains c d = - Array.init (get_domain_size c d) (get_domain c d);; -let get_array_sort c t = (get_array_sort_domain c t, get_array_sort_range c t);; -let get_tuple_sort c ty = - (get_tuple_sort_mk_decl c ty, - Array.init (get_tuple_sort_num_fields c ty) (get_tuple_sort_field_decl c ty));; -type datatype_constructor_refined = { - constructor : func_decl; - recognizer : func_decl; - accessors : func_decl array -} -let get_datatype_sort c ty = - Array.init (get_datatype_sort_num_constructors c ty) - (fun idx_c -> - let constr = get_datatype_sort_constructor c ty idx_c in - let recog = get_datatype_sort_recognizer c ty idx_c in - let num_acc = get_domain_size c constr in - { constructor = constr; - recognizer = recog; - accessors = Array.init num_acc (get_datatype_sort_constructor_accessor c ty idx_c); - }) -let get_model_constants c m = - Array.init (get_model_num_constants c m) (get_model_constant c m);; -let get_model_func_entry c m i j = - (Array.init - (get_model_func_entry_num_args c m i j) - (get_model_func_entry_arg c m i j), - get_model_func_entry_value c m i j);; -let get_model_func_entries c m i = - Array.init (get_model_func_num_entries c m i) (get_model_func_entry c m i);; -let get_model_funcs c m = - Array.init (get_model_num_funcs c m) - (fun i->(get_model_func_decl c m i |> get_decl_name c, - get_model_func_entries c m i, - get_model_func_else c m i));; -let get_smtlib_formulas c = - Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c);; -let get_smtlib_assumptions c = - Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c);; -let get_smtlib_decls c = - Array.init (get_smtlib_num_decls c) (get_smtlib_decl c);; -let get_smtlib_parse_results c = - (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c);; -let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = - (parse_smtlib_string c a1 a2 a3 a4 a5; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith "Z3: parse_smtlib_string_formula");; -let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = - (parse_smtlib_file c a1 a2 a3 a4 a5; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith "Z3: parse_smtlib_file_formula");; -let parse_smtlib_string_x c a1 a2 a3 a4 a5 = - (parse_smtlib_string c a1 a2 a3 a4 a5; get_smtlib_parse_results c);; -let parse_smtlib_file_x c a1 a2 a3 a4 a5 = - (parse_smtlib_file c a1 a2 a3 a4 a5; get_smtlib_parse_results c);; -(* Refinement: *) -type symbol_refined = - | Symbol_int of int - | Symbol_string of string - | Symbol_unknown;; -let symbol_refine c s = - match get_symbol_kind c s with - | INT_SYMBOL -> Symbol_int (get_symbol_int c s) - | STRING_SYMBOL -> Symbol_string (get_symbol_string c s);; -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_real - | Sort_bv of int - | Sort_array of (sort * sort) - | Sort_datatype of datatype_constructor_refined array - | Sort_relation - | Sort_finite_domain - | Sort_unknown of symbol;; -let sort_refine c ty = - match get_sort_kind c ty with - | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c ty) - | BOOL_SORT -> Sort_bool - | INT_SORT -> Sort_int - | REAL_SORT -> Sort_real - | BV_SORT -> Sort_bv (get_bv_sort_size c ty) - | ARRAY_SORT -> Sort_array (get_array_sort_domain c ty, get_array_sort_range c ty) - | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c ty) - | RELATION_SORT -> Sort_relation - | FINITE_DOMAIN_SORT -> Sort_finite_domain - | UNKNOWN_SORT -> Sort_unknown (get_sort_name c ty);; -let get_pattern_terms c p = - Array.init (get_pattern_num_terms c p) (get_pattern c p) -type binder_type = | Forall | Exists -type numeral_refined = - | Numeral_small of int64 * int64 - | Numeral_large of string -type term_refined = - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol *sort) array * ast - | Term_numeral of numeral_refined * sort - | Term_var of int * sort -let term_refine c t = - match get_ast_kind c t with - | NUMERAL_AST -> - let (is_small, n, d) = get_numeral_small c t in - if is_small then - Term_numeral(Numeral_small(n,d), get_sort c t) - else - Term_numeral(Numeral_large(get_numeral_string c t), get_sort c t) - | APP_AST -> - let t' = to_app c t in - let f = get_app_decl c t' in - let num_args = get_app_num_args c t' in - let args = Array.init num_args (get_app_arg c t') in - let k = get_decl_kind c f in - Term_app (k, f, args) - | QUANTIFIER_AST -> - let bt = if is_quantifier_forall c t then Forall else Exists in - let w = get_quantifier_weight c t in - let np = get_quantifier_num_patterns c t in - let pats = Array.init np (get_quantifier_pattern_ast c t) in - let pats = Array.map (get_pattern_terms c) pats in - let nb = get_quantifier_num_bound c t in - let bound = Array.init nb - (fun i -> (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i)) in - let body = get_quantifier_body c t in - Term_quantifier(bt, w, pats, bound, body) - | VAR_AST -> - Term_var(get_index_value c t, get_sort c t) - | _ -> assert false -type theory_callbacks = - { - mutable delete_theory : unit -> unit; - mutable reduce_eq : ast -> ast -> ast option; - mutable reduce_app : func_decl -> ast array -> ast option; - mutable reduce_distinct : ast array -> ast option; - mutable final_check : unit -> bool; - mutable new_app : ast -> unit; - mutable new_elem : ast -> unit; - mutable init_search: unit -> unit; - mutable push: unit -> unit; - mutable pop: unit -> unit; - mutable restart : unit -> unit; - mutable reset: unit -> unit; - mutable new_eq : ast -> ast -> unit; - mutable new_diseq : ast -> ast -> unit; - mutable new_assignment: ast -> bool -> unit; - mutable new_relevant : ast -> unit; - } -let mk_theory_callbacks() = - { - delete_theory = (fun () -> ()); - reduce_eq = (fun _ _ -> None); - reduce_app = (fun _ _ -> None); - reduce_distinct = (fun _ -> None); - final_check = (fun _ -> true); - new_app = (fun _ -> ()); - new_elem = (fun _ -> ()); - init_search= (fun () -> ()); - push= (fun () -> ()); - pop= (fun () -> ()); - restart = (fun () -> ()); - reset= (fun () -> ()); - new_eq = (fun _ _ -> ()); - new_diseq = (fun _ _ -> ()); - new_assignment = (fun _ _ -> ()); - new_relevant = (fun _ -> ()); - } -external get_theory_callbacks : theory -> theory_callbacks = "get_theory_callbacks" -external mk_theory_register : context -> string -> theory_callbacks -> theory = "mk_theory_register" -external set_delete_callback_register : theory -> unit = "set_delete_callback_register" -external set_reduce_app_callback_register : theory -> unit = "set_reduce_app_callback_register" -external set_reduce_eq_callback_register : theory -> unit = "set_reduce_eq_callback_register" -external set_reduce_distinct_callback_register : theory -> unit = "set_reduce_distinct_callback_register" -external set_new_app_callback_register : theory -> unit = "set_new_app_callback_register" -external set_new_elem_callback_register : theory -> unit = "set_new_elem_callback_register" -external set_init_search_callback_register : theory -> unit = "set_init_search_callback_register" -external set_push_callback_register : theory -> unit = "set_push_callback_register" -external set_pop_callback_register : theory -> unit = "set_pop_callback_register" -external set_restart_callback_register : theory -> unit = "set_restart_callback_register" -external set_reset_callback_register : theory -> unit = "set_reset_callback_register" -external set_final_check_callback_register : theory -> unit = "set_final_check_callback_register" -external set_new_eq_callback_register : theory -> unit = "set_new_eq_callback_register" -external set_new_diseq_callback_register : theory -> unit = "set_new_diseq_callback_register" -external set_new_assignment_callback_register : theory -> unit = "set_new_assignment_callback_register" -external set_new_relevant_callback_register : theory -> unit = "set_new_relevant_callback_register" -let is_some opt = - match opt with - | Some v -> true - | None -> false -let get_some opt = - match opt with - | Some v -> v - | None -> failwith "None unexpected" -let apply_delete (th:theory_callbacks) = th.delete_theory () -let set_delete_callback th cb = - let cbs = get_theory_callbacks th in - cbs.delete_theory <- cb; - set_delete_callback_register th -let mk_theory context name = - Callback.register "is_some" is_some; - Callback.register "get_some" get_some; - Callback.register "apply_delete" apply_delete; - let cbs = mk_theory_callbacks() in - mk_theory_register context name cbs -let apply_reduce_app (th:theory_callbacks) f args = th.reduce_app f args -let set_reduce_app_callback th cb = - Callback.register "apply_reduce_app" apply_reduce_app; - let cbs = get_theory_callbacks th in - cbs.reduce_app <- cb; - set_reduce_app_callback_register th -let apply_reduce_eq (th:theory_callbacks) a b = th.reduce_eq a b -let set_reduce_eq_callback th cb = - Callback.register "apply_reduce_eq" apply_reduce_eq; - let cbs = get_theory_callbacks th in - cbs.reduce_eq <- cb; - set_reduce_eq_callback_register th -let apply_reduce_distinct (th:theory_callbacks) args = th.reduce_distinct args -let set_reduce_distinct_callback th cb = - Callback.register "apply_reduce_distinct" apply_reduce_distinct; - let cbs = get_theory_callbacks th in - cbs.reduce_distinct <- cb; - set_reduce_distinct_callback_register th -let apply_new_app (th:theory_callbacks) a = th.new_app a -let set_new_app_callback th cb = - Callback.register "apply_new_app" apply_new_app; - let cbs = get_theory_callbacks th in - cbs.new_app <- cb; - set_new_app_callback_register th -let apply_new_elem (th:theory_callbacks) a = th.new_elem a -let set_new_elem_callback th cb = - Callback.register "apply_new_elem" apply_new_elem; - let cbs = get_theory_callbacks th in - cbs.new_elem <- cb; - set_new_elem_callback_register th -let apply_init_search (th:theory_callbacks) = th.init_search() -let set_init_search_callback th cb = - Callback.register "apply_init_search" apply_init_search; - let cbs = get_theory_callbacks th in - cbs.init_search <- cb; - set_init_search_callback_register th -let apply_push (th:theory_callbacks) = th.push() -let set_push_callback th cb = - Callback.register "apply_push" apply_push; - let cbs = get_theory_callbacks th in - cbs.push <- cb; - set_push_callback_register th -let apply_pop (th:theory_callbacks) = th.pop() -let set_pop_callback th cb = - Callback.register "apply_pop" apply_pop; - let cbs = get_theory_callbacks th in - cbs.pop <- cb; - set_pop_callback_register th -let apply_restart (th:theory_callbacks) = th.restart() -let set_restart_callback th cb = - Callback.register "apply_restart" apply_restart; - let cbs = get_theory_callbacks th in - cbs.restart <- cb; - set_restart_callback_register th -let apply_reset (th:theory_callbacks) = th.reset() -let set_reset_callback th cb = - Callback.register "apply_reset" apply_reset; - let cbs = get_theory_callbacks th in - cbs.reset <- cb; - set_reset_callback_register th -let apply_final_check (th:theory_callbacks) = th.final_check() -let set_final_check_callback th cb = - Callback.register "apply_final_check" apply_final_check; - let cbs = get_theory_callbacks th in - cbs.final_check <- cb; - set_final_check_callback_register th -let apply_new_eq (th:theory_callbacks) a b = th.new_eq a b -let set_new_eq_callback th cb = - Callback.register "apply_new_eq" apply_new_eq; - let cbs = get_theory_callbacks th in - cbs.new_eq <- cb; - set_new_eq_callback_register th -let apply_new_diseq (th:theory_callbacks) a b = th.new_diseq a b -let set_new_diseq_callback th cb = - Callback.register "apply_new_diseq" apply_new_diseq; - let cbs = get_theory_callbacks th in - cbs.new_diseq <- cb; - set_new_diseq_callback_register th -let apply_new_assignment (th:theory_callbacks) a b = th.new_assignment a b -let set_new_assignment_callback th cb = - Callback.register "apply_new_assignment" apply_new_assignment; - let cbs = get_theory_callbacks th in - cbs.new_assignment <- cb; - set_new_assignment_callback_register th -let apply_new_relevant (th:theory_callbacks) a = th.new_relevant a -let set_new_relevant_callback th cb = - Callback.register "apply_new_relevant" apply_new_relevant; - let cbs = get_theory_callbacks th in - cbs.new_relevant <- cb; - set_new_relevant_callback_register th - - -end - -======= (* Copyright (C) 2012 Microsoft Corporation Author: CM Wintersteiger (cwinter) 2012-12-17 @@ -3410,48 +23,42 @@ end class context settings = object (self) inherit idisposable - val mutable m_n_ctx : Z3native.z3_context option = None + + val mutable m_n_ctx : Z3native.z3_context = + let cfg = mk_config() in + let f e = (set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = mk_context_rc cfg in + del_config(cfg) ; + v + val mutable m_refCount : int = 0 - initializer - let cfg = mk_config() in - (match settings with - | Some(x) -> - let f e = (set_param_value cfg (fst e) (snd e)) in - (List.iter f x) - | _ -> () - ) ; - m_n_ctx <- Some (mk_context_rc cfg) ; - del_config(cfg) ; - Gc.finalise (fun self -> self#dispose) self + initializer Gc.finalise (fun self -> self#dispose) self method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing %d \n" (Oo.id self) ; - match m_n_ctx with - | Some(x) -> (del_context x) - | None -> () + (del_context m_n_ctx) ) else ( (* re-queue for finalization? *) ) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 method add_one_ctx_obj = m_refCount <- m_refCount + 1 + method get_native = m_n_ctx end class virtual z3object ctx_init obj_init = object (self) inherit idisposable - val mutable m_ctx : context option = ctx_init + val mutable m_ctx : context = ctx_init val mutable m_n_obj : Z3native.ptr option = obj_init initializer (match m_n_obj with | Some (x) -> self#incref x; - (match m_ctx with - | Some(x) -> x#add_one_ctx_obj - | None -> () - ) + m_ctx#add_one_ctx_obj | None -> () ); Gc.finalise (fun self -> self#dispose) self @@ -3465,15 +72,9 @@ object (self) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with - | Some (x) -> self#decref x; m_n_obj <- None + | Some (x) -> self#decref x; m_n_obj <- None; m_ctx#sub_one_ctx_obj | None -> () ); - (match m_ctx with - | Some (x) -> x#sub_one_ctx_obj - | None -> () - ); - m_ctx <- None - method get_native_object = m_n_obj @@ -3489,6 +90,7 @@ object (self) m_n_obj <- x method get_context = m_ctx + method get_native_context = m_ctx#get_native (* method array_to_native a = @@ -3500,11 +102,59 @@ object (self) | Some(x) -> (Array.length x) | None -> 0 *) +end + +class symbol ctx_init obj_init = +object (self) + inherit z3object ctx_init obj_init + + method incref o = () + method decref o = () + + method kind = match m_n_obj with + | Some(x) -> (int2symbol_kind (get_symbol_kind self#get_native_context x)) + | _ -> raise (Exception "Underlying object lost") + + method is_int_symbol = match m_n_obj with + | Some(x) -> self#kind == INT_SYMBOL + | _ -> false + + method is_string_symbol = match m_n_obj with + | Some(x) -> self#kind == STRING_SYMBOL + | _ -> false + + method to_string = match m_n_obj with + | Some(x) -> + ( + match self#kind with + | INT_SYMBOL -> (string_of_int (get_symbol_int self#get_native_context x)) + | STRING_SYMBOL -> (get_symbol_string self#get_native_context x) + ) + | None -> "" + + method create ctx obj = + match obj with + | Some(x) -> ( + match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with + | INT_SYMBOL -> (new intsymbol ctx obj :> symbol) + | STRING_SYMBOL -> (new stringsymbol ctx obj :> symbol) + ) + | None -> raise (Exception "Can't create null objects") end -<<<<<<< HEAD end ->>>>>>> More new ML API. -======= ->>>>>>> More ML API + +and intsymbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init + + method get_int = match m_n_obj with + | Some(x) -> (get_symbol_int m_ctx#get_native x) + | None -> 0 +end + +and stringsymbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end From b193b827ed05770ee5171093a75a1a1cde8b05bc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 04:10:38 +0000 Subject: [PATCH 235/507] ML API bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 20 +++++-- scripts/update_api.py | 21 +++++-- src/api/ml/z3.ml | 121 ++++++++++++++++++++++---------------- 3 files changed, 101 insertions(+), 61 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 9c704e4d0..c79b3cdaa 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,11 +4,19 @@ *) open Z3 - -let _ = ignore(Log.open_ "z3.log") ; - let cfg = Some [("model", "true"); ("proof", "false")] in - let ctx = (new context cfg) in - Printf.printf "Disposing...\n"; - ctx#dispose ; + +exception ExampleException of string + +let _ = + if not (Log.open_ "z3.log") then + raise (ExampleException "Log couldn't be opened.") + else + ( + Printf.printf "Running Z3 version %s\n" Version.to_string ; + let cfg = [("model", "true"); ("proof", "false")] in + let ctx = (new context cfg) in + Printf.printf "Disposing...\n"; + ctx#dispose (* can do, but we'd rather let it go out of scope *) ; + ); Printf.printf "Exiting.\n"; ;; diff --git a/scripts/update_api.py b/scripts/update_api.py index 9eb7d1405..25adce2af 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -325,7 +325,9 @@ def param2pystr(p): def param2ml(p): k = param_kind(p) if k == OUT: - if param_type(p) == STRING: + if param_type(p) == INT or param_type(p) == UINT or param_type(p) == INT64 or param_type(p) == UINT64: + return "int" + elif param_type(p) == STRING: return "string" else: return "ptr" @@ -1124,9 +1126,16 @@ def mk_ml(): ml_native.write('%s -> ' % param2ml(p)) if len(op) > 0: ml_native.write('(') - ml_native.write('%s' % type2ml(result)) + first = True + if result != VOID or len(op) == 0: + ml_native.write('%s' % type2ml(result)) + first = False for p in op: - ml_native.write(' * %s' % param2ml(p)) + if first: + first = False + else: + ml_native.write(' * ') + ml_native.write('%s' % param2ml(p)) if len(op) > 0: ml_native.write(')') ml_native.write('\n') @@ -1153,11 +1162,13 @@ def mk_ml(): i = i + 1 ml_native.write(' = \n') ml_native.write(' ') - if result == VOID: + if result == VOID and len(op) == 0: ml_native.write('let _ = ') else: ml_native.write('let res = ') ml_native.write('(ML2C.n_%s' % (ml_method_name(name))) + if len(ip) == 0: + ml_native.write(' ()') first = True i = 0; for p in params: @@ -1170,7 +1181,7 @@ def mk_ml(): ml_native.write(' if err <> OK then\n') ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (error_code2int err)))\n') ml_native.write(' else\n') - if result == VOID: + if result == VOID and len(op) == 0: ml_native.write(' ()\n') else: ml_native.write(' res\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 55ffd91e8..31bb7e5fc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -9,12 +9,27 @@ open Z3native module Log = struct let m_is_open = false - (* CMW: "open" seems to be an invalid function name*) - let open_ fn = int2lbool(open_log fn) == L_TRUE - let close = (close_log) - let append s = (append_log s) + (* CMW: "open" seems to be an invalid function name*) + let open_ fn = let rv = (open_log fn) in + Printf.printf "ol returned %d\n" rv ; + ((int2lbool rv) == L_TRUE) + let close = close_log + let append s = append_log s end - + +module Version = +struct + let major = let (x, _, _, _) = get_version in x + let minor = let (_, x, _, _) = get_version in x + let build = let (_, _, x, _) = get_version in x + let revision = let (_, _, _, x) = get_version in x + let to_string = + string_of_int major ^ "." ^ + string_of_int minor ^ "." ^ + string_of_int build ^ "." ^ + string_of_int revision ^ "." +end + class virtual idisposable = object method virtual dispose : unit @@ -25,7 +40,7 @@ object (self) inherit idisposable val mutable m_n_ctx : Z3native.z3_context = - let cfg = mk_config() in + let cfg = mk_config in let f e = (set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = mk_context_rc cfg in @@ -34,14 +49,15 @@ object (self) val mutable m_refCount : int = 0 - initializer Gc.finalise (fun self -> self#dispose) self + initializer + Gc.finalise (fun self -> self#dispose) self method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing %d \n" (Oo.id self) ; (del_context m_n_ctx) ) else ( - (* re-queue for finalization? *) + (* re-queue for finalization? *) ) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 @@ -66,9 +82,9 @@ object (self) method virtual incref : Z3native.ptr -> unit method virtual decref : Z3native.ptr -> unit - (* - Disposes of the underlying native Z3 object. - *) + (* + Disposes of the underlying native Z3 object. + *) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with @@ -92,16 +108,17 @@ object (self) method get_context = m_ctx method get_native_context = m_ctx#get_native - (* - method array_to_native a = +(* + method array_to_native a = let f e = e#get_native_object in (Array.map f a) - method array_length a = + method array_length a = match a with - | Some(x) -> (Array.length x) - | None -> 0 - *) + | Some(x) -> (Array.length x) + | None -> 0 +*) + end class symbol ctx_init obj_init = @@ -110,51 +127,55 @@ object (self) method incref o = () method decref o = () +end - method kind = match m_n_obj with - | Some(x) -> (int2symbol_kind (get_symbol_kind self#get_native_context x)) - | _ -> raise (Exception "Underlying object lost") +class int_symbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end - method is_int_symbol = match m_n_obj with - | Some(x) -> self#kind == INT_SYMBOL - | _ -> false +class string_symbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end - method is_string_symbol = match m_n_obj with - | Some(x) -> self#kind == STRING_SYMBOL - | _ -> false - - method to_string = match m_n_obj with - | Some(x) -> - ( - match self#kind with - | INT_SYMBOL -> (string_of_int (get_symbol_int self#get_native_context x)) - | STRING_SYMBOL -> (get_symbol_string self#get_native_context x) - ) - | None -> "" - - method create ctx obj = +module Symbol = +struct + let create ctx obj = match obj with | Some(x) -> ( match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with - | INT_SYMBOL -> (new intsymbol ctx obj :> symbol) - | STRING_SYMBOL -> (new stringsymbol ctx obj :> symbol) + | INT_SYMBOL -> (new int_symbol ctx obj :> symbol) + | STRING_SYMBOL -> (new string_symbol ctx obj :> symbol) ) | None -> raise (Exception "Can't create null objects") -end + let kind o = match o#m_n_obj with + | Some(x) -> (int2symbol_kind (get_symbol_kind o#get_native_context x)) + | _ -> raise (Exception "Underlying object lost") -end + let is_int_symbol o = match o#m_n_obj with + | Some(x) -> x#kind == INT_SYMBOL + | _ -> false -and intsymbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init + let is_string_symbol o = match o#m_n_obj with + | Some(x) -> x#kind == STRING_SYMBOL + | _ -> false - method get_int = match m_n_obj with - | Some(x) -> (get_symbol_int m_ctx#get_native x) + let get_int o = match o#m_n_obj with + | Some(x) -> (get_symbol_int o#get_native_context x) | None -> 0 -end -and stringsymbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init + let get_string o = match o#m_n_obj with + | Some(x) -> (get_symbol_string o#get_native_context x) + | None -> "" + + let to_string o = match o#m_n_obj with + | Some(x) -> + ( + match (kind o) with + | INT_SYMBOL -> (string_of_int (get_symbol_int o#get_native_context x)) + | STRING_SYMBOL -> (get_symbol_string o#get_native_context x) + ) + | None -> "" end From e87feb8e456e91d05a14dee17d62f9cf1c531e27 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 04:12:41 +0000 Subject: [PATCH 236/507] added temporary Makefile for ML annotations. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/api/ml/Makefile diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile new file mode 100644 index 000000000..f97a2dc30 --- /dev/null +++ b/src/api/ml/Makefile @@ -0,0 +1,6 @@ +# This is a temporary support file for emacs annotations. +# It does not compile the Z3 ML API; this will be built +# in the top-level build directory. + +all: + ocamlbuild -cflag -annot z3.cmxa \ No newline at end of file From 518da6b6e2b70ec17bda199f589d316605857fc1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 19:08:23 +0000 Subject: [PATCH 237/507] move old files Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/{ => old}/README-linux | 0 src/api/ml/{ => old}/README-osx | 0 src/api/ml/{ => old}/README-test-linux | 0 src/api/ml/{ => old}/README-test-osx | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/api/ml/{ => old}/README-linux (100%) rename src/api/ml/{ => old}/README-osx (100%) rename src/api/ml/{ => old}/README-test-linux (100%) rename src/api/ml/{ => old}/README-test-osx (100%) diff --git a/src/api/ml/README-linux b/src/api/ml/old/README-linux similarity index 100% rename from src/api/ml/README-linux rename to src/api/ml/old/README-linux diff --git a/src/api/ml/README-osx b/src/api/ml/old/README-osx similarity index 100% rename from src/api/ml/README-osx rename to src/api/ml/old/README-osx diff --git a/src/api/ml/README-test-linux b/src/api/ml/old/README-test-linux similarity index 100% rename from src/api/ml/README-test-linux rename to src/api/ml/old/README-test-linux diff --git a/src/api/ml/README-test-osx b/src/api/ml/old/README-test-osx similarity index 100% rename from src/api/ml/README-test-osx rename to src/api/ml/old/README-test-osx From 8e83f8d034949f3f4918267b014b647a3458d9c8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 20:51:18 +0000 Subject: [PATCH 238/507] ML build system checks Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 62 +++++++++++++++++++++++++++++++++++++++++++--- src/api/ml/z3.ml | 8 +++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index da7d22d54..8848d4ce4 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -32,6 +32,10 @@ CXXFLAGS=getenv("CXXFLAGS", "") EXAMP_DEBUG_FLAG='' LDFLAGS=getenv("LDFLAGS", "") JNI_HOME=getenv("JNI_HOME", None) +OCAMLC=getenv("OCAMLC", "ocamlc") +OCAMLOPT=getenv("OCAMLC", "ocamlopt") +OCAMLBUILD=getenv("OCAMLBUILD", "ocamlbuild") +OCAML_LIB=getenv("OCAML_LIB", None) CXX_COMPILERS=['g++', 'clang++'] C_COMPILERS=['gcc', 'clang'] @@ -335,6 +339,43 @@ def check_java(): if JNI_HOME == None: raise MKException("Failed to detect jni.h. Possible solution: set JNI_HOME with the path to JDK.") +def check_ml(): + t = TempFile('hello.ml') + t.add('print_string "Hello world!\n";;') + t.commit() + if is_verbose(): + print "Testing %s..." % OCAMLC + r = exec_cmd([OCAMLC, 'hello.ml']) + if r != 0: + raise MKException('Failed testing ocamlc compiler. Set environment variable OCAMLC with the path to the Ocaml compiler') + if is_verbose(): + print "Testing %s..." % OCAMLOPT + r = exec_cmd([OCAMLC, 'hello.ml']) + if r != 0: + raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler') + r = exec_cmd([OCAMLBUILD]) + if r != 0: + raise MKException('Failed testing ocamlbuild. Set environment variable OCAMLBUILD with the path to ocamlbuild') + find_ml_lib() + +def find_ml_lib(): + global OCAML_LIB + if is_verbose(): + print "Finding OCAML_LIB..." + t = TempFile('output') + null = open(os.devnull, 'wb') + try: + subprocess.call([OCAMLC, '-where'], stdout=t.fname, stderr=null) + t.commit() + except: + raise MKException('Failed to find Ocaml library; please set OCAML_LIB') + t = open('output', 'r') + for line in t: + OCAML_LIB = line[:-1] + if is_verbose(): + print 'OCAML_LIB=%s' % OCAML_LIB + return + def is64(): return sys.maxsize >= 2**32 @@ -474,6 +515,10 @@ def display_help(exit_code): print(" CXXFLAGS C++ compiler flags") print(" JDK_HOME JDK installation directory (only relevant if -j or --java option is provided)") print(" JNI_HOME JNI bindings directory (only relevant if -j or --java option is provided)") + print(" OCAMLC Ocaml byte-code compiler (only relevant with --ml)") + print(" OCAMLOPT Ocaml native compiler (only relevant with --ml)") + print(" OCAMLBUILD Ocaml build system (only relevant with --ml)") + print(" OCAML_LIB Ocaml library directory (only relevant with --ml)") exit(exit_code) # Parse configuration option for mk_make script @@ -1300,7 +1345,7 @@ class MLComponent(Component): for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) out.write('z3.cmxa: %s\n' % libfile) out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) @@ -1438,7 +1483,7 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example($EXE_EXT): z3.cmxa ') + out.write('ml_example($EXE_EXT): z3.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') @@ -1596,6 +1641,11 @@ def mk_config(): if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) + if is_ml_enabled(): + print('Ocaml Compiler: %s' % OCAMLC) + print('Ocaml Native: %s' % OCAMLOPT) + print('Ocamlbuild: %s' % OCAMLBUILD) + print('Ocaml Library: %s' % OCAML_LIB) else: global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG OS_DEFINES = "" @@ -1715,7 +1765,12 @@ def mk_config(): if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) - + if is_ml_enabled(): + print('Ocaml Compiler: %s' % OCAMLC) + print('Ocaml Native: %s' % OCAMLOPT) + print('Ocamlbuild: %s' % OCAMLBUILD) + print('Ocaml Library: %s' % OCAML_LIB) + def mk_install(out): out.write('install: ') for c in get_components(): @@ -2280,6 +2335,7 @@ def mk_bindings(api_files): check_java() mk_z3consts_java(api_files) if is_ml_enabled(): + check_ml() mk_z3consts_ml(api_files) _execfile(os.path.join('scripts', 'update_api.py'), g) # HACK cp_z3py_to_build() diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 31bb7e5fc..d901d09ef 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -10,11 +10,9 @@ module Log = struct let m_is_open = false (* CMW: "open" seems to be an invalid function name*) - let open_ fn = let rv = (open_log fn) in - Printf.printf "ol returned %d\n" rv ; - ((int2lbool rv) == L_TRUE) - let close = close_log - let append s = append_log s + let open_ fn = int2lbool(open_log fn) == L_TRUE + let close = (close_log) + let append s = (append_log s) end module Version = From 7efe7a2c16ad26a7021e7b0619a4450be2f8e6c7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 21 Dec 2012 03:02:12 +0000 Subject: [PATCH 239/507] ML native layer bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/Makefile | 7 ++ scripts/mk_util.py | 2 +- scripts/update_api.py | 165 +++++++++++++++++++++++++----------------- src/api/ml/z3.ml | 11 +-- 4 files changed, 113 insertions(+), 72 deletions(-) create mode 100644 examples/ml/Makefile diff --git a/examples/ml/Makefile b/examples/ml/Makefile new file mode 100644 index 000000000..4b3e7c4d2 --- /dev/null +++ b/examples/ml/Makefile @@ -0,0 +1,7 @@ +# This is a temporary support file for emacs annotations. +# It does not compile the Z3 ML example; this will be built +# in the top-level build directory. + +all: + OCAML_COMPAT=c ocamlc -g -annot -o ml_example.byte -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cma ml_example.ml + ocamlopt -g -annot -o ml_example -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cmxa ml_example.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8848d4ce4..b6cf4dedc 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2699,7 +2699,7 @@ def mk_z3consts_ml(api_files): idx = idx + 1 linenum = linenum + 1 if VERBOSE: - print "Generated '%s/enumerations.ml'" % ('%s' % gendir) + print "Generated '%s/z3enums.ml'" % ('%s' % gendir) def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 25adce2af..d0ef2ec86 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1,3 +1,4 @@ + ############################################ # Copyright (c) 2012 Microsoft Corporation # @@ -1097,6 +1098,45 @@ def is_array_param(p): else: return False +def arrayparams(params): + op = [] + for param in params: + if is_array_param(param): + op.append(param) + return op + + +def ml_unwrap(t): + if t == STRING: + return 'String_val' + elif t == BOOL or t == INT or PRINT_MODE or ERROR_CODE: + return 'Int_val' + elif t == UINT: + return 'Unsigned_int_val' + elif t == INT64: + return 'Long_val' + elif t == UINT64: + return 'Unsigned_long_val' + elif t == DOUBLE: + return 'Double_val' + else: + return 'Data_custom_val' + +def ml_set_wrap(t, d, n): + if t == VOID: + return d + ' = Val_unit;' + elif t == BOOL or t == INT or t == UINT or PRINT_MODE or ERROR_CODE: + return d + ' = Val_int(' + n + ');' + elif t == INT64 or t == UINT64: + return d + ' = Val_long(' + n + ');' + elif t == DOUBLE: + return 'Store_double_val(' + d + ', ' + n + ');' + elif t == STRING: + return d + ' = caml_copy_string((const char*) ' + n + ');' + else: + ts = type2str(t) + return d + ' = caml_alloc_custom(0, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' + def mk_ml(): global Type2Str if not is_ml_enabled(): @@ -1242,15 +1282,12 @@ def mk_ml(): for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) + ap = arrayparams(params) ret_size = len(op) if result != VOID: ret_size = ret_size + 1 # Setup frame - n_locals = 0 - for p in params: - if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): - n_locals = n_locals + 1 ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) first = True i = 0 @@ -1276,46 +1313,50 @@ def mk_ml(): i = i + 1 ml_wrapper.write(');\n') i = 0 - first = True - if result != VOID: - n_locals = n_locals + 1 - if ret_size > 1: - n_locals = n_locals + 1 - if n_locals > 0: - ml_wrapper.write(' CAMLlocal%s(' % (n_locals)) - if ret_size > 1: - if result != VOID: - ml_wrapper.write('result, ') - ml_wrapper.write('result_tuple') - first = False - elif result != VOID: - ml_wrapper.write('result') - first = False + if len(op) + len(ap) == 0: + ml_wrapper.write(' CAMLlocal1(result);\n') + else: + c = 0 for p in params: - if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('_a%s' % i) + if is_out_param(p) or is_array_param(p): + c = c + 1 + ml_wrapper.write(' CAMLlocal%s(result, res_val' % (c+2)) + for p in params: + if is_out_param(p) or is_array_param(p): + ml_wrapper.write(', _a%s_val' % i) i = i + 1 ml_wrapper.write(');\n') # preprocess arrays, strings, in/out arguments i = 0 for param in params: - if param_kind(param) == OUT_ARRAY: - ml_wrapper.write(' _a%s = (long) malloc(sizeof(%s) * ((long)a%s));\n' % (i, - type2str(param_type(param)), - param_array_capacity_pos(param))) - elif param_kind(param) == IN and param_type(param) == STRING: - ml_wrapper.write(' _a%s = (value) String_val(a%s);\n' % (i, i)) + k = param_kind(param) + if k == OUT_ARRAY: + ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * (_a%s));\n' % ( + type2str(param_type(param)), + i, + type2str(param_type(param)), + type2str(param_type(param)), + param_array_capacity_pos(param))) + elif k == IN_ARRAY or k == INOUT_ARRAY: + t = param_type(param) + ts = type2str(t) + ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) + ml_wrapper.write(' for (unsigned i = 0; i < a%s; i++) _a%s[i] = (%s) %s(Field(a%s, i));\n' % (param_array_capacity_pos(param), i, ts, ml_unwrap(t), i)) + elif k == IN: + t = param_type(param) + ml_wrapper.write(' %s _a%s = (%s) %s(a%s);\n' % (type2str(t), i, type2str(t), ml_unwrap(t), i)) + elif k == OUT: + ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) + elif k == INOUT: + ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) + i = i + 1 # invoke procedure ml_wrapper.write(' ') if result != VOID: - ml_wrapper.write('result = (value) ') + ml_wrapper.write('%s z3_result = ' % type2str(result)) ml_wrapper.write('%s(' % name) i = 0 first = True @@ -1326,58 +1367,50 @@ def mk_ml(): ml_wrapper.write(', ') k = param_kind(param) if k == OUT or k == INOUT: - ml_wrapper.write('(%s)&_a%s' % (param2str(param), i)) - elif k == INOUT_ARRAY or k == IN_ARRAY: - ml_wrapper.write('(%s*)a%s' % (type2str(param_type(param)), i)) - elif k == OUT_ARRAY: - ml_wrapper.write('(%s*)_a%s' % (type2str(param_type(param)), i)) - elif k == IN and param_type(param) == STRING: - ml_wrapper.write('(Z3_string) _a%s' % i) + ml_wrapper.write('&_a%s' % i) else: - ml_wrapper.write('(%s)a%i' % (param2str(param), i)) + ml_wrapper.write('_a%i' % i) i = i + 1 ml_wrapper.write(');\n') - # return tuples + # convert output params if len(op) > 0: - ml_wrapper.write(' result_tuple = caml_alloc(%s, 0);\n' % ret_size) + if result != VOID: + ml_wrapper.write(' %s\n' % ml_set_wrap(result, "res_val", "z3_result")) + i = 0; + for p in params: + if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: + ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) + ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) { value t; %s Store_field(_a%s, i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[i]'), i)) + elif is_out_param(p): + ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) + i = i + 1 + + # return tuples + if len(op) == 0: + ml_wrapper.write(' %s\n' % ml_set_wrap(result, "result", "z3_result")) + else: + ml_wrapper.write(' result = caml_alloc(%s, 0);\n' % ret_size) i = j = 0 if result != VOID: - if result == STRING: - ml_wrapper.write(' Store_field(result_tuple, 0, caml_copy_string(result));\n') - else: - ml_wrapper.write(' Store_field(result_tuple, 0, result);\n') + ml_wrapper.write(' Store_field(result, 0, res_val);\n') j = j + 1 for p in params: - if param_kind(p) == OUT_ARRAY or param_kind(p) == OUT: - ml_wrapper.write(' Store_field(result_tuple, %s, _a%s);\n' % (j, i)) - j = j + 1; - elif is_out_param(p): - if param_type(p) == STRING: - ml_wrapper.write(' Store_field(result_tuple, %s, caml_copy_string((const char *)_a%s));\n' % (j, i)) - else: - ml_wrapper.write(' Store_field(result_tuple, %s, a%s);\n' % (j, i)) + if is_out_param(p): + ml_wrapper.write(' Store_field(result, %s, _a%s_val);\n' % (j, i)) j = j + 1; i = i + 1 # local array cleanup i = 0 for p in params: - if param_kind(p) == OUT_ARRAY: - ml_wrapper.write(' free((long*)_a%s);\n' % i) + k = param_kind(p) + if k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: + ml_wrapper.write(' free(_a%s);\n' % i) i = i + 1 # return - if len(op) > 0: - ml_wrapper.write(' CAMLreturn(result_tuple);\n') - else: - if result == STRING: - ml_wrapper.write(' CAMLreturn(caml_copy_string((const char*) result));\n') - elif result == VOID: - ml_wrapper.write(' CAMLreturn(Val_unit);\n') - elif result != VOID: - ml_wrapper.write(' CAMLreturn(result);\n') - + ml_wrapper.write(' CAMLreturn(result);\n') ml_wrapper.write('}\n\n') if len(ip) > 5: ml_wrapper.write('CAMLprim value n_%s_bytecode(value * argv, int argn) {\n' % ml_method_name(name)) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index d901d09ef..cc1429f14 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -22,10 +22,11 @@ struct let build = let (_, _, x, _) = get_version in x let revision = let (_, _, _, x) = get_version in x let to_string = - string_of_int major ^ "." ^ - string_of_int minor ^ "." ^ - string_of_int build ^ "." ^ - string_of_int revision ^ "." + let (mj, mn, bld, rev) = get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." end class virtual idisposable = @@ -52,7 +53,7 @@ object (self) method dispose : unit = if m_refCount == 0 then ( - Printf.printf "Disposing %d \n" (Oo.id self) ; + Printf.printf "Disposing context %d \n" (Oo.id self) ; (del_context m_n_ctx) ) else ( (* re-queue for finalization? *) From 794823ba6d149561eec5c168cc8e7cd9d9a1387c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 21 Dec 2012 07:18:46 +0000 Subject: [PATCH 240/507] More ML API: Fixes in native layer. Added symbols. Prepared code for automatic documentation. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 5 ++ scripts/mk_util.py | 4 + scripts/update_api.py | 37 ++++++--- src/api/ml/z3.ml | 168 ++++++++++++++++++++++++++------------ 4 files changed, 151 insertions(+), 63 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index c79b3cdaa..7046a92b0 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,6 +4,7 @@ *) open Z3 +open Z3.Context exception ExampleException of string @@ -15,6 +16,10 @@ let _ = Printf.printf "Running Z3 version %s\n" Version.to_string ; let cfg = [("model", "true"); ("proof", "false")] in let ctx = (new context cfg) in + let is = (mk_symbol_int ctx 42) in + let ss = (mk_symbol_string ctx "mySymbol") in + Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); + Printf.printf "string symbol: %s\n" (Symbol.to_string (ss :> symbol)); Printf.printf "Disposing...\n"; ctx#dispose (* can do, but we'd rather let it go out of scope *) ; ); diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b6cf4dedc..68493b7b6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2628,6 +2628,7 @@ def mk_z3consts_ml(api_files): efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') + efile.write('(** The enumeration types of Z3. *)\n\n') for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) @@ -2673,15 +2674,18 @@ def mk_z3consts_ml(api_files): if m: name = words[1] if name not in DeprecatedEnums: + efile.write('(** %s *)\n' % name[3:]) efile.write('type %s =\n' % name[3:]) # strip Z3_ for k, i in decls.iteritems(): efile.write(' | %s \n' % k[3:]) # strip Z3_ efile.write('\n') + efile.write('(** Convert %s to int*)\n' % name[3:]) efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): efile.write(' | %s -> %d\n' % (k[3:], i)) efile.write('\n') + efile.write('(** Convert int to %s*)\n' % name[3:]) efile.write('let int2%s x : %s =\n' % (name[3:],name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): diff --git a/scripts/update_api.py b/scripts/update_api.py index d0ef2ec86..c8cd05c7e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1106,26 +1106,26 @@ def arrayparams(params): return op -def ml_unwrap(t): +def ml_unwrap(t, ts, s): if t == STRING: - return 'String_val' - elif t == BOOL or t == INT or PRINT_MODE or ERROR_CODE: - return 'Int_val' + return '(' + ts + ') String_val(' + s + ')' + elif t == BOOL or t == INT or t == PRINT_MODE or t == ERROR_CODE: + return '(' + ts + ') Int_val(' + s + ')' elif t == UINT: - return 'Unsigned_int_val' + return '(' + ts + ') Unsigned_int_val(' + s + ')' elif t == INT64: - return 'Long_val' + return '(' + ts + ') Long_val(' + s + ')' elif t == UINT64: - return 'Unsigned_long_val' + return '(' + ts + ') Unsigned_long_val(' + s + ')' elif t == DOUBLE: - return 'Double_val' + return '(' + ts + ') Double_val(' + s + ')' else: - return 'Data_custom_val' + return '* (' + ts + '*) Data_custom_val(' + s + ')' def ml_set_wrap(t, d, n): if t == VOID: return d + ' = Val_unit;' - elif t == BOOL or t == INT or t == UINT or PRINT_MODE or ERROR_CODE: + elif t == BOOL or t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: return d + ' = Val_int(' + n + ');' elif t == INT64 or t == UINT64: return d + ' = Val_long(' + n + ');' @@ -1135,7 +1135,7 @@ def ml_set_wrap(t, d, n): return d + ' = caml_copy_string((const char*) ' + n + ');' else: ts = type2str(t) - return d + ' = caml_alloc_custom(0, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' + return d + ' = caml_alloc_custom(&default_custom_ops, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' def mk_ml(): global Type2Str @@ -1146,7 +1146,9 @@ def mk_ml(): ml_wrapperf = os.path.join(ml_dir, 'z3native.c') ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n\n') + ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_native.write('open Z3enums\n\n') + ml_native.write('(**/**)\n') ml_native.write('type ptr\n') ml_native.write('and z3_symbol = ptr\n') for k, v in Type2Str.iteritems(): @@ -1226,6 +1228,7 @@ def mk_ml(): else: ml_native.write(' res\n') ml_native.write('\n') + ml_native.write('(**/**)\n') # C interface ml_wrapper = open(ml_wrapperf, 'w') @@ -1276,6 +1279,14 @@ def mk_ml(): ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') ml_wrapper.write('\n\n') + ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') + ml_wrapper.write(' identifier: "default handling",\n') + ml_wrapper.write(' finalize: custom_finalize_default,\n') + ml_wrapper.write(' compare: custom_compare_default,\n') + ml_wrapper.write(' hash: custom_hash_default,\n') + ml_wrapper.write(' serialize: custom_serialize_default,\n') + ml_wrapper.write(' deserialize: custom_deserialize_default\n') + ml_wrapper.write('};\n\n') ml_wrapper.write('#ifdef __cplusplus\n') ml_wrapper.write('extern "C" {\n') ml_wrapper.write('#endif\n\n') @@ -1342,10 +1353,10 @@ def mk_ml(): t = param_type(param) ts = type2str(t) ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) - ml_wrapper.write(' for (unsigned i = 0; i < a%s; i++) _a%s[i] = (%s) %s(Field(a%s, i));\n' % (param_array_capacity_pos(param), i, ts, ml_unwrap(t), i)) + ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) _a%s[i] = %s;\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', i)'))) elif k == IN: t = param_type(param) - ml_wrapper.write(' %s _a%s = (%s) %s(a%s);\n' % (type2str(t), i, type2str(t), ml_unwrap(t), i)) + ml_wrapper.write(' %s _a%s = %s;\n' % (type2str(t), i, ml_unwrap(t, type2str(t), 'a' + str(i)))) elif k == OUT: ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) elif k == INOUT: diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index cc1429f14..321b17c82 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,33 +1,17 @@ -(* +(** + The Z3 ML/Ocaml Interface. + Copyright (C) 2012 Microsoft Corporation - Author: CM Wintersteiger (cwinter) 2012-12-17 + @author CM Wintersteiger (cwinter) 2012-12-17 *) open Z3enums open Z3native -module Log = -struct - let m_is_open = false - (* CMW: "open" seems to be an invalid function name*) - let open_ fn = int2lbool(open_log fn) == L_TRUE - let close = (close_log) - let append s = (append_log s) -end +(**/**) -module Version = -struct - let major = let (x, _, _, _) = get_version in x - let minor = let (_, x, _, _) = get_version in x - let build = let (_, _, x, _) = get_version in x - let revision = let (_, _, _, x) = get_version in x - let to_string = - let (mj, mn, bld, rev) = get_version in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev ^ "." -end +(* Object definitions. These are internal and should be interacted + with only via the corresponding functions from modules. *) class virtual idisposable = object @@ -61,7 +45,7 @@ object (self) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 method add_one_ctx_obj = m_refCount <- m_refCount + 1 - method get_native = m_n_ctx + method gno = m_n_ctx end class virtual z3object ctx_init obj_init = @@ -91,9 +75,9 @@ object (self) | None -> () ); - method get_native_object = m_n_obj + method gno = m_n_obj - method set_native_object x = + method sno x = (match x with | Some(x) -> self#incref x | None -> () @@ -105,11 +89,11 @@ object (self) m_n_obj <- x method get_context = m_ctx - method get_native_context = m_ctx#get_native + method gnc = m_ctx#gno (* method array_to_native a = - let f e = e#get_native_object in + let f e = e#gno in (Array.map f a) method array_length a = @@ -120,61 +104,145 @@ object (self) end -class symbol ctx_init obj_init = +class symbol ctx obj = object (self) - inherit z3object ctx_init obj_init + inherit z3object ctx obj method incref o = () method decref o = () end -class int_symbol ctx_init obj_init = +class int_symbol ctx = object(self) - inherit symbol ctx_init obj_init + inherit symbol ctx None + method cnstr_obj obj = (self#sno obj) ; self + method cnstr_int i = (self#sno (Some (mk_int_symbol ctx#gno i))) ; self end -class string_symbol ctx_init obj_init = +class string_symbol ctx = object(self) - inherit symbol ctx_init obj_init + inherit symbol ctx None + method cnstr_obj obj = (self#sno obj) ; self + method cnstr_string name = (self#sno (Some (mk_string_symbol ctx#gno name))) ; self end +(**/**) + +(** Interaction logging for Z3. + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log = +struct + (** Open an interaction log file. + @param filename the name of the file to open. + @return True if opening the log file succeeds, false otherwise. + *) + (* CMW: "open" seems to be a reserved keyword? *) + let open_ filename = ((int2lbool (open_log filename)) == L_TRUE) + + (** Closes the interaction log. *) + let close = close_log + + (** Appends a user-provided string to the interaction log. + @param s the string to append*) + let append s = append_log s +end + +(** Version information. *) +module Version = +struct + (** The major version. *) + let major = let (x, _, _, _) = get_version in x + + (** The minor version. *) + let minor = let (_, x, _, _) = get_version in x + + (** The build version. *) + let build = let (_, _, x, _) = get_version in x + + (** The revision. *) + let revision = let (_, _, _, x) = get_version in x + + (** A string representation of the version information. *) + let to_string = + let (mj, mn, bld, rev) = get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + +(** Symbols are used to name several term and type constructors. *) module Symbol = struct +(**/**) let create ctx obj = match obj with | Some(x) -> ( - match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with - | INT_SYMBOL -> (new int_symbol ctx obj :> symbol) - | STRING_SYMBOL -> (new string_symbol ctx obj :> symbol) + match (int2symbol_kind (get_symbol_kind ctx#gno x)) with + | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj obj) :> symbol) + | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj obj) :> symbol) ) | None -> raise (Exception "Can't create null objects") +(**/**) - let kind o = match o#m_n_obj with - | Some(x) -> (int2symbol_kind (get_symbol_kind o#get_native_context x)) + (** The kind of the symbol (int or string) *) + let kind (o : symbol) = match o#gno with + | Some(x) -> (int2symbol_kind (get_symbol_kind o#gnc x)) | _ -> raise (Exception "Underlying object lost") - let is_int_symbol o = match o#m_n_obj with - | Some(x) -> x#kind == INT_SYMBOL + (** Indicates whether the symbol is of Int kind *) + let is_int_symbol (o : symbol) = match o#gno with + | Some(x) -> (kind o) == INT_SYMBOL | _ -> false - let is_string_symbol o = match o#m_n_obj with - | Some(x) -> x#kind == STRING_SYMBOL + (** Indicates whether the symbol is of string kind. *) + let is_string_symbol (o : symbol) = match o#gno with + | Some(x) -> (kind o) == STRING_SYMBOL | _ -> false - let get_int o = match o#m_n_obj with - | Some(x) -> (get_symbol_int o#get_native_context x) + (** The int value of the symbol. *) + let get_int (o : int_symbol) = match o#gno with + | Some(x) -> (get_symbol_int o#gnc x) | None -> 0 - let get_string o = match o#m_n_obj with - | Some(x) -> (get_symbol_string o#get_native_context x) + (** The string value of the symbol. *) + let get_string (o : string_symbol) = match o#gno with + | Some(x) -> (get_symbol_string o#gnc x) | None -> "" - let to_string o = match o#m_n_obj with + (** A string representation of the symbol. *) + let to_string (o : symbol) = match o#gno with | Some(x) -> ( match (kind o) with - | INT_SYMBOL -> (string_of_int (get_symbol_int o#get_native_context x)) - | STRING_SYMBOL -> (get_symbol_string o#get_native_context x) + | INT_SYMBOL -> (string_of_int (get_symbol_int o#gnc x)) + | STRING_SYMBOL -> (get_symbol_string o#gnc x) ) | None -> "" end + +(** The main interaction with Z3 happens via the Context. *) +module Context = +struct + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) + let mk_symbol_int ctx i = + (new int_symbol ctx)#cnstr_int i + + (** Creates a new symbol using a string. *) + let mk_symbol_string ctx s = + (new string_symbol ctx)#cnstr_string s + + (** + Create an array of symbols. + *) + let mk_symbols ctx names = + let f elem = mk_symbol_string ctx elem in + (Array.map f names) + +end From fc227e3c9613cb573a8048c68df0d70742c25dea Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 00:50:32 +0000 Subject: [PATCH 241/507] .NET API documentation bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Expr.cs | 2 +- src/api/dotnet/Params.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index f4a63a61b..53bf4d4f0 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -1311,7 +1311,7 @@ namespace Microsoft.Z3 #region Relational Terms /// - /// Indicates whether the term is of an array sort. + /// Indicates whether the term is of relation sort. /// public bool IsRelation { diff --git a/src/api/dotnet/Params.cs b/src/api/dotnet/Params.cs index c33728491..9a814b2ec 100644 --- a/src/api/dotnet/Params.cs +++ b/src/api/dotnet/Params.cs @@ -23,7 +23,7 @@ using System.Diagnostics.Contracts; namespace Microsoft.Z3 { /// - /// A ParameterSet represents a configuration in the form of Symbol/value pairs. + /// A Params objects represents a configuration in the form of Symbol/value pairs. /// [ContractVerification(true)] public class Params : Z3Object From dab162886e8036d59b5a853f99c8adc5d7ea0074 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 00:51:07 +0000 Subject: [PATCH 242/507] New ML API savepoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/Makefile | 6 +- src/api/ml/z3.ml | 5746 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 5659 insertions(+), 93 deletions(-) diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index f97a2dc30..4d4a6c08f 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -3,4 +3,8 @@ # in the top-level build directory. all: - ocamlbuild -cflag -annot z3.cmxa \ No newline at end of file + ocamlbuild -cflag -annot z3.cmxa + +doc: *.ml + mkdir -p doc + ocamldoc -html -d doc -I ../../../bld_dbg/api/ml *.ml -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 321b17c82..2100f371e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -6,7 +6,6 @@ *) open Z3enums -open Z3native (**/**) @@ -18,27 +17,28 @@ object method virtual dispose : unit end +(** Context objects *) class context settings = object (self) inherit idisposable val mutable m_n_ctx : Z3native.z3_context = - let cfg = mk_config in - let f e = (set_param_value cfg (fst e) (snd e)) in + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; - let v = mk_context_rc cfg in - del_config(cfg) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; v val mutable m_refCount : int = 0 initializer Gc.finalise (fun self -> self#dispose) self - + method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing context %d \n" (Oo.id self) ; - (del_context m_n_ctx) + (Z3native.del_context m_n_ctx) ) else ( (* re-queue for finalization? *) ) @@ -48,6 +48,8 @@ object (self) method gno = m_n_ctx end + +(** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) inherit idisposable @@ -56,14 +58,14 @@ object (self) initializer (match m_n_obj with - | Some (x) -> self#incref x; + | Some (x) -> self#incref m_ctx#gno x; m_ctx#add_one_ctx_obj | None -> () ); Gc.finalise (fun self -> self#dispose) self - method virtual incref : Z3native.ptr -> unit - method virtual decref : Z3native.ptr -> unit + method virtual incref : Z3native.ptr -> Z3native.ptr -> unit + method virtual decref : Z3native.ptr -> Z3native.ptr -> unit (* Disposes of the underlying native Z3 object. @@ -71,61 +73,415 @@ object (self) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with - | Some (x) -> self#decref x; m_n_obj <- None; m_ctx#sub_one_ctx_obj + | Some (x) -> self#decref m_ctx#gno x; m_n_obj <- None; m_ctx#sub_one_ctx_obj | None -> () ); - method gno = m_n_obj + method gno = match m_n_obj with + | Some(x) -> x + | None -> raise (Z3native.Exception "Z3 object lost") - method sno x = - (match x with - | Some(x) -> self#incref x - | None -> () - ); + method sno nc o = + self#incref nc o ; (match m_n_obj with - | Some(x) -> self#decref x + | Some(x) -> self#decref nc x | None -> () ); - m_n_obj <- x + m_n_obj <- Some o - method get_context = m_ctx + method gc = m_ctx method gnc = m_ctx#gno - -(* - method array_to_native a = - let f e = e#gno in - (Array.map f a) - - method array_length a = - match a with - | Some(x) -> (Array.length x) - | None -> 0 -*) - end -class symbol ctx obj = + +(** Parameter set objects *) +class params ctx obj = object (self) - inherit z3object ctx obj - - method incref o = () - method decref o = () + inherit z3object ctx obj as super + method incref ctx o = Z3native.params_inc_ref ctx o + method decref ctx o = Z3native.params_dec_ref ctx o end + +(** Symbol objects *) +class symbol ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method incref ctx o = () + method decref ctx o = () +end + +let symbolaton (a : symbol array) = + let f (e : symbol) = e#gno in + Array.map f a + +(** Int symbol objects *) class int_symbol ctx = object(self) - inherit symbol ctx None - method cnstr_obj obj = (self#sno obj) ; self - method cnstr_int i = (self#sno (Some (mk_int_symbol ctx#gno i))) ; self + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_int i = (self#sno ctx#gno (Z3native.mk_int_symbol ctx#gno i)) ; self end +(** String symbol objects *) class string_symbol ctx = object(self) - inherit symbol ctx None - method cnstr_obj obj = (self#sno obj) ; self - method cnstr_string name = (self#sno (Some (mk_string_symbol ctx#gno name))) ; self + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_string name = (self#sno ctx#gno (Z3native.mk_string_symbol ctx#gno name)) ; self end +let create_symbol ctx no = + match (int2symbol_kind (Z3native.get_symbol_kind ctx#gno no)) with + | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) + | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) + +(** AST objects *) +class ast ctx = +object (self) + inherit z3object ctx None as super (* CMW: derive from icomparable? *) + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + + method incref nc o = Z3native.inc_ref nc o + method decref nc o = Z3native.dec_ref nc o +end + +let astaton (a : ast array) = + let f (e : ast) = e#gno in + Array.map f a + +(** Sort objects *) +class sort ctx = +object (self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Arithmetic sort objects, i.e., Int or Real. *) +class arith_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Array sorts objects *) +class array_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx#gno (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self +end + +(** Bit-vector sort objects *) +class bitvec_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Boolean sort objects *) +class bool_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Datatype sort objects *) +class datatype_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_sc (name : symbol) constructors = (self#sno ctx#gno (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self +end + +(** Enum sort objects *) +class enum_sort ctx = +object (self) + inherit sort ctx as super + val mutable _constdecls = None + val mutable _testerdecls = None + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_ss (name : symbol) (enum_names : symbol array) = + let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in + _constdecls <- Some a ; + _testerdecls <- Some b ; + (self#sno ctx#gno r) ; + self + + method const_decls = match _constdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing const decls") + + method tester_decls = match _testerdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tester decls") +end + +(** Int sort objects *) +class int_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Real sort objects *) +class real_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Uninterpreted sort objects *) +class uninterpreted_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_s (s : symbol) = (self #sno ctx#gno (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self +end + +(** Finite domain sort objects *) +class finite_domain_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx#gno (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self +end + +(** Relation sort objects *) +class relation_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** List sort objects *) +class list_sort ctx = +object (self) + inherit sort ctx as super + val mutable _nildecl = None + val mutable _is_nildecl = None + val mutable _consdecl = None + val mutable _is_consdecl = None + val mutable _headdecl = None + val mutable _taildecl = None + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_ss (name : symbol) (elem_sort : sort) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in + _nildecl <- Some a ; + _is_nildecl <- Some b ; + _consdecl <- Some c ; + _is_consdecl <- Some d ; + _headdecl <- Some e ; + _taildecl <- Some f ; + (self#sno ctx#gno r) ; + self + + method nil_decl = match _nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing nil decl") + + method is_nil_decl = match _is_nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_nil decls") + + method cons_decl = match _consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing cons decls") + + method is_cons_decl = match _is_consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_cons decls") + + method head_decl = match _headdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing head decls") + + method tail_decl = match _taildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tail decls") + +end + +(** Set sort objects *) +class set_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_s (s : sort) = (self#sno ctx#gno s#gno) ; self +end + +(** Tuple sort objects *) +class tuple_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = + let (x,_,_) = (Z3native.mk_tuple_sort ctx#gno name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in + (self#sno ctx#gno x) ; + self +end + +let create_sort ctx obj = + match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with + | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) + | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) + | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) + | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) + | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) + | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) + | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) + | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) + | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + +(** Function declaration objects *) +class func_decl ctx = +object (self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self + + method incref nc o = super#incref nc o + method decref nc o = super#decref nc o +end + +class parameter = +object (self) + val mutable m_kind : parameter_kind = PARAMETER_INT; + val mutable m_i : int = 0 + val mutable m_d : float = 0.0 + val mutable m_sym : symbol option = None + val mutable m_srt : sort option = None + val mutable m_ast : ast option = None + val mutable m_fd : func_decl option = None + val mutable m_r : string = "" + + method cnstr_int i = m_kind <- PARAMETER_INT; m_i <- i + method cnstr_double d = m_kind <- PARAMETER_DOUBLE; m_d <- d + method cnstr_symbol sym = m_kind <- PARAMETER_SYMBOL; m_sym <- sym + method cnstr_sort srt = m_kind <- PARAMETER_SORT; m_srt <- srt + method cnstr_ast ast = m_kind <- PARAMETER_AST; m_ast <- ast + method cnstr_func_decl fd = m_kind <- PARAMETER_FUNC_DECL; m_fd <- fd + method cnstr_rational r = m_kind <- PARAMETER_RATIONAL; m_r <- r + + method kind = m_kind + method int = m_i + method double = m_d + method symbol = match m_sym with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter symbol") + method sort = match m_srt with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter sort") + method ast = match m_ast with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter ast") + method func_decl = match m_fd with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter func_decl") + method rational = m_r +end + +(** Expression objects *) +class expr ctx = +object(self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +let expraton (a : expr array) = + let f (e : expr) = e#gno in + Array.map f a + +(** Boolean expression objects *) +class bool_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Arithmetic expression objects (int/real) *) +class arith_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Int expression objects *) +class int_expr ctx = +object (self) + inherit arith_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Real expression objects *) +class real_expr ctx = +object (self) + inherit arith_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Bit-vector expression objects *) +class bitvec_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Array expression objects *) +class array_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Datatype expression objects *) +class datatype_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Integer numeral expression objects *) +class int_num ctx = +object (self) + inherit int_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Rational numeral expression objects *) +class rat_num ctx = +object (self) + inherit real_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Bit-vector numeral expression objects *) +class bitvec_num ctx = +object (self) + inherit bitvec_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Algebraic numeral expression objects *) +class algebraic_num ctx = +object (self) + inherit arith_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + + +(** Quantifier objects *) +class quantifier ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + + + (**/**) (** Interaction logging for Z3. @@ -138,34 +494,34 @@ struct @return True if opening the log file succeeds, false otherwise. *) (* CMW: "open" seems to be a reserved keyword? *) - let open_ filename = ((int2lbool (open_log filename)) == L_TRUE) + let open_ filename = ((int2lbool (Z3native.open_log filename)) == L_TRUE) (** Closes the interaction log. *) - let close = close_log + let close = Z3native.close_log (** Appends a user-provided string to the interaction log. @param s the string to append*) - let append s = append_log s + let append s = Z3native.append_log s end (** Version information. *) module Version = struct (** The major version. *) - let major = let (x, _, _, _) = get_version in x + let major = let (x, _, _, _) = Z3native.get_version in x (** The minor version. *) - let minor = let (_, x, _, _) = get_version in x + let minor = let (_, x, _, _) = Z3native.get_version in x (** The build version. *) - let build = let (_, _, x, _) = get_version in x + let build = let (_, _, x, _) = Z3native.get_version in x (** The revision. *) - let revision = let (_, _, _, x) = get_version in x + let revision = let (_, _, _, x) = Z3native.get_version in x (** A string representation of the version information. *) let to_string = - let (mj, mn, bld, rev) = get_version in + let (mj, mn, bld, rev) = Z3native.get_version in string_of_int mj ^ "." ^ string_of_int mn ^ "." ^ string_of_int bld ^ "." ^ @@ -174,75 +530,5281 @@ end (** Symbols are used to name several term and type constructors. *) module Symbol = -struct -(**/**) - let create ctx obj = - match obj with - | Some(x) -> ( - match (int2symbol_kind (get_symbol_kind ctx#gno x)) with - | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj obj) :> symbol) - | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj obj) :> symbol) - ) - | None -> raise (Exception "Can't create null objects") -(**/**) - +struct (** The kind of the symbol (int or string) *) - let kind (o : symbol) = match o#gno with - | Some(x) -> (int2symbol_kind (get_symbol_kind o#gnc x)) - | _ -> raise (Exception "Underlying object lost") + let kind (o : symbol) = (int2symbol_kind (Z3native.get_symbol_kind o#gnc o#gno)) (** Indicates whether the symbol is of Int kind *) - let is_int_symbol (o : symbol) = match o#gno with - | Some(x) -> (kind o) == INT_SYMBOL - | _ -> false + let is_int_symbol (o : symbol) = (kind o) == INT_SYMBOL (** Indicates whether the symbol is of string kind. *) - let is_string_symbol (o : symbol) = match o#gno with - | Some(x) -> (kind o) == STRING_SYMBOL - | _ -> false + let is_string_symbol (o : symbol) = (kind o) == STRING_SYMBOL (** The int value of the symbol. *) - let get_int (o : int_symbol) = match o#gno with - | Some(x) -> (get_symbol_int o#gnc x) - | None -> 0 + let get_int (o : int_symbol) = Z3native.get_symbol_int o#gnc o#gno (** The string value of the symbol. *) - let get_string (o : string_symbol) = match o#gno with - | Some(x) -> (get_symbol_string o#gnc x) - | None -> "" + let get_string (o : string_symbol) = Z3native.get_symbol_string o#gnc o#gno (** A string representation of the symbol. *) - let to_string (o : symbol) = match o#gno with - | Some(x) -> - ( - match (kind o) with - | INT_SYMBOL -> (string_of_int (get_symbol_int o#gnc x)) - | STRING_SYMBOL -> (get_symbol_string o#gnc x) - ) - | None -> "" + let to_string (o : symbol) = + match (kind o) with + | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int o#gnc o#gno)) + | STRING_SYMBOL -> (Z3native.get_symbol_string o#gnc o#gno) end -(** The main interaction with Z3 happens via the Context. *) + +(** + The Sort module implements type information for ASTs. +*) +module Sort = +struct + (** + Comparison operator. + @param a A sort + @param b A sort + @return True if and are from the same context + and represent the same sort; false otherwise. + *) + let ( = ) (a : sort) (b : sort) = (a == b) || + if a#gnc != b#gnc then + false + else + ((int2lbool (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) + + (** + Returns a unique identifier for the sort. + *) + let get_id (x : sort) = Z3native.get_sort_id x#gnc x#gno + + (** + The kind of the sort. + *) + let get_sort_kind (x : sort) = (int2sort_kind (Z3native.get_sort_kind x#gnc x#gno)) + + (** + The name of the sort + *) + let get_name (x : sort) = (create_symbol x#gc (Z3native.get_sort_name x#gnc x#gno)) + + (** + A string representation of the sort. + *) + let to_string (x : sort) = Z3native.sort_to_string x#gnc x#gno +end + +(** Array sorts *) +module ArraySort = +struct + (** The domain of the array sort. *) + let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) + + (** The range of the array sort. *) + let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) +end + +(** Bit-vector sorts *) +module BitVectorSort = +struct + (** The size of the bit-vector sort. *) + let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno +end + +(** Finite domain sorts. *) +module FiniteDomainSort = +struct + (** The size of the finite domain sort. *) + let get_size (x : finite_domain_sort) = + let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") +end + +(** Relation sorts. *) +module RelationSort = +struct + (** The arity of the relation sort. *) + let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno + + (** The sorts of the columns of the relation sort. *) + let get_column_sorts (x : relation_sort) = + let n = get_arity x in + let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in + Array.init n f + +end + +(**/**) +let create_expr ctx obj = + if int2ast_kind (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then + (((new quantifier ctx)#cnstr_obj obj) :> expr) + else + let s = Z3native.get_sort ctx#gno obj in + let sk = (int2sort_kind (Z3native.get_sort_kind ctx#gno s)) in + if (int2lbool (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then + (((new algebraic_num ctx)#cnstr_obj obj) :> expr) + else + if ((int2lbool (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && + (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + match sk with + | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) + | REAL_SORT -> (((new rat_num ctx)#cnstr_obj obj) :> expr) + | BV_SORT -> (((new bitvec_num ctx)#cnstr_obj obj) :> expr) + | _ -> raise (Z3native.Exception "Unsupported numeral object") + else + match sk with + | BOOL_SORT -> (((new bool_expr ctx)#cnstr_obj obj) :> expr) + | INT_SORT -> (((new int_expr ctx)#cnstr_obj obj) :> expr) + | REAL_SORT -> (((new real_expr ctx)#cnstr_obj obj) :> expr) + | BV_SORT -> (((new bitvec_expr ctx)#cnstr_obj obj) :> expr) + | ARRAY_SORT -> (((new array_expr ctx)#cnstr_obj obj) :> expr) + | DATATYPE_SORT -> (((new datatype_expr ctx)#cnstr_obj obj) :> expr) + | _ -> (new expr ctx)#cnstr_obj obj + +let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = + let o = Z3native.mk_app ctx#gno f#gno (Array.length args) (astaton args) in + create_expr ctx o + +let create_ast ctx no = + match (int2ast_kind (Z3native.get_ast_kind ctx#gno no)) with + | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) + | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) + | SORT_AST -> ((create_sort ctx no) :> ast) + | APP_AST + | NUMERAL_AST + | VAR_AST -> ((create_expr ctx no) :> ast) + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") +(**/**) + +(** Function declarations. *) +module FuncDecl = +struct +(** Parameters of Func_Decls *) + module Parameter = + struct + (** + The kind of the parameter. + *) + let get_kind (x : parameter) = x#kind + + (**The int value of the parameter.*) + let get_int (x : parameter) = + if (x#kind != PARAMETER_INT) then + raise (Z3native.Exception "parameter is not an int") + else + x#int + + (**The double value of the parameter.*) + let get_double (x : parameter) = + if (x#kind != PARAMETER_DOUBLE) then + raise (Z3native.Exception "parameter is not a double") + else + x#double + + (**The Symbol value of the parameter.*) + let get_symbol (x : parameter) = + if (x#kind != PARAMETER_SYMBOL) then + raise (Z3native.Exception "parameter is not a symbol") + else + x#symbol + + (**The Sort value of the parameter.*) + let get_sort (x : parameter) = + if (x#kind != PARAMETER_SORT) then + raise (Z3native.Exception "parameter is not a sort") + else + x#sort + + (**The AST value of the parameter.*) + let get_ast (x : parameter) = + if (x#kind != PARAMETER_AST) then + raise (Z3native.Exception "parameter is not an ast") + else + x#ast + + (**The FunctionDeclaration value of the parameter.*) + let get_ast (x : parameter) = + if (x#kind != PARAMETER_FUNC_DECL) then + raise (Z3native.Exception "parameter is not an function declaration") + else + x#func_decl + + (**The rational string value of the parameter.*) + let get_rational (x : parameter) = + if (x#kind != PARAMETER_RATIONAL) then + raise (Z3native.Exception "parameter is not a ratinoal string") + else + x#rational + end + + (** + Comparison operator. + @param a A func_decl + @param b A func_decl + @return True if and are from the same context + and represent the same func_decl; false otherwise. + *) + let ( = ) (a : func_decl) (b : func_decl) = (a == b) || + if a#gnc == a#gnc then + false + else + ((int2lbool (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) + (** + A string representations of the function declaration. + *) + let to_string (x : func_decl) = Z3native.func_decl_to_string x#gnc x#gno + + (** + Returns a unique identifier for the function declaration. + *) + let get_id (x : func_decl) = Z3native.get_func_decl_id x#gnc x#gno + + (** + The arity of the function declaration + *) + let get_arity (x : func_decl) = Z3native.get_arity x#gnc x#gno + + (** + The size of the domain of the function declaration + + *) + let get_domain_size (x : func_decl) = Z3native.get_domain_size x#gnc x#gno + + (** + The domain of the function declaration + *) + let get_domain (x : func_decl) = + let n = (get_domain_size x) in + let f i = create_sort x#gc (Z3native.get_domain x#gnc x#gno i) in + Array.init n f + + (** + The range of the function declaration + *) + let get_range (x : func_decl) = + create_sort x#gc (Z3native.get_range x#gnc x#gno) + + (** + The kind of the function declaration. + *) + let get_decl_kind (x : func_decl) = (int2decl_kind (Z3native.get_decl_kind x#gnc x#gno)) + + (** + The name of the function declaration + *) + let get_name (x : func_decl) = (create_symbol x#gc (Z3native.get_decl_name x#gnc x#gno)) + + (** + The number of parameters of the function declaration + *) + let get_num_parameters (x : func_decl) = (Z3native.get_decl_num_parameters x#gnc x#gno) + + (** + The parameters of the function declaration + *) + let get_parameters (x : func_decl) = + let n = (get_num_parameters x) in + let f i = ( + match (int2parameter_kind (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with + | PARAMETER_INT -> (new parameter)#cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) + | PARAMETER_DOUBLE -> (new parameter)#cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) + | PARAMETER_SYMBOL-> (new parameter)#cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) + | PARAMETER_SORT -> (new parameter)#cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) + | PARAMETER_AST -> (new parameter)#cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) + | PARAMETER_FUNC_DECL -> (new parameter)#cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) + | PARAMETER_RATIONAL -> (new parameter)#cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) + ) in + Array.init n f + + (** + Create expression that applies function to arguments. + + *) + let apply (x : func_decl) (args : expr array) = create_expr_fa x#gc x args + +end + +(** Datatype sorts *) +module DatatypeSort = +struct + (** The number of constructors of the datatype sort. *) + let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno + + (** The range of the array sort. *) + let get_constructors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in + Array.init n f + + (** The recognizers. *) + let get_recognizers (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in + Array.init n f + + (** The constructor accessors. *) + let get_accessors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = ( + let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in + let ds = (Z3native.get_domain_size fd#gnc fd#gno) in + let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in + Array.init ds g + ) in + Array.init n f +end + +(** Enumeration sorts. *) +module EnumSort = +struct + (** The function declarations of the constants in the enumeration. *) + let get_const_decls (x : enum_sort) = + let f e = ((new func_decl x#gc)#cnstr_obj e) in + Array.map f x#const_decls + + (** The test predicates for the constants in the enumeration. *) + let get_tester_decls (x : enum_sort) = + let f e = ((new func_decl x#gc)#cnstr_obj e) in + Array.map f x#tester_decls +end + +(** List sorts. *) +module ListSort = +struct + (** The declaration of the nil function of this list sort. *) + let get_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#nil_decl + + (** The declaration of the isNil function of this list sort. *) + let get_is_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_nil_decl + + (** The declaration of the cons function of this list sort. *) + let get_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#cons_decl + + (** The declaration of the isCons function of this list sort. *) + let get_is_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_cons_decl + + (** The declaration of the head function of this list sort.*) + let get_head_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#head_decl + + (** The declaration of the tail function of this list sort. *) + let get_tail_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#tail_decl + + (** The empty list. *) + let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] +end + +module TupleSort = +struct + (** The constructor function of the tuple.*) + let get_mk_decl (x : tuple_sort) = + (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) + + (** The number of fields in the tuple. *) + let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno + + (** The field declarations. *) + let get_field_decls (x : tuple_sort) = + let n = get_num_fields x in + let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in + Array.init n f +end + +(** The abstract syntax tree (AST) module. *) +module AST = +struct + (** + The AST's hash code. + @return A hash code + *) + let get_hash_code ( x : ast) = Z3native.get_ast_hash x#gnc x#gno + + (** + A unique identifier for the AST (unique among all ASTs). + *) + let get_id ( x : ast) = Z3native.get_ast_id x#gnc x#gno + + (** + The kind of the AST. + *) + let get_ast_kind ( x : ast) = (int2ast_kind (Z3native.get_ast_kind x#gnc x#gno)) + + (** + Indicates whether the AST is an Expr + *) + let is_expr ( x : ast) = + match get_ast_kind ( x : ast) with + | APP_AST + | NUMERAL_AST + | QUANTIFIER_AST + | VAR_AST -> true + | _ -> false + + (** + Indicates whether the AST is a BoundVariable + *) + let is_var ( x : ast) = (get_ast_kind x) == VAR_AST + + (** + Indicates whether the AST is a Quantifier + *) + let is_quantifier ( x : ast) = (get_ast_kind x) == QUANTIFIER_AST + + + (** + Indicates whether the AST is a Sort + *) + let is_sort ( x : ast) = (get_ast_kind x) == SORT_AST + + (** + Indicates whether the AST is a FunctionDeclaration + *) + let is_func_decl ( x : ast) = (get_ast_kind x) == FUNC_DECL_AST + + (** + A string representation of the AST. + *) + let to_string ( x : ast) = Z3native.ast_to_string x#gnc x#gno + + (** + A string representation of the AST in s-expression notation. + *) + let to_sexpr ( x : ast) = Z3native.ast_to_string x#gnc x#gno + + (** + Comparison operator. + @param a An AST + @param b An AST + @return True if and are from the same context + and represent the same sort; false otherwise. + *) + let ( = ) (a : expr) (b : expr) = (a == b) || + if a#gnc == b#gnc then + false + else + ((int2lbool (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) + + (** + Object Comparison. + @param other Another ast + @return Negative if the object should be sorted before , positive if after else zero. + *) + let compare a b = + if (get_id a) < (get_id b) then -1 else + if (get_id a) > (get_id b) then 1 else + 0 + + (** Operator < *) + let ( < ) (a : ast) (b : ast) = (compare a b) + + (** + Translates (copies) the AST to the Context . + @param ctx A context + @return A copy of the AST which is associated with + *) + let translate ( x : ast) to_ctx = + if x#gc == to_ctx then + x + else + (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) +end + +(** + Parameter sets + + A Params objects represents a configuration in the form of Symbol/value pairs. +*) +module Params = +struct + (** + Adds a parameter setting. + *) + let add_bool (p : params) (name : symbol) (value : bool) = + Z3native.params_set_bool p#gnc p#gno name#gno (lbool2int (if value then L_TRUE else L_FALSE)) + + (** + Adds a parameter setting. + *) + let add_int (p : params) (name : symbol) (value : int) = + Z3native.params_set_uint p#gnc p#gno name#gno value + + (** + Adds a parameter setting. + *) + let add_double (p : params) (name : symbol) (value : float) = + Z3native.params_set_double p#gnc p#gno name#gno value + + (** + Adds a parameter setting. + *) + let add_symbol (p : params) (name : symbol) (value : symbol) = + Z3native.params_set_symbol p#gnc p#gno name#gno value#gno + + (** + Adds a parameter setting. + *) + let add_s_bool (p : params) (name : string) (value : bool) = + add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_int (p : params) (name : string) (value : int) = + add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_double (p : params) (name : string) (value : float) = + add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_symbol (p : params) (name : string) (value : symbol) = + add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + A string representation of the parameter set. + *) + let to_string (p : params) = Z3native.params_to_string p#gnc p#gno +end + +(** Expressions (terms) *) +module Expr = +struct + (** + Returns a simplified version of the expression. + A set of parameters to configure the simplifier + + *) + let simplify ( x : expr ) ( p : params option ) = match p with + | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) + | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) + + (** + The function declaration of the function that is applied in this expression. + *) + let get_func_decl ( x : expr ) = (new func_decl x#gc)#cnstr_obj (Z3native.get_app_decl x#gnc x#gno) + + (** + Indicates whether the expression is the true or false expression + or something else (Z3_L_UNDEF). + *) + let get_bool_value ( x : expr ) = int2lbool (Z3native.get_bool_value x#gnc x#gno) + + (** + The number of arguments of the expression. + *) + let get_num_args ( x : expr ) = Z3native.get_app_num_args x#gnc x#gno + + (** + The arguments of the expression. + *) + let get_args ( x : expr ) = let n = (get_num_args x) in + let f i = create_expr x#gc (Z3native.get_app_arg x#gnc x#gno i) in + Array.init n f + + (** + Update the arguments of the expression using the arguments + The number of new arguments should coincide with the current number of arguments. + *) + let update ( x : expr ) args = + if (Array.length args <> (get_num_args x)) then + raise (Z3native.Exception "Number of arguments does not match") + else + x#sno x#gnc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) + + (** + Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + + The result is the new expression. The arrays from and to must have size num_exprs. + For every i smaller than num_exprs, we must have that + sort of from[i] must be equal to sort of to[i]. + + *) + let substitute ( x : expr ) from to_ = + if (Array.length from) <> (Array.length to_) then + raise (Z3native.Exception "Argument sizes do not match") + else + create_expr x#gc (Z3native.substitute x#gnc x#gno (Array.length from) (expraton from) (expraton to_)) + + (** + Substitute every occurrence of from in the expression with to. + + *) + let substitute_one ( x : expr ) from to_ = + substitute ( x : expr ) [| from |] [| to_ |] + + (** + Substitute the free variables in the expression with the expressions in + + For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. + + *) + let substitute_vars ( x : expr ) to_ = + create_expr x#gc (Z3native.substitute_vars x#gnc x#gno (Array.length to_) (expraton to_)) + + + (** + Translates (copies) the term to the Context . + A context + A copy of the term which is associated with + *) + let translate ( x : expr ) to_ctx = + if x#gc == to_ctx then + x + else + create_expr to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno) + + (** + Returns a string representation of the expression. + *) + let to_string ( x : expr ) = Z3native.ast_to_string x#gnc x#gno + + (** + Indicates whether the term is a numeral + *) + let is_numeral ( x : expr ) = int2lbool (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE + + (** + Indicates whether the term is well-sorted. + True if the term is well-sorted, false otherwise. + *) + let is_well_sorted ( x : expr ) = int2lbool (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE + + (** + The Sort of the term. + *) + let get_sort ( x : expr ) = create_sort x#gc (Z3native.get_sort x#gnc x#gno) + + (** + Indicates whether the term has Boolean sort. + *) + let is_bool ( x : expr ) = (AST.is_expr x) && + (int2lbool (Z3native.is_eq_sort x#gnc + (Z3native.mk_bool_sort x#gnc) + (Z3native.get_sort x#gnc x#gno))) == L_TRUE + + (** + Indicates whether the term is of integer sort. + *) + let is_int ( x : expr ) = + ((int2lbool (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + + (** + Indicates whether the term is of sort real. + *) + let is_real ( x : expr ) = + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + + (** + Indicates whether the term is of an array sort. + *) + let is_array ( x : expr ) = + ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + + (** + Indicates whether the term represents a constant. + *) + let is_const ( x : expr ) = (AST.is_expr x) && + (get_num_args x) == 0 && + FuncDecl.get_domain_size(get_func_decl x) == 0 + + (** + Indicates whether the term is an integer numeral. + *) + let is_int_numeral ( x : expr ) = (is_numeral x) && (is_int x) + + (** + Indicates whether the term is a real numeral. + *) + let is_rat_num ( x : expr ) = (is_numeral x) && (is_real x) + + (** + Indicates whether the term is an algebraic number + *) + let is_algebraic_number ( x : expr ) = int2lbool(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + + (** + Indicates whether the term is the constant true. + *) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + + (** + Indicates whether the term is the constant false. + *) + let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + + (** + Indicates whether the term is an equality predicate. + *) + let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + + (** + Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). + *) + let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + + (** + Indicates whether the term is a ternary if-then-else term + *) + let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + + (** + Indicates whether the term is an n-ary conjunction + *) + let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + + (** + Indicates whether the term is an n-ary disjunction + *) + let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + + (** + Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) + *) + let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + + (** + Indicates whether the term is an exclusive or + *) + let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + + (** + Indicates whether the term is a negation + *) + let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + + (** + Indicates whether the term is an implication + *) + let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) + + (** + Indicates whether the term is an arithmetic numeral. + *) + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ANUM) + + (** + Indicates whether the term is a less-than-or-equal + *) + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LE) + + (** + Indicates whether the term is a greater-than-or-equal + *) + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GE) + + (** + Indicates whether the term is a less-than + *) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LT) + + (** + Indicates whether the term is a greater-than + *) + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GT) + + (** + Indicates whether the term is addition (binary) + *) + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ADD) + + (** + Indicates whether the term is subtraction (binary) + *) + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SUB) + + (** + Indicates whether the term is a unary minus + *) + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UMINUS) + + (** + Indicates whether the term is multiplication (binary) + *) + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MUL) + + (** + Indicates whether the term is division (binary) + *) + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DIV) + + (** + Indicates whether the term is integer division (binary) + *) + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IDIV) + + (** + Indicates whether the term is remainder (binary) + *) + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REM) + + (** + Indicates whether the term is modulus (binary) + *) + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MOD) + + (** + Indicates whether the term is a coercion of integer to real (unary) + *) + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_REAL) + + (** + Indicates whether the term is a coercion of real to integer (unary) + *) + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_INT) + + (** + Indicates whether the term is a check that tests whether a real is integral (unary) + *) + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IS_INT) + + (** + Indicates whether the term is an array store. + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. + *) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_STORE) + + (** + Indicates whether the term is an array select. + *) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SELECT) + + (** + Indicates whether the term is a constant array. + For example, select(const(v),i) = v holds for every v and i. The function is unary. + *) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONST_ARRAY) + + (** + Indicates whether the term is a default array. + For example default(const(v)) = v. The function is unary. + *) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_DEFAULT) + + (** + Indicates whether the term is an array map. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + *) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_MAP) + + (** + Indicates whether the term is an as-array term. + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. + *) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AS_ARRAY) + + (** + Indicates whether the term is set union + *) + let is_set_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_UNION) + + (** + Indicates whether the term is set intersection + *) + let is_set_intersect ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_INTERSECT) + + (** + Indicates whether the term is set difference + *) + let is_set_difference ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_DIFFERENCE) + + (** + Indicates whether the term is set complement + *) + let is_set_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_COMPLEMENT) + + (** + Indicates whether the term is set subset + *) + let is_set_subset ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_SUBSET) + + (** + Indicates whether the terms is of bit-vector sort. + *) + let is_bv ( x : expr ) = + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) + + (** + Indicates whether the term is a bit-vector numeral + *) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNUM) + + (** + Indicates whether the term is a one-bit bit-vector with value one + *) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT1) + + (** + Indicates whether the term is a one-bit bit-vector with value zero + *) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT0) + + (** + Indicates whether the term is a bit-vector unary minus + *) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNEG) + + (** + Indicates whether the term is a bit-vector addition (binary) + *) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BADD) + + (** + Indicates whether the term is a bit-vector subtraction (binary) + *) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSUB) + + (** + Indicates whether the term is a bit-vector multiplication (binary) + *) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BMUL) + + (** + Indicates whether the term is a bit-vector signed division (binary) + *) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV) + + (** + Indicates whether the term is a bit-vector unsigned division (binary) + *) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV) + + (** + Indicates whether the term is a bit-vector signed remainder (binary) + *) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM) + + (** + Indicates whether the term is a bit-vector unsigned remainder (binary) + *) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM) + + (** + Indicates whether the term is a bit-vector signed modulus + *) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD) + + (** + Indicates whether the term is a bit-vector signed division by zero + *) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV0) + + (** + Indicates whether the term is a bit-vector unsigned division by zero + *) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV0) + + (** + Indicates whether the term is a bit-vector signed remainder by zero + *) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM0) + + (** + Indicates whether the term is a bit-vector unsigned remainder by zero + *) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM0) + + (** + Indicates whether the term is a bit-vector signed modulus by zero + *) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD0) + + (** + Indicates whether the term is an unsigned bit-vector less-than-or-equal + *) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULEQ) + + (** + Indicates whether the term is a signed bit-vector less-than-or-equal + *) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLEQ) + + (** + Indicates whether the term is an unsigned bit-vector greater-than-or-equal + *) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGEQ) + + (** + Indicates whether the term is a signed bit-vector greater-than-or-equal + *) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGEQ) + + (** + Indicates whether the term is an unsigned bit-vector less-than + *) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULT) + + (** + Indicates whether the term is a signed bit-vector less-than + *) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLT) + + (** + Indicates whether the term is an unsigned bit-vector greater-than + *) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGT) + + (** + Indicates whether the term is a signed bit-vector greater-than + *) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGT) + + (** + Indicates whether the term is a bit-wise AND + *) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BAND) + + (** + Indicates whether the term is a bit-wise OR + *) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BOR) + + (** + Indicates whether the term is a bit-wise NOT + *) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOT) + + (** + Indicates whether the term is a bit-wise XOR + *) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXOR) + + (** + Indicates whether the term is a bit-wise NAND + *) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNAND) + + (** + Indicates whether the term is a bit-wise NOR + *) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOR) + + (** + Indicates whether the term is a bit-wise XNOR + *) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXNOR) + + (** + Indicates whether the term is a bit-vector concatenation (binary) + *) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONCAT) + + (** + Indicates whether the term is a bit-vector sign extension + *) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SIGN_EXT) + + (** + Indicates whether the term is a bit-vector zero extension + *) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ZERO_EXT) + + (** + Indicates whether the term is a bit-vector extraction + *) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXTRACT) + + (** + Indicates whether the term is a bit-vector repetition + *) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REPEAT) + + (** + Indicates whether the term is a bit-vector reduce OR + *) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDOR) + + (** + Indicates whether the term is a bit-vector reduce AND + *) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDAND) + + (** + Indicates whether the term is a bit-vector comparison + *) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BCOMP) + + (** + Indicates whether the term is a bit-vector shift left + *) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSHL) + + (** + Indicates whether the term is a bit-vector logical shift right + *) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BLSHR) + + (** + Indicates whether the term is a bit-vector arithmetic shift left + *) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BASHR) + + (** + Indicates whether the term is a bit-vector rotate left + *) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_LEFT) + + (** + Indicates whether the term is a bit-vector rotate right + *) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_RIGHT) + + (** + Indicates whether the term is a bit-vector rotate left (extended) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. + *) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_LEFT) + + (** + Indicates whether the term is a bit-vector rotate right (extended) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. + *) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_RIGHT) + + (** + Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. + *) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_INT2BV) + + (** + Indicates whether the term is a coercion from bit-vector to integer + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. + *) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BV2INT) + + (** + Indicates whether the term is a bit-vector carry + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + *) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CARRY) + + (** + Indicates whether the term is a bit-vector ternary XOR + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) + *) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR3) + + (** + Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. + *) + let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) + + (** + Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) + *) + + (** + Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. + *) + let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + + (** + Indicates whether the term is a Proof for the expression 'true'. + *) + let is_proof_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRUE) + + (** + Indicates whether the term is a proof for a fact asserted by the user. + *) + let is_proof_asserted ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ASSERTED) + + (** + Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. + *) + let is_proof_goal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_GOAL) + + (** + Indicates whether the term is proof via modus ponens + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). + *) + let is_proof_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS) + + (** + Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. + *) + let is_proof_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REFLEXIVITY) + + (** + Indicates whether the term is proof by symmetricity of a relation + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. + + *) + let is_proof_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SYMMETRY) + + (** + Indicates whether the term is a proof by transitivity of a relation + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) + + *) + let is_proof_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY) + + (** + Indicates whether the term is a proof by condensed transitivity of a relation + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. + + *) + let is_proof_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + + + (** + Indicates whether the term is a monotonicity proof object. + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. + + *) + let is_proof_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MONOTONICITY) + + (** + Indicates whether the term is a quant-intro proof + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) + + *) + let is_proof_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INTRO) + + (** + Indicates whether the term is a distributivity proof object. + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. + + *) + let is_proof_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DISTRIBUTIVITY) + + (** + Indicates whether the term is a proof by elimination of AND + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i + + *) + let is_proof_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_AND_ELIM) + + (** + Indicates whether the term is a proof by eliminiation of not-or + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) + + *) + let is_proof_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NOT_OR_ELIM) + + (** + Indicates whether the term is a proof by rewriting + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) + + *) + let is_proof_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE) + + (** + Indicates whether the term is a proof by rewriting + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) + + *) + let is_proof_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE_STAR) + + (** + Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. + + *) + let is_proof_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT) + + (** + Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents + + *) + let is_proof_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT_STAR) + + (** + Indicates whether the term is a proof for pushing quantifiers in. + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents + + *) + let is_proof_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PUSH_QUANT) + + (** + Indicates whether the term is a proof for elimination of unused variables. + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. + + *) + let is_proof_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + + (** + Indicates whether the term is a proof for destructive equality resolution + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. + + *) + let is_proof_der ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DER) + + (** + Indicates whether the term is a proof for quantifier instantiation + + A proof of (or (not (forall (x) (P x))) (P a)) + + *) + let is_proof_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INST) + + (** + Indicates whether the term is a hypthesis marker. + Mark a hypothesis in a natural deduction style proof. + *) + let is_proof_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_HYPOTHESIS) + + (** + Indicates whether the term is a proof by lemma + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. + + *) + let is_proof_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_LEMMA) + + (** + Indicates whether the term is a proof by unit resolution + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') + + *) + let is_proof_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_UNIT_RESOLUTION) + + (** + Indicates whether the term is a proof by iff-true + + T1: p + [iff-true T1]: (iff p true) + + *) + let is_proof_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_TRUE) + + (** + Indicates whether the term is a proof by iff-false + + T1: (not p) + [iff-false T1]: (iff p false) + + *) + let is_proof_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_FALSE) + + (** + Indicates whether the term is a proof by commutativity + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. + + *) + let is_proof_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + + (** + Indicates whether the term is a proof for Tseitin-like axioms + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). + + *) + let is_proof_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_AXIOM) + + (** + Indicates whether the term is a proof for introduction of a name + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) + + *) + let is_proof_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_INTRO) + + (** + Indicates whether the term is a proof for application of a definition + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. + + *) + let is_proof_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_APPLY_DEF) + + (** + Indicates whether the term is a proof iff-oeq + + T1: (iff p q) + [iff~ T1]: (~ p q) + + *) + let is_proof_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_OEQ) + + (** + Indicates whether the term is a proof for a positive NNF step + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. + + *) + let is_proof_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_POS) + + (** + Indicates whether the term is a proof for a negative NNF step + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) + + *) + let is_proof_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_NEG) + + (** + Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. + + *) + let is_proof_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_STAR) + + (** + Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. + + *) + let is_proof_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_CNF_STAR) + + (** + Indicates whether the term is a proof for a Skolemization step + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. + + *) + let is_proof_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SKOLEMIZE) + + (** + Indicates whether the term is a proof by modus ponens for equi-satisfiability. + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q + + *) + let is_proof_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + + (** + Indicates whether the term is a proof for theory lemma + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. + + *) + let is_proof_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TH_LEMMA) + + (** + Indicates whether the term is of a relation sort. + *) + let is_Relation ( x : expr ) = + ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + + (** + Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. + + *) + let is_relation_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_STORE) + + (** + Indicates whether the term is an empty relation + *) + let is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_EMPTY) + + (** + Indicates whether the term is a test for the emptiness of a relation + *) + let is_is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_IS_EMPTY) + + (** + Indicates whether the term is a relational join + *) + let is_relational_join ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_JOIN) + + (** + Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. + *) + let is_relation_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_UNION) + + (** + Indicates whether the term is the widening of two relations + The function takes two arguments. + *) + let is_relation_widen ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_WIDEN) + + (** + Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. + *) + let is_relation_project ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_PROJECT) + + (** + Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. + + *) + let is_relation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_FILTER) + + (** + Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. + + *) + let is_relation_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_NEGATION_FILTER) + + (** + Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. + + *) + let is_relation_rename ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_RENAME) + + (** + Indicates whether the term is the complement of a relation + *) + let is_relation_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_COMPLEMENT) + + (** + Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. + + *) + let is_relation_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_SELECT) + + (** + Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind + to perform destructive updates to the first argument. + + *) + let is_relation_clone ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_CLONE) + + (** + Indicates whether the term is of an array sort. + *) + let is_finite_domain ( x : expr ) = + ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + + (** + Indicates whether the term is a less than predicate over a finite domain. + *) + let is_finite_domain_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FD_LT) + + (** + The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. + + *) + let get_index ( x : expr ) = + if not (AST.is_var x) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value x#gnc x#gno +end + +(* Integer Numerals *) +module IntNum = +struct + (** Retrieve the int value. *) + let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** Rational Numerals *) +module RatNum = +struct + + (** The numerator of a rational numeral. *) + let get_numerator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) + + (** The denominator of a rational numeral. *) + let get_denominator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : rat_num ) (precision : int) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** Bit-vector numerals *) +module BitVecNum = +struct + (** Retrieve the int value. *) + let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** Algebraic numbers *) +module AlgebraicNum = +struct + (** + Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + + the precision of the result + A numeral Expr of sort Real + *) + let to_upper ( x : algebraic_num ) ( precision : int ) = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) + + (** + Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + + + A numeral Expr of sort Real + *) + let to_lower ( x : algebraic_num ) precision = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** The main interaction with Z3 happens via the Context module. *) module Context = struct + + (* SYMBOLS *) + (** Creates a new symbol using an integer. Not all integers can be passed to this function. The legal range of unsigned integers is 0 to 2^30-1. *) - let mk_symbol_int ctx i = + let mk_symbol_int ( ctx : context ) i = (new int_symbol ctx)#cnstr_int i - + (** Creates a new symbol using a string. *) - let mk_symbol_string ctx s = + let mk_symbol_string ( ctx : context ) s = (new string_symbol ctx)#cnstr_string s (** Create an array of symbols. *) - let mk_symbols ctx names = - let f elem = mk_symbol_string ctx elem in + let mk_symbols_int ( ctx : context ) names = + let f elem = mk_symbol_int ( ctx : context ) elem in + (Array.map f names) + + (** + Create an array of symbols. + *) + let mk_symbols_string ( ctx : context ) names = + let f elem = mk_symbol_string ( ctx : context ) elem in (Array.map f names) + + (* SORTS *) + + (** + Create a new Boolean sort. + *) + let mk_bool_sort ( ctx : context ) = + (new bool_sort ctx) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_sort ( ctx : context ) (s : symbol) = + (new uninterpreted_sort ctx)#cnstr_s s + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_sort_s ( ctx : context ) (s : string) = + mk_uninterpreted_sort ctx ((mk_symbol_string ( ctx : context ) s) :> symbol) + + (** + Create a new integer sort. + *) + let mk_int_sort ( ctx : context ) = + (new int_sort ctx) + + (** + Create a real sort. + *) + let mk_real_sort ( ctx : context ) = + (new real_sort ctx) + + (** + Create a new bit-vector sort. + *) + let mk_bitvec_sort ( ctx : context ) size = + (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) + + (** + Create a new array sort. + *) + let mk_array_sort ( ctx : context ) domain range = + (new array_sort ctx)#cnstr_dr domain range + + (** + Create a new tuple sort. + *) + let mk_tuple_sort ( ctx : context ) name field_names field_sorts = + (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts + + (** + Create a new enumeration sort. + *) + let mk_enum_sort ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss name enum_names + + (** + Create a new enumeration sort. + *) + let mk_enum_sort_s ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss + ((mk_symbol_string ( ctx : context ) name) :> symbol) + (let f e = (e :> symbol) in + (Array.map f (mk_symbols_string ( ctx : context ) enum_names)) + ) + + (** + Create a new list sort. + *) + let mk_list_sort ( ctx : context ) (name : symbol) elem_sort = + (new list_sort ctx)#cnstr_ss name elem_sort + + (** + Create a new list sort. + *) + let mk_list_sort_s ( ctx : context ) (name : string) elem_sort = + mk_list_sort ctx ((mk_symbol_string ctx name) :> symbol) elem_sort + + + (** + Create a new finite domain sort. + *) + let mk_finite_domain_sort ( ctx : context ) ( name : symbol ) size = + (new finite_domain_sort ctx)#cnstr_si name size + + (** + Create a new finite domain sort. + *) + let mk_finite_domain_sort_s ( ctx : context ) ( name : string ) size = + (new finite_domain_sort ctx)#cnstr_si ((mk_symbol_string ctx name) :> symbol) size + +(** + +(* DATATYPES *) +(** + Create a datatype constructor. +*) + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) + { + + + + + return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs); + } + +(** + Create a datatype constructor. +*) + @param name + @param recognizer + @param fieldNames + @param sorts + @param sortRefs + @return + public Constructor MkConstructor(string name, string recognizer, string[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) + { + + + return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); + } + +(** + Create a new datatype sort. +*) + let mk_Datatype_Sort(Symbol name, Constructor[] constructors) + { + + + + + + + CheckContextMatch(name); + CheckContextMatch(constructors); + return new DatatypeSort(this, name, constructors); + } + +(** + Create a new datatype sort. +*) + let mk_Datatype_Sort(string name, Constructor[] constructors) + { + + + + + CheckContextMatch(constructors); + return new DatatypeSort(this, MkSymbol(name), constructors); + } + +(** + Create mutually recursive datatypes. +*) + @param names names of datatype sorts + @param c list of constructors, one list per sort. + let mk_Datatype_Sorts(Symbol[] names, Constructor[][] c) + { + + + + + + + + CheckContextMatch(names); + uint n = (uint)names.Length; + ConstructorList[] cla = new ConstructorList[n]; + IntPtr[] n_constr = new IntPtr[n]; + for (uint i = 0; i < n; i++) + { + Constructor[] constructor = c[i]; + + CheckContextMatch(constructor); + cla[i] = new ConstructorList(this, constructor); + n_constr[i] = cla[i].x#gno; + } + IntPtr[] n_res = new IntPtr[n]; + Z3native.mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr); + DatatypeSort[] res = new DatatypeSort[n]; + for (uint i = 0; i < n; i++) + res[i] = new DatatypeSort(this, n_res[i]); + return res; + } + +(** + Create mutually recursive data-types. +*) + @param names + @param c + @return + let mk_Datatype_Sorts(string[] names, Constructor[][] c) + { + + + + + + + + return MkDatatypeSorts(MkSymbols(names), c); + } + + + + +(* FUNCTION DECLARATIONS *) +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(Symbol name, Sort[] domain, Sort range) + { + + + + + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + return new Func_Decl(this, name, domain, range); + } + +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(Symbol name, Sort domain, Sort range) + { + + + + + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new Func_Decl(this, name, q, range); + } + +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(string name, Sort[] domain, Sort range) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(range); + return new Func_Decl(this, MkSymbol(name), domain, range); + } + +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(string name, Sort domain, Sort range) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new Func_Decl(this, MkSymbol(name), q, range); + } + +(** + Creates a fresh function declaration with a name prefixed with . +*) + + + let mk_Fresh_Func_Decl(string prefix, Sort[] domain, Sort range) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(range); + return new Func_Decl(this, prefix, domain, range); + } + +(** + Creates a new constant function declaration. +*) + let mk_Const_Decl(Symbol name, Sort range) + { + + + + + CheckContextMatch(name); + CheckContextMatch(range); + return new Func_Decl(this, name, null, range); + } + +(** + Creates a new constant function declaration. +*) + let mk_Const_Decl(string name, Sort range) + { + + + + CheckContextMatch(range); + return new Func_Decl(this, MkSymbol(name), null, range); + } + +(** + Creates a fresh constant function declaration with a name prefixed with . +*) + + + let mk_Fresh_ConstDecl(string prefix, Sort range) + { + + + + CheckContextMatch(range); + return new Func_Decl(this, prefix, null, range); + } + + +(* BOUND VARIABLES *) +(** + Creates a new bound variable. +*) + @param index The de-Bruijn index of the variable + @param ty The sort of the variable + public Expr MkBound(uint index, Sort ty) + { + + + + return Expr.Create(this, Z3native.mk_bound(nCtx, index, ty.x#gno)); + } + + +(* QUANTIFIER PATTERNS *) +(** + Create a quantifier pattern. +*) + public Pattern MkPattern(params Expr[] terms) + { + + if (terms.Length == 0) + throw new Z3Exception("Cannot create a pattern from zero terms"); + + + + + + IntPtr[] termsNative = AST.ArrayToNative(terms); + return new Pattern(this, Z3native.mk_pattern(nCtx, (uint)terms.Length, termsNative)); + } + + +(* CONSTANTS *) +(** + Creates a new Constant of sort and named . +*) + public Expr MkConst(Symbol name, Sort range) + { + + + + + CheckContextMatch(name); + CheckContextMatch(range); + + return Expr.Create(this, Z3native.mk_const(nCtx, name.x#gno, range.x#gno)); + } + +(** + Creates a new Constant of sort and named . +*) + public Expr MkConst(string name, Sort range) + { + + + + return MkConst(MkSymbol(name), range); + } + +(** + Creates a fresh Constant of sort and a + name prefixed with . +*) + let mk_Fresh_Const(string prefix, Sort range) + { + + + + CheckContextMatch(range); + return Expr.Create(this, Z3native.mk_fresh_const(nCtx, prefix, range.x#gno)); + } + +(** + Creates a fresh constant from the Func_Decl . +*) + @param f A decl of a 0-arity function + public Expr MkConst(Func_Decl f) + { + + + + return MkApp(f); + } + +(** + Create a Boolean constant. +*) + let mk_Bool_Const(Symbol name) + { + + + + return (BoolExpr)MkConst(name, BoolSort); + } + +(** + Create a Boolean constant. +*) + let mk_Bool_Const(string name) + { + + + return (BoolExpr)MkConst(MkSymbol(name), BoolSort); + } + +(** + Creates an integer constant. +*) + let mk_Int_Const(Symbol name) + { + + + + return (IntExpr)MkConst(name, IntSort); + } + +(** + Creates an integer constant. +*) + let mk_Int_Const(string name) + { + + + + return (IntExpr)MkConst(name, IntSort); + } + +(** + Creates a real constant. +*) + let mk_Real_Const(Symbol name) + { + + + + return (RealExpr)MkConst(name, RealSort); + } + +(** + Creates a real constant. +*) + let mk_Real_Const(string name) + { + + + return (RealExpr)MkConst(name, RealSort); + } + +(** + Creates a bit-vector constant. +*) + let mk_B_VConst(Symbol name, uint size) + { + + + + return (BitVecExpr)MkConst(name, MkBitVecSort(size)); + } + +(** + Creates a bit-vector constant. +*) + let mk_B_VConst(string name, uint size) + { + + + return (BitVecExpr)MkConst(name, MkBitVecSort(size)); + } + + +(* TERMS *) +(** + Create a new function application. +*) + public Expr MkApp(Func_Decl f, params Expr[] args) + { + + + + + CheckContextMatch(f); + CheckContextMatch(args); + return Expr.Create(this, f, args); + } + +(* PROPOSITIONAL *) +(** + The true Term. +*) + public BoolExpr MkTrue ( ctx : context ) = + { + + + return new BoolExpr(this, Z3native.mk_true(nCtx)); + } + +(** + The false Term. +*) + public BoolExpr MkFalse ( ctx : context ) = + { + + + return new BoolExpr(this, Z3native.mk_false(nCtx)); + } + +(** + Creates a Boolean value. +*) + public BoolExpr MkBool(bool value) + { + + + return value ? MkTrue ( ctx : context ) = : MkFalse ( ctx : context ) =; + } + +(** + Creates the equality = . +*) + public BoolExpr MkEq(Expr x, Expr y) + { + + + + + CheckContextMatch(x); + CheckContextMatch(y); + return new BoolExpr(this, Z3native.mk_eq(nCtx, x.x#gno, y.x#gno)); + } + +(** + Creates a distinct term. +*) + public BoolExpr MkDistinct(params Expr[] args) + { + + + + + + CheckContextMatch(args); + return new BoolExpr(this, Z3native.mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + +(** + Mk an expression representing not(a). +*) + public BoolExpr MkNot(BoolExpr a) + { + + + + CheckContextMatch(a); + return new BoolExpr(this, Z3native.mk_not(nCtx, a.x#gno)); + } + +(** + Create an expression representing an if-then-else: ite(t1, t2, t3). +*) + @param t1 An expression with Boolean sort + @param t2 An expression + @param t3 An expression with the same sort as + let mk_I_TE(BoolExpr t1, Expr t2, Expr t3) + { + + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(t3); + return Expr.Create(this, Z3native.mk_ite(nCtx, t1.x#gno, t2.x#gno, t3.x#gno)); + } + +(** + Create an expression representing t1 iff t2. +*) + public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_iff(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 -> t2. +*) + public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_implies(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 xor t2. +*) + public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_xor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t[0] and t[1] and .... +*) + public BoolExpr MkAnd(params BoolExpr[] t) + { + + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing t[0] or t[1] or .... +*) + public BoolExpr MkOr(params BoolExpr[] t) + { + + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + + +(* ARITHMETIC *) +(** + Create an expression representing t[0] + t[1] + .... +*) + public ArithExpr MkAdd(params ArithExpr[] t) + { + + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing t[0] * t[1] * .... +*) + public ArithExpr MkMul(params ArithExpr[] t) + { + + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing t[0] - t[1] - .... +*) + public ArithExpr MkSub(params ArithExpr[] t) + { + + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing -t. +*) + let mk_Unary_Minus(ArithExpr t) + { + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_unary_minus(nCtx, t.x#gno)); + } + +(** + Create an expression representing t1 / t2. +*) + public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr)Expr.Create(this, Z3native.mk_div(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 mod t2. +*) + The arguments must have int type. + public IntExpr MkMod(IntExpr t1, IntExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Z3native.mk_mod(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 rem t2. +*) + The arguments must have int type. + public IntExpr MkRem(IntExpr t1, IntExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Z3native.mk_rem(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 ^ t2. +*) + public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr)Expr.Create(this, Z3native.mk_power(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 < t2 +*) + public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_lt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 <= t2 +*) + public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_le(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 > t2 +*) + public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_gt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 >= t2 +*) + public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_ge(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Coerce an integer to a real. +*) + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. + + public RealExpr MkInt2Real(IntExpr t) + { + + + + CheckContextMatch(t); + return new RealExpr(this, Z3native.mk_int2real(nCtx, t.x#gno)); + } + +(** + Coerce a real to an integer. +*) + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. + + public IntExpr MkReal2Int(RealExpr t) + { + + + + CheckContextMatch(t); + return new IntExpr(this, Z3native.mk_real2int(nCtx, t.x#gno)); + } + +(** + Creates an expression that checks whether a real number is an integer. +*) + let mk_Is_Integer(RealExpr t) + { + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_is_int(nCtx, t.x#gno)); + } + + +(* BIT-VECTORS *) +(** + Bitwise negation. +*) + The argument must have a bit-vector sort. + let mk_B_VNot(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvnot(nCtx, t.x#gno)); + } + +(** + Take conjunction of bits in a vector, return vector of length 1. +*) + The argument must have a bit-vector sort. + let mk_B_VRedAND(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvredand(nCtx, t.x#gno)); + } + +(** + Take disjunction of bits in a vector, return vector of length 1. +*) + The argument must have a bit-vector sort. + let mk_B_VRedOR(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvredor(nCtx, t.x#gno)); + } + +(** + Bitwise conjunction. +*) + The arguments must have a bit-vector sort. + let mk_B_VAND(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvand(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise disjunction. +*) + The arguments must have a bit-vector sort. + let mk_B_VOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise XOR. +*) + The arguments must have a bit-vector sort. + let mk_B_VXOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvxor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise NAND. +*) + The arguments must have a bit-vector sort. + let mk_B_VNAND(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvnand(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise NOR. +*) + The arguments must have a bit-vector sort. + let mk_B_VNOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvnor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise XNOR. +*) + The arguments must have a bit-vector sort. + let mk_B_VXNOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvxnor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Standard two's complement unary minus. +*) + The arguments must have a bit-vector sort. + let mk_B_VNeg(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvneg(nCtx, t.x#gno)); + } + +(** + Two's complement addition. +*) + The arguments must have the same bit-vector sort. + let mk_B_VAdd(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvadd(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement subtraction. +*) + The arguments must have the same bit-vector sort. + let mk_B_VSub(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsub(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement multiplication. +*) + The arguments must have the same bit-vector sort. + let mk_B_VMul(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvmul(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned division. +*) + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VUDiv(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvudiv(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Signed division. +*) + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VSDiv(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsdiv(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned remainder. +*) + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VURem(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvurem(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Signed remainder. +*) + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VSRem(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsrem(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed remainder (sign follows divisor). +*) + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VSMod(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsmod(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned less-than +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VULT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvult(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed less-than +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSLT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvslt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned less-than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VULE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvule(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed less-than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSLE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsle(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned greater than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VUGE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvuge(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed greater than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSGE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsge(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned greater-than. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VUGT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvugt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed greater-than. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSGT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsgt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bit-vector concatenation. +*) + + The arguments must have a bit-vector sort. + + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). + + public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_concat(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bit-vector extraction. +*) + + Extract the bits down to from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. + The argument must have a bit-vector sort. + + public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_extract(nCtx, high, low, t.x#gno)); + } + +(** + Bit-vector sign extension. +*) + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. + The argument must have a bit-vector sort. + + let mk_Sign_Ext(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_sign_ext(nCtx, i, t.x#gno)); + } + +(** + Bit-vector zero extension. +*) + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. + The argument must have a bit-vector sort. + + let mk_Zero_Ext(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_zero_ext(nCtx, i, t.x#gno)); + } + +(** + Bit-vector repetition. +*) + + The argument must have a bit-vector sort. + + public BitVecExpr MkRepeat(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_repeat(nCtx, i, t.x#gno)); + } + +(** + Shift left. +*) + + It is equivalent to multiplication by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + + let mk_B_VSHL(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvshl(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Logical shift right +*) + + It is equivalent to unsigned division by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + + let mk_B_VLSHR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvlshr(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Arithmetic shift right +*) + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + + let mk_B_VASHR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvashr(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Rotate Left. +*) + + Rotate bits of \c t to the left \c i times. + The argument must have a bit-vector sort. + + let mk_B_VRotateLeft(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_rotate_left(nCtx, i, t.x#gno)); + } + +(** + Rotate Right. +*) + + Rotate bits of \c t to the right \c i times. + The argument must have a bit-vector sort. + + let mk_B_VRotateRight(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_rotate_right(nCtx, i, t.x#gno)); + } + +(** + Rotate Left. +*) + + Rotate bits of to the left times. + The arguments must have the same bit-vector sort. + + let mk_B_VRotateLeft(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_ext_rotate_left(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Rotate Right. +*) + + Rotate bits of to the right times. + The arguments must have the same bit-vector sort. + + let mk_B_VRotateRight(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_ext_rotate_right(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an bit bit-vector from the integer argument . +*) + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. + + public BitVecExpr MkInt2BV(uint n, IntExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_int2bv(nCtx, n, t.x#gno)); + } + +(** + Create an integer from the bit-vector argument . +*) + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in . + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of bit-vector sort. + + let mk_B_V2Int(BitVecExpr t, bool signed) + { + + + + CheckContextMatch(t); + return new IntExpr(this, Z3native.mk_bv2int(nCtx, t.x#gno, (signed) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise addition does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VAddNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvadd_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise addition does not underflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvadd_no_underflow(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise subtraction does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VSubNoOverflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsub_no_overflow(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise subtraction does not underflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsub_no_underflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise signed division does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsdiv_no_overflow(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise negation does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VNegNoOverflow(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_bvneg_no_overflow(nCtx, t.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise multiplication does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VMulNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvmul_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise multiplication does not underflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvmul_no_underflow(nCtx, t1.x#gno, t2.x#gno)); + } + + +(* ARRAYS *) +(** + Create an array constant. +*) + let mk_Array_Const(Symbol name, Sort domain, Sort range) + { + + + + + + return (ArrayExpr)MkConst(name, MkArraySort(domain, range)); + } + +(** + Create an array constant. +*) + let mk_Array_Const(string name, Sort domain, Sort range) + { + + + + + return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); + } + +(** + Array read. +*) + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + + + + public Expr MkSelect(ArrayExpr a, Expr i) + { + + + + + CheckContextMatch(a); + CheckContextMatch(i); + return Expr.Create(this, Z3native.mk_select(nCtx, a.x#gno, i.x#gno)); + } + +(** + Array update. +*) + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + + + + public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) + { + + + + + + CheckContextMatch(a); + CheckContextMatch(i); + CheckContextMatch(v); + return new ArrayExpr(this, Z3native.mk_store(nCtx, a.x#gno, i.x#gno, v.x#gno)); + } + +(** + Create a constant array. +*) + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + + + + let mk_Const_Array(Sort domain, Expr v) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(v); + return new ArrayExpr(this, Z3native.mk_const_array(nCtx, domain.x#gno, v.x#gno)); + } + +(** + Maps f on the argument arrays. +*) + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + + + + + public ArrayExpr MkMap(Func_Decl f, params ArrayExpr[] args) + { + + + + + CheckContextMatch(f); + CheckContextMatch(args); + return (ArrayExpr)Expr.Create(this, Z3native.mk_map(nCtx, f.x#gno, AST.ArrayLength(args), AST.ArrayToNative(args))); + } + +(** + Access the array default value. +*) + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. + + let mk_Term_Array(ArrayExpr array) + { + + + + CheckContextMatch(array); + return Expr.Create(this, Z3native.mk_array_default(nCtx, array.x#gno)); + } + + +(* SETS *) +(** + Create a set type. +*) + let mk_Set_Sort(Sort ty) + { + + + + CheckContextMatch(ty); + return new SetSort(this, ty); + } + +(** + Create an empty set. +*) + let mk_Empty_Set(Sort domain) + { + + + + CheckContextMatch(domain); + return Expr.Create(this, Z3native.mk_empty_set(nCtx, domain.x#gno)); + } + +(** + Create the full set. +*) + let mk_Full_Set(Sort domain) + { + + + + CheckContextMatch(domain); + return Expr.Create(this, Z3native.mk_full_set(nCtx, domain.x#gno)); + } + +(** + Add an element to the set. +*) + let mk_Set_Add(Expr set, Expr element) + { + + + + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create(this, Z3native.mk_set_add(nCtx, set.x#gno, element.x#gno)); + } + + +(** + Remove an element from a set. +*) + let mk_Set_Del(Expr set, Expr element) + { + + + + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create(this, Z3native.mk_set_del(nCtx, set.x#gno, element.x#gno)); + } + +(** + Take the union of a list of sets. +*) + let mk_Set_Union(params Expr[] args) + { + + + + CheckContextMatch(args); + return Expr.Create(this, Z3native.mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + +(** + Take the intersection of a list of sets. +*) + let mk_Set_Intersection(params Expr[] args) + { + + + + + CheckContextMatch(args); + return Expr.Create(this, Z3native.mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + +(** + Take the difference between two sets. +*) + let mk_Set_Difference(Expr arg1, Expr arg2) + { + + + + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create(this, Z3native.mk_set_difference(nCtx, arg1.x#gno, arg2.x#gno)); + } + +(** + Take the complement of a set. +*) + let mk_Set_Complement(Expr arg) + { + + + + CheckContextMatch(arg); + return Expr.Create(this, Z3native.mk_set_complement(nCtx, arg.x#gno)); + } + +(** + Check for set membership. +*) + let mk_Set_Membership(Expr elem, Expr set) + { + + + + + CheckContextMatch(elem); + CheckContextMatch(set); + return Expr.Create(this, Z3native.mk_set_member(nCtx, elem.x#gno, set.x#gno)); + } + +(** + Check for subsetness of sets. +*) + let mk_Set_Subset(Expr arg1, Expr arg2) + { + + + + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create(this, Z3native.mk_set_subset(nCtx, arg1.x#gno, arg2.x#gno)); + } + + +(* NUMERALS *) + +(* GENERAL NUMERALS *) +(** + Create a Term of a given sort. +*) + @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + @return A Term with value and sort + public Expr MkNumeral(string v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_numeral(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(int v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_int(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(uint v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_unsigned_int(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(long v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_int64(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(ulong v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_unsigned_int64(nCtx, v, ty.x#gno)); + } + + +(* REALS *) +(** + Create a real from a fraction. +*) + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + public RatNum MkReal(int num, int den) + { + if (den == 0) + throw new Z3Exception("Denominator is zero"); + + + + + return new RatNum(this, Z3native.mk_real(nCtx, num, den)); + } + +(** + Create a real numeral. +*) + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + public RatNum MkReal(string v) + { + + + return new RatNum(this, Z3native.mk_numeral(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(int v) + { + + + return new RatNum(this, Z3native.mk_int(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(uint v) + { + + + return new RatNum(this, Z3native.mk_unsigned_int(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(long v) + { + + + return new RatNum(this, Z3native.mk_int64(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(ulong v) + { + + + return new RatNum(this, Z3native.mk_unsigned_int64(nCtx, v, RealSort.x#gno)); + } + + +(* INTEGERS *) +(** + Create an integer numeral. +*) + @param v A string representing the Term value in decimal notation. + public IntNum MkInt(string v) + { + + + return new IntNum(this, Z3native.mk_numeral(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(int v) + { + + + return new IntNum(this, Z3native.mk_int(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(uint v) + { + + + return new IntNum(this, Z3native.mk_unsigned_int(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(long v) + { + + + return new IntNum(this, Z3native.mk_int64(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(ulong v) + { + + + return new IntNum(this, Z3native.mk_unsigned_int64(nCtx, v, IntSort.x#gno)); + } + + +(* BIT-VECTORS *) +(** + Create a bit-vector numeral. +*) + @param v A string representing the value in decimal notation. + @param size the size of the bit-vector + let mk_B_V(string v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(int v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(uint v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(long v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(ulong v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + + + // Numerals + +(* QUANTIFIERS *) +(** + Create a universal Quantifier. +*) + + Creates a forall formula, where is the weight, + is an array of patterns, is an array + with the sorts of the bound variables, is an array with the + 'names' of the bound variables, and is the body of the + quantifier. Quantifiers are associated with weights indicating + the importance of using the quantifier during instantiation. + + @param sorts the sorts of the bound variables. + @param names names of the bound variables + @param body the body of the quantifier. + @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + @param patterns array containing the patterns created using MkPattern. + @param noPatterns array containing the anti-patterns created using MkPattern. + @param quantifierID optional symbol to track quantifier. + @param skolemID optional symbol to track skolem constants. + public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + + + + + return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + +(** + Create a universal Quantifier. +*) + public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + +(** + Create an existential Quantifier. +*) + + public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + + + + return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + +(** + Create an existential Quantifier. +*) + public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + +(** + Create a Quantifier. +*) + public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + + + + + if (universal) + return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + +(** + Create a Quantifier. +*) + public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + if (universal) + return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + + + // Expr + +(* OPTIONS *) + +(** + Selects the format used for pretty-printing expressions. +*) + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the Z3_PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + + + + + + public Z3_ast_print_mode PrintMode + { + set { Z3native.set_ast_print_mode(nCtx, (uint)value); } + } + + +(* SMT Files & Strings *) +(** + Convert a benchmark into an SMT-LIB formatted string. +*) + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) + { + + + + + return Z3native.benchmark_to_smtlib_string(nCtx, name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula.x#gno); + } + +(** + Parse the given string using the SMT-LIB parser. +*) + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. + + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_string(nCtx, str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); + } + +(** + Parse the given file using the SMT-LIB parser. +*) + + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_file(nCtx, fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); + } + +(** + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBFormulas { get { return Z3native.get_smtlib_num_formulas(nCtx)) + +(** + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public BoolExpr[] SMTLIBFormulas + { + get + { + + + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_formula(nCtx, i)); + return res; + } + } + +(** + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBAssumptions { get { return Z3native.get_smtlib_num_assumptions(nCtx)) + +(** + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public BoolExpr[] SMTLIBAssumptions + { + get + { + + + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_assumption(nCtx, i)); + return res; + } + } + +(** + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBDecls { get { return Z3native.get_smtlib_num_decls(nCtx)) + +(** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public Func_Decl[] SMTLIBDecls + { + get + { + + + uint n = NumSMTLIBDecls; + Func_Decl[] res = new Func_Decl[n]; + for (uint i = 0; i < n; i++) + res[i] = new Func_Decl(this, Z3native.get_smtlib_decl(nCtx, i)); + return res; + } + } + +(** + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBSorts { get { return Z3native.get_smtlib_num_sorts(nCtx)) + +(** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public Sort[] SMTLIBSorts + { + get + { + + + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Z3native.get_smtlib_sort(nCtx, i)); + return res; + } + } + +(** + Parse the given string using the SMT-LIB2 parser. +*) + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_string(nCtx, str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + +(** + Parse the given file using the SMT-LIB2 parser. +*) + + public BoolExpr ParseSMTLIB2File(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_file(nCtx, fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + + +(* GOALS *) +(** + Creates a new Goal. +*) + + Note that the Context must have been created with proof generation support if + is set to true here. + + @param models Indicates whether model generation should be enabled. + @param unsatCores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) + { + + + return new Goal(this, models, unsatCores, proofs); + } + + +(* PARAMETERSETS *) +(** + Creates a new ParameterSet. +*) + public Params MkParams ( ctx : context ) = + { + + + return new Params(this); + } + + +(* TACTICS *) +(** + The number of supported tactics. +*) + public uint NumTactics + { + get { return Z3native.get_num_tactics(nCtx); } + } + +(** + The names of all supported tactics. +*) + public string[] TacticNames + { + get + { + + + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_tactic_name(nCtx, i); + return res; + } + } + +(** + Returns a string containing a description of the tactic with the given name. +*) + public string TacticDescription(string name) + { + + + return Z3native.tactic_get_descr(nCtx, name); + } + +(** + Creates a new Tactic. +*) + public Tactic MkTactic(string name) + { + + + return new Tactic(this, name); + } + +(** + Create a tactic that applies to a Goal and + then to every subgoal produced by . +*) + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + { + + + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(ts); + + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) + { + last = ts[ts.Length - 1].x#gno; + for (int i = ts.Length - 2; i >= 0; i--) + last = Z3native.tactic_and_then(nCtx, ts[i].x#gno, last); + } + if (last != IntPtr.Zero) + { + last = Z3native.tactic_and_then(nCtx, t2.x#gno, last); + return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, last)); + } + else + return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a tactic that applies to a Goal and + then to every subgoal produced by . +*) + + Shorthand for AndThen. + + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) + { + + + + + + return AndThen(t1, t2, ts); + } + +(** + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. +*) + public Tactic OrElse(Tactic t1, Tactic t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Z3native.tactic_or_else(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a tactic that applies to a goal for milliseconds. +*) + + If does not terminate within milliseconds, then it fails. + + public Tactic TryFor(Tactic t, uint ms) + { + + + + CheckContextMatch(t); + return new Tactic(this, Z3native.tactic_try_for(nCtx, t.x#gno, ms)); + } + +(** + Create a tactic that applies to a given goal if the probe + evaluates to true. +*) + + If evaluates to false, then the new tactic behaves like the skip tactic. + + public Tactic When(Probe p, Tactic t) + { + + + + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Z3native.tactic_when(nCtx, p.x#gno, t.x#gno)); + } + +(** + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. +*) + public Tactic Cond(Probe p, Tactic t1, Tactic t2) + { + + + + + + CheckContextMatch(p); + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Z3native.tactic_cond(nCtx, p.x#gno, t1.x#gno, t2.x#gno)); + } + +(** + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. +*) + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) + { + + + + CheckContextMatch(t); + return new Tactic(this, Z3native.tactic_repeat(nCtx, t.x#gno, max)); + } + +(** + Create a tactic that just returns the given goal. +*) + public Tactic Skip ( ctx : context ) = + { + + + return new Tactic(this, Z3native.tactic_skip(nCtx)); + } + +(** + Create a tactic always fails. +*) + public Tactic Fail ( ctx : context ) = + { + + + return new Tactic(this, Z3native.tactic_fail(nCtx)); + } + +(** + Create a tactic that fails if the probe evaluates to false. +*) + public Tactic FailIf(Probe p) + { + + + + CheckContextMatch(p); + return new Tactic(this, Z3native.tactic_fail_if(nCtx, p.x#gno)); + } + +(** + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). +*) + public Tactic FailIfNotDecided ( ctx : context ) = + { + + + return new Tactic(this, Z3native.tactic_fail_if_not_decided(nCtx)); + } + +(** + Create a tactic that applies using the given set of parameters . +*) + public Tactic UsingParams(Tactic t, Params p) + { + + + + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Z3native.tactic_using_params(nCtx, t.x#gno, p.x#gno)); + } + +(** + Create a tactic that applies using the given set of parameters . +*) + Alias for UsingParams + public Tactic With(Tactic t, Params p) + { + + + + + return UsingParams(t, p); + } + +(** + Create a tactic that applies the given tactics in parallel. +*) + public Tactic ParOr(params Tactic[] t) + { + + + + CheckContextMatch(t); + return new Tactic(this, Z3native.tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); + } + +(** + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. +*) + public Tactic ParAndThen(Tactic t1, Tactic t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Z3native.tactic_par_and_then(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Interrupt the execution of a Z3 procedure. +*) + This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt ( ctx : context ) = + { + Z3native.interrupt(nCtx); + } + + +(* PROBES *) +(** + The number of supported Probes. +*) + public uint NumProbes + { + get { return Z3native.get_num_probes(nCtx); } + } + +(** + The names of all supported Probes. +*) + public string[] ProbeNames + { + get + { + + + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_probe_name(nCtx, i); + return res; + } + } + +(** + Returns a string containing a description of the probe with the given name. +*) + public string ProbeDescription(string name) + { + + + return Z3native.probe_get_descr(nCtx, name); + } + +(** + Creates a new Probe. +*) + public Probe MkProbe(string name) + { + + + return new Probe(this, name); + } + +(** + Create a probe that always evaluates to . +*) + public Probe Const(double val) + { + + + return new Probe(this, Z3native.probe_const(nCtx, val)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by +*) + public Probe Lt(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_lt(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by +*) + public Probe Gt(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_gt(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by +*) + public Probe Le(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_le(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by +*) + public Probe Ge(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_ge(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by +*) + public Probe Eq(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_eq(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value + and evaluate to "true". +*) + public Probe And(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_and(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value + or evaluate to "true". +*) + public Probe Or(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_or(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". +*) + public Probe Not(Probe p) + { + + + + CheckContextMatch(p); + return new Probe(this, Z3native.probe_not(nCtx, p.x#gno)); + } + + +(* SOLVERS *) +(** + Creates a new (incremental) solver. +*) + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. + + public Solver MkSolver(Symbol logic = null) + { + + + if (logic == null) + return new Solver(this, Z3native.mk_solver(nCtx)); + else + return new Solver(this, Z3native.mk_solver_for_logic(nCtx, logic.x#gno)); + } + +(** + Creates a new (incremental) solver. +*) + + public Solver MkSolver(string logic) + { + + + return MkSolver(MkSymbol(logic)); + } + +(** + Creates a new (incremental) solver. +*) + let mk_Simple_Solver ( ctx : context ) = + { + + + return new Solver(this, Z3native.mk_simple_solver(nCtx)); + } + +(** + Creates a solver that is implemented using the given tactic. +*) + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. + + public Solver MkSolver(Tactic t) + { + + + + return new Solver(this, Z3native.mk_solver_from_tactic(nCtx, t.x#gno)); + } + + +(* FIXEDPOINTS *) +(** + Create a Fixedpoint context. +*) + public Fixedpoint MkFixedpoint ( ctx : context ) = + { + + + return new Fixedpoint(this); + } + + + +(* MISCELLANEOUS *) +(** + Wraps an AST. +*) + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) + { + + return AST.Create(this, nativeObject); + } + +(** + Unwraps an AST. +*) + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + public IntPtr UnwrapAST(AST a) + { + return a.x#gno; + } + +(** + Return a string describing all available parameters to Expr.Simplify. +*) + public string SimplifyHelp ( ctx : context ) = + { + + + return Z3native.simplify_get_help(nCtx); + } + +(** + Retrieves parameter descriptions for simplifier. +*) + public ParamDescrs SimplifyParameterDescriptions + { + get { return new ParamDescrs(this, Z3native.simplify_get_param_descrs(nCtx)); } + } + +(** + Enable/disable printing of warning messages to the console. +*) + Note that this function is static and effects the behaviour of + all contexts globally. + public static void ToggleWarningMessages(bool enabled) + { + Z3native.toggle_warning_messages((enabled) ? 1 : 0); + } + + +(* ERROR HANDLING *) + //(** + //A delegate which is executed when an error is raised. + //*) + // + //Note that it is possible for memory leaks to occur if error handlers + //throw exceptions. + // + //public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); + + //(** + //The OnError event. + //*) + //public event ErrorHandler OnError = null; + + +(* PARAMETERS *) +(** + Update a mutable configuration parameter. +*) + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + + + public void UpdateParamValue(string id, string value) + { + Z3native.update_param_value(nCtx, id, value); + } + +(** + Get a configuration parameter. +*) + + Returns null if the parameter value does not exist. + + + public string GetParamValue(string id) + { + IntPtr res = IntPtr.Zero; + int r = Z3native.get_param_value(nCtx, id, out res); + if (r == (int)Z3_lbool.Z3_L_FALSE) + return null; + else + return Marshal.PtrToStringAnsi(res); + } + + + +(* INTERNAL *) + internal IntPtr m_ctx = IntPtr.Zero; + internal Z3native.error_handler m_n_err_handler = null; + internal IntPtr nCtx { get { return m_ctx) + + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + { + // Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + } + + internal void InitContext ( ctx : context ) = + { + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); // keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); + } +*) end From 2277ad3654e4778d6ca9b0a904c4ac8e637cce4f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 01:45:10 +0000 Subject: [PATCH 243/507] ML API bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 8 ++- scripts/update_api.py | 2 +- src/api/ml/z3.ml | 136 ++++++++++++++++++++------------------ 3 files changed, 80 insertions(+), 66 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 7046a92b0..f414e9d1a 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -18,10 +18,16 @@ let _ = let ctx = (new context cfg) in let is = (mk_symbol_int ctx 42) in let ss = (mk_symbol_string ctx "mySymbol") in + let bs = (mk_bool_sort ctx) in + let ints = (mk_int_sort ctx) in + let rs = (mk_real_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); Printf.printf "string symbol: %s\n" (Symbol.to_string (ss :> symbol)); + Printf.printf "bool sort: %s\n" (Sort.to_string bs); + Printf.printf "int sort: %s\n" (Sort.to_string ints); + Printf.printf "real sort: %s\n" (Sort.to_string rs); Printf.printf "Disposing...\n"; - ctx#dispose (* can do, but we'd rather let it go out of scope *) ; + Gc.full_major () ); Printf.printf "Exiting.\n"; ;; diff --git a/scripts/update_api.py b/scripts/update_api.py index c8cd05c7e..c3f2abce6 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1280,7 +1280,7 @@ def mk_ml(): ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') ml_wrapper.write('\n\n') ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') - ml_wrapper.write(' identifier: "default handling",\n') + ml_wrapper.write(' identifier: (char*) "default handling",\n') ml_wrapper.write(' finalize: custom_finalize_default,\n') ml_wrapper.write(' compare: custom_compare_default,\n') ml_wrapper.write(' hash: custom_hash_default,\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 2100f371e..3a0e9208e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -30,21 +30,25 @@ object (self) Z3native.del_config(cfg) ; v - val mutable m_refCount : int = 0 + val mutable m_obj_cnt : int = 0 initializer - Gc.finalise (fun self -> self#dispose) self + (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) + let f = fun o -> o#dispose in + let v = self in + Gc.finalise f v method dispose : unit = - if m_refCount == 0 then ( - Printf.printf "Disposing context %d \n" (Oo.id self) ; + if m_obj_cnt == 0 then ( + (* Printf.printf "Disposing context %d \n" (Oo.id self) ; *) (Z3native.del_context m_n_ctx) ) else ( + Printf.printf "NOT DISPOSING context %d because it still has %d objects alive\n" (Oo.id self) m_obj_cnt; (* re-queue for finalization? *) ) - method sub_one_ctx_obj = m_refCount <- m_refCount - 1 - method add_one_ctx_obj = m_refCount <- m_refCount + 1 + method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 + method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 method gno = m_n_ctx end @@ -62,18 +66,21 @@ object (self) m_ctx#add_one_ctx_obj | None -> () ); - Gc.finalise (fun self -> self#dispose) self + (* Printf.printf "Installing finalizer on z3object %d \n" (Oo.id self) ; *) + let f = fun o -> o#dispose in + let v = self in + Gc.finalise f v method virtual incref : Z3native.ptr -> Z3native.ptr -> unit method virtual decref : Z3native.ptr -> Z3native.ptr -> unit - (* - Disposes of the underlying native Z3 object. - *) method dispose = - Printf.printf "Disposing z3object %d \n" (Oo.id self) ; + (* Printf.printf "Disposing z3object %d \n" (Oo.id self) ; *) (match m_n_obj with - | Some (x) -> self#decref m_ctx#gno x; m_n_obj <- None; m_ctx#sub_one_ctx_obj + | Some (x) -> + self#decref m_ctx#gno x; + m_ctx#sub_one_ctx_obj ; + m_n_obj <- None; | None -> () ); @@ -81,10 +88,11 @@ object (self) | Some(x) -> x | None -> raise (Z3native.Exception "Z3 object lost") - method sno nc o = - self#incref nc o ; + method sno (ctx : context) o = + m_ctx#add_one_ctx_obj ; + self#incref ctx#gno o ; (match m_n_obj with - | Some(x) -> self#decref nc x + | Some(x) -> self#decref ctx#gno x ; m_ctx#sub_one_ctx_obj | None -> () ); m_n_obj <- Some o @@ -107,7 +115,7 @@ end class symbol ctx = object (self) inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method incref ctx o = () method decref ctx o = () end @@ -120,16 +128,16 @@ let symbolaton (a : symbol array) = class int_symbol ctx = object(self) inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_int i = (self#sno ctx#gno (Z3native.mk_int_symbol ctx#gno i)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol ctx#gno i)) ; self end (** String symbol objects *) class string_symbol ctx = object(self) inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_string name = (self#sno ctx#gno (Z3native.mk_string_symbol ctx#gno name)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol ctx#gno name)) ; self end let create_symbol ctx no = @@ -141,7 +149,7 @@ let create_symbol ctx no = class ast ctx = object (self) inherit z3object ctx None as super (* CMW: derive from icomparable? *) - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method incref nc o = Z3native.inc_ref nc o method decref nc o = Z3native.dec_ref nc o @@ -155,44 +163,44 @@ let astaton (a : ast array) = class sort ctx = object (self) inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Arithmetic sort objects, i.e., Int or Real. *) class arith_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Array sorts objects *) class array_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx#gno (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self end (** Bit-vector sort objects *) class bitvec_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Boolean sort objects *) class bool_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Datatype sort objects *) class datatype_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_sc (name : symbol) constructors = (self#sno ctx#gno (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_sc (name : symbol) constructors = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self end (** Enum sort objects *) @@ -201,12 +209,12 @@ object (self) inherit sort ctx as super val mutable _constdecls = None val mutable _testerdecls = None - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (enum_names : symbol array) = let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in _constdecls <- Some a ; _testerdecls <- Some b ; - (self#sno ctx#gno r) ; + (self#sno ctx r) ; self method const_decls = match _constdecls with @@ -222,37 +230,37 @@ end class int_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Real sort objects *) class real_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Uninterpreted sort objects *) class uninterpreted_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_s (s : symbol) = (self #sno ctx#gno (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self end (** Finite domain sort objects *) class finite_domain_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx#gno (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self end (** Relation sort objects *) class relation_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** List sort objects *) @@ -265,7 +273,7 @@ object (self) val mutable _is_consdecl = None val mutable _headdecl = None val mutable _taildecl = None - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (elem_sort : sort) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in _nildecl <- Some a ; @@ -274,7 +282,7 @@ object (self) _is_consdecl <- Some d ; _headdecl <- Some e ; _taildecl <- Some f ; - (self#sno ctx#gno r) ; + (self#sno ctx r) ; self method nil_decl = match _nildecl with @@ -307,18 +315,18 @@ end class set_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_s (s : sort) = (self#sno ctx#gno s#gno) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_s (s : sort) = (self#sno ctx s#gno) ; self end (** Tuple sort objects *) class tuple_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = let (x,_,_) = (Z3native.mk_tuple_sort ctx#gno name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in - (self#sno ctx#gno x) ; + (self#sno ctx x) ; self end @@ -339,9 +347,9 @@ let create_sort ctx obj = class func_decl ctx = object (self) inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self - method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self method incref nc o = super#incref nc o method decref nc o = super#decref nc o @@ -388,7 +396,7 @@ end class expr ctx = object(self) inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end let expraton (a : expr array) = @@ -399,77 +407,77 @@ let expraton (a : expr array) = class bool_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Arithmetic expression objects (int/real) *) class arith_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Int expression objects *) class int_expr ctx = object (self) inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Real expression objects *) class real_expr ctx = object (self) inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Bit-vector expression objects *) class bitvec_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Array expression objects *) class array_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Datatype expression objects *) class datatype_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Integer numeral expression objects *) class int_num ctx = object (self) inherit int_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Rational numeral expression objects *) class rat_num ctx = object (self) inherit real_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Bit-vector numeral expression objects *) class bitvec_num ctx = object (self) inherit bitvec_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Algebraic numeral expression objects *) class algebraic_num ctx = object (self) inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end @@ -477,7 +485,7 @@ end class quantifier ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end @@ -1112,7 +1120,7 @@ struct if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - x#sno x#gnc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) + x#sno x#gc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. @@ -2483,7 +2491,7 @@ struct Create a new Boolean sort. *) let mk_bool_sort ( ctx : context ) = - (new bool_sort ctx) + (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) (** Create a new uninterpreted sort. @@ -2501,13 +2509,13 @@ struct Create a new integer sort. *) let mk_int_sort ( ctx : context ) = - (new int_sort ctx) + (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) (** Create a real sort. *) let mk_real_sort ( ctx : context ) = - (new real_sort ctx) + (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) (** Create a new bit-vector sort. From 524336ea3e21093639c54158f6c7b21b14811e02 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 03:57:18 +0000 Subject: [PATCH 244/507] New ML API savepoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 572 ++++++++++++++++++++++++++++++----------------- 1 file changed, 364 insertions(+), 208 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 3a0e9208e..116d7a230 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -33,11 +33,11 @@ object (self) val mutable m_obj_cnt : int = 0 initializer - (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) - let f = fun o -> o#dispose in - let v = self in - Gc.finalise f v - + (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) + let f = fun o -> o#dispose in + let v = self in + Gc.finalise f v + method dispose : unit = if m_obj_cnt == 0 then ( (* Printf.printf "Disposing context %d \n" (Oo.id self) ; *) @@ -110,7 +110,6 @@ object (self) method decref ctx o = Z3native.params_dec_ref ctx o end - (** Symbol objects *) class symbol ctx = object (self) @@ -166,6 +165,10 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +let sortaton (a : sort array) = + let f (e : sort) = e#gno in + Array.map f a + (** Arithmetic sort objects, i.e., Int or Real. *) class arith_sort ctx = object (self) @@ -195,20 +198,12 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end -(** Datatype sort objects *) -class datatype_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : symbol) constructors = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self -end - (** Enum sort objects *) class enum_sort ctx = object (self) inherit sort ctx as super - val mutable _constdecls = None - val mutable _testerdecls = None + val mutable _constdecls : Z3native.ptr array option = None + val mutable _testerdecls : Z3native.ptr array option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (enum_names : symbol array) = let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in @@ -267,12 +262,12 @@ end class list_sort ctx = object (self) inherit sort ctx as super - val mutable _nildecl = None - val mutable _is_nildecl = None - val mutable _consdecl = None - val mutable _is_consdecl = None - val mutable _headdecl = None - val mutable _taildecl = None + val mutable _nildecl : Z3native.ptr option = None + val mutable _is_nildecl : Z3native.ptr option = None + val mutable _consdecl : Z3native.ptr option = None + val mutable _is_consdecl : Z3native.ptr option = None + val mutable _headdecl : Z3native.ptr option = None + val mutable _taildecl : Z3native.ptr option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (elem_sort : sort) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in @@ -291,23 +286,23 @@ object (self) method is_nil_decl = match _is_nildecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_nil decls") + | None -> raise (Z3native.Exception "Missing is_nil decl") method cons_decl = match _consdecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing cons decls") + | None -> raise (Z3native.Exception "Missing cons decl") method is_cons_decl = match _is_consdecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_cons decls") + | None -> raise (Z3native.Exception "Missing is_cons decl") method head_decl = match _headdecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing head decls") + | None -> raise (Z3native.Exception "Missing head decl") method tail_decl = match _taildecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tail decls") + | None -> raise (Z3native.Exception "Missing tail decl") end @@ -330,18 +325,6 @@ object (self) self end -let create_sort ctx obj = - match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with - | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) - | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) - | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) - | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) - | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) - | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) - | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) - | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) - | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") (** Function declaration objects *) class func_decl ctx = @@ -392,6 +375,126 @@ object (self) method rational = m_r end + +(** Constructor objects *) +class constructor ctx = +object (self) + inherit z3object ctx None as super + val mutable m_n : int = 0 + val mutable m_tester_decl : func_decl option = None + val mutable m_constructor_decl : func_decl option = None + val mutable m_accessor_decls : func_decl array option = None + method incref ctx o = () + method decref ctx o = () + initializer + let f = fun o -> Z3native.del_constructor o#gnc o#gno in + let v = self in + Gc.finalise f v + + method cnstr_ssssi (name : symbol) (recognizer : symbol) (field_names : symbol array) (sorts : sort array) (sort_refs : int array) = + m_n <- (Array.length field_names) ; + if m_n != (Array.length sorts) then + raise (Z3native.Exception "Number of field names does not match number of sorts") + else + if m_n != (Array.length sort_refs) then + raise (Z3native.Exception "Number of field names does not match number of sort refs") + else + let o = (Z3native.mk_constructor ctx#gno name#gno recognizer#gno m_n (symbolaton field_names) + (sortaton sorts) + sort_refs) in + self#sno ctx o ; + self + + method private init = + match m_tester_decl with + | None -> + let (a, b, c) = (Z3native.query_constructor self#gnc self#gno m_n) in + m_constructor_decl <- Some ((new func_decl ctx)#cnstr_obj a) ; + m_tester_decl <- Some ((new func_decl ctx)#cnstr_obj b) ; + m_accessor_decls <- Some (let f e = ((new func_decl ctx)#cnstr_obj e) in Array.map f c) ; + () + | _ -> () + + method get_n = m_n + + method tester_decl = match m_tester_decl with + | Some(x) -> x + | None -> self#init ; self#tester_decl + + method constructor_decl = match m_constructor_decl with + | Some(x) -> x + | None -> self#init ; self#constructor_decl + + method accessor_decls = match m_accessor_decls with + | Some(x) -> x + | None -> self#init ; self#accessor_decls +end + +let constructoraton (a : constructor array) = + let f (e : constructor) = e#gno in + Array.map f a + +(** Constructor list objects *) +class constructor_list ctx = +object (self) + inherit z3object ctx None + method incref ctx o = () + method decref ctx o = () + initializer + let f = fun o -> Z3native.del_constructor_list o#gnc o#gno in + let v = self in + Gc.finalise f v + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ca ( c : constructor array ) = + self#sno ctx (Z3native.mk_constructor_list ctx#gno (Array.length c) (constructoraton c)) ; + self +end + +let constructor_listaton (a : constructor_list array) = + let f (e : constructor_list) = e#gno in + Array.map f a + +(** Datatype sort objects *) +class datatype_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (constructoraton constructors)))) ; self +end + +let create_sort ctx obj = + match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with + | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) + | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) + | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) + | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) + | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) + | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) + | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) + | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) + | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + +(** AST vector objects *) +class ast_vector ctx = +object (self) + inherit z3object ctx None + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref ctx o = Z3native.ast_vector_inc_ref ctx o + method decref ctx o = Z3native.ast_vector_dec_ref ctx o +end + + +(** AST map objects *) +class ast_map ctx = +object (self) + inherit z3object ctx None + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref ctx o = Z3native.ast_map_inc_ref ctx o + method decref ctx o = Z3native.ast_map_dec_ref ctx o +end + + (** Expression objects *) class expr ctx = object(self) @@ -492,7 +595,8 @@ end (**/**) -(** Interaction logging for Z3. +(** Interaction logging for Z3 + Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) module Log = @@ -512,7 +616,7 @@ struct let append s = Z3native.append_log s end -(** Version information. *) +(** Version information *) module Version = struct (** The major version. *) @@ -536,7 +640,7 @@ struct string_of_int rev ^ "." end -(** Symbols are used to name several term and type constructors. *) +(** Symbols are used to name several term and type constructors *) module Symbol = struct (** The kind of the symbol (int or string) *) @@ -562,9 +666,7 @@ struct end -(** - The Sort module implements type information for ASTs. -*) +(** The Sort module implements type information for ASTs *) module Sort = struct (** @@ -612,13 +714,13 @@ struct end (** Bit-vector sorts *) -module BitVectorSort = +module BitVecSort = struct (** The size of the bit-vector sort. *) let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno end -(** Finite domain sorts. *) +(** Finite domain sorts *) module FiniteDomainSort = struct (** The size of the finite domain sort. *) @@ -628,7 +730,7 @@ struct else raise (Z3native.Exception "Conversion failed.") end -(** Relation sorts. *) +(** Relation sorts *) module RelationSort = struct (** The arity of the relation sort. *) @@ -684,60 +786,60 @@ let create_ast ctx no = | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") (**/**) -(** Function declarations. *) +(** Function declarations *) module FuncDecl = struct -(** Parameters of Func_Decls *) + (** Parameters of Func_Decls *) module Parameter = struct - (** - The kind of the parameter. - *) + (** + The kind of the parameter. + *) let get_kind (x : parameter) = x#kind - (**The int value of the parameter.*) + (**The int value of the parameter.*) let get_int (x : parameter) = if (x#kind != PARAMETER_INT) then raise (Z3native.Exception "parameter is not an int") else x#int - (**The double value of the parameter.*) + (**The double value of the parameter.*) let get_double (x : parameter) = if (x#kind != PARAMETER_DOUBLE) then raise (Z3native.Exception "parameter is not a double") else x#double - (**The Symbol value of the parameter.*) + (**The Symbol value of the parameter.*) let get_symbol (x : parameter) = if (x#kind != PARAMETER_SYMBOL) then raise (Z3native.Exception "parameter is not a symbol") else x#symbol - (**The Sort value of the parameter.*) + (**The Sort value of the parameter.*) let get_sort (x : parameter) = if (x#kind != PARAMETER_SORT) then raise (Z3native.Exception "parameter is not a sort") else x#sort - (**The AST value of the parameter.*) + (**The AST value of the parameter.*) let get_ast (x : parameter) = if (x#kind != PARAMETER_AST) then raise (Z3native.Exception "parameter is not an ast") else x#ast - (**The FunctionDeclaration value of the parameter.*) + (**The FunctionDeclaration value of the parameter.*) let get_ast (x : parameter) = if (x#kind != PARAMETER_FUNC_DECL) then raise (Z3native.Exception "parameter is not an function declaration") else x#func_decl - (**The rational string value of the parameter.*) + (**The rational string value of the parameter.*) let get_rational (x : parameter) = if (x#kind != PARAMETER_RATIONAL) then raise (Z3native.Exception "parameter is not a ratinoal string") @@ -826,7 +928,7 @@ struct (** Create expression that applies function to arguments. - + @param args The arguments *) let apply (x : func_decl) (args : expr array) = create_expr_fa x#gc x args @@ -862,7 +964,7 @@ struct Array.init n f end -(** Enumeration sorts. *) +(** Enumeration sorts *) module EnumSort = struct (** The function declarations of the constants in the enumeration. *) @@ -876,7 +978,7 @@ struct Array.map f x#tester_decls end -(** List sorts. *) +(** List sorts *) module ListSort = struct (** The declaration of the nil function of this list sort. *) @@ -901,6 +1003,7 @@ struct let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] end +(** Tuple sorts *) module TupleSort = struct (** The constructor function of the tuple.*) @@ -917,7 +1020,7 @@ struct Array.init n f end -(** The abstract syntax tree (AST) module. *) +(** The abstract syntax tree (AST) module *) module AST = struct (** @@ -1077,12 +1180,107 @@ struct let to_string (p : params) = Z3native.params_to_string p#gnc p#gno end +(** Vectors of ASTs *) +module ASTVector = +struct + (** The size of the vector *) + let get_size ( x : ast_vector ) = + Z3native.ast_vector_size x#gnc x#gno + + (** + Retrieves the i-th object in the vector. + @param i Index + @return An AST + *) + let get ( x : ast_vector ) ( i : int ) = + create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) + + (** Sets the i-th object in the vector. *) + let set ( x : ast_vector ) ( i : int ) ( value : ast ) = + Z3native.ast_vector_set x#gnc x#gno i value#gno + + (** Resize the vector to . + @param newSize The new size of the vector. *) + let resize ( x : ast_vector ) ( new_size : int ) = + Z3native.ast_vector_resize x#gnc x#gno new_size + + (** + Add the AST to the back of the vector. The size + is increased by 1. + @param a An AST + *) + let push ( x : ast_vector ) ( a : ast ) = + Z3native.ast_vector_push x#gnc x#gno a#gno + + (** + Translates all ASTs in the vector to . + @param to_ctx A context + @return A new ASTVector + *) + let translate ( x : ast_vector ) ( to_ctx : context ) = + (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) + + (** Retrieves a string representation of the vector. *) + let to_string ( x : ast_vector ) = + Z3native.ast_vector_to_string x#gnc x#gno +end + +(** Map from AST to AST *) +module ASTMap = +struct + (** Checks whether the map contains the key . + @param k An AST + @return True if is a key in the map, false otherwise. *) + let contains ( m : ast_map ) ( key : ast ) = + (int2lbool (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + + (** Finds the value associated with the key . + + This function signs an error when is not a key in the map. + + @param k An AST + *) + let find ( m : ast_map ) ( key : ast ) = + create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) + + (** + Stores or replaces a new key/value pair in the map. + @param k The key AST + @param v The value AST + *) + let insert ( m : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert m#gnc m#gno key#gno value#gno + + (** + Erases the key from the map. + @param k An AST + *) + let erase ( m : ast_map ) ( key : ast ) = + Z3native.ast_map_erase m#gnc m#gno key#gno + + (** Removes all keys from the map. *) + let reset ( m : ast_map ) = + Z3native.ast_map_reset m#gnc m#gno + + (** The size of the map *) + let get_size ( m : ast_map ) = + Z3native.ast_map_size m#gnc m#gno + + (** The keys stored in the map. *) + let get_keys ( m : ast_map ) = + (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) + + (** Retrieves a string representation of the map.*) + let to_strnig ( m : ast_map ) = + Z3native.ast_map_to_string m#gnc m#gno +end + (** Expressions (terms) *) module Expr = struct (** Returns a simplified version of the expression. - A set of parameters to configure the simplifier + @param p A set of parameters to configure the simplifier *) let simplify ( x : expr ) ( p : params option ) = match p with @@ -1155,8 +1353,8 @@ struct (** Translates (copies) the term to the Context . - A context - A copy of the term which is associated with + @param ctx A context + @return A copy of the term which is associated with *) let translate ( x : expr ) to_ctx = if x#gc == to_ctx then @@ -1176,7 +1374,7 @@ struct (** Indicates whether the term is well-sorted. - True if the term is well-sorted, false otherwise. + @return True if the term is well-sorted, false otherwise. *) let is_well_sorted ( x : expr ) = int2lbool (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE @@ -2372,13 +2570,13 @@ struct Z3native.get_index_value x#gnc x#gno end -(* Integer Numerals *) +(** Integer Numerals *) module IntNum = struct (** Retrieve the int value. *) let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -2410,9 +2608,9 @@ module BitVecNum = struct (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") - + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno end @@ -2424,9 +2622,8 @@ struct Return a upper bound for a given real algebraic number. The interval isolating the number is smaller than 1/10^. - - the precision of the result - A numeral Expr of sort Real + @param precision the precision of the result + @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) @@ -2435,9 +2632,8 @@ struct Return a lower bound for the given real algebraic number. The interval isolating the number is smaller than 1/10^. - - - A numeral Expr of sort Real + @param precision the precision of the result + @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) @@ -2450,8 +2646,24 @@ struct (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno end + +(** Constructors are used for datatype sorts *) +module Constructor = +struct + (** The number of fields of the constructor. *) + let get_num_fields ( x : constructor ) = x#get_n + + (** The function declaration of the constructor. *) + let get_constructor_decl ( x : constructor ) = x#constructor_decl + + (** The function declaration of the tester. *) + let get_tester_decl ( x : constructor ) = x#tester_decl + + (** The function declarations of the accessors *) + let get_accessor_decls ( x : constructor ) = x#accessor_decls +end -(** The main interaction with Z3 happens via the Context module. *) +(** The main interaction with Z3 happens via the Context module *) module Context = struct @@ -2551,151 +2763,95 @@ struct (Array.map f (mk_symbols_string ( ctx : context ) enum_names)) ) - (** - Create a new list sort. - *) + (** + Create a new list sort. + *) let mk_list_sort ( ctx : context ) (name : symbol) elem_sort = - (new list_sort ctx)#cnstr_ss name elem_sort + (new list_sort ctx)#cnstr_ss name elem_sort - (** - Create a new list sort. - *) + (** + Create a new list sort. + *) let mk_list_sort_s ( ctx : context ) (name : string) elem_sort = mk_list_sort ctx ((mk_symbol_string ctx name) :> symbol) elem_sort - (** - Create a new finite domain sort. - *) + (** + Create a new finite domain sort. + *) let mk_finite_domain_sort ( ctx : context ) ( name : symbol ) size = (new finite_domain_sort ctx)#cnstr_si name size - (** - Create a new finite domain sort. - *) + (** + Create a new finite domain sort. + *) let mk_finite_domain_sort_s ( ctx : context ) ( name : string ) size = (new finite_domain_sort ctx)#cnstr_si ((mk_symbol_string ctx name) :> symbol) size -(** - -(* DATATYPES *) -(** - Create a datatype constructor. -*) - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) - { + (* DATATYPES *) + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + mk_constructor ctx ((mk_symbol_string ctx name) :> symbol) recognizer field_names sorts sort_refs - return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs); - } + (** + Create a new datatype sort. + *) + let mk_datatype_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + (new datatype_sort ctx)#cnstr_sc name constructors + + (** + Create a new datatype sort. + *) + let mk_datatype_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = + mk_datatype_sort ctx ((mk_symbol_string ctx name) :> symbol) constructors + + (** + Create mutually recursive datatypes. + @param names names of datatype sorts + @param c list of constructors, one list per sort. + *) + let mk_datatype_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let n = (Array.length names) in + let f e = ( (new constructor_list ctx)#cnstr_ca e ) in + let cla = (Array.map f c) in + let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in + let g e = ( (new datatype_sort ctx)#cnstr_obj e) in + (Array.map g r) + + (** Create mutually recursive data-types. *) + let mk_datatype_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + mk_datatype_sorts ctx + ( + let f e = ((mk_symbol_string ctx e) :> symbol) in + Array.map f names + ) + c (** - Create a datatype constructor. -*) - @param name - @param recognizer - @param fieldNames - @param sorts - @param sortRefs - @return - public Constructor MkConstructor(string name, string recognizer, string[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) - { - - - return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); - } - -(** - Create a new datatype sort. -*) - let mk_Datatype_Sort(Symbol name, Constructor[] constructors) - { - - - - - - - CheckContextMatch(name); - CheckContextMatch(constructors); - return new DatatypeSort(this, name, constructors); - } - -(** - Create a new datatype sort. -*) - let mk_Datatype_Sort(string name, Constructor[] constructors) - { - - - - - CheckContextMatch(constructors); - return new DatatypeSort(this, MkSymbol(name), constructors); - } - -(** - Create mutually recursive datatypes. -*) - @param names names of datatype sorts - @param c list of constructors, one list per sort. - let mk_Datatype_Sorts(Symbol[] names, Constructor[][] c) - { - - - - - - - - CheckContextMatch(names); - uint n = (uint)names.Length; - ConstructorList[] cla = new ConstructorList[n]; - IntPtr[] n_constr = new IntPtr[n]; - for (uint i = 0; i < n; i++) - { - Constructor[] constructor = c[i]; - - CheckContextMatch(constructor); - cla[i] = new ConstructorList(this, constructor); - n_constr[i] = cla[i].x#gno; - } - IntPtr[] n_res = new IntPtr[n]; - Z3native.mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr); - DatatypeSort[] res = new DatatypeSort[n]; - for (uint i = 0; i < n; i++) - res[i] = new DatatypeSort(this, n_res[i]); - return res; - } - -(** - Create mutually recursive data-types. -*) - @param names - @param c - @return - let mk_Datatype_Sorts(string[] names, Constructor[][] c) - { - - - - - - - - return MkDatatypeSorts(MkSymbols(names), c); - } - - (* FUNCTION DECLARATIONS *) From d6a2048785d3ad803c6af74fd632fab736fb53ef Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 21:06:13 +0000 Subject: [PATCH 245/507] More new ML API Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 4 +- scripts/update_api.py | 11 +- src/api/ml/Makefile | 2 +- src/api/ml/z3.ml | 1025 +++++++++++++++++++++++++++++++++++------ 4 files changed, 901 insertions(+), 141 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 68493b7b6..9b5ab1a7a 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2680,13 +2680,13 @@ def mk_z3consts_ml(api_files): efile.write(' | %s \n' % k[3:]) # strip Z3_ efile.write('\n') efile.write('(** Convert %s to int*)\n' % name[3:]) - efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ + efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): efile.write(' | %s -> %d\n' % (k[3:], i)) efile.write('\n') efile.write('(** Convert int to %s*)\n' % name[3:]) - efile.write('let int2%s x : %s =\n' % (name[3:],name[3:])) # strip Z3_ + efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): efile.write(' | %d -> %s\n' % (i, k[3:])) diff --git a/scripts/update_api.py b/scripts/update_api.py index c3f2abce6..27f7dd507 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1154,7 +1154,9 @@ def mk_ml(): for k, v in Type2Str.iteritems(): if is_obj(k): ml_native.write('and %s = ptr\n' % v.lower()) - ml_native.write('\nexception Exception of string\n\n') + ml_native.write('\nexternal is_null : ptr -> bool\n') + ml_native.write(' = "n_is_null"\n\n') + ml_native.write('exception Exception of string\n\n') # ML declarations ml_native.write(' module ML2C = struct\n\n') @@ -1219,9 +1221,9 @@ def mk_ml(): i = i + 1 ml_native.write(') in\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (int2error_code (ML2C.n_get_error_code a0)) in \n') + ml_native.write(' let err = (error_code_of_int (ML2C.n_get_error_code a0)) in \n') ml_native.write(' if err <> OK then\n') - ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (error_code2int err)))\n') + ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (int_of_error_code err)))\n') ml_native.write(' else\n') if result == VOID and len(op) == 0: ml_native.write(' ()\n') @@ -1290,6 +1292,9 @@ def mk_ml(): ml_wrapper.write('#ifdef __cplusplus\n') ml_wrapper.write('extern "C" {\n') ml_wrapper.write('#endif\n\n') + ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') + ml_wrapper.write(' return Val_bool(Data_custom_val(p) == 0);\n') + ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index 4d4a6c08f..ad5442327 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -7,4 +7,4 @@ all: doc: *.ml mkdir -p doc - ocamldoc -html -d doc -I ../../../bld_dbg/api/ml *.ml -hide Z3 + ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.ml -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 116d7a230..c22ef869b 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -9,9 +9,6 @@ open Z3enums (**/**) -(* Object definitions. These are internal and should be interacted - with only via the corresponding functions from modules. *) - class virtual idisposable = object method virtual dispose : unit @@ -106,8 +103,8 @@ end class params ctx obj = object (self) inherit z3object ctx obj as super - method incref ctx o = Z3native.params_inc_ref ctx o - method decref ctx o = Z3native.params_dec_ref ctx o + method incref nc o = Z3native.params_inc_ref nc o + method decref nc o = Z3native.params_dec_ref nc o end (** Symbol objects *) @@ -115,8 +112,8 @@ class symbol ctx = object (self) inherit z3object ctx None as super method cnstr_obj obj = (self#sno ctx obj) ; self - method incref ctx o = () - method decref ctx o = () + method incref nc o = () + method decref nc o = () end let symbolaton (a : symbol array) = @@ -140,7 +137,7 @@ object(self) end let create_symbol ctx no = - match (int2symbol_kind (Z3native.get_symbol_kind ctx#gno no)) with + match (symbol_kind_of_int (Z3native.get_symbol_kind ctx#gno no)) with | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) @@ -198,29 +195,6 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end -(** Enum sort objects *) -class enum_sort ctx = -object (self) - inherit sort ctx as super - val mutable _constdecls : Z3native.ptr array option = None - val mutable _testerdecls : Z3native.ptr array option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (enum_names : symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in - _constdecls <- Some a ; - _testerdecls <- Some b ; - (self#sno ctx r) ; - self - - method const_decls = match _constdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing const decls") - - method tester_decls = match _testerdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tester decls") -end - (** Int sort objects *) class int_sort ctx = object (self) @@ -258,54 +232,6 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end -(** List sort objects *) -class list_sort ctx = -object (self) - inherit sort ctx as super - val mutable _nildecl : Z3native.ptr option = None - val mutable _is_nildecl : Z3native.ptr option = None - val mutable _consdecl : Z3native.ptr option = None - val mutable _is_consdecl : Z3native.ptr option = None - val mutable _headdecl : Z3native.ptr option = None - val mutable _taildecl : Z3native.ptr option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in - _nildecl <- Some a ; - _is_nildecl <- Some b ; - _consdecl <- Some c ; - _is_consdecl <- Some d ; - _headdecl <- Some e ; - _taildecl <- Some f ; - (self#sno ctx r) ; - self - - method nil_decl = match _nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing nil decl") - - method is_nil_decl = match _is_nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_nil decl") - - method cons_decl = match _consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing cons decl") - - method is_cons_decl = match _is_consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_cons decl") - - method head_decl = match _headdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing head decl") - - method tail_decl = match _taildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tail decl") - -end - (** Set sort objects *) class set_sort ctx = object (self) @@ -376,6 +302,76 @@ object (self) end +(** Enum sort objects *) +class enum_sort ctx = +object (self) + inherit sort ctx as super + val mutable _constdecls : func_decl array option = None + val mutable _testerdecls : func_decl array option = None + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ss (name : symbol) (enum_names : symbol array) = + let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in + _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; + _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; + (self#sno ctx r) ; + self + + method const_decls = match _constdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing const decls") + + method tester_decls = match _testerdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tester decls") +end + +(** List sort objects *) +class list_sort ctx = +object (self) + inherit sort ctx as super + val mutable _nildecl : func_decl option = None + val mutable _is_nildecl : func_decl option = None + val mutable _consdecl : func_decl option = None + val mutable _is_consdecl : func_decl option = None + val mutable _headdecl : func_decl option = None + val mutable _taildecl : func_decl option = None + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ss (name : symbol) (elem_sort : sort) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in + _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; + _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; + _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; + _is_consdecl <- Some ((new func_decl ctx)#cnstr_obj d) ; + _headdecl <- Some ((new func_decl ctx)#cnstr_obj e) ; + _taildecl <- Some ((new func_decl ctx)#cnstr_obj f) ; + (self#sno ctx r) ; + self + + method nil_decl = match _nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing nil decl") + + method is_nil_decl = match _is_nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_nil decl") + + method cons_decl = match _consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing cons decl") + + method is_cons_decl = match _is_consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_cons decl") + + method head_decl = match _headdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing head decl") + + method tail_decl = match _taildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tail decl") +end + (** Constructor objects *) class constructor ctx = object (self) @@ -384,8 +380,8 @@ object (self) val mutable m_tester_decl : func_decl option = None val mutable m_constructor_decl : func_decl option = None val mutable m_accessor_decls : func_decl array option = None - method incref ctx o = () - method decref ctx o = () + method incref nc o = () + method decref nc o = () initializer let f = fun o -> Z3native.del_constructor o#gnc o#gno in let v = self in @@ -438,8 +434,8 @@ let constructoraton (a : constructor array) = class constructor_list ctx = object (self) inherit z3object ctx None - method incref ctx o = () - method decref ctx o = () + method incref nc o = () + method decref nc o = () initializer let f = fun o -> Z3native.del_constructor_list o#gnc o#gno in let v = self in @@ -463,7 +459,7 @@ object (self) end let create_sort ctx obj = - match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with + match (sort_kind_of_int (Z3native.get_sort_kind ctx#gno obj)) with | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) @@ -480,8 +476,8 @@ class ast_vector ctx = object (self) inherit z3object ctx None method cnstr_obj obj = (self#sno ctx obj) ; self - method incref ctx o = Z3native.ast_vector_inc_ref ctx o - method decref ctx o = Z3native.ast_vector_dec_ref ctx o + method incref nc o = Z3native.ast_vector_inc_ref nc o + method decref nc o = Z3native.ast_vector_dec_ref nc o end @@ -490,8 +486,8 @@ class ast_map ctx = object (self) inherit z3object ctx None method cnstr_obj obj = (self#sno ctx obj) ; self - method incref ctx o = Z3native.ast_map_inc_ref ctx o - method decref ctx o = Z3native.ast_map_dec_ref ctx o + method incref nc o = Z3native.ast_map_inc_ref nc o + method decref nc o = Z3native.ast_map_dec_ref nc o end @@ -583,7 +579,6 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end - (** Quantifier objects *) class quantifier ctx = object (self) @@ -591,10 +586,127 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +(** Parameter description objects *) +class param_descrs ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.param_descrs_inc_ref nc o + method decref nc o = Z3native.param_descrs_dec_ref nc o +end +(** Goal objects *) +class goal ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.goal_inc_ref nc o + method decref nc o = Z3native.goal_dec_ref nc o +end + +(** Tactic objects *) +class tactic ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.tactic_inc_ref nc o + method decref nc o = Z3native.tactic_dec_ref nc o +end + +(** Function interpretation entry objects *) +class func_entry ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.func_entry_inc_ref nc o + method decref nc o = Z3native.func_entry_dec_ref nc o +end + +(** Function interpretation objects *) +class func_interp ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.func_interp_inc_ref nc o + method decref nc o = Z3native.func_interp_dec_ref nc o +end + +(** Model objects *) +class model ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.model_inc_ref nc o + method decref nc o = Z3native.model_dec_ref nc o +end + +(** Tactic application result objects *) +class apply_result ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.apply_result_inc_ref nc o + method decref nc o = Z3native.apply_result_dec_ref nc o +end + +(** Probe objects *) +class probe ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.probe_inc_ref nc o + method decref nc o = Z3native.probe_dec_ref nc o +end + +(** Statistical value objects *) +class statistics_entry = +object (self) + val mutable m_key : string = "" + val mutable m_is_int = false + val mutable m_is_float = false + val mutable m_int = 0 + val mutable m_float = 0.0 + + method cnstr_si k v = + m_key <- k; + m_is_int <- true; + m_int <- v; + self + + method cnstr_sd k v = + m_key <- k; + m_is_float <- true; + m_float <- v; + self + + method key = m_key + method int = m_int + method float = m_float + method is_int = m_is_int + method is_float = m_is_float +end + +(** Statistics objects *) +class statistics ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.stats_inc_ref nc o + method decref nc o = Z3native.stats_dec_ref nc o +end + +(** Solver objects *) +class solver ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.solver_inc_ref nc o + method decref nc o = Z3native.solver_dec_ref nc o +end (**/**) + (** Interaction logging for Z3 Note that this is a global, static log and if multiple Context @@ -606,7 +718,7 @@ struct @return True if opening the log file succeeds, false otherwise. *) (* CMW: "open" seems to be a reserved keyword? *) - let open_ filename = ((int2lbool (Z3native.open_log filename)) == L_TRUE) + let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) (** Closes the interaction log. *) let close = Z3native.close_log @@ -644,7 +756,7 @@ end module Symbol = struct (** The kind of the symbol (int or string) *) - let kind (o : symbol) = (int2symbol_kind (Z3native.get_symbol_kind o#gnc o#gno)) + let kind (o : symbol) = (symbol_kind_of_int (Z3native.get_symbol_kind o#gnc o#gno)) (** Indicates whether the symbol is of Int kind *) let is_int_symbol (o : symbol) = (kind o) == INT_SYMBOL @@ -680,7 +792,7 @@ struct if a#gnc != b#gnc then false else - ((int2lbool (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) + ((lbool_of_int (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) (** Returns a unique identifier for the sort. @@ -690,7 +802,7 @@ struct (** The kind of the sort. *) - let get_sort_kind (x : sort) = (int2sort_kind (Z3native.get_sort_kind x#gnc x#gno)) + let get_sort_kind (x : sort) = (sort_kind_of_int (Z3native.get_sort_kind x#gnc x#gno)) (** The name of the sort @@ -726,7 +838,7 @@ struct (** The size of the finite domain sort. *) let get_size (x : finite_domain_sort) = let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in - if int2lbool(r) == L_TRUE then v + if lbool_of_int(r) == L_TRUE then v else raise (Z3native.Exception "Conversion failed.") end @@ -746,15 +858,15 @@ end (**/**) let create_expr ctx obj = - if int2ast_kind (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then + if ast_kind_of_int (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then (((new quantifier ctx)#cnstr_obj obj) :> expr) else let s = Z3native.get_sort ctx#gno obj in - let sk = (int2sort_kind (Z3native.get_sort_kind ctx#gno s)) in - if (int2lbool (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then + let sk = (sort_kind_of_int (Z3native.get_sort_kind ctx#gno s)) in + if (lbool_of_int (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then (((new algebraic_num ctx)#cnstr_obj obj) :> expr) else - if ((int2lbool (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && + if ((lbool_of_int (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) @@ -776,7 +888,7 @@ let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = create_expr ctx o let create_ast ctx no = - match (int2ast_kind (Z3native.get_ast_kind ctx#gno no)) with + match (ast_kind_of_int (Z3native.get_ast_kind ctx#gno no)) with | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) | SORT_AST -> ((create_sort ctx no) :> ast) @@ -858,7 +970,7 @@ struct if a#gnc == a#gnc then false else - ((int2lbool (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) + ((lbool_of_int (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) (** A string representations of the function declaration. *) @@ -897,7 +1009,7 @@ struct (** The kind of the function declaration. *) - let get_decl_kind (x : func_decl) = (int2decl_kind (Z3native.get_decl_kind x#gnc x#gno)) + let get_decl_kind (x : func_decl) = (decl_kind_of_int (Z3native.get_decl_kind x#gnc x#gno)) (** The name of the function declaration @@ -915,7 +1027,7 @@ struct let get_parameters (x : func_decl) = let n = (get_num_parameters x) in let f i = ( - match (int2parameter_kind (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with + match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with | PARAMETER_INT -> (new parameter)#cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) | PARAMETER_DOUBLE -> (new parameter)#cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) | PARAMETER_SYMBOL-> (new parameter)#cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) @@ -968,36 +1080,32 @@ end module EnumSort = struct (** The function declarations of the constants in the enumeration. *) - let get_const_decls (x : enum_sort) = - let f e = ((new func_decl x#gc)#cnstr_obj e) in - Array.map f x#const_decls + let get_const_decls (x : enum_sort) = x#const_decls (** The test predicates for the constants in the enumeration. *) - let get_tester_decls (x : enum_sort) = - let f e = ((new func_decl x#gc)#cnstr_obj e) in - Array.map f x#tester_decls + let get_tester_decls (x : enum_sort) = x#tester_decls end (** List sorts *) module ListSort = struct (** The declaration of the nil function of this list sort. *) - let get_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#nil_decl + let get_nil_decl (x : list_sort) = x#nil_decl (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_nil_decl + let get_is_nil_decl (x : list_sort) = x#is_nil_decl (** The declaration of the cons function of this list sort. *) - let get_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#cons_decl + let get_cons_decl (x : list_sort) = x#cons_decl (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_cons_decl + let get_is_cons_decl (x : list_sort) = x#is_cons_decl (** The declaration of the head function of this list sort.*) - let get_head_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#head_decl + let get_head_decl (x : list_sort) = x#head_decl (** The declaration of the tail function of this list sort. *) - let get_tail_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#tail_decl + let get_tail_decl (x : list_sort) = x#tail_decl (** The empty list. *) let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] @@ -1037,7 +1145,7 @@ struct (** The kind of the AST. *) - let get_ast_kind ( x : ast) = (int2ast_kind (Z3native.get_ast_kind x#gnc x#gno)) + let get_ast_kind ( x : ast) = (ast_kind_of_int (Z3native.get_ast_kind x#gnc x#gno)) (** Indicates whether the AST is an Expr @@ -1092,7 +1200,7 @@ struct if a#gnc == b#gnc then false else - ((int2lbool (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) + ((lbool_of_int (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) (** Object Comparison. @@ -1130,7 +1238,7 @@ struct Adds a parameter setting. *) let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno (lbool2int (if value then L_TRUE else L_FALSE)) + Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) (** Adds a parameter setting. @@ -1232,7 +1340,7 @@ struct @param k An AST @return True if is a key in the map, false otherwise. *) let contains ( m : ast_map ) ( key : ast ) = - (int2lbool (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE (** Finds the value associated with the key . @@ -1296,7 +1404,7 @@ struct Indicates whether the expression is the true or false expression or something else (Z3_L_UNDEF). *) - let get_bool_value ( x : expr ) = int2lbool (Z3native.get_bool_value x#gnc x#gno) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value x#gnc x#gno) (** The number of arguments of the expression. @@ -1370,13 +1478,13 @@ struct (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = int2lbool (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE + let is_numeral ( x : expr ) = lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = int2lbool (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE + let is_well_sorted ( x : expr ) = lbool_of_int (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE (** The Sort of the term. @@ -1387,7 +1495,7 @@ struct Indicates whether the term has Boolean sort. *) let is_bool ( x : expr ) = (AST.is_expr x) && - (int2lbool (Z3native.is_eq_sort x#gnc + (lbool_of_int (Z3native.is_eq_sort x#gnc (Z3native.mk_bool_sort x#gnc) (Z3native.get_sort x#gnc x#gno))) == L_TRUE @@ -1395,21 +1503,21 @@ struct Indicates whether the term is of integer sort. *) let is_int ( x : expr ) = - ((int2lbool (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) (** Indicates whether the term is of sort real. *) let is_real ( x : expr ) = - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) (** Indicates whether the term is of an array sort. *) let is_array ( x : expr ) = - ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) (** Indicates whether the term represents a constant. @@ -1431,7 +1539,7 @@ struct (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : expr ) = int2lbool(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE (** Indicates whether the term is the constant true. @@ -1634,7 +1742,7 @@ struct Indicates whether the terms is of bit-vector sort. *) let is_bv ( x : expr ) = - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) (** Indicates whether the term is a bit-vector numeral @@ -2422,8 +2530,8 @@ struct Indicates whether the term is of a relation sort. *) let is_Relation ( x : expr ) = - ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) (** Indicates whether the term is an relation store @@ -2536,8 +2644,8 @@ struct Indicates whether the term is of an array sort. *) let is_finite_domain ( x : expr ) = - ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) (** Indicates whether the term is a less than predicate over a finite domain. @@ -2575,7 +2683,7 @@ module IntNum = struct (** Retrieve the int value. *) let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v + if lbool_of_int(r) == L_TRUE then v else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) @@ -2608,7 +2716,7 @@ module BitVecNum = struct (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v + if lbool_of_int(r) == L_TRUE then v else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) @@ -2662,7 +2770,654 @@ struct (** The function declarations of the accessors *) let get_accessor_decls ( x : constructor ) = x#accessor_decls end + + +(** ParamDescrs describe sets of parameters.*) +module ParamDescrs = +struct + + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno + + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size x#gnc x#gno in + let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno + + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno + +end + +(** Goals + + A goal (aka problem). A goal is essentially a + of formulas, that can be solved and/or transformed using + tactics and solvers. *) +module Goal = +struct + + (** The precision of the goal. + + Goals can be transformed using over and under approximations. + An under approximation is applied when the objective is to find a model for a given goal. + An over approximation is applied when the objective is to find a proof for a given goal. + *) + let get_precision ( x : goal ) = + goal_prec_of_int (Z3native.goal_precision x#gnc x#gno) + + (** Indicates whether the goal is precise. *) + let is_precise ( x : goal ) = + (get_precision x) == GOAL_PRECISE + + (** Indicates whether the goal is an under-approximation. *) + let is_underapproximation ( x : goal ) = + (get_precision x) == GOAL_UNDER + + (** Indicates whether the goal is an over-approximation. *) + let is_overapproximation ( x : goal ) = + (get_precision x) == GOAL_OVER + + (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) + let is_garbage ( x : goal ) = + (get_precision x) == GOAL_UNDER_OVER + + (** Adds the constraints to the given goal. *) + (* CMW: assert seems to be a keyword. *) + let assert_ ( x : goal ) ( constraints : bool_expr array ) = + let f e = Z3native.goal_assert x#gnc x#gno e#gno in + Array.map f constraints + + (** Indicates whether the goal contains `false'. *) + let is_inconsistent ( x : goal ) = + (lbool_of_int (Z3native.goal_inconsistent x#gnc x#gno)) == L_TRUE + + (** The depth of the goal. + This tracks how many transformations were applied to it. *) + let get_depth ( x : goal ) = Z3native.goal_depth x#gnc x#gno + + (** Erases all formulas from the given goal. *) + let reset ( x : goal ) = Z3native.goal_reset x#gnc x#gno + + (** The number of formulas in the goal. *) + let get_size ( x : goal ) = Z3native.goal_size x#gnc x#gno + + (** The formulas in the goal. *) + let get_formulas ( x : goal ) = + let n = get_size x in + let f i = (new bool_expr x#gc)#cnstr_obj (Z3native.goal_formula x#gnc x#gno i) in + Array.init n f + + (** The number of formulas, subformulas and terms in the goal. *) + let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs x#gnc x#gno + + (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) + let is_decided_sat ( x : goal ) = + (lbool_of_int (Z3native.goal_is_decided_sat x#gnc x#gno)) == L_TRUE + + (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) + let is_decided_unsat ( x : goal ) = + (lbool_of_int (Z3native.goal_is_decided_unsat x#gnc x#gno)) == L_TRUE + + (** Translates (copies) the Goal to the target Context . *) + let translate ( x : goal ) ( to_ctx : context ) = + (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno to_ctx#gno) + + (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) + let simplify ( x : goal ) ( p : params option ) = + let tn = Z3native.mk_tactic x#gnc "simplify" in + Z3native.tactic_inc_ref x#gnc tn ; + let arn = match p with + | None -> Z3native.tactic_apply x#gnc tn x#gno + | Some(pn) -> Z3native.tactic_apply_ex x#gnc tn x#gno pn#gno + in + Z3native.apply_result_inc_ref x#gnc arn ; + let sg = Z3native.apply_result_get_num_subgoals x#gnc arn in + let res = if sg == 0 then + raise (Z3native.Exception "No subgoals") + else + Z3native.apply_result_get_subgoal x#gnc arn 0 in + Z3native.apply_result_dec_ref x#gnc arn ; + Z3native.tactic_dec_ref x#gnc tn ; + (new goal x#gc)#cnstr_obj res + + (** A string representation of the Goal. *) + let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno +end + + +(** Tactics + + Tactics are the basic building block for creating custom solvers for specific problem domains. + The complete list of tactics may be obtained using Context.get_num_tactics + and Context.get_tactic_names. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Tactic = +struct + (** A string containing a description of parameters accepted by the tactic. *) + let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno + + + (** Retrieves parameter descriptions for Tactics. *) + let get_param_descrs ( x : tactic ) = + (new param_descrs x#gc)#cnstr_obj (Z3native.tactic_get_param_descrs x#gnc x#gno) + + (** Apply the tactic to the goal. *) + let apply ( x : tactic ) ( g : goal ) ( p : params option ) = + match p with + | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) + | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) + + (** Creates a solver that is implemented using the given tactic. + *) + let get_solver ( x : tactic ) = + (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) + +end + + +(** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. +*) +module FuncInterp = +struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") +end + +(** Models. + + A Model contains interpretations (assignments) of constants and functions. *) +module Model = +struct + (** Retrieves the interpretation (the assignment) of in the model. + A function declaration of zero arity + An expression if the function has an interpretation in the model, null otherwise. *) + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null np) then + None + else + Some (create_expr x#gc np) + + (** Retrieves the interpretation (the assignment) of in the model. + A Constant + An expression if the constant has an interpretation in the model, null otherwise. + *) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + (** Retrieves the interpretation (the assignment) of a non-constant in the model. + A function declaration of non-zero arity + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl x#gnc n in + get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in + if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno + + (** The function declarations of the constants in the model. *) + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.init n f + + + (** The number of function interpretations in the model. *) + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno + + (** The function declarations of the function interpretations in the model. *) + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + Array.init n f + + (** All symbols that have an interpretation in the model. *) + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.append (Array.init n_funcs f) (Array.init n_consts g) + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** + Evaluates the expression in the current model. + + + This function may fail if contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + + An expression + + When this flag is enabled, a model value will be assigned to any constant + or function that does not have an interpretation in the model. + + The evaluation of in the model. + *) + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in + if (lbool_of_int r) == L_FALSE then + raise (ModelEvaluationFailedException "evaluation failed") + else + create_expr x#gc v + + (** Alias for eval. *) + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + + + + *) + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in + Array.init n f + + + (** The finite set of distinct values that represent the interpretation for sort . + + An uninterpreted sort + An array of expressions, where each is an element of the universe of + *) + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in + let n = (ASTVector.get_size n_univ) in + let f i = (ASTVector.get n_univ i) in + Array.init n f + + (** Conversion of models to strings. + A string representation of the model. + *) + let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno +end + +(** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) +module ApplyResult = +struct + (** The number of Subgoals. *) + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals x#gnc x#gno + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in + Array.init n f + + (** Convert a model for the subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g + *) + let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = + (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) + + (** A string representation of the ApplyResult. *) + let to_string ( x : apply_result) = Z3native.apply_result_to_string x#gnc x#gno +end + +(** Objects that track statistical information about solvers. *) +module Statistics = +struct + + (** + Statistical data is organized into pairs of [Key, Entry], where every + Entry is either a DoubleEntry or a UIntEntry + *) + module Entry = + struct + (** The key of the entry. *) + let get_key (x : statistics_entry) = x#key + + (** The int-value of the entry. *) + let get_int (x : statistics_entry) = x#int + + (** The float-value of the entry. *) + let get_float (x : statistics_entry) = x#float + + (** True if the entry is uint-valued. *) + let is_int (x : statistics_entry) = x#is_int + + (** True if the entry is double-valued. *) + let is_float (x : statistics_entry) = x#is_float + + (** The string representation of the the entry's value. *) + let to_string_value (x : statistics_entry) = + if (is_int x) then + string_of_int (get_int x) + else if (is_float x) then + string_of_float (get_float x) + else + raise (Z3native.Exception "Unknown statistical entry type") + + (** The string representation of the entry (key and value) *) + let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) + end + + (** A string representation of the statistical data. *) + let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno + + (** The number of statistical data. *) + let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno + + (** The data entries. *) + let get_entries ( x : statistics ) = + let n = (get_size x ) in + let f i = ( + let k = Z3native.stats_get_key x#gnc x#gno i in + if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then + ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) + else + ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) + ) in + Array.init n f + + (** + The statistical counters. + *) + let get_keys ( x : statistics ) = + let n = (get_size x) in + let f i = (Z3native.stats_get_key x#gnc x#gno i) in + Array.init n f + + (** + The value of a particular statistical counter. + *) + let get ( x : statistics ) ( key : string ) = + let f p c = (if (Entry.get_key c) = key then (Some c) else p) in + Array.fold_left f None (get_entries x) + +end + +(** Solvers *) +module Solver = +struct + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + (** + A string that describes all available solver parameters. + *) + let get_help ( x : solver ) = Z3native.solver_get_help x#gnc x#gno + + (** + Sets the solver parameters. + *) + let set_parameters ( x : solver ) ( value : params )= + Z3native.solver_set_params x#gnc x#gno value#gno + + (** + Retrieves parameter descriptions for solver. + *) + let get_param_descrs ( x : solver ) = + (new param_descrs x#gc)#cnstr_obj (Z3native.solver_get_param_descrs x#gnc x#gno) + + (** + The current number of backtracking points (scopes). + + + *) + let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes x#gnc x#gno + + (** + Creates a backtracking point. + + *) + let push ( x : solver ) = Z3native.solver_push x#gnc x#gno + + (** + Backtracks backtracking points. + Note that an exception is thrown if is not smaller than NumScopes + + *) + let pop ( x : solver ) ( n : int ) = Z3native.solver_pop x#gnc x#gno n + + (** + Resets the Solver. + This removes all assertions from the solver. + *) + let reset ( x : solver ) = Z3native.solver_reset x#gnc x#gno + + (** + Assert a constraint (or multiple) into the solver. + *) + let assert_ ( x : solver ) ( constraints : bool_expr array ) = + let f e = (Z3native.solver_assert x#gnc x#gno e#gno) in + Array.map f constraints + + (** + The number of assertions in the solver. + *) + let get_num_assertions ( x : solver ) = + let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + (ASTVector.get_size a) + + + (** + The set of asserted formulas. + *) + let get_assertions ( x : solver ) = + let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + let n = (ASTVector.get_size a) in + let f i = ((new bool_expr x#gc)#cnstr_obj (ASTVector.get a i)#gno) in + Array.init n f + + (** + Checks whether the assertions in the solver are consistent or not. + + + + + + *) + let check ( x : solver ) ( assumptions : bool_expr array option) = + let r = + match assumptions with + | None -> lbool_of_int (Z3native.solver_check x#gnc x#gno) + | Some (ass) -> lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length ass) (astaton ass)) + in + match r with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN + + (** + The model of the last Check. + + The result is None if Check was not invoked before, + if its results was not SATISFIABLE, or if model production is not enabled. + + *) + let get_model ( x : solver ) = + let q = Z3native.solver_get_model x#gnc x#gno in + if (Z3native.is_null q) then + None + else + Some ((new model x#gc)#cnstr_obj q) + + (** + The proof of the last Check. + + The result is null if Check was not invoked before, + if its results was not UNSATISFIABLE, or if proof production is disabled. + + *) + let get_proof ( x : solver ) = + let q = Z3native.solver_get_proof x#gnc x#gno in + if (Z3native.is_null q) then + None + else + Some (create_expr x#gc q) + + (** + The unsat core of the last Check. + + The unsat core is a subset of Assertions + The result is empty if Check was not invoked before, + if its results was not UNSATISFIABLE, or if core production is disabled. + + *) + let get_unsat_core ( x : solver ) = + let cn = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_unsat_core x#gnc x#gno) in + let n = (ASTVector.get_size cn) in + let f i = (ASTVector.get cn i) in + Array.init n f + + (** + A brief justification of why the last call to Check returned UNKNOWN. + *) + let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown x#gnc x#gno + + + (** + Solver statistics. + *) + let get_statistics ( x : solver ) = + (new statistics x#gc)#cnstr_obj (Z3native.solver_get_statistics x#gnc x#gno) + + (** + A string representation of the solver. + *) + let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno +end + +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe = +struct + (** + Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. + *) + let apply ( x : probe ) (g : goal) = + Z3native.probe_apply x#gnc x#gno g#gno +end + + (** The main interaction with Z3 happens via the Context module *) module Context = struct From 3684b3a87d438d0bd989752ad69268bbf9f37c51 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 23 Dec 2012 02:20:24 +0000 Subject: [PATCH 246/507] New ML API savepoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 6488 +++++++++++++++++++--------------------------- 1 file changed, 2629 insertions(+), 3859 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c22ef869b..5f67e11e2 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -586,6 +586,13 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +(** Quantifier pattern objects *) +class pattern ctx = +object (self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self +end + (** Parameter description objects *) class param_descrs ctx = object (self) @@ -775,6 +782,33 @@ struct match (kind o) with | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int o#gnc o#gno)) | STRING_SYMBOL -> (Z3native.get_symbol_string o#gnc o#gno) + + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) + let mk_int ( ctx : context ) i = + (new int_symbol ctx)#cnstr_int i + + (** Creates a new symbol using a string. *) + let mk_string ( ctx : context ) s = + (new string_symbol ctx)#cnstr_string s + + (** + Create an array of symbols. + *) + let mk_ints ( ctx : context ) ( names : int array ) = + let f elem = mk_int ( ctx : context ) elem in + (Array.map f names) + + (** + Create an array of symbols. + *) + let mk_strings ( ctx : context ) ( names : string array ) = + let f elem = mk_string ( ctx : context ) elem in + (Array.map f names) end @@ -813,49 +847,26 @@ struct A string representation of the sort. *) let to_string (x : sort) = Z3native.sort_to_string x#gnc x#gno + + (** + Create a new Boolean sort. + *) + let mk_bool ( ctx : context ) = + (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted ( ctx : context ) (s : symbol) = + (new uninterpreted_sort ctx)#cnstr_s s + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_s ( ctx : context ) (s : string) = + mk_uninterpreted ctx ((Symbol.mk_string ( ctx : context ) s) :> symbol) end -(** Array sorts *) -module ArraySort = -struct - (** The domain of the array sort. *) - let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) - - (** The range of the array sort. *) - let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) -end - -(** Bit-vector sorts *) -module BitVecSort = -struct - (** The size of the bit-vector sort. *) - let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno -end - -(** Finite domain sorts *) -module FiniteDomainSort = -struct - (** The size of the finite domain sort. *) - let get_size (x : finite_domain_sort) = - let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") -end - -(** Relation sorts *) -module RelationSort = -struct - (** The arity of the relation sort. *) - let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno - - (** The sorts of the columns of the relation sort. *) - let get_column_sorts (x : relation_sort) = - let n = get_arity x in - let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in - Array.init n f - -end - (**/**) let create_expr ctx obj = if ast_kind_of_int (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then @@ -957,6 +968,48 @@ struct raise (Z3native.Exception "parameter is not a ratinoal string") else x#rational + + (** + Creates a new function declaration. + *) + let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name domain range + + (** + Creates a new function declaration. + *) + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = + mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range + + (** + Creates a fresh function declaration with a name prefixed with . + + + *) + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix domain range + + (** + Creates a new constant function declaration. + *) + let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name [||] range + + + (** + Creates a new constant function declaration. + *) + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range + + (** + Creates a fresh constant function declaration with a name prefixed with . + + + *) + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix [||] range + end (** @@ -1046,91 +1099,103 @@ struct end -(** Datatype sorts *) -module DatatypeSort = -struct - (** The number of constructors of the datatype sort. *) - let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno - - (** The range of the array sort. *) - let get_constructors (x : datatype_sort) = - let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in - Array.init n f - - (** The recognizers. *) - let get_recognizers (x : datatype_sort) = - let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in - Array.init n f - - (** The constructor accessors. *) - let get_accessors (x : datatype_sort) = - let n = (get_num_constructors x) in - let f i = ( - let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in - let ds = (Z3native.get_domain_size fd#gnc fd#gno) in - let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in - Array.init ds g - ) in - Array.init n f -end - -(** Enumeration sorts *) -module EnumSort = -struct - (** The function declarations of the constants in the enumeration. *) - let get_const_decls (x : enum_sort) = x#const_decls - - (** The test predicates for the constants in the enumeration. *) - let get_tester_decls (x : enum_sort) = x#tester_decls -end - -(** List sorts *) -module ListSort = -struct - (** The declaration of the nil function of this list sort. *) - let get_nil_decl (x : list_sort) = x#nil_decl - - (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl (x : list_sort) = x#is_nil_decl - - (** The declaration of the cons function of this list sort. *) - let get_cons_decl (x : list_sort) = x#cons_decl - - (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl (x : list_sort) = x#is_cons_decl - - (** The declaration of the head function of this list sort.*) - let get_head_decl (x : list_sort) = x#head_decl - - (** The declaration of the tail function of this list sort. *) - let get_tail_decl (x : list_sort) = x#tail_decl - - (** The empty list. *) - let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] -end - -(** Tuple sorts *) -module TupleSort = -struct - (** The constructor function of the tuple.*) - let get_mk_decl (x : tuple_sort) = - (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) - - (** The number of fields in the tuple. *) - let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno - - (** The field declarations. *) - let get_field_decls (x : tuple_sort) = - let n = get_num_fields x in - let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in - Array.init n f -end - (** The abstract syntax tree (AST) module *) module AST = struct + (** Vectors of ASTs *) + module ASTVector = + struct + (** The size of the vector *) + let get_size ( x : ast_vector ) = + Z3native.ast_vector_size x#gnc x#gno + + (** + Retrieves the i-th object in the vector. + @param i Index + @return An AST + *) + let get ( x : ast_vector ) ( i : int ) = + create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) + + (** Sets the i-th object in the vector. *) + let set ( x : ast_vector ) ( i : int ) ( value : ast ) = + Z3native.ast_vector_set x#gnc x#gno i value#gno + + (** Resize the vector to . + @param newSize The new size of the vector. *) + let resize ( x : ast_vector ) ( new_size : int ) = + Z3native.ast_vector_resize x#gnc x#gno new_size + + (** + Add the AST to the back of the vector. The size + is increased by 1. + @param a An AST + *) + let push ( x : ast_vector ) ( a : ast ) = + Z3native.ast_vector_push x#gnc x#gno a#gno + + (** + Translates all ASTs in the vector to . + @param to_ctx A context + @return A new ASTVector + *) + let translate ( x : ast_vector ) ( to_ctx : context ) = + (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) + + (** Retrieves a string representation of the vector. *) + let to_string ( x : ast_vector ) = + Z3native.ast_vector_to_string x#gnc x#gno + end + + (** Map from AST to AST *) + module ASTMap = + struct + (** Checks whether the map contains the key . + @param k An AST + @return True if is a key in the map, false otherwise. *) + let contains ( m : ast_map ) ( key : ast ) = + (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + + (** Finds the value associated with the key . + + This function signs an error when is not a key in the map. + @param k An AST + *) + let find ( m : ast_map ) ( key : ast ) = + create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) + + (** + Stores or replaces a new key/value pair in the map. + @param k The key AST + @param v The value AST + *) + let insert ( m : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert m#gnc m#gno key#gno value#gno + + (** + Erases the key from the map. + @param k An AST + *) + let erase ( m : ast_map ) ( key : ast ) = + Z3native.ast_map_erase m#gnc m#gno key#gno + + (** Removes all keys from the map. *) + let reset ( m : ast_map ) = + Z3native.ast_map_reset m#gnc m#gno + + (** The size of the map *) + let get_size ( m : ast_map ) = + Z3native.ast_map_size m#gnc m#gno + + (** The keys stored in the map. *) + let get_keys ( m : ast_map ) = + (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) + + (** Retrieves a string representation of the map.*) + let to_strnig ( m : ast_map ) = + Z3native.ast_map_to_string m#gnc m#gno + end + (** The AST's hash code. @return A hash code @@ -1159,7 +1224,7 @@ struct | _ -> false (** - Indicates whether the AST is a BoundVariable + Indicates whether the AST is a bound variable *) let is_var ( x : ast) = (get_ast_kind x) == VAR_AST @@ -1227,163 +1292,7 @@ struct (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) end -(** - Parameter sets - - A Params objects represents a configuration in the form of Symbol/value pairs. -*) -module Params = -struct - (** - Adds a parameter setting. - *) - let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) - - (** - Adds a parameter setting. - *) - let add_int (p : params) (name : symbol) (value : int) = - Z3native.params_set_uint p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_double (p : params) (name : symbol) (value : float) = - Z3native.params_set_double p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_symbol (p : params) (name : symbol) (value : symbol) = - Z3native.params_set_symbol p#gnc p#gno name#gno value#gno - - (** - Adds a parameter setting. - *) - let add_s_bool (p : params) (name : string) (value : bool) = - add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_int (p : params) (name : string) (value : int) = - add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_double (p : params) (name : string) (value : float) = - add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_symbol (p : params) (name : string) (value : symbol) = - add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - A string representation of the parameter set. - *) - let to_string (p : params) = Z3native.params_to_string p#gnc p#gno -end - -(** Vectors of ASTs *) -module ASTVector = -struct - (** The size of the vector *) - let get_size ( x : ast_vector ) = - Z3native.ast_vector_size x#gnc x#gno - - (** - Retrieves the i-th object in the vector. - @param i Index - @return An AST - *) - let get ( x : ast_vector ) ( i : int ) = - create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) - - (** Sets the i-th object in the vector. *) - let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set x#gnc x#gno i value#gno - - (** Resize the vector to . - @param newSize The new size of the vector. *) - let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize x#gnc x#gno new_size - - (** - Add the AST to the back of the vector. The size - is increased by 1. - @param a An AST - *) - let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push x#gnc x#gno a#gno - - (** - Translates all ASTs in the vector to . - @param to_ctx A context - @return A new ASTVector - *) - let translate ( x : ast_vector ) ( to_ctx : context ) = - (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) - - (** Retrieves a string representation of the vector. *) - let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string x#gnc x#gno -end - -(** Map from AST to AST *) -module ASTMap = -struct - (** Checks whether the map contains the key . - @param k An AST - @return True if is a key in the map, false otherwise. *) - let contains ( m : ast_map ) ( key : ast ) = - (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE - - (** Finds the value associated with the key . - - This function signs an error when is not a key in the map. - - @param k An AST - *) - let find ( m : ast_map ) ( key : ast ) = - create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) - - (** - Stores or replaces a new key/value pair in the map. - @param k The key AST - @param v The value AST - *) - let insert ( m : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert m#gnc m#gno key#gno value#gno - - (** - Erases the key from the map. - @param k An AST - *) - let erase ( m : ast_map ) ( key : ast ) = - Z3native.ast_map_erase m#gnc m#gno key#gno - - (** Removes all keys from the map. *) - let reset ( m : ast_map ) = - Z3native.ast_map_reset m#gnc m#gno - - (** The size of the map *) - let get_size ( m : ast_map ) = - Z3native.ast_map_size m#gnc m#gno - - (** The keys stored in the map. *) - let get_keys ( m : ast_map ) = - (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) - - (** Retrieves a string representation of the map.*) - let to_strnig ( m : ast_map ) = - Z3native.ast_map_to_string m#gnc m#gno -end - -(** Expressions (terms) *) +(** General expressions (terms), including Boolean logic *) module Expr = struct (** @@ -1402,7 +1311,7 @@ struct (** Indicates whether the expression is the true or false expression - or something else (Z3_L_UNDEF). + or something else (L_UNDEF). *) let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value x#gnc x#gno) @@ -1434,7 +1343,6 @@ struct The result is the new expression. The arrays from and to must have size num_exprs. For every i smaller than num_exprs, we must have that sort of from[i] must be equal to sort of to[i]. - *) let substitute ( x : expr ) from to_ = if (Array.length from) <> (Array.length to_) then @@ -1453,7 +1361,6 @@ struct Substitute the free variables in the expression with the expressions in For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. - *) let substitute_vars ( x : expr ) to_ = create_expr x#gc (Z3native.substitute_vars x#gnc x#gno (Array.length to_) (expraton to_)) @@ -1496,28 +1403,8 @@ struct *) let is_bool ( x : expr ) = (AST.is_expr x) && (lbool_of_int (Z3native.is_eq_sort x#gnc - (Z3native.mk_bool_sort x#gnc) - (Z3native.get_sort x#gnc x#gno))) == L_TRUE - - (** - Indicates whether the term is of integer sort. - *) - let is_int ( x : expr ) = - ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) - - (** - Indicates whether the term is of sort real. - *) - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) - - (** - Indicates whether the term is of an array sort. - *) - let is_array ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + (Z3native.mk_bool_sort x#gnc) + (Z3native.get_sort x#gnc x#gno))) == L_TRUE (** Indicates whether the term represents a constant. @@ -1526,21 +1413,6 @@ struct (get_num_args x) == 0 && FuncDecl.get_domain_size(get_func_decl x) == 0 - (** - Indicates whether the term is an integer numeral. - *) - let is_int_numeral ( x : expr ) = (is_numeral x) && (is_int x) - - (** - Indicates whether the term is a real numeral. - *) - let is_rat_num ( x : expr ) = (is_numeral x) && (is_real x) - - (** - Indicates whether the term is an algebraic number - *) - let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE - (** Indicates whether the term is the constant true. *) @@ -1597,146 +1469,1189 @@ struct let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) (** - Indicates whether the term is an arithmetic numeral. + Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ANUM) + let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) (** - Indicates whether the term is a less-than-or-equal + Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LE) (** - Indicates whether the term is a greater-than-or-equal + Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GE) + let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) (** - Indicates whether the term is a less-than + Creates a new Constant of sort and named . *) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LT) + let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = + create_expr ctx (Z3native.mk_const ctx#gno name#gno range#gno) + (** - Indicates whether the term is a greater-than + Creates a new Constant of sort and named . *) - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GT) + let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = + mk_const ctx ((Symbol.mk_string ctx name) :> symbol) range + (** - Indicates whether the term is addition (binary) + Creates a constant from the func_decl . + @param f An expression of a 0-arity function *) - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ADD) + let mk_const_f ( ctx : context ) ( f : func_decl ) = + create_expr_fa ctx f [||] (** - Indicates whether the term is subtraction (binary) + Creates a fresh constant of sort and a + name prefixed with . *) - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SUB) + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort) = + create_expr ctx (Z3native.mk_fresh_const ctx#gno prefix range#gno) (** - Indicates whether the term is a unary minus - *) - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UMINUS) + Create a Boolean constant. + *) + let mk_bool_const ( ctx : context ) ( name : symbol ) = + ((mk_const ctx name (Sort.mk_bool ctx)) :> bool_expr) + + (** + Create a Boolean constant. + *) + let mk_bool_const_s ( ctx : context ) ( name : string ) = + mk_bool_const ctx ((Symbol.mk_string ctx name) :> symbol) (** - Indicates whether the term is multiplication (binary) + Create a new function application. *) - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MUL) + let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = + create_expr_fa ctx f args (** - Indicates whether the term is division (binary) - *) - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DIV) + The true Term. + *) + let mk_true ( ctx : context ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_true ctx#gno) (** - Indicates whether the term is integer division (binary) - *) - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IDIV) + The false Term. + *) + let mk_false ( ctx : context ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_false ctx#gno) (** - Indicates whether the term is remainder (binary) - *) - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REM) + Creates a Boolean value. + *) + let mk_bool ( ctx : context ) ( value : bool) = + if value then mk_true ctx else mk_false ctx (** - Indicates whether the term is modulus (binary) + Creates the equality = . *) - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MOD) + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq ctx#gno x#gno y#gno) (** - Indicates whether the term is a coercion of integer to real (unary) + Creates a distinct term. *) - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_REAL) + let mk_distinct ( ctx : context ) ( args : expr array ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct ctx#gno (Array.length args) (astaton args)) + + (** + Mk an expression representing not(a). + *) + let mk_not ( ctx : context ) ( a : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_not ctx#gno a#gno) + + (** + Create an expression representing an if-then-else: ite(t1, t2, t3). + @param t1 An expression with Boolean sort + @param t2 An expression + @param t3 An expression with the same sort as + *) + let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = + create_expr ctx (Z3native.mk_ite ctx#gno t1#gno t2#gno t3#gno) + + (** + Create an expression representing t1 iff t2. + *) + let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff ctx#gno t1#gno t2#gno) (** - Indicates whether the term is a coercion of real to integer (unary) + Create an expression representing t1 -> t2. *) - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_INT) + let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies ctx#gno t1#gno t2#gno) (** - Indicates whether the term is a check that tests whether a real is integral (unary) + Create an expression representing t1 xor t2. *) - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IS_INT) + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor ctx#gno t1#gno t2#gno) + + (** + Create an expression representing the AND of args + *) + let mk_and ( ctx : context ) ( args : bool_expr array ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_and ctx#gno (Array.length args) (astaton args)) + + (** + Create an expression representing the OR of args + *) + let mk_or ( ctx : context ) ( args : bool_expr array ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_or ctx#gno (Array.length args) (astaton args)) +end + +(** Functions to manipulate Array expressions *) +module Arrays = +struct + (** + Create a new array sort. + *) + let mk_sort ( ctx : context ) domain range = + (new array_sort ctx)#cnstr_dr domain range (** Indicates whether the term is an array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. + Array store takes at least 3 arguments. *) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_STORE) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) (** Indicates whether the term is an array select. *) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SELECT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONST_ARRAY) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. + For example default(const(v)) = v. The function is unary. *) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_DEFAULT) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_MAP) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) (** Indicates whether the term is an as-array term. An as-array term is n array value that behaves as the function graph of the - function passed as parameter. + function passed as parameter. *) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AS_ARRAY) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + (** + Indicates whether the term is of an array sort. + *) + let is_array ( x : expr ) = + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + + (** The domain of the array sort. *) + let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) + + (** The range of the array sort. *) + let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) + + + (** + Create an array constant. + *) + let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = + ((Expr.mk_const ctx name ((mk_sort ctx domain range) :> sort)) :> array_expr) + + (** + Create an array constant. + *) + let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = + mk_const ctx ((Symbol.mk_string ctx name) :> symbol) domain range + + (** + Array read. + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + + + *) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = + ((create_expr ctx (Z3native.mk_select ctx#gno a#gno i#gno)) :> array_expr) + + (** + Array update. + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + + + *) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr) = + (new array_expr ctx)#cnstr_obj (Z3native.mk_store ctx#gno a#gno i#gno v#gno) + + (** + Create a constant array. + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + + + *) + let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = + (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array ctx#gno domain#gno v#gno) + + (** + Maps f on the argument arrays. + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + + + + *) + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = + ((create_expr ctx (Z3native.mk_map ctx#gno f#gno (Array.length args) (astaton args))) :> array_expr) + + (** + Access the array default value. + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. + *) + let mk_term_array ( ctx : context ) ( arg : array_expr ) = + ((create_expr ctx (Z3native.mk_array_default ctx#gno arg#gno)) :> array_expr) +end + +(** Functions to manipulate Set expressions *) +module Sets = +struct (** Indicates whether the term is set union *) - let is_set_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_UNION) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) (** Indicates whether the term is set intersection *) - let is_set_intersect ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_INTERSECT) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) (** Indicates whether the term is set difference *) - let is_set_difference ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_DIFFERENCE) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) (** Indicates whether the term is set complement *) - let is_set_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_COMPLEMENT) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) (** Indicates whether the term is set subset *) - let is_set_subset ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_SUBSET) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + +(** + Create a set type. +*) +let mk_sort ( ctx : context ) ( ty : sort) = + (new set_sort ctx)#cnstr_s ty + +(** + Create an empty set. +*) +let mk_empty ( ctx : context ) ( domain : sort ) = + (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) + + (** + Create the full set. + *) +let mk_full ( ctx : context ) ( domain : sort ) = + create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) + +(** + Add an element to the set. +*) +let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) + + (** + Remove an element from a set. + *) +let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) + + (** + Take the union of a list of sets. + *) +let mk_union ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) + +(** + Take the intersection of a list of sets. +*) +let mk_intersection ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) + +(** + Take the difference between two sets. +*) +let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) + +(** + Take the complement of a set. +*) +let mk_complement ( ctx : context ) ( arg : expr ) = + create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) + +(** + Check for set membership. +*) +let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) + + (** + Check for subsetness of sets. + *) +let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) + +end + +(** Functions to manipulate Finite Domain expressions *) +module FiniteDomains = +struct + (** + Create a new finite domain sort. + *) + let mk_sort ( ctx : context ) ( name : symbol ) size = + (new finite_domain_sort ctx)#cnstr_si name size + + (** + Create a new finite domain sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) size = + (new finite_domain_sort ctx)#cnstr_si ((Symbol.mk_string ctx name) :> symbol) size + + + (** + Indicates whether the term is of an array sort. + *) + let is_finite_domain ( x : expr ) = + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + + (** + Indicates whether the term is a less than predicate over a finite domain. + *) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + + (** The size of the finite domain sort. *) + let get_size (x : finite_domain_sort) = + let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in + if lbool_of_int(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") +end + +(** Functions to manipulate Relation expressions *) +module Relations = +struct + (** + Indicates whether the term is of a relation sort. + *) + let is_relation ( x : expr ) = + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + + (** + Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. + *) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + + (** + Indicates whether the term is an empty relation + *) + let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + + (** + Indicates whether the term is a test for the emptiness of a relation + *) + let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + + (** + Indicates whether the term is a relational join + *) + let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + + (** + Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. + *) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + + (** + Indicates whether the term is the widening of two relations + The function takes two arguments. + *) + let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + + (** + Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. + *) + let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + + (** + Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. + *) + let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + + (** + Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. + *) + let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + + (** + Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. + *) + let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + + (** + Indicates whether the term is the complement of a relation + *) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + + (** + Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. + *) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + + (** + Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind + to perform destructive updates to the first argument. + *) + let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + + (** The arity of the relation sort. *) + let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno + + (** The sorts of the columns of the relation sort. *) + let get_column_sorts (x : relation_sort) = + let n = get_arity x in + let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in + Array.init n f + +end + +(** Quantifier expressions *) +module Quantifiers = +struct + (** + The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. + *) + let get_index ( x : expr ) = + if not (AST.is_var x) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value x#gnc x#gno + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. + *) + module Pattern = + struct + (** + The number of terms in the pattern. + *) + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms x#gnc x#gno + + (** + The terms in the pattern. + *) + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the pattern. + *) + let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno + end + + (** + Indicates whether the quantifier is universal. + *) + let is_universal ( x : quantifier ) = + lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE + + (** + Indicates whether the quantifier is existential. + *) + let is_existential ( x : quantifier ) = not (is_universal x) + + (** + The weight of the quantifier. + *) + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno + + (** + The number of patterns. + *) + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno + + (** + The patterns. + *) + let get_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of no-patterns. + *) + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno + + (** + The no-patterns. + *) + let get_no_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of bound variables. + *) + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno + + (** + The symbols for the bound variables. + *) + let get_bound_variable_names ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + Array.init n f + + (** + The sorts of the bound variables. + *) + let get_bound_variable_sorts ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in + Array.init n f + + (** + The body of the quantifier. + *) + let get_body ( x : quantifier ) = + (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) + + (** + Creates a new bound variable. + @param index The de-Bruijn index of the variable + @param ty The sort of the variable + *) + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) + + (** + Create a quantifier pattern. + *) + let mk_pattern ( ctx : context ) ( terms : expr array ) = + if (Array.length terms) == 0 then + raise (Z3native.Exception "Cannot create a pattern from zero terms") + else + (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) +end + +(** Functions to manipulate Datatype expressions *) +module Datatypes = +struct + (** Constructors *) + module Constructor = + struct + (** The number of fields of the constructor. *) + let get_num_fields ( x : constructor ) = x#get_n + + (** The function declaration of the constructor. *) + let get_constructor_decl ( x : constructor ) = x#constructor_decl + + (** The function declaration of the tester. *) + let get_tester_decl ( x : constructor ) = x#tester_decl + + (** The function declarations of the accessors *) + let get_accessor_decls ( x : constructor ) = x#accessor_decls + end + + (* DATATYPES *) + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs + + + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + mk_constructor ctx ((Symbol.mk_string ctx name) :> symbol) recognizer field_names sorts sort_refs + + + (** + Create a new datatype sort. + *) + let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + (new datatype_sort ctx)#cnstr_sc name constructors + + (** + Create a new datatype sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = + mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) constructors + + (** + Create mutually recursive datatypes. + @param names names of datatype sorts + @param c list of constructors, one list per sort. + *) + let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let n = (Array.length names) in + let f e = ( (new constructor_list ctx)#cnstr_ca e ) in + let cla = (Array.map f c) in + let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in + let g e = ( (new datatype_sort ctx)#cnstr_obj e) in + (Array.map g r) + + (** Create mutually recursive data-types. *) + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + mk_sorts ctx + ( + let f e = ((Symbol.mk_string ctx e) :> symbol) in + Array.map f names + ) + c + + (** The number of constructors of the datatype sort. *) + let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno + + (** The range of the array sort. *) + let get_constructors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in + Array.init n f + + (** The recognizers. *) + let get_recognizers (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in + Array.init n f + + (** The constructor accessors. *) + let get_accessors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = ( + let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in + let ds = (Z3native.get_domain_size fd#gnc fd#gno) in + let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in + Array.init ds g + ) in + Array.init n f +end + +(** Functions to manipulate Enumeration expressions *) +module Enumerations = +struct + (** + Create a new enumeration sort. + *) + let mk_sort ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss name enum_names + + (** + Create a new enumeration sort. + *) + let mk_sort_s ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss + ((Symbol.mk_string ( ctx : context ) name) :> symbol) + (let f e = (e :> symbol) in + (Array.map f (Symbol.mk_strings ( ctx : context ) enum_names)) + ) + + (** The function declarations of the constants in the enumeration. *) + let get_const_decls (x : enum_sort) = x#const_decls + + (** The test predicates for the constants in the enumeration. *) + let get_tester_decls (x : enum_sort) = x#tester_decls +end + +(** Functions to manipulate List expressions *) +module Lists = +struct + (** + Create a new list sort. + *) + let mk_sort ( ctx : context ) (name : symbol) elem_sort = + (new list_sort ctx)#cnstr_ss name elem_sort + + (** + Create a new list sort. + *) + let mk_list_s ( ctx : context ) (name : string) elem_sort = + mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) elem_sort + + + (** The declaration of the nil function of this list sort. *) + let get_nil_decl (x : list_sort) = x#nil_decl + + (** The declaration of the isNil function of this list sort. *) + let get_is_nil_decl (x : list_sort) = x#is_nil_decl + + (** The declaration of the cons function of this list sort. *) + let get_cons_decl (x : list_sort) = x#cons_decl + + (** The declaration of the isCons function of this list sort. *) + let get_is_cons_decl (x : list_sort) = x#is_cons_decl + + (** The declaration of the head function of this list sort. *) + let get_head_decl (x : list_sort) = x#head_decl + + (** The declaration of the tail function of this list sort. *) + let get_tail_decl (x : list_sort) = x#tail_decl + + (** The empty list. *) + let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] +end + +(** Functions to manipulate Tuple expressions *) +module Tuples = +struct + (** + Create a new tuple sort. + *) + let mk_sort ( ctx : context ) name field_names field_sorts = + (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts + + (** The constructor function of the tuple. *) + let get_mk_decl (x : tuple_sort) = + (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) + + (** The number of fields in the tuple. *) + let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno + + (** The field declarations. *) + let get_field_decls (x : tuple_sort) = + let n = get_num_fields x in + let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in + Array.init n f +end + +(** Functions to manipulate arithmetic expressions *) +module Arithmetic = +struct + (** + Create a new integer sort. + *) + let mk_int_sort ( ctx : context ) = + (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) + + (** + Create a real sort. + *) + let mk_real_sort ( ctx : context ) = + (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) + + (** + Indicates whether the term is of integer sort. + *) + let is_int ( x : expr ) = + ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + + (** + Indicates whether the term is an arithmetic numeral. + *) + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + + (** + Indicates whether the term is a less-than-or-equal + *) + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + + (** + Indicates whether the term is a greater-than-or-equal + *) + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + + (** + Indicates whether the term is a less-than + *) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + + (** + Indicates whether the term is a greater-than + *) + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + + (** + Indicates whether the term is addition (binary) + *) + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + + (** + Indicates whether the term is subtraction (binary) + *) + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + + (** + Indicates whether the term is a unary minus + *) + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + + (** + Indicates whether the term is multiplication (binary) + *) + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + + (** + Indicates whether the term is division (binary) + *) + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + + (** + Indicates whether the term is integer division (binary) + *) + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + + (** + Indicates whether the term is remainder (binary) + *) + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + + (** + Indicates whether the term is modulus (binary) + *) + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + + (** + Indicates whether the term is a coercion of integer to real (unary) + *) + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + + (** + Indicates whether the term is a coercion of real to integer (unary) + *) + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + + (** + Indicates whether the term is a check that tests whether a real is integral (unary) + *) + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + + (** + Indicates whether the term is of sort real. + *) + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + + (** + Indicates whether the term is an integer numeral. + *) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + + (** + Indicates whether the term is a real numeral. + *) + let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) + + (** + Indicates whether the term is an algebraic number + *) + let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + + (** Retrieve the int value. *) + let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if lbool_of_int(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno + + (** The numerator of a rational numeral. *) + let get_numerator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) + + (** The denominator of a rational numeral. *) + let get_denominator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : rat_num ) (precision : int) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno + + (** + Creates an integer constant. + *) + let mk_int_const ( ctx : context ) ( name : symbol ) = + ((Expr.mk_const ctx name (mk_int_sort ctx)) :> int_expr) + + (** + Creates an integer constant. + *) + let mk_int_const_s ( ctx : context ) ( name : string ) = + mk_int_const ctx ((Symbol.mk_string ctx name) :> symbol) + + (** + Creates a real constant. + *) + let mk_real_const ( ctx : context ) ( name : symbol ) = + ((Expr.mk_const ctx name (mk_real_sort ctx)) :> real_expr) + + (** + Creates a real constant. + *) + let mk_real_const_s ( ctx : context ) ( name : string ) = + mk_real_const ctx ((Symbol.mk_string ctx name) :> symbol) + + (** + Create an expression representing t[0] + t[1] + .... + *) + let mk_add ( ctx : context ) ( t : arith_expr array ) = + (create_expr ctx (Z3native.mk_add ctx#gno (Array.length t) (astaton t)) :> arith_expr) + + (** + Create an expression representing t[0] * t[1] * .... + *) + let mk_mul ( ctx : context ) ( t : arith_expr array ) = + (create_expr ctx (Z3native.mk_mul ctx#gno (Array.length t) (astaton t)) :> arith_expr) + + (** + Create an expression representing t[0] - t[1] - .... + *) + let mk_sub ( ctx : context ) ( t : arith_expr array ) = + (create_expr ctx (Z3native.mk_sub ctx#gno (Array.length t) (astaton t)) :> arith_expr) + + (** + Create an expression representing -t. + *) + let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = + (create_expr ctx (Z3native.mk_unary_minus ctx#gno t#gno) :> arith_expr) + + (** + Create an expression representing t1 / t2. + *) + let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + (create_expr ctx (Z3native.mk_div ctx#gno t1#gno t2#gno) :> arith_expr) + + (** + Create an expression representing t1 mod t2. + The arguments must have int type. + *) + let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_mod ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 rem t2. + The arguments must have int type. + *) + let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_rem ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 ^ t2. + *) + let mk_Power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (create_expr ctx (Z3native.mk_power ctx#gno t1#gno t2#gno) :> arith_expr) + + (** + Create an expression representing t1 < t2 + *) + let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 <= t2 + *) + let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_le ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 > t2 + *) + let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 >= t2 + *) + let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge ctx#gno t1#gno t2#gno) + + (** + Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. + *) + let mk_int2real ( ctx : context ) ( t : int_expr ) = + (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real ctx#gno t#gno) + + (** + Coerce a real to an integer. + + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. + *) + let mk_real2int ( ctx : context ) ( t : real_expr ) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int ctx#gno t#gno) + + (** + Creates an expression that checks whether a real number is an integer. + *) + let mk_is_integer ( ctx : context ) ( t : real_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int ctx#gno t#gno) + + (** + Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_upper ( x : algebraic_num ) ( precision : int ) = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) + + (** + Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_lower ( x : algebraic_num ) precision = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno +end + + +(** Functions to manipulate bit-vector expressions *) +module BitVectors = +struct + (** + Create a new bit-vector sort. + *) + let mk_sort ( ctx : context ) size = + (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) (** Indicates whether the terms is of bit-vector sort. @@ -1747,300 +2662,750 @@ struct (** Indicates whether the term is a bit-vector numeral *) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNUM) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) (** Indicates whether the term is a one-bit bit-vector with value one *) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT1) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) (** Indicates whether the term is a one-bit bit-vector with value zero *) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT0) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) (** Indicates whether the term is a bit-vector unary minus *) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNEG) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) (** Indicates whether the term is a bit-vector addition (binary) *) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BADD) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) (** Indicates whether the term is a bit-vector subtraction (binary) *) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSUB) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) (** Indicates whether the term is a bit-vector multiplication (binary) *) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BMUL) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) (** Indicates whether the term is a bit-vector signed division (binary) *) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) (** Indicates whether the term is a bit-vector unsigned division (binary) *) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) (** Indicates whether the term is a bit-vector signed remainder (binary) *) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) (** Indicates whether the term is a bit-vector signed modulus *) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) (** Indicates whether the term is a bit-vector signed division by zero *) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV0) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) (** Indicates whether the term is a bit-vector unsigned division by zero *) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV0) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) (** Indicates whether the term is a bit-vector signed remainder by zero *) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM0) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM0) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) (** Indicates whether the term is a bit-vector signed modulus by zero *) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD0) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULEQ) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLEQ) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGEQ) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGEQ) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) (** Indicates whether the term is an unsigned bit-vector less-than *) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULT) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) (** Indicates whether the term is a signed bit-vector less-than *) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLT) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) (** Indicates whether the term is an unsigned bit-vector greater-than *) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGT) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) (** Indicates whether the term is a signed bit-vector greater-than *) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGT) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) (** Indicates whether the term is a bit-wise AND *) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BAND) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) (** Indicates whether the term is a bit-wise OR *) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BOR) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) (** Indicates whether the term is a bit-wise NOT *) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOT) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) (** Indicates whether the term is a bit-wise XOR *) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXOR) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) (** Indicates whether the term is a bit-wise NAND *) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNAND) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) (** Indicates whether the term is a bit-wise NOR *) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOR) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) (** Indicates whether the term is a bit-wise XNOR *) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXNOR) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) (** Indicates whether the term is a bit-vector concatenation (binary) *) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONCAT) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) (** Indicates whether the term is a bit-vector sign extension *) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SIGN_EXT) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) (** Indicates whether the term is a bit-vector zero extension *) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ZERO_EXT) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) (** Indicates whether the term is a bit-vector extraction *) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXTRACT) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) (** Indicates whether the term is a bit-vector repetition *) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REPEAT) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) (** Indicates whether the term is a bit-vector reduce OR *) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDOR) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) (** Indicates whether the term is a bit-vector reduce AND *) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDAND) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) (** Indicates whether the term is a bit-vector comparison *) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BCOMP) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) (** Indicates whether the term is a bit-vector shift left *) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSHL) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) (** Indicates whether the term is a bit-vector logical shift right *) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) (** Indicates whether the term is a bit-vector arithmetic shift left *) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BASHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) (** Indicates whether the term is a bit-vector rotate left *) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right *) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. + rudimentary simplification rules are applied to this function. *) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_INT2BV) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. + rudimentary simplification rules are applied to this function. *) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BV2INT) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CARRY) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR3) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + + (** The size of a bit-vector sort. *) + let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno + + (** Retrieve the int value. *) + let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if lbool_of_int(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno (** - Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. + Creates a bit-vector constant. *) - let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) + let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = + ((Expr.mk_const ctx name (mk_sort ctx size)) :> bitvec_expr) (** - Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) + Creates a bit-vector constant. *) + let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_const ctx ((Symbol.mk_string ctx name) :> symbol) size (** - Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. + Bitwise negation. + The argument must have a bit-vector sort. *) - let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + let mk_not ( ctx : context ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot ctx#gno t#gno) + (** + Take conjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. + *) + let mk_redand ( ctx : context ) ( t : bitvec_expr) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand ctx#gno t#gno) + + (** + Take disjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. + *) + let mk_redor ( ctx : context ) ( t : bitvec_expr) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor ctx#gno t#gno) + + (** + Bitwise conjunction. + The arguments must have a bit-vector sort. + *) + let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand ctx#gno t1#gno t2#gno) + + (** + Bitwise disjunction. + The arguments must have a bit-vector sort. + *) + let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor ctx#gno t1#gno t2#gno) + + (** + Bitwise XOR. + The arguments must have a bit-vector sort. + *) + let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor ctx#gno t1#gno t2#gno) + + (** + Bitwise NAND. + The arguments must have a bit-vector sort. + *) + let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand ctx#gno t1#gno t2#gno) + + (** + Bitwise NOR. + The arguments must have a bit-vector sort. + *) + let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor ctx#gno t1#gno t2#gno) + + (** + Bitwise XNOR. + The arguments must have a bit-vector sort. + *) + let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor ctx#gno t1#gno t2#gno) + + (** + Standard two's complement unary minus. + The arguments must have a bit-vector sort. + *) + let mk_neg ( ctx : context ) ( t : bitvec_expr) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg ctx#gno t#gno) + + (** + Two's complement addition. + The arguments must have the same bit-vector sort. + *) + let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd ctx#gno t1#gno t2#gno) + + (** + Two's complement subtraction. + The arguments must have the same bit-vector sort. + *) + let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub ctx#gno t1#gno t2#gno) + + (** + Two's complement multiplication. + The arguments must have the same bit-vector sort. + *) + let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul ctx#gno t1#gno t2#gno) + + (** + Unsigned division. + + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv ctx#gno t1#gno t2#gno) + + (** + Signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv ctx#gno t1#gno t2#gno) + + (** + Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem ctx#gno t1#gno t2#gno) + + (** + Signed remainder. + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem ctx#gno t1#gno t2#gno) + + (** + Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod ctx#gno t1#gno t2#gno) + + (** + Unsigned less-than + + The arguments must have the same bit-vector sort. + *) + let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult ctx#gno t1#gno t2#gno) + + (** + Two's complement signed less-than + + The arguments must have the same bit-vector sort. + *) + let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt ctx#gno t1#gno t2#gno) + + (** + Unsigned less-than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule ctx#gno t1#gno t2#gno) + + (** + Two's complement signed less-than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle ctx#gno t1#gno t2#gno) + + (** + Unsigned greater than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge ctx#gno t1#gno t2#gno) + + (** + Two's complement signed greater than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge ctx#gno t1#gno t2#gno) + + (** + Unsigned greater-than. + + The arguments must have the same bit-vector sort. + *) + let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt ctx#gno t1#gno t2#gno) + + (** + Two's complement signed greater-than. + + The arguments must have the same bit-vector sort. + *) + let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt ctx#gno t1#gno t2#gno) + + (** + Bit-vector concatenation. + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). + *) + let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat ctx#gno t1#gno t2#gno) + + (** + Bit-vector extraction. + + Extract the bits down to from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. + The argument must have a bit-vector sort. + *) + let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract ctx#gno high low t#gno) + + (** + Bit-vector sign extension. + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. + The argument must have a bit-vector sort. + *) + let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext ctx#gno i t#gno) + + (** + Bit-vector zero extension. + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. + The argument must have a bit-vector sort. + *) + let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext ctx#gno i t#gno) + + (** + Bit-vector repetition. + + The argument must have a bit-vector sort. + *) + let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat ctx#gno i t#gno) + + (** + Shift left. + + + It is equivalent to multiplication by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + *) + let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl ctx#gno t1#gno t2#gno) + + (** + Logical shift right + + It is equivalent to unsigned division by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + *) + let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr ctx#gno t1#gno t2#gno) + + (** + Arithmetic shift right + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + *) + let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr ctx#gno t1#gno t2#gno) + + (** + Rotate Left. + + Rotate bits of \c t to the left \c i times. + The argument must have a bit-vector sort. + *) + let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left ctx#gno i t#gno) + + (** + Rotate Right. + + Rotate bits of \c t to the right \c i times. + The argument must have a bit-vector sort. + *) + let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right ctx#gno i t#gno) + + (** + Rotate Left. + + Rotate bits of to the left times. + The arguments must have the same bit-vector sort. + *) + let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left ctx#gno t1#gno t2#gno) + + (** + Rotate Right. + + + Rotate bits of to the right times. + The arguments must have the same bit-vector sort. + *) + let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right ctx#gno t1#gno t2#gno) + + (** + Create an bit bit-vector from the integer argument . + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. + *) + let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv ctx#gno n t#gno) + + (** + Create an integer from the bit-vector argument . + + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in . + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of bit-vector sort. + *) + let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise addition does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise addition does not underflow. + + The arguments must be of bit-vector sort. + *) + let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow ctx#gno t1#gno t2#gno) + + (** + Create a predicate that checks that the bit-wise subtraction does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow ctx#gno t1#gno t2#gno) + + (** + Create a predicate that checks that the bit-wise subtraction does not underflow. + + The arguments must be of bit-vector sort. + *) + let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise signed division does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow ctx#gno t1#gno t2#gno) + + (** + Create a predicate that checks that the bit-wise negation does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow ctx#gno t#gno) + + (** + Create a predicate that checks that the bit-wise multiplication does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise multiplication does not underflow. + + The arguments must be of bit-vector sort. + *) + let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow ctx#gno t1#gno t2#gno) + +end + +(** Functions to manipulate Proof objects *) +module Proofs = +struct (** Indicates whether the term is a Proof for the expression 'true'. *) - let is_proof_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRUE) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) (** Indicates whether the term is a proof for a fact asserted by the user. *) - let is_proof_asserted ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ASSERTED) + let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - let is_proof_goal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_GOAL) + let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) (** Indicates whether the term is proof via modus ponens @@ -2049,18 +3414,18 @@ struct T1: p T2: (implies p q) [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). + The second antecedents may also be a proof for (iff p q). *) - let is_proof_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS) + let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. This proof object has no antecedents. The only reflexive relations that are used are equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. + That is, R is either '~', '=' or 'iff'. *) - let is_proof_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REFLEXIVITY) + let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) (** Indicates whether the term is proof by symmetricity of a relation @@ -2069,9 +3434,8 @@ struct T1: (R t s) [symmetry T1]: (R s t) T1 is the antecedent of this proof object. - *) - let is_proof_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SYMMETRY) + let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) (** Indicates whether the term is a proof by transitivity of a relation @@ -2081,9 +3445,8 @@ struct T1: (R t s) T2: (R s u) [trans T1 T2]: (R t u) - *) - let is_proof_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY) + let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) (** Indicates whether the term is a proof by condensed transitivity of a relation @@ -2102,9 +3465,8 @@ struct using the antecedents, symmetry and transitivity. That is, if there is a path from s to t, if we view every antecedent (R a b) as an edge between a and b. - *) - let is_proof_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) (** @@ -2116,9 +3478,8 @@ struct [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) Remark: if t_i == s_i, then the antecedent Ti is suppressed. That is, reflexivity proofs are supressed to save space. - *) - let is_proof_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MONOTONICITY) + let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) (** Indicates whether the term is a quant-intro proof @@ -2126,9 +3487,8 @@ struct Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). T1: (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - *) - let is_proof_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INTRO) + let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) (** Indicates whether the term is a distributivity proof object. @@ -2144,9 +3504,8 @@ struct This proof object has no antecedents. Remark. This rule is used by the CNF conversion pass and instantiated by f = or, and g = and. - *) - let is_proof_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) (** Indicates whether the term is a proof by elimination of AND @@ -2154,9 +3513,8 @@ struct Given a proof for (and l_1 ... l_n), produces a proof for l_i T1: (and l_1 ... l_n) [and-elim T1]: l_i - *) - let is_proof_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_AND_ELIM) + let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) (** Indicates whether the term is a proof by eliminiation of not-or @@ -2164,9 +3522,8 @@ struct Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) - *) - let is_proof_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) (** Indicates whether the term is a proof by rewriting @@ -2183,9 +3540,8 @@ struct (= (+ ( x : expr ) 0) x) (= (+ ( x : expr ) 1 2) (+ 3 x)) (iff (or ( x : expr ) false) x) - *) - let is_proof_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE) + let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) (** Indicates whether the term is a proof by rewriting @@ -2199,17 +3555,15 @@ struct - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - When converting bit-vectors to Booleans (BIT2BOOL=true) - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - *) - let is_proof_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE_STAR) + let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) (** Indicates whether the term is a proof for pulling quantifiers out. A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - *) - let is_proof_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) (** Indicates whether the term is a proof for pulling quantifiers out. @@ -2217,9 +3571,8 @@ struct A proof for (iff P Q) where Q is in prenex normal form. This proof object is only used if the parameter PROOF_MODE is 1. This proof object has no antecedents - *) - let is_proof_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) (** Indicates whether the term is a proof for pushing quantifiers in. @@ -2230,9 +3583,9 @@ struct ... (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) This proof object has no antecedents - *) - let is_proof_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PUSH_QUANT) + + let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) (** Indicates whether the term is a proof for elimination of unused variables. @@ -2242,9 +3595,9 @@ struct It is used to justify the elimination of unused variables. This proof object has no antecedents. - *) - let is_proof_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + + let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) (** Indicates whether the term is a proof for destructive equality resolution @@ -2256,23 +3609,22 @@ struct This proof object has no antecedents. Several variables can be eliminated simultaneously. - *) - let is_proof_der ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DER) + + let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) (** Indicates whether the term is a proof for quantifier instantiation A proof of (or (not (forall (x) (P x))) (P a)) - *) - let is_proof_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INST) + let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. + Mark a hypothesis in a natural deduction style proof. *) - let is_proof_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_HYPOTHESIS) + let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) (** Indicates whether the term is a proof by lemma @@ -2283,9 +3635,8 @@ struct This proof object has one antecedent: a hypothetical proof for false. It converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 contains the hypotheses: l_1, ..., l_n. - *) - let is_proof_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_LEMMA) + let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) (** Indicates whether the term is a proof by unit resolution @@ -2295,27 +3646,24 @@ struct ... T(n+1): (not l_n) [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - *) - let is_proof_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) (** Indicates whether the term is a proof by iff-true T1: p [iff-true T1]: (iff p true) - *) - let is_proof_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) (** Indicates whether the term is a proof by iff-false T1: (not p) [iff-false T1]: (iff p false) - *) - let is_proof_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_FALSE) + let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) (** Indicates whether the term is a proof by commutativity @@ -2326,9 +3674,8 @@ struct This proof object has no antecedents. Remark: if f is bool, then = is iff. - *) - let is_proof_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) (** Indicates whether the term is a proof for Tseitin-like axioms @@ -2362,9 +3709,8 @@ struct You can recover the propositional tautologies by unfolding the Boolean connectives in the axioms a small bounded number of steps (=3). - *) - let is_proof_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) (** Indicates whether the term is a proof for introduction of a name @@ -2385,9 +3731,8 @@ struct Otherwise: [def-intro]: (= n e) - *) - let is_proof_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_INTRO) + let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) (** Indicates whether the term is a proof for application of a definition @@ -2395,18 +3740,16 @@ struct [apply-def T1]: F ~ n F is 'equivalent' to n, given that T1 is a proof that n is a name for F. - *) - let is_proof_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_APPLY_DEF) + let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) (** Indicates whether the term is a proof iff-oeq T1: (iff p q) [iff~ T1]: (~ p q) - *) - let is_proof_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_OEQ) + let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) (** Indicates whether the term is a proof for a positive NNF step @@ -2432,9 +3775,8 @@ struct for NNF_POS are 'implies', 'iff', 'xor', 'ite'. NNF_NEG furthermore handles the case where negation is pushed over Boolean connectives 'and' and 'or'. - *) - let is_proof_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) (** Indicates whether the term is a proof for a negative NNF step @@ -2457,9 +3799,8 @@ struct T4: s_2 ~ r_2' [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 r_2) (or r_1' r_2'))) - *) - let is_proof_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. @@ -2469,9 +3810,8 @@ struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) - let is_proof_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_STAR) + let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. @@ -2479,9 +3819,8 @@ struct A proof for (~ P Q) where Q is in conjunctive normal form. This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) - let is_proof_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_CNF_STAR) + let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) (** Indicates whether the term is a proof for a Skolemization step @@ -2492,9 +3831,8 @@ struct [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) This proof object has no antecedents. - *) - let is_proof_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SKOLEMIZE) + let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. @@ -2503,9 +3841,8 @@ struct T1: p T2: (~ p q) [mp~ T1 T2]: q - *) - let is_proof_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) (** Indicates whether the term is a proof for theory lemma @@ -2520,259 +3857,74 @@ struct - farkas - followed by rational coefficients. Multiply the coefficients to the inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - *) - let is_proof_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TH_LEMMA) - - (** - Indicates whether the term is of a relation sort. - *) - let is_Relation ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) - - (** - Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. - - *) - let is_relation_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_STORE) - - (** - Indicates whether the term is an empty relation - *) - let is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_EMPTY) - - (** - Indicates whether the term is a test for the emptiness of a relation - *) - let is_is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_IS_EMPTY) - - (** - Indicates whether the term is a relational join - *) - let is_relational_join ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_JOIN) - - (** - Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. - *) - let is_relation_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_UNION) - - (** - Indicates whether the term is the widening of two relations - The function takes two arguments. - *) - let is_relation_widen ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_WIDEN) - - (** - Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. - *) - let is_relation_project ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_PROJECT) - - (** - Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. - - *) - let is_relation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_FILTER) - - (** - Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. - - *) - let is_relation_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_NEGATION_FILTER) - - (** - Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. - - *) - let is_relation_rename ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_RENAME) - - (** - Indicates whether the term is the complement of a relation - *) - let is_relation_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_COMPLEMENT) - - (** - Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. - - *) - let is_relation_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_SELECT) - - (** - Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind - to perform destructive updates to the first argument. - - *) - let is_relation_clone ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_CLONE) - - (** - Indicates whether the term is of an array sort. - *) - let is_finite_domain ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) - - (** - Indicates whether the term is a less than predicate over a finite domain. - *) - let is_finite_domain_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FD_LT) - - (** - The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. - - *) - let get_index ( x : expr ) = - if not (AST.is_var x) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value x#gnc x#gno + let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end -(** Integer Numerals *) -module IntNum = -struct - (** Retrieve the int value. *) - let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") +(** + Parameter sets (of Solvers, Tactics, ...) - (** Returns a string representation of the numeral. *) - let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno -end - -(** Rational Numerals *) -module RatNum = -struct - - (** The numerator of a rational numeral. *) - let get_numerator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) - - (** The denominator of a rational numeral. *) - let get_denominator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) - - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : rat_num ) (precision : int) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision - - (** Returns a string representation of the numeral. *) - let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno -end - -(** Bit-vector numerals *) -module BitVecNum = -struct - (** Retrieve the int value. *) - let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") - - (** Returns a string representation of the numeral. *) - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno -end - -(** Algebraic numbers *) -module AlgebraicNum = + A Params objects represents a configuration in the form of symbol/value pairs. +*) +module Params = struct (** - Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real + Adds a parameter setting. *) - let to_upper ( x : algebraic_num ) ( precision : int ) = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) - - (** - Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) - let to_lower ( x : algebraic_num ) precision = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + let add_bool (p : params) (name : symbol) (value : bool) = + Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision + (** + Adds a parameter setting. + *) + let add_int (p : params) (name : symbol) (value : int) = + Z3native.params_set_uint p#gnc p#gno name#gno value - (** Returns a string representation of the numeral. *) - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno + (** + Adds a parameter setting. + *) + let add_double (p : params) (name : symbol) (value : float) = + Z3native.params_set_double p#gnc p#gno name#gno value + + (** + Adds a parameter setting. + *) + let add_symbol (p : params) (name : symbol) (value : symbol) = + Z3native.params_set_symbol p#gnc p#gno name#gno value#gno + + (** + Adds a parameter setting. + *) + let add_s_bool (p : params) (name : string) (value : bool) = + add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_int (p : params) (name : string) (value : int) = + add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_double (p : params) (name : string) (value : float) = + add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_symbol (p : params) (name : string) (value : symbol) = + add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + A string representation of the parameter set. + *) + let to_string (p : params) = Z3native.params_to_string p#gnc p#gno end -(** Constructors are used for datatype sorts *) -module Constructor = -struct - (** The number of fields of the constructor. *) - let get_num_fields ( x : constructor ) = x#get_n - - (** The function declaration of the constructor. *) - let get_constructor_decl ( x : constructor ) = x#constructor_decl - - (** The function declaration of the tester. *) - let get_tester_decl ( x : constructor ) = x#tester_decl - - (** The function declarations of the accessors *) - let get_accessor_decls ( x : constructor ) = x#accessor_decls -end - - -(** ParamDescrs describe sets of parameters.*) +(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) module ParamDescrs = struct @@ -2917,102 +4069,100 @@ struct | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) - (** Creates a solver that is implemented using the given tactic. + (** creates a solver that is implemented using the given tactic. *) let get_solver ( x : tactic ) = (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) end - -(** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. -*) -module FuncInterp = -struct - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) - module FuncEntry = - struct - (** - Return the (symbolic) value of this entry. - *) - let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) - - (** - The number of arguments of the entry. - *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno - - (** - The arguments of the function entry. - *) - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the function entry. - *) - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") - end - - (** - The number of entries in the function interpretation. - *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno - - (** - The entries in the function interpretation - *) - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in - Array.init n f - - (** - The (symbolic) `else' value of the function interpretation. - *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) - - (** - The arity of the function interpretation - *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno - - (** - A string representation of the function interpretation. - *) - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (Array.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") -end - -(** Models. +(** Models A Model contains interpretations (assignments) of constants and functions. *) module Model = struct - + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. + *) + module FuncInterp = + struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + (** Retrieves the interpretation (the assignment) of in the model. A function declaration of zero arity An expression if the function has an interpretation in the model, null otherwise. *) @@ -3093,7 +4243,7 @@ struct This function may fail if contains quantifiers, is partial (MODEL_PARTIAL enabled), or if is not well-sorted. In this case a ModelEvaluationFailedException is thrown. - + An expression When this flag is enabled, a model value will be assigned to any constant @@ -3120,7 +4270,6 @@ struct Z3 also provides an intepretation for uninterpreted sorts used in a formula. The interpretation for a sort is a finite set of distinct values. We say this finite set is the "universe" of the sort. - *) @@ -3137,8 +4286,8 @@ struct *) let sort_universe ( x : model ) ( s : sort ) = let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in - let n = (ASTVector.get_size n_univ) in - let f i = (ASTVector.get n_univ i) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in Array.init n f (** Conversion of models to strings. @@ -3174,84 +4323,85 @@ struct let to_string ( x : apply_result) = Z3native.apply_result_to_string x#gnc x#gno end -(** Objects that track statistical information about solvers. *) -module Statistics = -struct - - (** - Statistical data is organized into pairs of [Key, Entry], where every - Entry is either a DoubleEntry or a UIntEntry - *) - module Entry = - struct - (** The key of the entry. *) - let get_key (x : statistics_entry) = x#key - - (** The int-value of the entry. *) - let get_int (x : statistics_entry) = x#int - - (** The float-value of the entry. *) - let get_float (x : statistics_entry) = x#float - - (** True if the entry is uint-valued. *) - let is_int (x : statistics_entry) = x#is_int - - (** True if the entry is double-valued. *) - let is_float (x : statistics_entry) = x#is_float - - (** The string representation of the the entry's value. *) - let to_string_value (x : statistics_entry) = - if (is_int x) then - string_of_int (get_int x) - else if (is_float x) then - string_of_float (get_float x) - else - raise (Z3native.Exception "Unknown statistical entry type") - - (** The string representation of the entry (key and value) *) - let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) - end - - (** A string representation of the statistical data. *) - let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno - - (** The number of statistical data. *) - let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno - - (** The data entries. *) - let get_entries ( x : statistics ) = - let n = (get_size x ) in - let f i = ( - let k = Z3native.stats_get_key x#gnc x#gno i in - if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then - ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) - else - ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) - ) in - Array.init n f - - (** - The statistical counters. - *) - let get_keys ( x : statistics ) = - let n = (get_size x) in - let f i = (Z3native.stats_get_key x#gnc x#gno i) in - Array.init n f - - (** - The value of a particular statistical counter. - *) - let get ( x : statistics ) ( key : string ) = - let f p c = (if (Entry.get_key c) = key then (Some c) else p) in - Array.fold_left f None (get_entries x) - -end - (** Solvers *) module Solver = struct type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + (** Objects that track statistical information about solvers. *) + module Statistics = + struct + + (** + Statistical data is organized into pairs of [Key, Entry], where every + Entry is either a DoubleEntry or a UIntEntry + *) + module Entry = + struct + (** The key of the entry. *) + let get_key (x : statistics_entry) = x#key + + (** The int-value of the entry. *) + let get_int (x : statistics_entry) = x#int + + (** The float-value of the entry. *) + let get_float (x : statistics_entry) = x#float + + (** True if the entry is uint-valued. *) + let is_int (x : statistics_entry) = x#is_int + + (** True if the entry is double-valued. *) + let is_float (x : statistics_entry) = x#is_float + + (** The string representation of the the entry's value. *) + let to_string_value (x : statistics_entry) = + if (is_int x) then + string_of_int (get_int x) + else if (is_float x) then + string_of_float (get_float x) + else + raise (Z3native.Exception "Unknown statistical entry type") + + (** The string representation of the entry (key and value) *) + let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) + end + + (** A string representation of the statistical data. *) + let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno + + (** The number of statistical data. *) + let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno + + (** The data entries. *) + let get_entries ( x : statistics ) = + let n = (get_size x ) in + let f i = ( + let k = Z3native.stats_get_key x#gnc x#gno i in + if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then + ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) + else + ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) + ) in + Array.init n f + + (** + The statistical counters. + *) + let get_keys ( x : statistics ) = + let n = (get_size x) in + let f i = (Z3native.stats_get_key x#gnc x#gno i) in + Array.init n f + + (** + The value of a particular statistical counter. + *) + let get ( x : statistics ) ( key : string ) = + let f p c = (if (Entry.get_key c) = key then (Some c) else p) in + Array.fold_left f None (get_entries x) + + end + + (** A string that describes all available solver parameters. *) @@ -3284,14 +4434,14 @@ struct (** Backtracks backtracking points. - Note that an exception is thrown if is not smaller than NumScopes + Note that an exception is thrown if is not smaller than NumScopes *) let pop ( x : solver ) ( n : int ) = Z3native.solver_pop x#gnc x#gno n (** Resets the Solver. - This removes all assertions from the solver. + This removes all assertions from the solver. *) let reset ( x : solver ) = Z3native.solver_reset x#gnc x#gno @@ -3307,7 +4457,7 @@ struct *) let get_num_assertions ( x : solver ) = let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in - (ASTVector.get_size a) + (AST.ASTVector.get_size a) (** @@ -3315,8 +4465,8 @@ struct *) let get_assertions ( x : solver ) = let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in - let n = (ASTVector.get_size a) in - let f i = ((new bool_expr x#gc)#cnstr_obj (ASTVector.get a i)#gno) in + let n = (AST.ASTVector.get_size a) in + let f i = ((new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get a i)#gno) in Array.init n f (** @@ -3325,7 +4475,6 @@ struct - *) let check ( x : solver ) ( assumptions : bool_expr array option) = let r = @@ -3343,7 +4492,6 @@ struct The result is None if Check was not invoked before, if its results was not SATISFIABLE, or if model production is not enabled. - *) let get_model ( x : solver ) = let q = Z3native.solver_get_model x#gnc x#gno in @@ -3357,7 +4505,6 @@ struct The result is null if Check was not invoked before, if its results was not UNSATISFIABLE, or if proof production is disabled. - *) let get_proof ( x : solver ) = let q = Z3native.solver_get_proof x#gnc x#gno in @@ -3372,12 +4519,11 @@ struct The unsat core is a subset of Assertions The result is empty if Check was not invoked before, if its results was not UNSATISFIABLE, or if core production is disabled. - *) let get_unsat_core ( x : solver ) = let cn = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_unsat_core x#gnc x#gno) in - let n = (ASTVector.get_size cn) in - let f i = (ASTVector.get cn i) in + let n = (AST.ASTVector.get_size cn) in + let f i = (AST.ASTVector.get cn i) in Array.init n f (** @@ -3418,3312 +4564,936 @@ struct end -(** The main interaction with Z3 happens via the Context module *) -module Context = -struct +(* STUFF FROM THE CONTEXT *) - (* SYMBOLS *) - - (** - Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) - let mk_symbol_int ( ctx : context ) i = - (new int_symbol ctx)#cnstr_int i - - (** Creates a new symbol using a string. *) - let mk_symbol_string ( ctx : context ) s = - (new string_symbol ctx)#cnstr_string s - - (** - Create an array of symbols. - *) - let mk_symbols_int ( ctx : context ) names = - let f elem = mk_symbol_int ( ctx : context ) elem in - (Array.map f names) - - (** - Create an array of symbols. - *) - let mk_symbols_string ( ctx : context ) names = - let f elem = mk_symbol_string ( ctx : context ) elem in - (Array.map f names) - - - (* SORTS *) - - (** - Create a new Boolean sort. - *) - let mk_bool_sort ( ctx : context ) = - (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted_sort ( ctx : context ) (s : symbol) = - (new uninterpreted_sort ctx)#cnstr_s s - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted_sort_s ( ctx : context ) (s : string) = - mk_uninterpreted_sort ctx ((mk_symbol_string ( ctx : context ) s) :> symbol) - - (** - Create a new integer sort. - *) - let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) - - (** - Create a real sort. - *) - let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) - - (** - Create a new bit-vector sort. - *) - let mk_bitvec_sort ( ctx : context ) size = - (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) - - (** - Create a new array sort. - *) - let mk_array_sort ( ctx : context ) domain range = - (new array_sort ctx)#cnstr_dr domain range - - (** - Create a new tuple sort. - *) - let mk_tuple_sort ( ctx : context ) name field_names field_sorts = - (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts - - (** - Create a new enumeration sort. - *) - let mk_enum_sort ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss name enum_names - - (** - Create a new enumeration sort. - *) - let mk_enum_sort_s ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss - ((mk_symbol_string ( ctx : context ) name) :> symbol) - (let f e = (e :> symbol) in - (Array.map f (mk_symbols_string ( ctx : context ) enum_names)) - ) - - (** - Create a new list sort. - *) - let mk_list_sort ( ctx : context ) (name : symbol) elem_sort = - (new list_sort ctx)#cnstr_ss name elem_sort - - (** - Create a new list sort. - *) - let mk_list_sort_s ( ctx : context ) (name : string) elem_sort = - mk_list_sort ctx ((mk_symbol_string ctx name) :> symbol) elem_sort - - - (** - Create a new finite domain sort. - *) - let mk_finite_domain_sort ( ctx : context ) ( name : symbol ) size = - (new finite_domain_sort ctx)#cnstr_si name size - - (** - Create a new finite domain sort. - *) - let mk_finite_domain_sort_s ( ctx : context ) ( name : string ) size = - (new finite_domain_sort ctx)#cnstr_si ((mk_symbol_string ctx name) :> symbol) size - - (* DATATYPES *) - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs - - - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - mk_constructor ctx ((mk_symbol_string ctx name) :> symbol) recognizer field_names sorts sort_refs - - - (** - Create a new datatype sort. - *) - let mk_datatype_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = - (new datatype_sort ctx)#cnstr_sc name constructors - - (** - Create a new datatype sort. - *) - let mk_datatype_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = - mk_datatype_sort ctx ((mk_symbol_string ctx name) :> symbol) constructors - - (** - Create mutually recursive datatypes. - @param names names of datatype sorts - @param c list of constructors, one list per sort. - *) - let mk_datatype_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = - let n = (Array.length names) in - let f e = ( (new constructor_list ctx)#cnstr_ca e ) in - let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in - let g e = ( (new datatype_sort ctx)#cnstr_obj e) in - (Array.map g r) - - (** Create mutually recursive data-types. *) - let mk_datatype_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = - mk_datatype_sorts ctx - ( - let f e = ((mk_symbol_string ctx e) :> symbol) in - Array.map f names - ) - c - -(** - - -(* FUNCTION DECLARATIONS *) -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(Symbol name, Sort[] domain, Sort range) - { - - - - - - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); - return new Func_Decl(this, name, domain, range); - } - -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(Symbol name, Sort domain, Sort range) - { - - - - - - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); - Sort[] q = new Sort[] { domain }; - return new Func_Decl(this, name, q, range); - } - -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(string name, Sort[] domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new Func_Decl(this, MkSymbol(name), domain, range); - } - -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(string name, Sort domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - Sort[] q = new Sort[] { domain }; - return new Func_Decl(this, MkSymbol(name), q, range); - } - -(** - Creates a fresh function declaration with a name prefixed with . -*) - - - let mk_Fresh_Func_Decl(string prefix, Sort[] domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new Func_Decl(this, prefix, domain, range); - } - -(** - Creates a new constant function declaration. -*) - let mk_Const_Decl(Symbol name, Sort range) - { - - - - - CheckContextMatch(name); - CheckContextMatch(range); - return new Func_Decl(this, name, null, range); - } - -(** - Creates a new constant function declaration. -*) - let mk_Const_Decl(string name, Sort range) - { - - - - CheckContextMatch(range); - return new Func_Decl(this, MkSymbol(name), null, range); - } - -(** - Creates a fresh constant function declaration with a name prefixed with . -*) - - - let mk_Fresh_ConstDecl(string prefix, Sort range) - { - - - - CheckContextMatch(range); - return new Func_Decl(this, prefix, null, range); - } - - -(* BOUND VARIABLES *) -(** - Creates a new bound variable. -*) - @param index The de-Bruijn index of the variable - @param ty The sort of the variable - public Expr MkBound(uint index, Sort ty) - { - - - - return Expr.Create(this, Z3native.mk_bound(nCtx, index, ty.x#gno)); - } - - -(* QUANTIFIER PATTERNS *) -(** - Create a quantifier pattern. -*) - public Pattern MkPattern(params Expr[] terms) - { - - if (terms.Length == 0) - throw new Z3Exception("Cannot create a pattern from zero terms"); - - - - - - IntPtr[] termsNative = AST.ArrayToNative(terms); - return new Pattern(this, Z3native.mk_pattern(nCtx, (uint)terms.Length, termsNative)); - } - - -(* CONSTANTS *) -(** - Creates a new Constant of sort and named . -*) - public Expr MkConst(Symbol name, Sort range) - { - - - - - CheckContextMatch(name); - CheckContextMatch(range); - - return Expr.Create(this, Z3native.mk_const(nCtx, name.x#gno, range.x#gno)); - } - -(** - Creates a new Constant of sort and named . -*) - public Expr MkConst(string name, Sort range) - { - - - - return MkConst(MkSymbol(name), range); - } - -(** - Creates a fresh Constant of sort and a - name prefixed with . -*) - let mk_Fresh_Const(string prefix, Sort range) - { - - - - CheckContextMatch(range); - return Expr.Create(this, Z3native.mk_fresh_const(nCtx, prefix, range.x#gno)); - } - -(** - Creates a fresh constant from the Func_Decl . -*) - @param f A decl of a 0-arity function - public Expr MkConst(Func_Decl f) - { - - - - return MkApp(f); - } - -(** - Create a Boolean constant. -*) - let mk_Bool_Const(Symbol name) - { - - - - return (BoolExpr)MkConst(name, BoolSort); - } - -(** - Create a Boolean constant. -*) - let mk_Bool_Const(string name) - { - - - return (BoolExpr)MkConst(MkSymbol(name), BoolSort); - } - -(** - Creates an integer constant. -*) - let mk_Int_Const(Symbol name) - { - - - - return (IntExpr)MkConst(name, IntSort); - } - -(** - Creates an integer constant. -*) - let mk_Int_Const(string name) - { - - - - return (IntExpr)MkConst(name, IntSort); - } - -(** - Creates a real constant. -*) - let mk_Real_Const(Symbol name) - { - - - - return (RealExpr)MkConst(name, RealSort); - } - -(** - Creates a real constant. -*) - let mk_Real_Const(string name) - { - - - return (RealExpr)MkConst(name, RealSort); - } - -(** - Creates a bit-vector constant. -*) - let mk_B_VConst(Symbol name, uint size) - { - - - - return (BitVecExpr)MkConst(name, MkBitVecSort(size)); - } - -(** - Creates a bit-vector constant. -*) - let mk_B_VConst(string name, uint size) - { - - - return (BitVecExpr)MkConst(name, MkBitVecSort(size)); - } - - -(* TERMS *) -(** - Create a new function application. -*) - public Expr MkApp(Func_Decl f, params Expr[] args) - { - - - - - CheckContextMatch(f); - CheckContextMatch(args); - return Expr.Create(this, f, args); - } - -(* PROPOSITIONAL *) -(** - The true Term. -*) - public BoolExpr MkTrue ( ctx : context ) = - { - - - return new BoolExpr(this, Z3native.mk_true(nCtx)); - } - -(** - The false Term. -*) - public BoolExpr MkFalse ( ctx : context ) = - { - - - return new BoolExpr(this, Z3native.mk_false(nCtx)); - } - -(** - Creates a Boolean value. -*) - public BoolExpr MkBool(bool value) - { - - - return value ? MkTrue ( ctx : context ) = : MkFalse ( ctx : context ) =; - } - -(** - Creates the equality = . -*) - public BoolExpr MkEq(Expr x, Expr y) - { - - - - - CheckContextMatch(x); - CheckContextMatch(y); - return new BoolExpr(this, Z3native.mk_eq(nCtx, x.x#gno, y.x#gno)); - } - -(** - Creates a distinct term. -*) - public BoolExpr MkDistinct(params Expr[] args) - { - - - - - - CheckContextMatch(args); - return new BoolExpr(this, Z3native.mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args))); - } - -(** - Mk an expression representing not(a). -*) - public BoolExpr MkNot(BoolExpr a) - { - - - - CheckContextMatch(a); - return new BoolExpr(this, Z3native.mk_not(nCtx, a.x#gno)); - } - -(** - Create an expression representing an if-then-else: ite(t1, t2, t3). -*) - @param t1 An expression with Boolean sort - @param t2 An expression - @param t3 An expression with the same sort as - let mk_I_TE(BoolExpr t1, Expr t2, Expr t3) - { - - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(t3); - return Expr.Create(this, Z3native.mk_ite(nCtx, t1.x#gno, t2.x#gno, t3.x#gno)); - } - -(** - Create an expression representing t1 iff t2. -*) - public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_iff(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 -> t2. -*) - public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_implies(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 xor t2. -*) - public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_xor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t[0] and t[1] and .... -*) - public BoolExpr MkAnd(params BoolExpr[] t) - { - - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing t[0] or t[1] or .... -*) - public BoolExpr MkOr(params BoolExpr[] t) - { - - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - - -(* ARITHMETIC *) -(** - Create an expression representing t[0] + t[1] + .... -*) - public ArithExpr MkAdd(params ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing t[0] * t[1] * .... -*) - public ArithExpr MkMul(params ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing t[0] - t[1] - .... -*) - public ArithExpr MkSub(params ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing -t. -*) - let mk_Unary_Minus(ArithExpr t) - { - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_unary_minus(nCtx, t.x#gno)); - } - -(** - Create an expression representing t1 / t2. -*) - public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr)Expr.Create(this, Z3native.mk_div(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 mod t2. -*) - The arguments must have int type. - public IntExpr MkMod(IntExpr t1, IntExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Z3native.mk_mod(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 rem t2. -*) - The arguments must have int type. - public IntExpr MkRem(IntExpr t1, IntExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Z3native.mk_rem(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 ^ t2. -*) - public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr)Expr.Create(this, Z3native.mk_power(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 < t2 -*) - public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_lt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 <= t2 -*) - public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_le(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 > t2 -*) - public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_gt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 >= t2 -*) - public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_ge(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Coerce an integer to a real. -*) - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. - - public RealExpr MkInt2Real(IntExpr t) - { - - - - CheckContextMatch(t); - return new RealExpr(this, Z3native.mk_int2real(nCtx, t.x#gno)); - } - -(** - Coerce a real to an integer. -*) - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. - - public IntExpr MkReal2Int(RealExpr t) - { - - - - CheckContextMatch(t); - return new IntExpr(this, Z3native.mk_real2int(nCtx, t.x#gno)); - } - -(** - Creates an expression that checks whether a real number is an integer. -*) - let mk_Is_Integer(RealExpr t) - { - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_is_int(nCtx, t.x#gno)); - } - - -(* BIT-VECTORS *) -(** - Bitwise negation. -*) - The argument must have a bit-vector sort. - let mk_B_VNot(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvnot(nCtx, t.x#gno)); - } - -(** - Take conjunction of bits in a vector, return vector of length 1. -*) - The argument must have a bit-vector sort. - let mk_B_VRedAND(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvredand(nCtx, t.x#gno)); - } - -(** - Take disjunction of bits in a vector, return vector of length 1. -*) - The argument must have a bit-vector sort. - let mk_B_VRedOR(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvredor(nCtx, t.x#gno)); - } - -(** - Bitwise conjunction. -*) - The arguments must have a bit-vector sort. - let mk_B_VAND(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvand(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise disjunction. -*) - The arguments must have a bit-vector sort. - let mk_B_VOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise XOR. -*) - The arguments must have a bit-vector sort. - let mk_B_VXOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvxor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise NAND. -*) - The arguments must have a bit-vector sort. - let mk_B_VNAND(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvnand(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise NOR. -*) - The arguments must have a bit-vector sort. - let mk_B_VNOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvnor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise XNOR. -*) - The arguments must have a bit-vector sort. - let mk_B_VXNOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvxnor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Standard two's complement unary minus. -*) - The arguments must have a bit-vector sort. - let mk_B_VNeg(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvneg(nCtx, t.x#gno)); - } - -(** - Two's complement addition. -*) - The arguments must have the same bit-vector sort. - let mk_B_VAdd(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvadd(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement subtraction. -*) - The arguments must have the same bit-vector sort. - let mk_B_VSub(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsub(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement multiplication. -*) - The arguments must have the same bit-vector sort. - let mk_B_VMul(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvmul(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned division. -*) - - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VUDiv(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvudiv(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Signed division. -*) - - It is defined in the following way: - - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VSDiv(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsdiv(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned remainder. -*) - - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VURem(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvurem(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Signed remainder. -*) - - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VSRem(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsrem(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed remainder (sign follows divisor). -*) - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VSMod(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsmod(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned less-than -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VULT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvult(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed less-than -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSLT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvslt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned less-than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VULE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvule(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed less-than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSLE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsle(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned greater than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VUGE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvuge(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed greater than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSGE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsge(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned greater-than. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VUGT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvugt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed greater-than. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSGT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsgt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bit-vector concatenation. -*) - - The arguments must have a bit-vector sort. - - @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). - - public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_concat(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bit-vector extraction. -*) - - Extract the bits down to from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. - The argument must have a bit-vector sort. - - public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_extract(nCtx, high, low, t.x#gno)); - } - -(** - Bit-vector sign extension. -*) - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. - The argument must have a bit-vector sort. - - let mk_Sign_Ext(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_sign_ext(nCtx, i, t.x#gno)); - } - -(** - Bit-vector zero extension. -*) - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the - given bit-vector. - The argument must have a bit-vector sort. - - let mk_Zero_Ext(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_zero_ext(nCtx, i, t.x#gno)); - } - -(** - Bit-vector repetition. -*) - - The argument must have a bit-vector sort. - - public BitVecExpr MkRepeat(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_repeat(nCtx, i, t.x#gno)); - } - -(** - Shift left. -*) - - It is equivalent to multiplication by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - - let mk_B_VSHL(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvshl(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Logical shift right -*) - - It is equivalent to unsigned division by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - - let mk_B_VLSHR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvlshr(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Arithmetic shift right -*) - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - - let mk_B_VASHR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvashr(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Rotate Left. -*) - - Rotate bits of \c t to the left \c i times. - The argument must have a bit-vector sort. - - let mk_B_VRotateLeft(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_rotate_left(nCtx, i, t.x#gno)); - } - -(** - Rotate Right. -*) - - Rotate bits of \c t to the right \c i times. - The argument must have a bit-vector sort. - - let mk_B_VRotateRight(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_rotate_right(nCtx, i, t.x#gno)); - } - -(** - Rotate Left. -*) - - Rotate bits of to the left times. - The arguments must have the same bit-vector sort. - - let mk_B_VRotateLeft(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_ext_rotate_left(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Rotate Right. -*) - - Rotate bits of to the right times. - The arguments must have the same bit-vector sort. - - let mk_B_VRotateRight(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_ext_rotate_right(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an bit bit-vector from the integer argument . -*) - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. - - public BitVecExpr MkInt2BV(uint n, IntExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_int2bv(nCtx, n, t.x#gno)); - } - -(** - Create an integer from the bit-vector argument . -*) - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where - N are the number of bits in . - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of bit-vector sort. - - let mk_B_V2Int(BitVecExpr t, bool signed) - { - - - - CheckContextMatch(t); - return new IntExpr(this, Z3native.mk_bv2int(nCtx, t.x#gno, (signed) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise addition does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VAddNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvadd_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise addition does not underflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvadd_no_underflow(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise subtraction does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VSubNoOverflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsub_no_overflow(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise subtraction does not underflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsub_no_underflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise signed division does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsdiv_no_overflow(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise negation does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VNegNoOverflow(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_bvneg_no_overflow(nCtx, t.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise multiplication does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VMulNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvmul_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise multiplication does not underflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvmul_no_underflow(nCtx, t1.x#gno, t2.x#gno)); - } - - -(* ARRAYS *) -(** - Create an array constant. -*) - let mk_Array_Const(Symbol name, Sort domain, Sort range) - { - - - - - - return (ArrayExpr)MkConst(name, MkArraySort(domain, range)); - } - -(** - Create an array constant. -*) - let mk_Array_Const(string name, Sort domain, Sort range) - { - - - - - return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); - } - -(** - Array read. -*) - - The argument a is the array and i is the index - of the array that gets read. - - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. - - - - public Expr MkSelect(ArrayExpr a, Expr i) - { - - - - - CheckContextMatch(a); - CheckContextMatch(i); - return Expr.Create(this, Z3native.mk_select(nCtx, a.x#gno, i.x#gno)); - } - -(** - Array update. -*) - - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). - - - - public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) - { - - - - - - CheckContextMatch(a); - CheckContextMatch(i); - CheckContextMatch(v); - return new ArrayExpr(this, Z3native.mk_store(nCtx, a.x#gno, i.x#gno, v.x#gno)); - } - -(** - Create a constant array. -*) - - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. - - - - let mk_Const_Array(Sort domain, Expr v) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(v); - return new ArrayExpr(this, Z3native.mk_const_array(nCtx, domain.x#gno, v.x#gno)); - } - -(** - Maps f on the argument arrays. -*) - - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. - - - - - public ArrayExpr MkMap(Func_Decl f, params ArrayExpr[] args) - { - - - - - CheckContextMatch(f); - CheckContextMatch(args); - return (ArrayExpr)Expr.Create(this, Z3native.mk_map(nCtx, f.x#gno, AST.ArrayLength(args), AST.ArrayToNative(args))); - } - -(** - Access the array default value. -*) - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. - - let mk_Term_Array(ArrayExpr array) - { - - - - CheckContextMatch(array); - return Expr.Create(this, Z3native.mk_array_default(nCtx, array.x#gno)); - } - - -(* SETS *) -(** - Create a set type. -*) - let mk_Set_Sort(Sort ty) - { - - - - CheckContextMatch(ty); - return new SetSort(this, ty); - } - -(** - Create an empty set. -*) - let mk_Empty_Set(Sort domain) - { - - - - CheckContextMatch(domain); - return Expr.Create(this, Z3native.mk_empty_set(nCtx, domain.x#gno)); - } - -(** - Create the full set. -*) - let mk_Full_Set(Sort domain) - { - - - - CheckContextMatch(domain); - return Expr.Create(this, Z3native.mk_full_set(nCtx, domain.x#gno)); - } - -(** - Add an element to the set. -*) - let mk_Set_Add(Expr set, Expr element) - { - - - - - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create(this, Z3native.mk_set_add(nCtx, set.x#gno, element.x#gno)); - } - - -(** - Remove an element from a set. -*) - let mk_Set_Del(Expr set, Expr element) - { - - - - - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create(this, Z3native.mk_set_del(nCtx, set.x#gno, element.x#gno)); - } - -(** - Take the union of a list of sets. -*) - let mk_Set_Union(params Expr[] args) - { - - - - CheckContextMatch(args); - return Expr.Create(this, Z3native.mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args))); - } - -(** - Take the intersection of a list of sets. -*) - let mk_Set_Intersection(params Expr[] args) - { - - - - - CheckContextMatch(args); - return Expr.Create(this, Z3native.mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args))); - } - -(** - Take the difference between two sets. -*) - let mk_Set_Difference(Expr arg1, Expr arg2) - { - - - - - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create(this, Z3native.mk_set_difference(nCtx, arg1.x#gno, arg2.x#gno)); - } - -(** - Take the complement of a set. -*) - let mk_Set_Complement(Expr arg) - { - - - - CheckContextMatch(arg); - return Expr.Create(this, Z3native.mk_set_complement(nCtx, arg.x#gno)); - } - -(** - Check for set membership. -*) - let mk_Set_Membership(Expr elem, Expr set) - { - - - - - CheckContextMatch(elem); - CheckContextMatch(set); - return Expr.Create(this, Z3native.mk_set_member(nCtx, elem.x#gno, set.x#gno)); - } - -(** - Check for subsetness of sets. -*) - let mk_Set_Subset(Expr arg1, Expr arg2) - { - - - - - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create(this, Z3native.mk_set_subset(nCtx, arg1.x#gno, arg2.x#gno)); - } - +(** (* NUMERALS *) (* GENERAL NUMERALS *) (** - Create a Term of a given sort. + Create a Term of a given sort. *) - @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - @return A Term with value and sort - public Expr MkNumeral(string v, Sort ty) - { + @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + @return A Term with value and sort + public Expr MkNumeral(string v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_numeral(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_numeral ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(int v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(int v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_int(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_int ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(uint v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(uint v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_unsigned_int(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_unsigned_int ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(long v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(long v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_int64(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_int64 ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(ulong v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(ulong v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_unsigned_int64(nCtx, v, ty.x#gno)); - } - + create_expr ctx (Z3native.mk_unsigned_int64 ctx#gno v, ty#gno) (* REALS *) (** - Create a real from a fraction. + Create a real from a fraction. *) - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - public RatNum MkReal(int num, int den) - { - if (den == 0) - throw new Z3Exception("Denominator is zero"); + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + public RatNum MkReal(int num, int den) + if (den == 0) + throw new Z3Exception("Denominator is zero"); - - - return new RatNum(this, Z3native.mk_real(nCtx, num, den)); - } + new RatNum(this, Z3native.mk_real ctx#gno num, den) (** - Create a real numeral. + Create a real numeral. *) - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - public RatNum MkReal(string v) - { + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + public RatNum MkReal(string v) - - return new RatNum(this, Z3native.mk_numeral(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_numeral ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(int v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(int v) - - return new RatNum(this, Z3native.mk_int(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_int ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(uint v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(uint v) - - return new RatNum(this, Z3native.mk_unsigned_int(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_unsigned_int ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(long v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(long v) - - return new RatNum(this, Z3native.mk_int64(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_int64 ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(ulong v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(ulong v) - - return new RatNum(this, Z3native.mk_unsigned_int64(nCtx, v, RealSort.x#gno)); - } - + new RatNum(this, Z3native.mk_unsigned_int64 ctx#gno v, RealSort#gno) (* INTEGERS *) (** - Create an integer numeral. + Create an integer numeral. *) - @param v A string representing the Term value in decimal notation. - public IntNum MkInt(string v) - { + @param v A string representing the Term value in decimal notation. + public IntNum MkInt(string v) - - return new IntNum(this, Z3native.mk_numeral(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_numeral ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(int v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(int v) - - return new IntNum(this, Z3native.mk_int(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_int ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(uint v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(uint v) - - return new IntNum(this, Z3native.mk_unsigned_int(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_unsigned_int ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(long v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(long v) - - return new IntNum(this, Z3native.mk_int64(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_int64 ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(ulong v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(ulong v) - - return new IntNum(this, Z3native.mk_unsigned_int64(nCtx, v, IntSort.x#gno)); - } - + new IntNum(this, Z3native.mk_unsigned_int64 ctx#gno v, IntSort#gno) (* BIT-VECTORS *) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v A string representing the value in decimal notation. - @param size the size of the bit-vector - let mk_B_V(string v, uint size) - { + @param v A string representing the value in decimal notation. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) string v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(int v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) int v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(uint v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) uint v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(long v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) long v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(ulong v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) ulong v, uint size) + (BitVecNum)MkNumeral(v, MkBitVecSort(size) - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - - // Numerals + // Numerals (* QUANTIFIERS *) (** - Create a universal Quantifier. + Create a universal Quantifier. + + Creates a forall formula, where is the weight, + is an array of patterns, is an array + with the sorts of the bound variables, is an array with the + 'names' of the bound variables, and is the body of the + quantifier. Quantifiers are associated with weights indicating + the importance of using the quantifier during instantiation. *) - - Creates a forall formula, where is the weight, - is an array of patterns, is an array - with the sorts of the bound variables, is an array with the - 'names' of the bound variables, and is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during instantiation. - - @param sorts the sorts of the bound variables. - @param names names of the bound variables - @param body the body of the quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param patterns array containing the patterns created using MkPattern. - @param noPatterns array containing the anti-patterns created using MkPattern. - @param quantifierID optional symbol to track quantifier. - @param skolemID optional symbol to track skolem constants. - public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { - - - - - - - - - - - - return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + @param sorts the sorts of the bound variables. + @param names names of the bound variables + @param body the body of the quantifier. + @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + @param patterns array containing the patterns created using MkPattern. + @param noPatterns array containing the anti-patterns created using MkPattern. + @param quantifierID optional symbol to track quantifier. + @param skolemID optional symbol to track skolem constants. + public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create a universal Quantifier. + Create a universal Quantifier. *) - public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { + public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - - - - - - return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create an existential Quantifier. + Create an existential Quantifier. *) - - public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { + + public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - - - - - - - - - return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create an existential Quantifier. + Create an existential Quantifier. *) - public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { - - - - - - - return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create a Quantifier. + Create a Quantifier. *) - public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { - - - - - - - - - - - - if (universal) - return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + if (universal) + MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create a Quantifier. + Create a Quantifier. *) - public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { + public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + if (universal) + MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - - - - - - if (universal) - return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - - - // Expr + // Expr (* OPTIONS *) (** - Selects the format used for pretty-printing expressions. + Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the Z3_PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. *) - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the Z3_PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. - - - - - - public Z3_ast_print_mode PrintMode - { - set { Z3native.set_ast_print_mode(nCtx, (uint)value); } - } - + + + + + public Z3_ast_print_mode PrintMode + + set { Z3native.set_ast_print_mode ctx#gno (uint)value); } (* SMT Files & Strings *) (** - Convert a benchmark into an SMT-LIB formatted string. + Convert a benchmark into an SMT-LIB formatted string. *) - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - public string BenchmarkToSMTString(string name, string logic, string status, string attributes, - BoolExpr[] assumptions, BoolExpr formula) - { + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) - - - - return Z3native.benchmark_to_smtlib_string(nCtx, name, logic, status, attributes, - (uint)assumptions.Length, AST.ArrayToNative(assumptions), - formula.x#gno); - } + Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula#gno); (** - Parse the given string using the SMT-LIB parser. + Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. - - public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_string(nCtx, str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); - } + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - Parse the given file using the SMT-LIB parser. + Parse the given file using the SMT-LIB parser. *) - - public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_file(nCtx, fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); - } + + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBFormulas { get { return Z3native.get_smtlib_num_formulas(nCtx)) + public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) (** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public BoolExpr[] SMTLIBFormulas - { - get - { + let[] SMTLIBFormulas + get + + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) + res; - uint n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_formula(nCtx, i)); - return res; - } - } (** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBAssumptions { get { return Z3native.get_smtlib_num_assumptions(nCtx)) + public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) (** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public BoolExpr[] SMTLIBAssumptions - { - get - { + let[] SMTLIBAssumptions + get + + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) + res; - uint n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_assumption(nCtx, i)); - return res; - } - } (** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBDecls { get { return Z3native.get_smtlib_num_decls(nCtx)) + public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Func_Decl[] SMTLIBDecls - { - get - { + public Func_Decl[] SMTLIBDecls + get + + uint n = NumSMTLIBDecls; + Func_Decl[] res = new Func_Decl[n]; + for (uint i = 0; i < n; i++) + res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) + res; - uint n = NumSMTLIBDecls; - Func_Decl[] res = new Func_Decl[n]; - for (uint i = 0; i < n; i++) - res[i] = new Func_Decl(this, Z3native.get_smtlib_decl(nCtx, i)); - return res; - } - } (** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBSorts { get { return Z3native.get_smtlib_num_sorts(nCtx)) + public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Sort[] SMTLIBSorts - { - get - { + public Sort[] SMTLIBSorts + get + + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) + res; - uint n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (uint i = 0; i < n; i++) - res[i] = Sort.Create(this, Z3native.get_smtlib_sort(nCtx, i)); - return res; - } - } (** - Parse the given string using the SMT-LIB2 parser. + Parse the given string using the SMT-LIB2 parser. *) - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_string(nCtx, str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); - } + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (** - Parse the given file using the SMT-LIB2 parser. + Parse the given file using the SMT-LIB2 parser. *) - - public BoolExpr ParseSMTLIB2File(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { + + let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_file(nCtx, fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); - } - + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (* GOALS *) (** - Creates a new Goal. + Creates a new Goal. + + Note that the Context must have been created with proof generation support if + is set to true here. *) - - Note that the Context must have been created with proof generation support if - is set to true here. - - @param models Indicates whether model generation should be enabled. - @param unsatCores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - { + @param models Indicates whether model generation should be enabled. + @param unsatCores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - - return new Goal(this, models, unsatCores, proofs); - } - + new Goal(this, models, unsatCores, proofs); (* PARAMETERSETS *) (** - Creates a new ParameterSet. + Creates a new ParameterSet. *) - public Params MkParams ( ctx : context ) = - { + public Params MkParams ( ctx : context ) = - - return new Params(this); - } - + new Params(this); (* TACTICS *) (** - The number of supported tactics. + The number of supported tactics. *) - public uint NumTactics - { - get { return Z3native.get_num_tactics(nCtx); } - } + public uint NumTactics + + get {Z3native.get_num_tactics ctx#gno); } (** - The names of all supported tactics. + The names of all supported tactics. *) - public string[] TacticNames - { - get - { + public string[] TacticNames + get + + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_tactic_name ctx#gno i); + res; - uint n = NumTactics; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_tactic_name(nCtx, i); - return res; - } - } (** - Returns a string containing a description of the tactic with the given name. + Returns a string containing a description of the tactic with the given name. *) - public string TacticDescription(string name) - { + public string TacticDescription(string name) - - return Z3native.tactic_get_descr(nCtx, name); - } + Z3native.tactic_get_descr ctx#gno name); (** - Creates a new Tactic. + Creates a new Tactic. *) - public Tactic MkTactic(string name) - { + public Tactic MkTactic(string name) - - return new Tactic(this, name); - } + new Tactic(this, name); (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . + Create a tactic that applies to a Goal and + then to every subgoal produced by . *) - public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) - { + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) + last = ts[ts.Length - 1]#gno; + for (int i = ts.Length - 2; i >= 0; i--) + last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); + if (last != IntPtr.Zero) + last = Z3native.tactic_and_then ctx#gno t2#gno last); + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(ts); - - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) - { - last = ts[ts.Length - 1].x#gno; - for (int i = ts.Length - 2; i >= 0; i--) - last = Z3native.tactic_and_then(nCtx, ts[i].x#gno, last); - } - if (last != IntPtr.Zero) - { - last = Z3native.tactic_and_then(nCtx, t2.x#gno, last); - return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, last)); - } - else - return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, t2.x#gno)); - } + else + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . + Create a tactic that applies to a Goal and + then to every subgoal produced by . + + Shorthand for AndThen. *) - - Shorthand for AndThen. - - public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - { + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - - - - - return AndThen(t1, t2, ts); - } + AndThen(t1, t2, ts); (** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. *) - public Tactic OrElse(Tactic t1, Tactic t2) - { + public Tactic OrElse(Tactic t1, Tactic t2) - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Z3native.tactic_or_else(nCtx, t1.x#gno, t2.x#gno)); - } + new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a goal for milliseconds. + Create a tactic that applies to a goal for milliseconds. + + If does not terminate within milliseconds, then it fails. *) - - If does not terminate within milliseconds, then it fails. - - public Tactic TryFor(Tactic t, uint ms) - { + public Tactic TryFor(Tactic t, uint ms) - - - CheckContextMatch(t); - return new Tactic(this, Z3native.tactic_try_for(nCtx, t.x#gno, ms)); - } + new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) (** - Create a tactic that applies to a given goal if the probe - evaluates to true. + Create a tactic that applies to a given goal if the probe + evaluates to true. + + If evaluates to false, then the new tactic behaves like the skip tactic. *) - - If evaluates to false, then the new tactic behaves like the skip tactic. - - public Tactic When(Probe p, Tactic t) - { + public Tactic When(Probe p, Tactic t) - - - - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Z3native.tactic_when(nCtx, p.x#gno, t.x#gno)); - } + new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) (** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. *) - public Tactic Cond(Probe p, Tactic t1, Tactic t2) - { + public Tactic Cond(Probe p, Tactic t1, Tactic t2) - - - - - CheckContextMatch(p); - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Z3native.tactic_cond(nCtx, p.x#gno, t1.x#gno, t2.x#gno)); - } + new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) (** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. *) - public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - { + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - - - CheckContextMatch(t); - return new Tactic(this, Z3native.tactic_repeat(nCtx, t.x#gno, max)); - } + new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) (** - Create a tactic that just returns the given goal. + Create a tactic that just returns the given goal. *) - public Tactic Skip ( ctx : context ) = - { + public Tactic Skip ( ctx : context ) = - - return new Tactic(this, Z3native.tactic_skip(nCtx)); - } + new Tactic(this, Z3native.tactic_skip ctx#gno) (** - Create a tactic always fails. + Create a tactic always fails. *) - public Tactic Fail ( ctx : context ) = - { + public Tactic Fail ( ctx : context ) = - - return new Tactic(this, Z3native.tactic_fail(nCtx)); - } + new Tactic(this, Z3native.tactic_fail ctx#gno) (** - Create a tactic that fails if the probe evaluates to false. + Create a tactic that fails if the probe evaluates to false. *) - public Tactic FailIf(Probe p) - { + public Tactic FailIf(Probe p) - - - CheckContextMatch(p); - return new Tactic(this, Z3native.tactic_fail_if(nCtx, p.x#gno)); - } + new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) (** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) - public Tactic FailIfNotDecided ( ctx : context ) = - { + public Tactic FailIfNotDecided ( ctx : context ) = - - return new Tactic(this, Z3native.tactic_fail_if_not_decided(nCtx)); - } + new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) (** - Create a tactic that applies using the given set of parameters . + Create a tactic that applies using the given set of parameters . *) - public Tactic UsingParams(Tactic t, Params p) - { + public Tactic UsingParams(Tactic t, Params p) - - - - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Z3native.tactic_using_params(nCtx, t.x#gno, p.x#gno)); - } + new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) (** - Create a tactic that applies using the given set of parameters . -*) - Alias for UsingParams - public Tactic With(Tactic t, Params p) - { + Create a tactic that applies using the given set of parameters . + Alias for UsingParams*) + public Tactic With(Tactic t, Params p) - - - - return UsingParams(t, p); - } + UsingParams(t, p); (** - Create a tactic that applies the given tactics in parallel. + Create a tactic that applies the given tactics in parallel. *) - public Tactic ParOr(params Tactic[] t) - { + public Tactic ParOr(params Tactic[] t) - - - CheckContextMatch(t); - return new Tactic(this, Z3native.tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); - } + new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) (** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. *) - public Tactic ParAndThen(Tactic t1, Tactic t2) - { + public Tactic ParAndThen(Tactic t1, Tactic t2) - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Z3native.tactic_par_and_then(nCtx, t1.x#gno, t2.x#gno)); - } + new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) (** - Interrupt the execution of a Z3 procedure. + Interrupt the execution of a Z3 procedure. *) - This procedure can be used to interrupt: solvers, simplifiers and tactics. - public void Interrupt ( ctx : context ) = - { - Z3native.interrupt(nCtx); - } - + This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt ( ctx : context ) = + + Z3native.interrupt ctx#gno); (* PROBES *) (** - The number of supported Probes. + The number of supported Probes. *) - public uint NumProbes - { - get { return Z3native.get_num_probes(nCtx); } - } + public uint NumProbes + + get {Z3native.get_num_probes ctx#gno); } (** - The names of all supported Probes. + The names of all supported Probes. *) - public string[] ProbeNames - { - get - { + public string[] ProbeNames + get + + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_probe_name ctx#gno i); + res; - uint n = NumProbes; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_probe_name(nCtx, i); - return res; - } - } (** - Returns a string containing a description of the probe with the given name. + Returns a string containing a description of the probe with the given name. *) - public string ProbeDescription(string name) - { + public string ProbeDescription(string name) - - return Z3native.probe_get_descr(nCtx, name); - } + Z3native.probe_get_descr ctx#gno name); (** - Creates a new Probe. + Creates a new Probe. *) - public Probe MkProbe(string name) - { + public Probe MkProbe(string name) - - return new Probe(this, name); - } + new Probe(this, name); (** - Create a probe that always evaluates to . + Create a probe that always evaluates to . *) - public Probe Const(double val) - { + public Probe Const(double val) - - return new Probe(this, Z3native.probe_const(nCtx, val)); - } + new Probe(this, Z3native.probe_const ctx#gno val) (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by *) - public Probe Lt(Probe p1, Probe p2) - { + public Probe Lt(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_lt(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by *) - public Probe Gt(Probe p1, Probe p2) - { + public Probe Gt(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_gt(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by *) - public Probe Le(Probe p1, Probe p2) - { + public Probe Le(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_le(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by *) - public Probe Ge(Probe p1, Probe p2) - { + public Probe Ge(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_ge(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by *) - public Probe Eq(Probe p1, Probe p2) - { + public Probe Eq(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_eq(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". + Create a probe that evaluates to "true" when the value + and evaluate to "true". *) - public Probe And(Probe p1, Probe p2) - { + public Probe And(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_and(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". + Create a probe that evaluates to "true" when the value + or evaluate to "true". *) - public Probe Or(Probe p1, Probe p2) - { + public Probe Or(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_or(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". + Create a probe that evaluates to "true" when the value + does not evaluate to "true". *) - public Probe Not(Probe p) - { + public Probe Not(Probe p) - - - CheckContextMatch(p); - return new Probe(this, Z3native.probe_not(nCtx, p.x#gno)); - } - + new Probe(this, Z3native.probe_not ctx#gno p#gno) (* SOLVERS *) (** - Creates a new (incremental) solver. -*) - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. - - public Solver MkSolver(Symbol logic = null) - { + Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. +*) + public Solver MkSolver(Symbol logic = null) - - if (logic == null) - return new Solver(this, Z3native.mk_solver(nCtx)); - else - return new Solver(this, Z3native.mk_solver_for_logic(nCtx, logic.x#gno)); - } + if (logic == null) + new Solver(this, Z3native.mk_solver ctx#gno) + else + new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - - public Solver MkSolver(string logic) - { + + public Solver MkSolver(string logic) - - return MkSolver(MkSymbol(logic)); - } + MkSolver(MkSymbol(logic) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - let mk_Simple_Solver ( ctx : context ) = - { + let mk_Simple_Solver ( ctx : context ) ctx : context ) = - - return new Solver(this, Z3native.mk_simple_solver(nCtx)); - } + new Solver(this, Z3native.mk_simple_solver ctx#gno) (** - Creates a solver that is implemented using the given tactic. + Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. - - public Solver MkSolver(Tactic t) - { + public Solver MkSolver(Tactic t) - - - return new Solver(this, Z3native.mk_solver_from_tactic(nCtx, t.x#gno)); - } - + new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) (* FIXEDPOINTS *) (** - Create a Fixedpoint context. + Create a Fixedpoint context. *) - public Fixedpoint MkFixedpoint ( ctx : context ) = - { - - - return new Fixedpoint(this); - } - + public Fixedpoint MkFixedpoint ( ctx : context ) = + new Fixedpoint(this); (* MISCELLANEOUS *) (** - Wraps an AST. + Wraps an AST. *) - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - public AST WrapAST(IntPtr nativeObject) - { + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) - return AST.Create(this, nativeObject); - } + AST.Create(this, nativeObject); (** - Unwraps an AST. + Unwraps an AST. *) - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - public IntPtr UnwrapAST(AST a) - { - return a.x#gno; - } + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + public IntPtr UnwrapAST(AST a) + + a#gno; (** - Return a string describing all available parameters to Expr.Simplify. + a string describing all available parameters to Expr.Simplify. *) - public string SimplifyHelp ( ctx : context ) = - { + public string SimplifyHelp ( ctx : context ) = - - return Z3native.simplify_get_help(nCtx); - } + Z3native.simplify_get_help ctx#gno); (** - Retrieves parameter descriptions for simplifier. + Retrieves parameter descriptions for simplifier. *) - public ParamDescrs SimplifyParameterDescriptions - { - get { return new ParamDescrs(this, Z3native.simplify_get_param_descrs(nCtx)); } - } + public ParamDescrs SimplifyParameterDescriptions + + get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } (** - Enable/disable printing of warning messages to the console. + Enable/disable printing of warning messages to the console. *) - Note that this function is static and effects the behaviour of - all contexts globally. - public static void ToggleWarningMessages(bool enabled) - { - Z3native.toggle_warning_messages((enabled) ? 1 : 0); - } - + Note that this function is static and effects the behaviour of + all contexts globally. + public static void ToggleWarningMessages(bool enabled) + + Z3native.toggle_warning_messages((enabled) ? 1 : 0); (* ERROR HANDLING *) - //(** - //A delegate which is executed when an error is raised. - //*) - // - //Note that it is possible for memory leaks to occur if error handlers - //throw exceptions. - // - //public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); +(** + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. +*) + public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); - //(** - //The OnError event. - //*) - //public event ErrorHandler OnError = null; - +(** + The OnError event. +*) + public event ErrorHandler OnError = null; (* PARAMETERS *) (** - Update a mutable configuration parameter. + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. *) - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - - - public void UpdateParamValue(string id, string value) - { - Z3native.update_param_value(nCtx, id, value); - } + + public void UpdateParamValue(string id, string value) + + Z3native.update_param_value ctx#gno id, value); (** - Get a configuration parameter. + Get a configuration parameter. + + Returns null if the parameter value does not exist. + *) - - Returns null if the parameter value does not exist. - - - public string GetParamValue(string id) - { - IntPtr res = IntPtr.Zero; - int r = Z3native.get_param_value(nCtx, id, out res); - if (r == (int)Z3_lbool.Z3_L_FALSE) - return null; - else - return Marshal.PtrToStringAnsi(res); - } + public string GetParamValue(string id) - + IntPtr res = IntPtr.Zero; + int r = Z3native.get_param_value ctx#gno id, out res); + if (r == (int)Z3_lbool.L_FALSE) + null; + else + Marshal.PtrToStringAnsi(res); (* INTERNAL *) - internal IntPtr m_ctx = IntPtr.Zero; - internal Z3native.error_handler m_n_err_handler = null; - internal IntPtr nCtx { get { return m_ctx) + internal IntPtr m_ctx = IntPtr.Zero; + internal Z3native.error_handler m_n_err_handler = null; + internal IntPtr nCtx { get {m_ctx) - internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) - { - // Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - } + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + + internal void InitContext ( ctx : context ) = + + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); - internal void InitContext ( ctx : context ) = - { - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); // keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); - } *) -end + From 371db347afe3bfa80568c5cd131ff50c98d6ed93 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 23 Dec 2012 04:00:34 +0000 Subject: [PATCH 247/507] More new ML API. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 8 +- scripts/update_api.py | 13 +- src/api/ml/z3.ml | 1644 ++++++++++++++++++------------------- 3 files changed, 807 insertions(+), 858 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index f414e9d1a..dde9f944a 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,7 +4,7 @@ *) open Z3 -open Z3.Context +open Z3.Arithmetic exception ExampleException of string @@ -16,9 +16,9 @@ let _ = Printf.printf "Running Z3 version %s\n" Version.to_string ; let cfg = [("model", "true"); ("proof", "false")] in let ctx = (new context cfg) in - let is = (mk_symbol_int ctx 42) in - let ss = (mk_symbol_string ctx "mySymbol") in - let bs = (mk_bool_sort ctx) in + let is = (Symbol.mk_int ctx 42) in + let ss = (Symbol.mk_string ctx "mySymbol") in + let bs = (Sort.mk_bool ctx) in let ints = (mk_int_sort ctx) in let rs = (mk_real_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); diff --git a/scripts/update_api.py b/scripts/update_api.py index 27f7dd507..acaa9478e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1154,8 +1154,11 @@ def mk_ml(): for k, v in Type2Str.iteritems(): if is_obj(k): ml_native.write('and %s = ptr\n' % v.lower()) - ml_native.write('\nexternal is_null : ptr -> bool\n') + ml_native.write('\n') + ml_native.write('external is_null : ptr -> bool\n') ml_native.write(' = "n_is_null"\n\n') + ml_native.write('external mk_null : unit -> ptr\n') + ml_native.write(' = "n_mk_null"\n\n') ml_native.write('exception Exception of string\n\n') # ML declarations @@ -1295,6 +1298,14 @@ def mk_ml(): ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') ml_wrapper.write(' return Val_bool(Data_custom_val(p) == 0);\n') ml_wrapper.write('}\n\n') + ml_wrapper.write('CAMLprim value n_mk_null( void ) {\n') + ml_wrapper.write(' CAMLparam0();\n') + ml_wrapper.write(' CAMLlocal1(result);\n') + ml_wrapper.write(' void * z3_result = 0;\n') + ml_wrapper.write(' result = caml_alloc_custom(&default_custom_ops, sizeof(void*), 0, 1);\n') + ml_wrapper.write(' memcpy( Data_custom_val(result), &z3_result, sizeof(void*));\n') + ml_wrapper.write(' CAMLreturn (result);\n') + ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 5f67e11e2..f6454b797 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -593,6 +593,10 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +let patternaton (a : pattern array) = + let f (e : pattern) = e#gno in + Array.map f a + (** Parameter description objects *) class param_descrs ctx = object (self) @@ -1607,6 +1611,306 @@ struct *) let mk_or ( ctx : context ) ( args : bool_expr array ) = (new bool_expr ctx)#cnstr_obj (Z3native.mk_or ctx#gno (Array.length args) (astaton args)) + + (** + Create a numeral of a given sort. + @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + @return A Term with value and sort + *) + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = + create_expr ctx (Z3native.mk_numeral ctx#gno v ty#gno) + + (** + Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + *) + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = + create_expr ctx (Z3native.mk_int ctx#gno v ty#gno) +end + +(** Quantifier expressions *) +module Quantifiers = +struct + (** + The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. + *) + let get_index ( x : expr ) = + if not (AST.is_var x) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value x#gnc x#gno + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. + *) + module Pattern = + struct + (** + The number of terms in the pattern. + *) + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms x#gnc x#gno + + (** + The terms in the pattern. + *) + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the pattern. + *) + let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno + end + + (** + Indicates whether the quantifier is universal. + *) + let is_universal ( x : quantifier ) = + lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE + + (** + Indicates whether the quantifier is existential. + *) + let is_existential ( x : quantifier ) = not (is_universal x) + + (** + The weight of the quantifier. + *) + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno + + (** + The number of patterns. + *) + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno + + (** + The patterns. + *) + let get_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of no-patterns. + *) + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno + + (** + The no-patterns. + *) + let get_no_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of bound variables. + *) + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno + + (** + The symbols for the bound variables. + *) + let get_bound_variable_names ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + Array.init n f + + (** + The sorts of the bound variables. + *) + let get_bound_variable_sorts ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in + Array.init n f + + (** + The body of the quantifier. + *) + let get_body ( x : quantifier ) = + (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) + + (** + Creates a new bound variable. + @param index The de-Bruijn index of the variable + @param ty The sort of the variable + *) + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) + + (** + Create a quantifier pattern. + *) + let mk_pattern ( ctx : context ) ( terms : expr array ) = + if (Array.length terms) == 0 then + raise (Z3native.Exception "Cannot create a pattern from zero terms") + else + (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) + + (** + Create a universal Quantifier. + + Creates a forall formula, where is the weight, + is an array of patterns, is an array + with the sorts of the bound variables, is an array with the + 'names' of the bound variables, and is the body of the + quantifier. Quantifiers are associated with weights indicating + the importance of using the quantifier during instantiation. + + @param sorts the sorts of the bound variables. + @param names names of the bound variables + @param body the body of the quantifier. + @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + @param patterns array containing the patterns created using MkPattern. + @param noPatterns array containing the anti-patterns created using MkPattern. + @param quantifierID optional symbol to track quantifier. + @param skolemID optional symbol to track skolem constants. + *) + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (Array.length sorts) != (Array.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + + (** + Create a universal Quantifier. + *) + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + (** + Create an existential Quantifier. + + *) + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (Array.length sorts) != (Array.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + + (** + Create an existential Quantifier. + *) + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + + (** + Create a Quantifier. + *) + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (universal) then + (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + else + (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + + + (** + Create a Quantifier. + *) + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (universal) then + mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id + else + mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id end (** Functions to manipulate Array expressions *) @@ -1777,71 +2081,71 @@ struct *) let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) -(** - Create a set type. -*) -let mk_sort ( ctx : context ) ( ty : sort) = - (new set_sort ctx)#cnstr_s ty + (** + Create a set type. + *) + let mk_sort ( ctx : context ) ( ty : sort) = + (new set_sort ctx)#cnstr_s ty -(** - Create an empty set. -*) -let mk_empty ( ctx : context ) ( domain : sort ) = - (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) - - (** - Create the full set. - *) -let mk_full ( ctx : context ) ( domain : sort ) = - create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) + (** + Create an empty set. + *) + let mk_empty ( ctx : context ) ( domain : sort ) = + (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) + + (** + Create the full set. + *) + let mk_full ( ctx : context ) ( domain : sort ) = + create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) -(** - Add an element to the set. -*) -let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) - - (** - Remove an element from a set. - *) -let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) - - (** - Take the union of a list of sets. - *) -let mk_union ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) - -(** - Take the intersection of a list of sets. -*) -let mk_intersection ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) + (** + Add an element to the set. + *) + let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) + + (** + Remove an element from a set. + *) + let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) + + (** + Take the union of a list of sets. + *) + let mk_union ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) + + (** + Take the intersection of a list of sets. + *) + let mk_intersection ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) -(** - Take the difference between two sets. -*) -let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) + (** + Take the difference between two sets. + *) + let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) -(** - Take the complement of a set. -*) -let mk_complement ( ctx : context ) ( arg : expr ) = - create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) + (** + Take the complement of a set. + *) + let mk_complement ( ctx : context ) ( arg : expr ) = + create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) -(** - Check for set membership. -*) -let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) + (** + Check for set membership. + *) + let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) - (** - Check for subsetness of sets. - *) -let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) + (** + Check for subsetness of sets. + *) + let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) end @@ -2001,148 +2305,6 @@ struct Array.init n f end - -(** Quantifier expressions *) -module Quantifiers = -struct - (** - The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. - *) - let get_index ( x : expr ) = - if not (AST.is_var x) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value x#gnc x#gno - - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. - *) - module Pattern = - struct - (** - The number of terms in the pattern. - *) - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms x#gnc x#gno - - (** - The terms in the pattern. - *) - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the pattern. - *) - let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno - end - - (** - Indicates whether the quantifier is universal. - *) - let is_universal ( x : quantifier ) = - lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE - - (** - Indicates whether the quantifier is existential. - *) - let is_existential ( x : quantifier ) = not (is_universal x) - - (** - The weight of the quantifier. - *) - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno - - (** - The number of patterns. - *) - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno - - (** - The patterns. - *) - let get_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in - Array.init n f - - (** - The number of no-patterns. - *) - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno - - (** - The no-patterns. - *) - let get_no_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in - Array.init n f - - (** - The number of bound variables. - *) - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno - - (** - The symbols for the bound variables. - *) - let get_bound_variable_names ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in - Array.init n f - - (** - The sorts of the bound variables. - *) - let get_bound_variable_sorts ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in - Array.init n f - - (** - The body of the quantifier. - *) - let get_body ( x : quantifier ) = - (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) - - (** - Creates a new bound variable. - @param index The de-Bruijn index of the variable - @param ty The sort of the variable - *) - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) - - (** - Create a quantifier pattern. - *) - let mk_pattern ( ctx : context ) ( terms : expr array ) = - if (Array.length terms) == 0 then - raise (Z3native.Exception "Cannot create a pattern from zero terms") - else - (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) -end (** Functions to manipulate Datatype expressions *) module Datatypes = @@ -2638,7 +2800,54 @@ struct The result has at most decimal places.*) let to_decimal_string ( x : algebraic_num ) ( precision : int ) = Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** + Create a real from a fraction. + + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + *) + let mk_real_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + if (den == 0) then + raise (Z3native.Exception "Denominator is zero") + else + (new rat_num ctx)#cnstr_obj (Z3native.mk_real ctx#gno num den) + + (** + Create a real numeral. + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + *) + let mk_real_numeral_s ( ctx : context ) ( v : string ) = + (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_real_sort ctx)#gno) + + (** + Create a real numeral. + + @param v value of the numeral. + @return A Term with value and sort Real + *) + let mk_real_numeral_i ( ctx : context ) ( v : int ) = + (new rat_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_real_sort ctx)#gno) + + (** + Create an integer numeral. + @param v A string representing the Term value in decimal notation. + *) + let mk_int_numeral_s ( ctx : context ) ( v : string ) = + (new int_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_int_sort ctx)#gno) + + (** + Create an integer numeral. + @param v value of the numeral. + @return A Term with value and sort Integer + *) + let mk_int_numeral_i ( ctx : context ) ( v : int ) = + (new int_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_int_sort ctx)#gno) + (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno end @@ -3386,10 +3595,18 @@ struct *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow ctx#gno t1#gno t2#gno) - + + (** + Create a bit-vector numeral. + + @param v A string representing the value in decimal notation. + @param size the size of the bit-vector + *) + let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = + (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_sort ctx size)#gno) end -(** Functions to manipulate Proof objects *) +(** Functions to manipulate proof expressions *) module Proofs = struct (** @@ -4567,933 +4784,654 @@ end (* STUFF FROM THE CONTEXT *) (** - -(* NUMERALS *) - -(* GENERAL NUMERALS *) -(** - Create a Term of a given sort. -*) - @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - @return A Term with value and sort - public Expr MkNumeral(string v, Sort ty) - - create_expr ctx (Z3native.mk_numeral ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(int v, Sort ty) - - create_expr ctx (Z3native.mk_int ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(uint v, Sort ty) - - create_expr ctx (Z3native.mk_unsigned_int ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(long v, Sort ty) - - create_expr ctx (Z3native.mk_int64 ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(ulong v, Sort ty) - - create_expr ctx (Z3native.mk_unsigned_int64 ctx#gno v, ty#gno) - -(* REALS *) -(** - Create a real from a fraction. -*) - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - public RatNum MkReal(int num, int den) - - if (den == 0) - throw new Z3Exception("Denominator is zero"); - - new RatNum(this, Z3native.mk_real ctx#gno num, den) - -(** - Create a real numeral. -*) - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - public RatNum MkReal(string v) - - new RatNum(this, Z3native.mk_numeral ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(int v) - - new RatNum(this, Z3native.mk_int ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(uint v) - - new RatNum(this, Z3native.mk_unsigned_int ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(long v) - - new RatNum(this, Z3native.mk_int64 ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(ulong v) - - new RatNum(this, Z3native.mk_unsigned_int64 ctx#gno v, RealSort#gno) - -(* INTEGERS *) -(** - Create an integer numeral. -*) - @param v A string representing the Term value in decimal notation. - public IntNum MkInt(string v) - - new IntNum(this, Z3native.mk_numeral ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(int v) - - new IntNum(this, Z3native.mk_int ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(uint v) - - new IntNum(this, Z3native.mk_unsigned_int ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(long v) - - new IntNum(this, Z3native.mk_int64 ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(ulong v) - - new IntNum(this, Z3native.mk_unsigned_int64 ctx#gno v, IntSort#gno) - -(* BIT-VECTORS *) -(** - Create a bit-vector numeral. -*) - @param v A string representing the value in decimal notation. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) string v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) int v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) uint v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) long v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) ulong v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - - // Numerals - -(* QUANTIFIERS *) -(** - Create a universal Quantifier. - - Creates a forall formula, where is the weight, - is an array of patterns, is an array - with the sorts of the bound variables, is an array with the - 'names' of the bound variables, and is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during instantiation. -*) - @param sorts the sorts of the bound variables. - @param names names of the bound variables - @param body the body of the quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param patterns array containing the patterns created using MkPattern. - @param noPatterns array containing the anti-patterns created using MkPattern. - @param quantifierID optional symbol to track quantifier. - @param skolemID optional symbol to track skolem constants. - public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create a universal Quantifier. -*) - public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create an existential Quantifier. -*) - - public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create an existential Quantifier. -*) - public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create a Quantifier. -*) - public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - if (universal) - MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create a Quantifier. -*) - public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - if (universal) - MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - - // Expr - (* OPTIONS *) (** - Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the Z3_PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the Z3_PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. *) - - - - - public Z3_ast_print_mode PrintMode + + + + + public Z3_ast_print_mode PrintMode - set { Z3native.set_ast_print_mode ctx#gno (uint)value); } + set { Z3native.set_ast_print_mode ctx#gno (uint)value); } (* SMT Files & Strings *) (** - Convert a benchmark into an SMT-LIB formatted string. + Convert a benchmark into an SMT-LIB formatted string. *) - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - public string BenchmarkToSMTString(string name, string logic, string status, string attributes, - BoolExpr[] assumptions, BoolExpr formula) + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) - Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, - (uint)assumptions.Length, AST.ArrayToNative(assumptions), - formula#gno); + Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula#gno); (** - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. + Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) - public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - Parse the given file using the SMT-LIB parser. + Parse the given file using the SMT-LIB parser. *) - - public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) + public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) (** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let[] SMTLIBFormulas + let[] SMTLIBFormulas - get + get - uint n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) - res; + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) + res; (** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) + public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) (** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let[] SMTLIBAssumptions + let[] SMTLIBAssumptions - get + get - uint n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) - res; + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) + res; (** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) + public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Func_Decl[] SMTLIBDecls + public Func_Decl[] SMTLIBDecls - get + get - uint n = NumSMTLIBDecls; - Func_Decl[] res = new Func_Decl[n]; - for (uint i = 0; i < n; i++) - res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) - res; + uint n = NumSMTLIBDecls; + Func_Decl[] res = new Func_Decl[n]; + for (uint i = 0; i < n; i++) + res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) + res; (** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) + public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Sort[] SMTLIBSorts + public Sort[] SMTLIBSorts - get + get - uint n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (uint i = 0; i < n; i++) - res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) - res; + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) + res; (** - Parse the given string using the SMT-LIB2 parser. + Parse the given string using the SMT-LIB2 parser. *) - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (** - Parse the given file using the SMT-LIB2 parser. + Parse the given file using the SMT-LIB2 parser. *) - - let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (* GOALS *) (** - Creates a new Goal. - - Note that the Context must have been created with proof generation support if - is set to true here. + Creates a new Goal. + + Note that the Context must have been created with proof generation support if + is set to true here. *) - @param models Indicates whether model generation should be enabled. - @param unsatCores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) + @param models Indicates whether model generation should be enabled. + @param unsatCores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - new Goal(this, models, unsatCores, proofs); + new Goal(this, models, unsatCores, proofs); (* PARAMETERSETS *) (** - Creates a new ParameterSet. + Creates a new ParameterSet. *) - public Params MkParams ( ctx : context ) = + public Params MkParams ( ctx : context ) = - new Params(this); + new Params(this); (* TACTICS *) (** - The number of supported tactics. + The number of supported tactics. *) - public uint NumTactics + public uint NumTactics - get {Z3native.get_num_tactics ctx#gno); } + get {Z3native.get_num_tactics ctx#gno); } (** - The names of all supported tactics. + The names of all supported tactics. *) - public string[] TacticNames + public string[] TacticNames - get + get - uint n = NumTactics; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_tactic_name ctx#gno i); - res; + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_tactic_name ctx#gno i); + res; (** - Returns a string containing a description of the tactic with the given name. + Returns a string containing a description of the tactic with the given name. *) - public string TacticDescription(string name) + public string TacticDescription(string name) - Z3native.tactic_get_descr ctx#gno name); + Z3native.tactic_get_descr ctx#gno name); (** - Creates a new Tactic. + Creates a new Tactic. *) - public Tactic MkTactic(string name) + public Tactic MkTactic(string name) - new Tactic(this, name); + new Tactic(this, name); (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . + Create a tactic that applies to a Goal and + then to every subgoal produced by . *) - public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) - last = ts[ts.Length - 1]#gno; - for (int i = ts.Length - 2; i >= 0; i--) - last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); + last = ts[ts.Length - 1]#gno; + for (int i = ts.Length - 2; i >= 0; i--) + last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); - if (last != IntPtr.Zero) + if (last != IntPtr.Zero) - last = Z3native.tactic_and_then ctx#gno t2#gno last); - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) + last = Z3native.tactic_and_then ctx#gno t2#gno last); + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) - else - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) + else + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . - - Shorthand for AndThen. + Create a tactic that applies to a Goal and + then to every subgoal produced by . + + Shorthand for AndThen. *) - public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - AndThen(t1, t2, ts); + AndThen(t1, t2, ts); (** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. *) - public Tactic OrElse(Tactic t1, Tactic t2) + public Tactic OrElse(Tactic t1, Tactic t2) - new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) + new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a goal for milliseconds. - - If does not terminate within milliseconds, then it fails. + Create a tactic that applies to a goal for milliseconds. + + If does not terminate within milliseconds, then it fails. *) - public Tactic TryFor(Tactic t, uint ms) + public Tactic TryFor(Tactic t, uint ms) - new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) + new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) (** - Create a tactic that applies to a given goal if the probe - evaluates to true. - - If evaluates to false, then the new tactic behaves like the skip tactic. + Create a tactic that applies to a given goal if the probe + evaluates to true. + + If evaluates to false, then the new tactic behaves like the skip tactic. *) - public Tactic When(Probe p, Tactic t) + public Tactic When(Probe p, Tactic t) - new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) + new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) (** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. *) - public Tactic Cond(Probe p, Tactic t1, Tactic t2) + public Tactic Cond(Probe p, Tactic t1, Tactic t2) - new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) + new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) (** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. *) - public Tactic Repeat(Tactic t, uint max = uint.MaxValue) + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) + new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) (** - Create a tactic that just returns the given goal. + Create a tactic that just returns the given goal. *) - public Tactic Skip ( ctx : context ) = + public Tactic Skip ( ctx : context ) = - new Tactic(this, Z3native.tactic_skip ctx#gno) + new Tactic(this, Z3native.tactic_skip ctx#gno) (** - Create a tactic always fails. + Create a tactic always fails. *) - public Tactic Fail ( ctx : context ) = + public Tactic Fail ( ctx : context ) = - new Tactic(this, Z3native.tactic_fail ctx#gno) + new Tactic(this, Z3native.tactic_fail ctx#gno) (** - Create a tactic that fails if the probe evaluates to false. + Create a tactic that fails if the probe evaluates to false. *) - public Tactic FailIf(Probe p) + public Tactic FailIf(Probe p) - new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) + new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) (** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) - public Tactic FailIfNotDecided ( ctx : context ) = + public Tactic FailIfNotDecided ( ctx : context ) = - new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) + new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) (** - Create a tactic that applies using the given set of parameters . + Create a tactic that applies using the given set of parameters . *) - public Tactic UsingParams(Tactic t, Params p) + public Tactic UsingParams(Tactic t, Params p) - new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) + new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) (** - Create a tactic that applies using the given set of parameters . - Alias for UsingParams*) - public Tactic With(Tactic t, Params p) + Create a tactic that applies using the given set of parameters . + Alias for UsingParams*) + public Tactic With(Tactic t, Params p) - UsingParams(t, p); + UsingParams(t, p); (** - Create a tactic that applies the given tactics in parallel. + Create a tactic that applies the given tactics in parallel. *) - public Tactic ParOr(params Tactic[] t) + public Tactic ParOr(params Tactic[] t) - new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) + new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) (** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. *) - public Tactic ParAndThen(Tactic t1, Tactic t2) + public Tactic ParAndThen(Tactic t1, Tactic t2) - new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) + new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) (** - Interrupt the execution of a Z3 procedure. + Interrupt the execution of a Z3 procedure. *) - This procedure can be used to interrupt: solvers, simplifiers and tactics. - public void Interrupt ( ctx : context ) = + This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt ( ctx : context ) = - Z3native.interrupt ctx#gno); + Z3native.interrupt ctx#gno); (* PROBES *) (** - The number of supported Probes. + The number of supported Probes. *) - public uint NumProbes + public uint NumProbes - get {Z3native.get_num_probes ctx#gno); } + get {Z3native.get_num_probes ctx#gno); } (** - The names of all supported Probes. + The names of all supported Probes. *) - public string[] ProbeNames + public string[] ProbeNames - get + get - uint n = NumProbes; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_probe_name ctx#gno i); - res; + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_probe_name ctx#gno i); + res; (** - Returns a string containing a description of the probe with the given name. + Returns a string containing a description of the probe with the given name. *) - public string ProbeDescription(string name) + public string ProbeDescription(string name) - Z3native.probe_get_descr ctx#gno name); + Z3native.probe_get_descr ctx#gno name); (** - Creates a new Probe. + Creates a new Probe. *) - public Probe MkProbe(string name) + public Probe MkProbe(string name) - new Probe(this, name); + new Probe(this, name); (** - Create a probe that always evaluates to . + Create a probe that always evaluates to . *) - public Probe Const(double val) + public Probe Const(double val) - new Probe(this, Z3native.probe_const ctx#gno val) + new Probe(this, Z3native.probe_const ctx#gno val) (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by *) - public Probe Lt(Probe p1, Probe p2) + public Probe Lt(Probe p1, Probe p2) - new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by *) - public Probe Gt(Probe p1, Probe p2) + public Probe Gt(Probe p1, Probe p2) - new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by *) - public Probe Le(Probe p1, Probe p2) + public Probe Le(Probe p1, Probe p2) - new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by *) - public Probe Ge(Probe p1, Probe p2) + public Probe Ge(Probe p1, Probe p2) - new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by *) - public Probe Eq(Probe p1, Probe p2) + public Probe Eq(Probe p1, Probe p2) - new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". + Create a probe that evaluates to "true" when the value + and evaluate to "true". *) - public Probe And(Probe p1, Probe p2) + public Probe And(Probe p1, Probe p2) - new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". + Create a probe that evaluates to "true" when the value + or evaluate to "true". *) - public Probe Or(Probe p1, Probe p2) + public Probe Or(Probe p1, Probe p2) - new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". + Create a probe that evaluates to "true" when the value + does not evaluate to "true". *) - public Probe Not(Probe p) + public Probe Not(Probe p) - new Probe(this, Z3native.probe_not ctx#gno p#gno) + new Probe(this, Z3native.probe_not ctx#gno p#gno) (* SOLVERS *) (** - Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. + Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) - public Solver MkSolver(Symbol logic = null) + public Solver MkSolver(Symbol logic = null) - if (logic == null) - new Solver(this, Z3native.mk_solver ctx#gno) - else - new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) + if (logic == null) + new Solver(this, Z3native.mk_solver ctx#gno) + else + new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - - public Solver MkSolver(string logic) + + public Solver MkSolver(string logic) - MkSolver(MkSymbol(logic) + MkSolver(MkSymbol(logic) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - let mk_Simple_Solver ( ctx : context ) ctx : context ) = + let mk_Simple_Solver( ctx : context ) ctx : context ) = - new Solver(this, Z3native.mk_simple_solver ctx#gno) + new Solver(this, Z3native.mk_simple_solver ctx#gno) (** - Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. + Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) - public Solver MkSolver(Tactic t) + public Solver MkSolver(Tactic t) - new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) + new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) (* FIXEDPOINTS *) (** - Create a Fixedpoint context. + Create a Fixedpoint context. *) - public Fixedpoint MkFixedpoint ( ctx : context ) = + public Fixedpoint MkFixedpoint ( ctx : context ) = - new Fixedpoint(this); + new Fixedpoint(this); (* MISCELLANEOUS *) (** - Wraps an AST. + Wraps an AST. *) - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - public AST WrapAST(IntPtr nativeObject) + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) - AST.Create(this, nativeObject); + AST.Create(this, nativeObject); (** - Unwraps an AST. + Unwraps an AST. *) - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - public IntPtr UnwrapAST(AST a) + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + public IntPtr UnwrapAST(AST a) - a#gno; + a#gno; (** - a string describing all available parameters to Expr.Simplify. + a string describing all available parameters to Expr.Simplify. *) - public string SimplifyHelp ( ctx : context ) = + public string SimplifyHelp ( ctx : context ) = - Z3native.simplify_get_help ctx#gno); + Z3native.simplify_get_help ctx#gno); (** - Retrieves parameter descriptions for simplifier. + Retrieves parameter descriptions for simplifier. *) - public ParamDescrs SimplifyParameterDescriptions + public ParamDescrs SimplifyParameterDescriptions - get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } + get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } (** - Enable/disable printing of warning messages to the console. + Enable/disable printing of warning messages to the console. *) - Note that this function is static and effects the behaviour of - all contexts globally. - public static void ToggleWarningMessages(bool enabled) + Note that this function is static and effects the behaviour of + all contexts globally. + public static void ToggleWarningMessages(bool enabled) - Z3native.toggle_warning_messages((enabled) ? 1 : 0); + Z3native.toggle_warning_messages((enabled) ? 1 : 0); (* ERROR HANDLING *) (** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. *) - public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); + public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); (** - The OnError event. + The OnError event. *) - public event ErrorHandler OnError = null; + public event ErrorHandler OnError = null; (* PARAMETERS *) (** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. *) - - public void UpdateParamValue(string id, string value) + + public void UpdateParamValue(string id, string value) - Z3native.update_param_value ctx#gno id, value); + Z3native.update_param_value ctx#gno id, value); (** - Get a configuration parameter. - - Returns null if the parameter value does not exist. - + Get a configuration parameter. + + Returns null if the parameter value does not exist. + *) - public string GetParamValue(string id) + public string GetParamValue(string id) - IntPtr res = IntPtr.Zero; - int r = Z3native.get_param_value ctx#gno id, out res); - if (r == (int)Z3_lbool.L_FALSE) - null; - else - Marshal.PtrToStringAnsi(res); + IntPtr res = IntPtr.Zero; + int r = Z3native.get_param_value ctx#gno id, out res); + if (r == (int)Z3_lbool.L_FALSE) + null; + else + Marshal.PtrToStringAnsi(res); (* INTERNAL *) - internal IntPtr m_ctx = IntPtr.Zero; - internal Z3native.error_handler m_n_err_handler = null; - internal IntPtr nCtx { get {m_ctx) + internal IntPtr m_ctx = IntPtr.Zero; + internal Z3native.error_handler m_n_err_handler = null; + internal IntPtr nCtx { get {m_ctx) - internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - internal void InitContext ( ctx : context ) = + internal void InitContext ( ctx : context ) = - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); *) - From 39e538a8bc4bb2c1dbf7cbdd0b65576d101d5224 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Dec 2012 02:47:41 +0000 Subject: [PATCH 248/507] More new ML API; Status: everything is there except for error handling. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 1498 +++++++++++++++++++++++++--------------------- 1 file changed, 809 insertions(+), 689 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index f6454b797..088bfbd6f 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,33 +7,52 @@ open Z3enums -(**/**) +(** Context objects. -class virtual idisposable = -object - method virtual dispose : unit -end +Most interactions with Z3 are interpreted in some context; most users will only +require one such object, but power users may require more than one. To start using +Z3, do -(** Context objects *) + + let ctx = (new context [||]) in + (...) + + +where [||] is a (possibly empty) list of pairs of strings, which can +be used to set options on the context, e.g., like so: + + + let cfg = [("model", "true"); ("...", "...")] in + let ctx = (new context cfg) in + (...) + + +*) class context settings = +(**/**) object (self) - inherit idisposable - val mutable m_n_ctx : Z3native.z3_context = let cfg = Z3native.mk_config in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = Z3native.mk_context_rc cfg in Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; v +(* CMW: Install error handler here! + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); +*) + val mutable m_obj_cnt : int = 0 initializer (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) let f = fun o -> o#dispose in let v = self in - Gc.finalise f v + Gc.finalise f v; method dispose : unit = if m_obj_cnt == 0 then ( @@ -47,13 +66,14 @@ object (self) method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 method gno = m_n_ctx +(**/**) end +(**/**) (** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) - inherit idisposable val mutable m_ctx : context = ctx_init val mutable m_n_obj : Z3native.ptr option = obj_init @@ -100,9 +120,10 @@ end (** Parameter set objects *) -class params ctx obj = +class params ctx = object (self) - inherit z3object ctx obj as super + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self method incref nc o = Z3native.params_inc_ref nc o method decref nc o = Z3native.params_dec_ref nc o end @@ -264,6 +285,10 @@ object (self) method decref nc o = super#decref nc o end +let func_declaton (a : func_decl array) = + let f (e : func_decl) = e#gno in + Array.map f a + class parameter = object (self) val mutable m_kind : parameter_kind = PARAMETER_INT; @@ -624,6 +649,10 @@ object (self) method decref nc o = Z3native.tactic_dec_ref nc o end +let tacticaton (a : tactic array) = + let f (e : tactic) = e#gno in + Array.map f a + (** Function interpretation entry objects *) class func_entry ctx = object (self) @@ -715,6 +744,15 @@ object (self) method decref nc o = Z3native.solver_dec_ref nc o end +(** Fixedpoint objects *) +class fixedpoint ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.fixedpoint_inc_ref nc o + method decref nc o = Z3native.fixedpoint_dec_ref nc o +end + (**/**) @@ -1294,6 +1332,33 @@ struct x else (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) + +(** + Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. +*) + let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = + create_ast ctx ptr + +(** + Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. +*) + let unwrap_ast ( a : ast ) = a#gno end (** General expressions (terms), including Boolean logic *) @@ -1308,6 +1373,18 @@ struct | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) +(** + a string describing all available parameters to Expr.Simplify. +*) + let get_simplify_help ( ctx : context ) = + Z3native.simplify_get_help ctx#gno + +(** + Retrieves parameter descriptions for simplifier. +*) + let get_simplify_parameter_descrs ( ctx : context ) = + (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs ctx#gno) + (** The function declaration of the function that is applied in this expression. *) @@ -4087,6 +4164,30 @@ end *) module Params = struct +(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) +module ParamDescrs = +struct + + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno + + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size x#gnc x#gno in + let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno + + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno +end + (** Adds a parameter setting. *) @@ -4135,37 +4236,18 @@ struct let add_s_symbol (p : params) (name : string) (value : symbol) = add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + (** + Creates a new parameter set + *) + let mk_params ( ctx : context ) = + (new params ctx)#cnstr_obj (Z3native.mk_params ctx#gno) + (** A string representation of the parameter set. *) let to_string (p : params) = Z3native.params_to_string p#gnc p#gno end -(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) -module ParamDescrs = -struct - - (** Validate a set of parameters. *) - let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) - - (** Retrieve all names of parameters. *) - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size x#gnc x#gno in - let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in - Array.init n f - - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - - (** Retrieves a string representation of the ParamDescrs. *) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno - -end - (** Goals A goal (aka problem). A goal is essentially a @@ -4258,6 +4340,22 @@ struct Z3native.tactic_dec_ref x#gnc tn ; (new goal x#gc)#cnstr_obj res + + (** + Creates a new Goal. + + Note that the Context must have been created with proof generation support if + is set to true here. + @param models Indicates whether model generation should be enabled. + @param unsat_cores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + *) + let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = + (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno + (int_of_lbool (if models then L_TRUE else L_FALSE)) + (int_of_lbool (if unsat_cores then L_TRUE else L_FALSE)) + (int_of_lbool (if proofs then L_TRUE else L_FALSE))) + (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno end @@ -4272,6 +4370,33 @@ end *) module Tactic = struct +(** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) +module ApplyResult = +struct + (** The number of Subgoals. *) + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals x#gnc x#gno + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in + Array.init n f + + (** Convert a model for the subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g + *) + let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = + (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) + + (** A string representation of the ApplyResult. *) + let to_string ( x : apply_result ) = Z3native.apply_result_to_string x#gnc x#gno +end + (** A string containing a description of parameters accepted by the tactic. *) let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno @@ -4291,6 +4416,147 @@ struct let get_solver ( x : tactic ) = (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) + (** + The number of supported tactics. + *) + let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics ctx#gno + + (** + The names of all supported tactics. + *) + let get_tactic_names ( ctx : context ) = + let n = (get_num_tactics ctx ) in + let f i = (Z3native.get_tactic_name ctx#gno i) in + Array.init n f + + + (** + Returns a string containing a description of the tactic with the given name. + *) + let get_tactic_description ( ctx : context ) ( name : string ) = + Z3native.tactic_get_descr ctx#gno name + + (** + Creates a new Tactic. + *) + let mk_tactic ( ctx : context ) ( name : string ) = + (new tactic ctx)#cnstr_obj (Z3native.mk_tactic ctx#gno name) + + (** + Create a tactic that applies to a Goal and + then to every subgoal produced by . + *) + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array option ) = + match + match ts with + | None -> None + | Some(rts) -> ( + let f p c = (match p with + | None -> (Some c#gno) + | Some(x) -> (Some (Z3native.tactic_and_then ctx#gno c#gno x))) in + Array.fold_left f None rts) + with + | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno t2#gno) + | Some(x) -> + let o = (Z3native.tactic_and_then ctx#gno t2#gno x) in + (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno o) + + (** + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. + *) + let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else ctx#gno t1#gno t2#gno) + + (** + Create a tactic that applies to a goal for milliseconds. + + If does not terminate within milliseconds, then it fails. + *) + let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for ctx#gno t#gno ms) + + (** + Create a tactic that applies to a given goal if the probe + evaluates to true. + + If evaluates to false, then the new tactic behaves like the skip tactic. + *) + (* CMW: when is a keyword *) + let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_when ctx#gno p#gno t#gno) + + (** + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. + *) + let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) + + (** + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. + *) + let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat ctx#gno t#gno max) + + (** + Create a tactic that just returns the given goal. + *) + let skip ( ctx : context ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_skip ctx#gno) + + (** + Create a tactic always fails. + *) + let fail ( ctx : context ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail ctx#gno) + + (** + Create a tactic that fails if the probe evaluates to false. + *) + let fail_if ( ctx : context ) ( p : probe ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if ctx#gno p#gno) + + (** + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). + *) + let fail_if_not_decided ( ctx : context ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided ctx#gno) + + (** + Create a tactic that applies using the given set of parameters . + *) + let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params ctx#gno t#gno p#gno) + + (** + Create a tactic that applies using the given set of parameters . + Alias for UsingParams*) + (* CMW: with is a keyword *) + let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = + using_params ctx t p + + (** + Create a tactic that applies the given tactics in parallel. + *) + let par_or ( ctx : context ) ( t : tactic array ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or ctx#gno (Array.length t) (tacticaton t)) + + (** + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. + *) + let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) + + (** + Interrupt the execution of a Z3 procedure. + This procedure can be used to interrupt: solvers, simplifiers and tactics. + *) + let interrupt ( ctx : context ) = + Z3native.interrupt ctx#gno end (** Models @@ -4337,7 +4603,7 @@ struct let to_string ( x : func_entry ) = let a = (get_args x) in let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") end (** @@ -4513,33 +4779,6 @@ struct let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno end -(** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) -module ApplyResult = -struct - (** The number of Subgoals. *) - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals x#gnc x#gno - - (** Retrieves the subgoals from the apply_result. *) - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in - Array.init n f - - (** Convert a model for the subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g - *) - let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = - (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) - - (** A string representation of the ApplyResult. *) - let to_string ( x : apply_result) = Z3native.apply_result_to_string x#gnc x#gno -end - (** Solvers *) module Solver = struct @@ -4615,10 +4854,8 @@ struct let get ( x : statistics ) ( key : string ) = let f p c = (if (Entry.get_key c) = key then (Some c) else p) in Array.fold_left f None (get_entries x) - end - (** A string that describes all available solver parameters. *) @@ -4755,12 +4992,222 @@ struct let get_statistics ( x : solver ) = (new statistics x#gc)#cnstr_obj (Z3native.solver_get_statistics x#gnc x#gno) + (** + Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. + *) + let mk_solver ( ctx : context ) ( logic : symbol option) = + match logic with + | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver ctx#gno) + | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic ctx#gno x#gno) + + (** + Creates a new (incremental) solver. + + *) + let mk_solver_s ( ctx : context ) ( logic : string ) = + mk_solver ctx (Some ((Symbol.mk_string ctx logic) :> symbol)) + + (** + Creates a new (incremental) solver. + *) + let mk_simple_solver ( ctx : context ) = + (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver ctx#gno) + + (** + Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. + *) + let mk_solver_t ( ctx : context ) ( t : tactic ) = + (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic ctx#gno t#gno) + (** A string representation of the solver. *) let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno end +(** Fixedpoint solving *) +module Fixedpoints = +struct + (** + A string that describes all available fixedpoint solver parameters. + *) + let get_help ( x : fixedpoint ) = + Z3native.fixedpoint_get_help x#gnc x#gno + + (** + Sets the fixedpoint solver parameters. + *) + let set_params ( x : fixedpoint ) ( p : params )= + Z3native.fixedpoint_set_params x#gnc x#gno p#gno + + (** + Retrieves parameter descriptions for Fixedpoint solver. + *) + let get_param_descrs ( x : fixedpoint ) = + (new param_descrs x#gc)#cnstr_obj (Z3native.fixedpoint_get_param_descrs x#gnc x#gno) + + (** + Assert a constraints into the fixedpoint solver. + *) + let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = + let f e = (Z3native.fixedpoint_assert x#gnc x#gno e#gno) in + Array.map f constraints + + (** + Register predicate as recursive relation. + *) + let register_relation ( x : fixedpoint ) ( f : func_decl ) = + Z3native.fixedpoint_register_relation x#gnc x#gno f#gno + + (** + Add rule into the fixedpoint solver. + *) + let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = + match name with + | None -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno (Z3native.mk_null()) + | Some(y) -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno y#gno + + (** + Add table fact to the fixedpoint solver. + *) + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = + Z3native.fixedpoint_add_fact x#gnc x#gno pred#gno (Array.length args) args + + (** + Query the fixedpoint solver. + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. + *) + let query ( x : fixedpoint ) ( query : bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query x#gnc x#gno query#gno)) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + (** + Query the fixedpoint solver. + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. + *) + let query_r ( x : fixedpoint ) ( relations : func_decl array ) = + match (lbool_of_int (Z3native.fixedpoint_query_relations x#gnc x#gno (Array.length relations) (func_declaton relations))) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + (** + Creates a backtracking point. + + *) + let push ( x : fixedpoint ) = + Z3native.fixedpoint_push x#gnc x#gno + + (** + Backtrack one backtracking point. + + Note that an exception is thrown if Pop is called without a corresponding Push + + *) + let pop ( x : fixedpoint ) = + Z3native.fixedpoint_pop x#gnc x#gno + + (** + Update named rule into in the fixedpoint solver. + *) + let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = + Z3native.fixedpoint_update_rule x#gnc x#gno rule#gno name#gno + + (** + Retrieve satisfying instance or instances of solver, + or definitions for the recursive predicates that show unsatisfiability. + *) + let get_answer ( x : fixedpoint ) = + let q = (Z3native.fixedpoint_get_answer x#gnc x#gno) in + if (Z3native.is_null q) then + None + else + Some (create_expr x#gc q) + + (** + Retrieve explanation why fixedpoint engine returned status Unknown. + *) + let get_reason_unknown ( x : fixedpoint ) = + Z3native.fixedpoint_get_reason_unknown x#gnc x#gno + + (** + Retrieve the number of levels explored for a given predicate. + *) + let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = + Z3native.fixedpoint_get_num_levels x#gnc x#gno predicate#gno + + (** + Retrieve the cover of a predicate. + *) + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = + let q = (Z3native.fixedpoint_get_cover_delta x#gnc x#gno level predicate#gno) in + if (Z3native.is_null q) then + None + else + Some (create_expr x#gc q) + + (** + Add property about the predicate. + The property is added at level. + *) + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = + Z3native.fixedpoint_add_cover x#gnc x#gno level predicate#gno, property#gno + + (** + Retrieve internal string representation of fixedpoint object. + *) + let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string x#gnc x#gno 0 [||] + + (** + Instrument the Datalog engine on which table representation to use for recursive predicate. + *) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = + Z3native.fixedpoint_set_predicate_representation x#gnc x#gno f#gno (Array.length kinds) (symbolaton kinds) + + (** + Convert benchmark given as set of axioms, rules and queries to a string. + *) + let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = + Z3native.fixedpoint_to_string x#gnc x#gno (Array.length queries) (astaton queries) + + (** + Retrieve set of rules added to fixedpoint context. + *) + let get_rules ( x : fixedpoint ) = + let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_rules x#gnc x#gno)) in + let n = (AST.ASTVector.get_size v) in + let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + Array.init n f + + (** + Retrieve set of assertions added to fixedpoint context. + *) + let get_assertions ( x : fixedpoint ) = + let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_assertions x#gnc x#gno)) in + let n = (AST.ASTVector.get_size v) in + let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + Array.init n f + + (** + Create a Fixedpoint context. + *) + let mk_fixedpoint ( ctx : context ) = + (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint ctx#gno) +end + (** Probes Probes are used to inspect a goal (aka problem) and collect information that may be used to decide @@ -4778,660 +5225,333 @@ struct *) let apply ( x : probe ) (g : goal) = Z3native.probe_apply x#gnc x#gno g#gno + + (** + The number of supported Probes. + *) + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes ctx#gno + + (** + The names of all supported Probes. + *) + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name ctx#gno i) in + Array.init n f + + (** + Returns a string containing a description of the probe with the given name. + *) + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr ctx#gno name + + (** + Creates a new Probe. + *) + let mk_probe ( ctx : context ) ( name : string ) = + (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) + + (** + Create a probe that always evaluates to . + *) + let const ( ctx : context ) ( v : float ) = + (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by + *) + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by + *) + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by + *) + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by + *) + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by + *) + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + and evaluate to "true". + *) + (* CMW: and is a keyword *) + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + or evaluate to "true". + *) + (* CMW: or is a keyword *) + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". + *) + (* CMW: is not a keyword? *) + let not_ ( ctx : context ) ( p : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) end - -(* STUFF FROM THE CONTEXT *) - -(** -(* OPTIONS *) +(** Global and context options + + Note: This module contains functions that set parameters/options for context + objects as well as functions that set options that are used globally, across + contexts.*) +module Options = +struct (** - Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the Z3_PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + *) - - - - - public Z3_ast_print_mode PrintMode + let update_param_value ( ctx : context ) ( id : string) ( value : string )= + Z3native.update_param_value ctx#gno id value - set { Z3native.set_ast_print_mode ctx#gno (uint)value); } - -(* SMT Files & Strings *) (** - Convert a benchmark into an SMT-LIB formatted string. + Get a configuration parameter. + + Returns None if the parameter value does not exist. + *) - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - public string BenchmarkToSMTString(string name, string logic, string status, string attributes, - BoolExpr[] assumptions, BoolExpr formula) + let get_param_value ( ctx : context ) ( id : string ) = + let (r, v) = (Z3native.get_param_value ctx#gno id) in + if ((lbool_of_int r) == L_FALSE) then + None + else + Some v - Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, - (uint)assumptions.Length, AST.ArrayToNative(assumptions), - formula#gno); + (** + Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + + + + + *) + let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = + Z3native.set_ast_print_mode ctx#gno (int_of_ast_print_mode value) (** - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. + Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) - public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + let toggle_warning_messages ( enabled: bool ) = + Z3native.toggle_warning_messages (int_of_lbool (if enabled then L_TRUE else L_FALSE)) +end - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) +(** Functions for handling SMT and SMT2 expressions and files *) +module SMT = +struct + (** + Convert a benchmark into an SMT-LIB formatted string. -(** - Parse the given file using the SMT-LIB parser. -*) - - public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) - -(** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) - -(** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - let[] SMTLIBFormulas - - get - - uint n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) - res; - - -(** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) - -(** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - let[] SMTLIBAssumptions - - get - - uint n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) - res; - - -(** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) - -(** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public Func_Decl[] SMTLIBDecls - - get - - uint n = NumSMTLIBDecls; - Func_Decl[] res = new Func_Decl[n]; - for (uint i = 0; i < n; i++) - res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) - res; - - -(** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) - -(** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public Sort[] SMTLIBSorts - - get - - uint n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (uint i = 0; i < n; i++) - res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) - res; - - -(** - Parse the given string using the SMT-LIB2 parser. -*) - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) - -(** - Parse the given file using the SMT-LIB2 parser. -*) - - let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) - -(* GOALS *) -(** - Creates a new Goal. - - Note that the Context must have been created with proof generation support if - is set to true here. -*) - @param models Indicates whether model generation should be enabled. - @param unsatCores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - - new Goal(this, models, unsatCores, proofs); - -(* PARAMETERSETS *) -(** - Creates a new ParameterSet. -*) - public Params MkParams ( ctx : context ) = - - new Params(this); - -(* TACTICS *) -(** - The number of supported tactics. -*) - public uint NumTactics - - get {Z3native.get_num_tactics ctx#gno); } - -(** - The names of all supported tactics. -*) - public string[] TacticNames - - get - - uint n = NumTactics; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_tactic_name ctx#gno i); - res; - - -(** - Returns a string containing a description of the tactic with the given name. -*) - public string TacticDescription(string name) - - Z3native.tactic_get_descr ctx#gno name); - -(** - Creates a new Tactic. -*) - public Tactic MkTactic(string name) - - new Tactic(this, name); - -(** - Create a tactic that applies to a Goal and - then to every subgoal produced by . -*) - public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) - - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) - - last = ts[ts.Length - 1]#gno; - for (int i = ts.Length - 2; i >= 0; i--) - last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); - - if (last != IntPtr.Zero) - - last = Z3native.tactic_and_then ctx#gno t2#gno last); - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + *) + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = + Z3native.benchmark_to_smtlib_string ctx#gno name logic status attributes + (Array.length assumptions) (astaton assumptions) + formula#gno + (** + Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. + *) + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") else - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) - -(** - Create a tactic that applies to a Goal and - then to every subgoal produced by . - - Shorthand for AndThen. -*) - public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - - AndThen(t1, t2, ts); - -(** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. -*) - public Tactic OrElse(Tactic t1, Tactic t2) - - new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) - -(** - Create a tactic that applies to a goal for milliseconds. - - If does not terminate within milliseconds, then it fails. -*) - public Tactic TryFor(Tactic t, uint ms) - - new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) - -(** - Create a tactic that applies to a given goal if the probe - evaluates to true. - - If evaluates to false, then the new tactic behaves like the skip tactic. -*) - public Tactic When(Probe p, Tactic t) - - new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) - -(** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. -*) - public Tactic Cond(Probe p, Tactic t1, Tactic t2) - - new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) - -(** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. -*) - public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - - new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) - -(** - Create a tactic that just returns the given goal. -*) - public Tactic Skip ( ctx : context ) = - - new Tactic(this, Z3native.tactic_skip ctx#gno) - -(** - Create a tactic always fails. -*) - public Tactic Fail ( ctx : context ) = - - new Tactic(this, Z3native.tactic_fail ctx#gno) - -(** - Create a tactic that fails if the probe evaluates to false. -*) - public Tactic FailIf(Probe p) - - new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) - -(** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). -*) - public Tactic FailIfNotDecided ( ctx : context ) = - - new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) - -(** - Create a tactic that applies using the given set of parameters . -*) - public Tactic UsingParams(Tactic t, Params p) - - new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) - -(** - Create a tactic that applies using the given set of parameters . - Alias for UsingParams*) - public Tactic With(Tactic t, Params p) - - UsingParams(t, p); - -(** - Create a tactic that applies the given tactics in parallel. -*) - public Tactic ParOr(params Tactic[] t) - - new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) - -(** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. -*) - public Tactic ParAndThen(Tactic t1, Tactic t2) - - new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) - -(** - Interrupt the execution of a Z3 procedure. -*) - This procedure can be used to interrupt: solvers, simplifiers and tactics. - public void Interrupt ( ctx : context ) = - - Z3native.interrupt ctx#gno); - -(* PROBES *) -(** - The number of supported Probes. -*) - public uint NumProbes - - get {Z3native.get_num_probes ctx#gno); } - -(** - The names of all supported Probes. -*) - public string[] ProbeNames - - get - - uint n = NumProbes; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_probe_name ctx#gno i); - res; - - -(** - Returns a string containing a description of the probe with the given name. -*) - public string ProbeDescription(string name) - - Z3native.probe_get_descr ctx#gno name); - -(** - Creates a new Probe. -*) - public Probe MkProbe(string name) - - new Probe(this, name); - -(** - Create a probe that always evaluates to . -*) - public Probe Const(double val) - - new Probe(this, Z3native.probe_const ctx#gno val) - -(** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by -*) - public Probe Lt(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by -*) - public Probe Gt(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by -*) - public Probe Le(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by -*) - public Probe Ge(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by -*) - public Probe Eq(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value - and evaluate to "true". -*) - public Probe And(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value - or evaluate to "true". -*) - public Probe Or(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". -*) - public Probe Not(Probe p) - - new Probe(this, Z3native.probe_not ctx#gno p#gno) - -(* SOLVERS *) -(** - Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. -*) - public Solver MkSolver(Symbol logic = null) - - if (logic == null) - new Solver(this, Z3native.mk_solver ctx#gno) + Z3native.parse_smtlib_string ctx#gno str + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + + (** + Parse the given file using the SMT-LIB parser. + + *) + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") else - new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) + Z3native.parse_smtlib_file ctx#gno file_name + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (** + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas ctx#gno -(** - Creates a new (incremental) solver. -*) - - public Solver MkSolver(string logic) + (** + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_formulas ( ctx : context ) = + let n = (get_num_smtlib_formulas ctx ) in + let f i = ((create_expr ctx (Z3native.get_smtlib_formula ctx#gno i)) :> bool_expr) in + Array.init n f - MkSolver(MkSymbol(logic) -(** - Creates a new (incremental) solver. -*) - let mk_Simple_Solver( ctx : context ) ctx : context ) = + (** + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions ctx#gno - new Solver(this, Z3native.mk_simple_solver ctx#gno) + (** + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_assumptions ( ctx : context ) = + let n = (get_num_smtlib_assumptions ctx ) in + let f i = ((create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i)) :> bool_expr ) in + Array.init n f -(** - Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. -*) - public Solver MkSolver(Tactic t) + (** + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls ctx#gno - new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) + (** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_decls ( ctx : context ) = + let n = (get_num_smtlib_decls ctx) in + let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl ctx#gno i) in + Array.init n f -(* FIXEDPOINTS *) -(** - Create a Fixedpoint context. -*) - public Fixedpoint MkFixedpoint ( ctx : context ) = + (** + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts ctx#gno - new Fixedpoint(this); + (** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_sorts ( ctx : context ) = + let n = (get_num_smtlib_sorts ctx) in + let f i = (create_sort ctx (Z3native.get_smtlib_sort ctx#gno i)) in + Array.init n f -(* MISCELLANEOUS *) -(** - Wraps an AST. -*) - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - public AST WrapAST(IntPtr nativeObject) + (** + Parse the given string using the SMT-LIB2 parser. - AST.Create(this, nativeObject); - -(** - Unwraps an AST. -*) - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - public IntPtr UnwrapAST(AST a) - - a#gno; - -(** - a string describing all available parameters to Expr.Simplify. -*) - public string SimplifyHelp ( ctx : context ) = - - Z3native.simplify_get_help ctx#gno); - -(** - Retrieves parameter descriptions for simplifier. -*) - public ParamDescrs SimplifyParameterDescriptions - - get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } - -(** - Enable/disable printing of warning messages to the console. -*) - Note that this function is static and effects the behaviour of - all contexts globally. - public static void ToggleWarningMessages(bool enabled) - - Z3native.toggle_warning_messages((enabled) ? 1 : 0); - -(* ERROR HANDLING *) -(** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. -*) - public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); - -(** - The OnError event. -*) - public event ErrorHandler OnError = null; - -(* PARAMETERS *) -(** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. -*) - - public void UpdateParamValue(string id, string value) - - Z3native.update_param_value ctx#gno id, value); - -(** - Get a configuration parameter. - - Returns null if the parameter value does not exist. - -*) - public string GetParamValue(string id) - - IntPtr res = IntPtr.Zero; - int r = Z3native.get_param_value ctx#gno id, out res); - if (r == (int)Z3_lbool.L_FALSE) - null; + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + *) + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") else - Marshal.PtrToStringAnsi(res); + Z3native.parse_smtlib2_string ctx#gno str + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) -(* INTERNAL *) - internal IntPtr m_ctx = IntPtr.Zero; - internal Z3native.error_handler m_n_err_handler = null; - internal IntPtr nCtx { get {m_ctx) + (** + Parse the given file using the SMT-LIB2 parser. + + *) + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Z3native.parse_smtlib2_string ctx#gno file_name + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) +end - internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) +(* - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. +(** + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. +*) + public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); - internal void InitContext ( ctx : context ) = + internal Z3native.error_handler m_n_err_handler = null; - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); + internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) + + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. *) From a42e21ede1c4fece515ee532be1b2ce80296e2df Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Dec 2012 03:00:39 +0000 Subject: [PATCH 249/507] ML API: mk_context added. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 4 +- src/api/ml/z3.ml | 687 +++++++++++++++++++------------------- 2 files changed, 349 insertions(+), 342 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index dde9f944a..32c9458f5 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -14,8 +14,8 @@ let _ = else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = [("model", "true"); ("proof", "false")] in - let ctx = (new context cfg) in + let cfg = (Some [("model", "true"); ("proof", "false")]) in + let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in let ss = (Symbol.mk_string ctx "mySymbol") in let bs = (Sort.mk_bool ctx) in diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 088bfbd6f..fee6f9fe0 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,29 +7,9 @@ open Z3enums -(** Context objects. - -Most interactions with Z3 are interpreted in some context; most users will only -require one such object, but power users may require more than one. To start using -Z3, do - - - let ctx = (new context [||]) in - (...) - - -where [||] is a (possibly empty) list of pairs of strings, which can -be used to set options on the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (new context cfg) in - (...) - - -*) -class context settings = (**/**) + +class context settings = object (self) val mutable m_n_ctx : Z3native.z3_context = let cfg = Z3native.mk_config in @@ -66,11 +46,37 @@ object (self) method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 method gno = m_n_ctx -(**/**) end (**/**) +(** Create a context object. + +Most interactions with Z3 are interpreted in some context; many users will only +require one such object, but power users may require more than one. To start using +Z3, do + + + let ctx = (mk_context None) in + (...) + + +where a list of pairs of strings may be passed to set options on +the context, e.g., like so: + + + let cfg = (Some [("model", "true"); ("...", "...")]) in + let ctx = (mk_context cfg) in + (...) + +*) +let mk_context ( cfg : ( string * string ) list option ) = + match cfg with + | None -> new context [] + | Some(x) -> new context x + +(**/**) + (** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) @@ -4559,224 +4565,114 @@ end Z3native.interrupt ctx#gno end -(** Models +(** Probes - A Model contains interpretations (assignments) of constants and functions. *) -module Model = + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe = struct - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. - *) - module FuncInterp = - struct - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) - module FuncEntry = - struct - (** - Return the (symbolic) value of this entry. - *) - let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) - - (** - The number of arguments of the entry. - *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno - - (** - The arguments of the function entry. - *) - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the function entry. - *) - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - (** - The number of entries in the function interpretation. - *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno - - (** - The entries in the function interpretation - *) - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in - Array.init n f - - (** - The (symbolic) `else' value of the function interpretation. - *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) - - (** - The arity of the function interpretation - *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno - - (** - A string representation of the function interpretation. - *) - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (Array.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - (** Retrieves the interpretation (the assignment) of in the model. - A function declaration of zero arity - An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null np) then - None - else - Some (create_expr x#gc np) - - (** Retrieves the interpretation (the assignment) of in the model. - A Constant - An expression if the constant has an interpretation in the model, null otherwise. - *) - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - (** Retrieves the interpretation (the assignment) of a non-constant in the model. - A function declaration of non-zero arity - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl x#gnc n in - get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in - if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno - - (** The function declarations of the constants in the model. *) - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.init n f - - - (** The number of function interpretations in the model. *) - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno - - (** The function declarations of the function interpretations in the model. *) - let get_func_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - Array.init n f - - (** All symbols that have an interpretation in the model. *) - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.append (Array.init n_funcs f) (Array.init n_consts g) - - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - (** - Evaluates the expression in the current model. - - - This function may fail if contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - - An expression - - When this flag is enabled, a model value will be assigned to any constant - or function that does not have an interpretation in the model. - - The evaluation of in the model. + Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in - if (lbool_of_int r) == L_FALSE then - raise (ModelEvaluationFailedException "evaluation failed") - else - create_expr x#gc v + let apply ( x : probe ) (g : goal) = + Z3native.probe_apply x#gnc x#gno g#gno - (** Alias for eval. *) - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - (** The number of uninterpreted sorts that the model has an interpretation for. *) - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - - + (** + The number of supported Probes. *) - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes ctx#gno + + (** + The names of all supported Probes. + *) + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name ctx#gno i) in Array.init n f + (** + Returns a string containing a description of the probe with the given name. + *) + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr ctx#gno name - (** The finite set of distinct values that represent the interpretation for sort . - - An uninterpreted sort - An array of expressions, where each is an element of the universe of + (** + Creates a new Probe. + *) + let mk_probe ( ctx : context ) ( name : string ) = + (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) + + (** + Create a probe that always evaluates to . *) - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - Array.init n f - - (** Conversion of models to strings. - A string representation of the model. + let const ( ctx : context ) ( v : float ) = + (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by *) - let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by + *) + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by + *) + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by + *) + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by + *) + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + and evaluate to "true". + *) + (* CMW: and is a keyword *) + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + or evaluate to "true". + *) + (* CMW: or is a keyword *) + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". + *) + (* CMW: is not a keyword? *) + let not_ ( ctx : context ) ( p : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) end (** Solvers *) @@ -5032,6 +4928,227 @@ struct let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno end + +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model = +struct + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. + *) + module FuncInterp = + struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + + (** Retrieves the interpretation (the assignment) of in the model. + A function declaration of zero arity + An expression if the function has an interpretation in the model, null otherwise. *) + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null np) then + None + else + Some (create_expr x#gc np) + + (** Retrieves the interpretation (the assignment) of in the model. + A Constant + An expression if the constant has an interpretation in the model, null otherwise. + *) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + (** Retrieves the interpretation (the assignment) of a non-constant in the model. + A function declaration of non-zero arity + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl x#gnc n in + get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in + if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno + + (** The function declarations of the constants in the model. *) + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.init n f + + + (** The number of function interpretations in the model. *) + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno + + (** The function declarations of the function interpretations in the model. *) + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + Array.init n f + + (** All symbols that have an interpretation in the model. *) + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.append (Array.init n_funcs f) (Array.init n_consts g) + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** + Evaluates the expression in the current model. + + + This function may fail if contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + + An expression + + When this flag is enabled, a model value will be assigned to any constant + or function that does not have an interpretation in the model. + + The evaluation of in the model. + *) + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in + if (lbool_of_int r) == L_FALSE then + raise (ModelEvaluationFailedException "evaluation failed") + else + create_expr x#gc v + + (** Alias for eval. *) + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + + + *) + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in + Array.init n f + + + (** The finite set of distinct values that represent the interpretation for sort . + + An uninterpreted sort + An array of expressions, where each is an element of the universe of + *) + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in + Array.init n f + + (** Conversion of models to strings. + A string representation of the model. + *) + let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno +end + (** Fixedpoint solving *) module Fixedpoints = struct @@ -5208,116 +5325,6 @@ struct (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint ctx#gno) end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Probe = -struct - (** - Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - *) - let apply ( x : probe ) (g : goal) = - Z3native.probe_apply x#gnc x#gno g#gno - - (** - The number of supported Probes. - *) - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes ctx#gno - - (** - The names of all supported Probes. - *) - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name ctx#gno i) in - Array.init n f - - (** - Returns a string containing a description of the probe with the given name. - *) - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr ctx#gno name - - (** - Creates a new Probe. - *) - let mk_probe ( ctx : context ) ( name : string ) = - (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) - - (** - Create a probe that always evaluates to . - *) - let const ( ctx : context ) ( v : float ) = - (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by - *) - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by - *) - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by - *) - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by - *) - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by - *) - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". - *) - (* CMW: and is a keyword *) - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". - *) - (* CMW: or is a keyword *) - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". - *) - (* CMW: is not a keyword? *) - let not_ ( ctx : context ) ( p : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) -end - (** Global and context options Note: This module contains functions that set parameters/options for context From bffef2e8083f2d42877a6701923c3792a41c23dd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Dec 2012 15:16:16 +0000 Subject: [PATCH 250/507] New ML API bugfixes and first example. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 122 ++++++++++++++++++++++++++++++++++++++ scripts/update_api.py | 10 +++- src/api/ml/z3.ml | 112 +++++++++++++++++----------------- 3 files changed, 186 insertions(+), 58 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 32c9458f5..945c9a494 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,10 +4,131 @@ *) open Z3 +open Z3.Symbol +open Z3.Sort +open Z3.Expr +open Z3.FuncDecl +open Z3.Goal +open Z3.Tactic +open Z3.Probe +open Z3.Solver open Z3.Arithmetic exception ExampleException of string + +(** + Some basic tests. +*) +let basic_tests ( ctx : context ) = + Printf.printf "BasicTests\n" ; + let qi = (mk_int ctx 1) in + let fname = ((mk_string ctx "f") :> symbol) in + let x = ((mk_string ctx "x") :> symbol) in + let y = ((mk_string ctx "y") :> symbol) in + let bs = (Sort.mk_bool ctx) in + let domain = [| bs; bs |] in + let f = (FuncDecl.mk_func_decl ctx fname domain bs) in + let fapp = (mk_app ctx f + [| (mk_const ctx x bs); (mk_const ctx y bs) |]) in + let fargs2 = [| (mk_fresh_const ctx "cp" bs) |] in + let domain2 = [| bs |] in + let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in + let trivial_eq = (mk_eq ctx fapp fapp) in + let nontrivial_eq = (mk_eq ctx fapp fapp2) in + let g = (mk_goal ctx true false false) in + (Goal.assert_ g [| trivial_eq |]) ; + (Goal.assert_ g [| nontrivial_eq |]) ; + Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; + let solver = (mk_solver ctx None) in + (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; + if (check solver None) != SATISFIABLE then + raise (ExampleException "") + else + Printf.printf "Test passed.\n" ; + () + +(* + ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); + if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) + throw new TestFailedException(); + + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + + g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), + ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + + Goal g2 = ctx.MkGoal(true, true); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + + g2 = ctx.MkGoal(true, true); + g2.Assert(ctx.MkFalse()); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + Goal g3 = ctx.MkGoal(true, true); + Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); + Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); + g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); + g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort))); + BoolExpr constr = ctx.MkEq(xc, yc); + g3.Assert(constr); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + ModelConverterTest(ctx); + + // Real num/den test. + RatNum rn = ctx.MkReal(42, 43); + Expr inum = rn.Numerator; + Expr iden = rn.Denominator; + Console.WriteLine("Numerator: " + inum + " Denominator: " + iden); + if (inum.ToString() != "42" || iden.ToString() != "43") + throw new TestFailedException(); + + if (rn.ToDecimalString(3) != "0.976?") + throw new TestFailedException(); + + BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-234234333")); + BigIntCheck(ctx, ctx.MkReal("234234333/2")); + + + string bn = "1234567890987654321"; + + if (ctx.MkInt(bn).BigInteger.ToString() != bn) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 128).BigInteger.ToString() != bn) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn) + throw new TestFailedException(); + + // Error handling test. + try + { + IntExpr i = ctx.MkInt("1/2"); + throw new TestFailedException(); // unreachable + } + catch (Z3Exception) + { + } + } +*) + + let _ = if not (Log.open_ "z3.log") then raise (ExampleException "Log couldn't be opened.") @@ -27,6 +148,7 @@ let _ = Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); Printf.printf "Disposing...\n"; + basic_tests ctx ; Gc.full_major () ); Printf.printf "Exiting.\n"; diff --git a/scripts/update_api.py b/scripts/update_api.py index acaa9478e..5d95a12f8 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -159,7 +159,7 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I # Mapping to ML types Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', STRING : 'string', STRING_PTR : 'char**', - BOOL : 'int', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } + BOOL : 'bool', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -1109,7 +1109,9 @@ def arrayparams(params): def ml_unwrap(t, ts, s): if t == STRING: return '(' + ts + ') String_val(' + s + ')' - elif t == BOOL or t == INT or t == PRINT_MODE or t == ERROR_CODE: + elif t == BOOL: + return '(' + ts + ') Bool_val(' + s + ')' + elif t == INT or t == PRINT_MODE or t == ERROR_CODE: return '(' + ts + ') Int_val(' + s + ')' elif t == UINT: return '(' + ts + ') Unsigned_int_val(' + s + ')' @@ -1125,7 +1127,9 @@ def ml_unwrap(t, ts, s): def ml_set_wrap(t, d, n): if t == VOID: return d + ' = Val_unit;' - elif t == BOOL or t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: + elif t == BOOL: + return d + ' = Val_bool(' + n + ');' + elif t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: return d + ' = Val_int(' + n + ');' elif t == INT64 or t == UINT64: return d + ' = Val_long(' + n + ');' diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index fee6f9fe0..b4d58711c 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -874,7 +874,7 @@ struct if a#gnc != b#gnc then false else - ((lbool_of_int (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) + (Z3native.is_eq_sort a#gnc a#gno b#gno) (** Returns a unique identifier for the sort. @@ -922,10 +922,10 @@ let create_expr ctx obj = else let s = Z3native.get_sort ctx#gno obj in let sk = (sort_kind_of_int (Z3native.get_sort_kind ctx#gno s)) in - if (lbool_of_int (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then + if (Z3native.is_algebraic_number ctx#gno obj) then (((new algebraic_num ctx)#cnstr_obj obj) :> expr) else - if ((lbool_of_int (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && + if (Z3native.is_numeral_ast ctx#gno obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) @@ -1016,6 +1016,7 @@ struct raise (Z3native.Exception "parameter is not a ratinoal string") else x#rational + end (** Creates a new function declaration. @@ -1058,7 +1059,6 @@ struct let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = (new func_decl ctx)#cnstr_pdr prefix [||] range - end (** Comparison operator. @@ -1071,7 +1071,7 @@ struct if a#gnc == a#gnc then false else - ((lbool_of_int (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) + (Z3native.is_eq_func_decl a#gnc a#gno b#gno) (** A string representations of the function declaration. *) @@ -1202,7 +1202,7 @@ struct @param k An AST @return True if is a key in the map, false otherwise. *) let contains ( m : ast_map ) ( key : ast ) = - (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + (Z3native.ast_map_contains m#gnc m#gno key#gno) (** Finds the value associated with the key . @@ -1313,7 +1313,7 @@ struct if a#gnc == b#gnc then false else - ((lbool_of_int (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) + (Z3native.is_eq_ast a#gnc a#gno b#gno) (** Object Comparison. @@ -1472,13 +1472,13 @@ struct (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast x#gnc x#gno) (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = lbool_of_int (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted x#gnc x#gno (** The Sort of the term. @@ -1489,9 +1489,9 @@ struct Indicates whether the term has Boolean sort. *) let is_bool ( x : expr ) = (AST.is_expr x) && - (lbool_of_int (Z3native.is_eq_sort x#gnc - (Z3native.mk_bool_sort x#gnc) - (Z3native.get_sort x#gnc x#gno))) == L_TRUE + (Z3native.is_eq_sort x#gnc + (Z3native.mk_bool_sort x#gnc) + (Z3native.get_sort x#gnc x#gno)) (** Indicates whether the term represents a constant. @@ -1774,7 +1774,7 @@ struct Indicates whether the quantifier is universal. *) let is_universal ( x : quantifier ) = - lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE + Z3native.is_quantifier_forall x#gnc x#gno (** Indicates whether the quantifier is existential. @@ -1879,7 +1879,7 @@ struct if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) (match patterns with | None -> [||] | Some(x) -> (patternaton x)) @@ -1888,7 +1888,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -1905,7 +1905,7 @@ struct *) let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) @@ -1913,7 +1913,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -1931,7 +1931,7 @@ struct if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) (match patterns with | None -> [||] | Some(x) -> (patternaton x)) @@ -1940,7 +1940,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -1957,7 +1957,7 @@ struct *) let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) @@ -1965,7 +1965,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -2046,7 +2046,7 @@ struct Indicates whether the term is of an array sort. *) let is_array ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (Z3native.is_app x#gnc x#gno) && ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) (** The domain of the array sort. *) @@ -2252,7 +2252,7 @@ struct Indicates whether the term is of an array sort. *) let is_finite_domain ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (Z3native.is_app x#gnc x#gno) && (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) (** @@ -2263,7 +2263,7 @@ struct (** The size of the finite domain sort. *) let get_size (x : finite_domain_sort) = let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v + if r then v else raise (Z3native.Exception "Conversion failed.") end @@ -2274,8 +2274,8 @@ struct Indicates whether the term is of a relation sort. *) let is_relation ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + ((Z3native.is_app x#gnc x#gno) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT)) (** Indicates whether the term is an relation store @@ -2604,7 +2604,7 @@ struct Indicates whether the term is of integer sort. *) let is_int ( x : expr ) = - ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + (Z3native.is_numeral_ast x#gnc x#gno) && ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) (** @@ -2706,12 +2706,13 @@ struct (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number x#gnc x#gno (** Retrieve the int value. *) - let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") + let get_int ( x : int_num ) = + let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if r then v + else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3219,9 +3220,10 @@ struct let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno (** Retrieve the int value. *) - let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") + let get_int ( x : bitvec_num ) = + let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if r then v + else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3613,7 +3615,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3621,7 +3623,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3645,7 +3647,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3669,7 +3671,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -4198,7 +4200,7 @@ end Adds a parameter setting. *) let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) + Z3native.params_set_bool p#gnc p#gno name#gno value (** Adds a parameter setting. @@ -4291,11 +4293,12 @@ struct (* CMW: assert seems to be a keyword. *) let assert_ ( x : goal ) ( constraints : bool_expr array ) = let f e = Z3native.goal_assert x#gnc x#gno e#gno in - Array.map f constraints + ignore (Array.map f constraints) ; + () (** Indicates whether the goal contains `false'. *) let is_inconsistent ( x : goal ) = - (lbool_of_int (Z3native.goal_inconsistent x#gnc x#gno)) == L_TRUE + Z3native.goal_inconsistent x#gnc x#gno (** The depth of the goal. This tracks how many transformations were applied to it. *) @@ -4318,11 +4321,11 @@ struct (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) let is_decided_sat ( x : goal ) = - (lbool_of_int (Z3native.goal_is_decided_sat x#gnc x#gno)) == L_TRUE + Z3native.goal_is_decided_sat x#gnc x#gno (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) let is_decided_unsat ( x : goal ) = - (lbool_of_int (Z3native.goal_is_decided_unsat x#gnc x#gno)) == L_TRUE + Z3native.goal_is_decided_unsat x#gnc x#gno (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = @@ -4357,10 +4360,7 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno - (int_of_lbool (if models then L_TRUE else L_FALSE)) - (int_of_lbool (if unsat_cores then L_TRUE else L_FALSE)) - (int_of_lbool (if proofs then L_TRUE else L_FALSE))) + (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno models unsat_cores proofs) (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno @@ -4729,7 +4729,7 @@ struct let n = (get_size x ) in let f i = ( let k = Z3native.stats_get_key x#gnc x#gno i in - if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then + if (Z3native.stats_is_uint x#gnc x#gno i) then ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) else ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) @@ -4800,7 +4800,8 @@ struct *) let assert_ ( x : solver ) ( constraints : bool_expr array ) = let f e = (Z3native.solver_assert x#gnc x#gno e#gno) in - Array.map f constraints + ignore (Array.map f constraints) ; + () (** The number of assertions in the solver. @@ -5049,7 +5050,7 @@ struct else match sk with | ARRAY_SORT -> - if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then + if not (Z3native.is_as_array x#gnc n) then raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl x#gnc n in @@ -5105,8 +5106,8 @@ struct The evaluation of in the model. *) let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in - if (lbool_of_int r) == L_FALSE then + let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno completion) in + if not r then raise (ModelEvaluationFailedException "evaluation failed") else create_expr x#gc v @@ -5175,7 +5176,8 @@ struct *) let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = let f e = (Z3native.fixedpoint_assert x#gnc x#gno e#gno) in - Array.map f constraints + ignore (Array.map f constraints) ; + () (** Register predicate as recursive relation. @@ -5353,7 +5355,7 @@ struct *) let get_param_value ( ctx : context ) ( id : string ) = let (r, v) = (Z3native.get_param_value ctx#gno id) in - if ((lbool_of_int r) == L_FALSE) then + if not r then None else Some v @@ -5383,7 +5385,7 @@ struct all contexts globally. *) let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages (int_of_lbool (if enabled then L_TRUE else L_FALSE)) + Z3native.toggle_warning_messages enabled end (** Functions for handling SMT and SMT2 expressions and files *) From cef9c2fa6901b549d4459902a07409b35ba59353 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 26 Dec 2012 16:54:45 +0000 Subject: [PATCH 251/507] more ML Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 58 +++++++++++++++++++++------------------ src/api/ml/z3.ml | 4 +++ 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 945c9a494..7fcd2e9f7 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -10,11 +10,12 @@ open Z3.Expr open Z3.FuncDecl open Z3.Goal open Z3.Tactic +open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic -exception ExampleException of string +exception TestFailedException of string (** @@ -43,32 +44,37 @@ let basic_tests ( ctx : context ) = let solver = (mk_solver ctx None) in (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; if (check solver None) != SATISFIABLE then - raise (ExampleException "") + raise (TestFailedException "") else Printf.printf "Test passed.\n" ; - () - -(* - ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); - if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) - throw new TestFailedException(); - - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) - throw new TestFailedException(); - - g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), - ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) - throw new TestFailedException(); - - - Goal g2 = ctx.MkGoal(true, true); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) - throw new TestFailedException(); - + () ; + let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) + (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) + ; + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + let g2 = (mk_goal ctx true true false) in + let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + () +(* g2 = ctx.MkGoal(true, true); g2.Assert(ctx.MkFalse()); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); @@ -131,7 +137,7 @@ let basic_tests ( ctx : context ) = let _ = if not (Log.open_ "z3.log") then - raise (ExampleException "Log couldn't be opened.") + raise (TestFailedException "Log couldn't be opened.") else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b4d58711c..8806a70ee 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -4391,6 +4391,10 @@ struct let n = (get_num_subgoals x) in let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in Array.init n f + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoal ( x : apply_result ) ( i : int ) = + (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) (** Convert a model for the subgoal into a model for the original goal g, that the ApplyResult was obtained from. From 597409c8acbb8df351c50b83f60c893efe033f2f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Dec 2012 15:51:42 +0000 Subject: [PATCH 252/507] ML API bugfixes More ML examples Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 165 ++++++++++++++++++++++++++------------ scripts/mk_util.py | 6 +- src/api/ml/z3.ml | 5 ++ 3 files changed, 124 insertions(+), 52 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 7fcd2e9f7..0e8122ae0 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -17,6 +17,50 @@ open Z3.Arithmetic exception TestFailedException of string +(** + Model Converter test +*) +let model_converter_test ( ctx : context ) = + Printf.printf "ModelConverterTest\n"; + let xr = ((mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_real_sort ctx )) :> arith_expr) in + let yr = ((mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_real_sort ctx )) :> arith_expr) in + let g4 = (mk_goal ctx true false false ) in + (Goal.assert_ g4 [| (mk_gt ctx xr (mk_real_numeral_nd ctx 10 1)) |]) ; + (Goal.assert_ g4 [| (mk_eq ctx yr (mk_add ctx [| xr; (mk_real_numeral_nd ctx 1 1) |] )) |] ) ; + (Goal.assert_ g4 [| (mk_gt ctx yr (mk_real_numeral_nd ctx 1 1)) |]) ; + ( + let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") None) g4 None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ; + let solver = (mk_solver ctx None) in + let f e = (Solver.assert_ solver [| e |]) in + ignore (Array.map f (get_formulas (get_subgoal ar 0))) ; + let q = (check solver None) in + if q != SATISFIABLE then + raise (TestFailedException "") + else + let m = (get_model solver) in + match m with + | None -> raise (TestFailedException "") + | Some (m) -> + Printf.printf "Solver says: %s\n" (string_of_status q) ; + Printf.printf "Model: \n%s\n" (Model.to_string m) ; + Printf.printf "Converted Model: \n%s\n" (Model.to_string (convert_model ar 0 m)) + ) (** Some basic tests. @@ -41,59 +85,78 @@ let basic_tests ( ctx : context ) = (Goal.assert_ g [| trivial_eq |]) ; (Goal.assert_ g [| nontrivial_eq |]) ; Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; - let solver = (mk_solver ctx None) in - (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; - if (check solver None) != SATISFIABLE then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" ; - () ; - let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in - if ((get_num_subgoals ar) == 1 && - ((is_decided_sat (get_subgoal ar 0)) || - (is_decided_unsat (get_subgoal ar 0)))) then + ( + let solver = (mk_solver ctx None) in + (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; + if (check solver None) != SATISFIABLE then raise (TestFailedException "") else - let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_sat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) - (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) - ; - let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - let g2 = (mk_goal ctx true true false) in - let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_sat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - () -(* - g2 = ctx.MkGoal(true, true); - g2.Assert(ctx.MkFalse()); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) - throw new TestFailedException(); - - Goal g3 = ctx.MkGoal(true, true); - Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); - Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); - g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); - g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort))); - BoolExpr constr = ctx.MkEq(xc, yc); - g3.Assert(constr); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) - throw new TestFailedException(); - - ModelConverterTest(ctx); - + Printf.printf "Test passed.\n" + ); + ( + let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) + (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) + ; + ( + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let g2 = (mk_goal ctx true true false) in + let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let g2 = (mk_goal ctx true true false) in + (Goal.assert_ g2 [| (mk_false ctx) |]) ; + let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let g3 = (mk_goal ctx true true false) in + let xc = (mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_int_sort ctx)) in + let yc = (mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_int_sort ctx)) in + (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (mk_int_sort ctx))) |]) ; + (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (mk_int_sort ctx))) |]) ; + let constr = (mk_eq ctx xc yc) in + (Goal.assert_ g3 [| constr |] ) ; + let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ) ; + model_converter_test ctx +(* // Real num/den test. RatNum rn = ctx.MkReal(42, 43); Expr inum = rn.Numerator; diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 9b5ab1a7a..9587951ba 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -353,9 +353,13 @@ def check_ml(): r = exec_cmd([OCAMLC, 'hello.ml']) if r != 0: raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler') + os.remove('hello.cmi') + os.remove('hello.cmo') + os.remove('a.out') r = exec_cmd([OCAMLBUILD]) if r != 0: raise MKException('Failed testing ocamlbuild. Set environment variable OCAMLBUILD with the path to ocamlbuild') + shutil.rmtree('_build') find_ml_lib() def find_ml_lib(): @@ -499,7 +503,7 @@ def display_help(exit_code): if IS_WINDOWS: print(" -n, --nodotnet do not generate Microsoft.Z3.dll make rules.") print(" -j, --java generate Java bindings.") - print(" --ml generate Ocaml bindinds.") + print(" --ml generate OCaml bindings.") print(" --staticlib build Z3 static library.") if not IS_WINDOWS: print(" -g, --gmp use GMP.") diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8806a70ee..c0711b4eb 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -4684,6 +4684,11 @@ module Solver = struct type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + let string_of_status ( s : status) = match s with + | UNSATISFIABLE -> "unsatisfiable" + | SATISFIABLE -> "satisfiable" + | _ -> "unknown" + (** Objects that track statistical information about solvers. *) module Statistics = struct From d0591334a262679f0f9f72541fe2d28c4097a068 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 15:32:25 +0000 Subject: [PATCH 253/507] ML API: made native layer ANSI-C compliant to avoid compilation issues. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 12 ++++++---- scripts/update_api.py | 55 ++++++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 9587951ba..028d6c8d7 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -345,21 +345,20 @@ def check_ml(): t.commit() if is_verbose(): print "Testing %s..." % OCAMLC - r = exec_cmd([OCAMLC, 'hello.ml']) + r = exec_cmd([OCAMLC, '-o', 'a.out', 'hello.ml']) if r != 0: raise MKException('Failed testing ocamlc compiler. Set environment variable OCAMLC with the path to the Ocaml compiler') if is_verbose(): print "Testing %s..." % OCAMLOPT - r = exec_cmd([OCAMLC, 'hello.ml']) + r = exec_cmd([OCAMLC, '-o', 'a.out', 'hello.ml']) if r != 0: raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler') os.remove('hello.cmi') os.remove('hello.cmo') os.remove('a.out') - r = exec_cmd([OCAMLBUILD]) + r = exec_cmd([OCAMLBUILD, '-version']) if r != 0: raise MKException('Failed testing ocamlbuild. Set environment variable OCAMLBUILD with the path to ocamlbuild') - shutil.rmtree('_build') find_ml_lib() def find_ml_lib(): @@ -1350,7 +1349,10 @@ class MLComponent(Component): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + if WINDOWS: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + else: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) out.write('z3.cmxa: %s\n' % libfile) out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('z3.cma: %s\n' % libfile) diff --git a/scripts/update_api.py b/scripts/update_api.py index 5d95a12f8..1986f4a7e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1262,39 +1262,39 @@ def mk_ml(): ml_wrapper.write('#include \n\n') ml_wrapper.write('#define CAMLlocal6(X1,X2,X3,X4,X5,X6) \\\n') ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal1(X6); \n') + ml_wrapper.write(' CAMLlocal1(X6) \n') ml_wrapper.write('#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \\\n') ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal2(X6,X7); \n') + ml_wrapper.write(' CAMLlocal2(X6,X7) \n') ml_wrapper.write('#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal3(X6,X7,X8); \n') + ml_wrapper.write(' CAMLlocal3(X6,X7,X8) \n') ml_wrapper.write('\n') ml_wrapper.write('#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam2(X6,X7); \n') + ml_wrapper.write(' CAMLxparam2(X6,X7) \n') ml_wrapper.write('#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam3(X6,X7,X8); \n') + ml_wrapper.write(' CAMLxparam3(X6,X7,X8) \n') ml_wrapper.write('#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9); \n') + ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9) \n') ml_wrapper.write('#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') - ml_wrapper.write(' CAMLxparam2(X11,X12); \n') + ml_wrapper.write(' CAMLxparam2(X11,X12) \n') ml_wrapper.write('#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') - ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') + ml_wrapper.write(' CAMLxparam3(X11,X12,X13) \n') ml_wrapper.write('\n\n') ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') - ml_wrapper.write(' identifier: (char*) "default handling",\n') - ml_wrapper.write(' finalize: custom_finalize_default,\n') - ml_wrapper.write(' compare: custom_compare_default,\n') - ml_wrapper.write(' hash: custom_hash_default,\n') - ml_wrapper.write(' serialize: custom_serialize_default,\n') - ml_wrapper.write(' deserialize: custom_deserialize_default\n') + ml_wrapper.write(' (char*) "default handling",\n') + ml_wrapper.write(' custom_finalize_default,\n') + ml_wrapper.write(' custom_compare_default,\n') + ml_wrapper.write(' custom_hash_default,\n') + ml_wrapper.write(' custom_serialize_default,\n') + ml_wrapper.write(' custom_deserialize_default\n') ml_wrapper.write('};\n\n') ml_wrapper.write('#ifdef __cplusplus\n') ml_wrapper.write('extern "C" {\n') @@ -1358,7 +1358,10 @@ def mk_ml(): i = i + 1 ml_wrapper.write(');\n') - # preprocess arrays, strings, in/out arguments + if len(ap) != 0: + ml_wrapper.write(' unsigned _i;\n') + + # declare locals, preprocess arrays, strings, in/out arguments i = 0 for param in params: k = param_kind(param) @@ -1372,22 +1375,32 @@ def mk_ml(): elif k == IN_ARRAY or k == INOUT_ARRAY: t = param_type(param) ts = type2str(t) - ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) - ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) _a%s[i] = %s;\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', i)'))) + ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * _a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) elif k == IN: t = param_type(param) ml_wrapper.write(' %s _a%s = %s;\n' % (type2str(t), i, ml_unwrap(t, type2str(t), 'a' + str(i)))) elif k == OUT: ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) elif k == INOUT: - ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) - + ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) + i = i + 1 + + if result != VOID: + ml_wrapper.write(' %s z3_result;\n' % type2str(result)) + + i = 0 + for param in params: + k = param_kind(param) + if k == IN_ARRAY or k == INOUT_ARRAY: + t = param_type(param) + ts = type2str(t) + ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { _a%s[_i] = %s; }\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', _i)'))) i = i + 1 # invoke procedure ml_wrapper.write(' ') if result != VOID: - ml_wrapper.write('%s z3_result = ' % type2str(result)) + ml_wrapper.write('z3_result = ') ml_wrapper.write('%s(' % name) i = 0 first = True @@ -1412,7 +1425,7 @@ def mk_ml(): for p in params: if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) - ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) { value t; %s Store_field(_a%s, i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[i]'), i)) + ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) elif is_out_param(p): ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) i = i + 1 From 297604bee2850a857acd7e0b278fc901165f1a98 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 18:49:19 +0000 Subject: [PATCH 254/507] ML API: linker fix --- scripts/mk_util.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 028d6c8d7..ce4ed7118 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1349,10 +1349,7 @@ class MLComponent(Component): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - if WINDOWS: - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) - else: - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT) -L%s -lcamlrun\n' % (libfile, os.path.join('api', 'ml', 'z3native'), OCAML_LIB)) out.write('z3.cmxa: %s\n' % libfile) out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('z3.cma: %s\n' % libfile) From 35ef2d1c407bf20da54dae59e892776542ba8034 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 18:56:19 +0000 Subject: [PATCH 255/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ce4ed7118..68ede3b81 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1349,7 +1349,10 @@ class MLComponent(Component): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT) -L%s -lcamlrun\n' % (libfile, os.path.join('api', 'ml', 'z3native'), OCAML_LIB)) + if IS_WINDOWS: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + else: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT) -L%s -lcamlrun\n' % (libfile, os.path.join('api', 'ml', 'z3native'), OCAML_LIB)) out.write('z3.cmxa: %s\n' % libfile) out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('z3.cma: %s\n' % libfile) From 7aef3fa5c6eaebb3fe9651b734ee8b7d51f91c76 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 22:44:55 +0000 Subject: [PATCH 256/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 68ede3b81..ae2418be1 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1348,7 +1348,7 @@ class MLComponent(Component): for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I"%s" -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) if IS_WINDOWS: out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) else: From 9eea0f3232dc554c12531c7398581eaad6cec17b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 20:56:49 +0000 Subject: [PATCH 257/507] ML API: build system changes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 65 +++++++++++++++++++++++----------------------- src/api/ml/README | 5 ++++ 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ae2418be1..9edbf2658 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -33,8 +33,7 @@ EXAMP_DEBUG_FLAG='' LDFLAGS=getenv("LDFLAGS", "") JNI_HOME=getenv("JNI_HOME", None) OCAMLC=getenv("OCAMLC", "ocamlc") -OCAMLOPT=getenv("OCAMLC", "ocamlopt") -OCAMLBUILD=getenv("OCAMLBUILD", "ocamlbuild") +OCAMLOPT=getenv("OCAMLOPT", "ocamlopt") OCAML_LIB=getenv("OCAML_LIB", None) CXX_COMPILERS=['g++', 'clang++'] @@ -350,15 +349,12 @@ def check_ml(): raise MKException('Failed testing ocamlc compiler. Set environment variable OCAMLC with the path to the Ocaml compiler') if is_verbose(): print "Testing %s..." % OCAMLOPT - r = exec_cmd([OCAMLC, '-o', 'a.out', 'hello.ml']) + r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml']) if r != 0: raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler') os.remove('hello.cmi') os.remove('hello.cmo') os.remove('a.out') - r = exec_cmd([OCAMLBUILD, '-version']) - if r != 0: - raise MKException('Failed testing ocamlbuild. Set environment variable OCAMLBUILD with the path to ocamlbuild') find_ml_lib() def find_ml_lib(): @@ -520,7 +516,6 @@ def display_help(exit_code): print(" JNI_HOME JNI bindings directory (only relevant if -j or --java option is provided)") print(" OCAMLC Ocaml byte-code compiler (only relevant with --ml)") print(" OCAMLOPT Ocaml native compiler (only relevant with --ml)") - print(" OCAMLBUILD Ocaml build system (only relevant with --ml)") print(" OCAML_LIB Ocaml library directory (only relevant with --ml)") exit(exit_code) @@ -1336,27 +1331,29 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): - deffile = open('%s.mllib' % os.path.join(self.src_dir, "z3"), 'w') + src_dir = self.to_src_dir + sub_dir = os.path.join('api', 'ml') + mk_dir(os.path.join(BUILD_DIR, sub_dir)) + for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): + shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): + shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + out.write('z3.cmxa:') for mlfile in get_ml_files(self.src_dir): - deffile.write('%s\n' % (string.upper(mlfile[0]) + mlfile[1:-3])) - deffile.close() - - bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') - mk_dir(bld_dir) - libfile = '%s$(SO_EXT)' % self.lib_name - out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) + out.write(' %s' % os.path.join(src_dir, mlfile)) + out.write('\n') + out.write('\tpushd %s && %s ' % (sub_dir, OCAMLOPT)) + if DEBUG_MODE: + out.write('-g ') + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cmxa -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) + out.write('z3.cma:') for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I"%s" -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - if IS_WINDOWS: - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) - else: - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT) -L%s -lcamlrun\n' % (libfile, os.path.join('api', 'ml', 'z3native'), OCAML_LIB)) - out.write('z3.cmxa: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) - out.write('z3.cma: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -custom,-cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3native$(OBJ_EXT) z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR)) + out.write('\tpushd %s && %s ' % (sub_dir, OCAMLC)) + if DEBUG_MODE: + out.write('-g ') + out.write('-custom -ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cma -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) out.write('ml: z3.cmxa z3.cma\n') out.write('\n') @@ -1485,7 +1482,10 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') - out.write('\tocamlc -g -o ml_example.byte -I . z3.cma -I api/ml') + out.write('\t%s ' % OCAMLC) + if DEBUG_MODE: + out.write('-g ') + out.write('-custom -o ml_example.byte -I . z3.cma -I api/ml') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -1493,7 +1493,10 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') - out.write('\tocamlopt -g -o ml_example -I . z3.cmxa -I api/ml') + out.write('\t%s ' % OCAMLOPT) + if DEBUG_MODE: + out.write('-g ') + out.write('-o ml_example($EXE_EXT) -I . z3.cmxa -I api/ml') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -1648,10 +1651,9 @@ def mk_config(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) if is_ml_enabled(): - print('Ocaml Compiler: %s' % OCAMLC) - print('Ocaml Native: %s' % OCAMLOPT) - print('Ocamlbuild: %s' % OCAMLBUILD) - print('Ocaml Library: %s' % OCAML_LIB) + print('OCaml Compiler: %s' % OCAMLC) + print('OCaml Native: %s' % OCAMLOPT) + print('OCaml Library: %s' % OCAML_LIB) else: global CXX, CC, GMP, FOCI2, CPPFLAGS, CXXFLAGS, LDFLAGS, EXAMP_DEBUG_FLAG OS_DEFINES = "" @@ -1774,9 +1776,8 @@ def mk_config(): if is_ml_enabled(): print('Ocaml Compiler: %s' % OCAMLC) print('Ocaml Native: %s' % OCAMLOPT) - print('Ocamlbuild: %s' % OCAMLBUILD) print('Ocaml Library: %s' % OCAML_LIB) - + def mk_install(out): out.write('install: ') for c in get_components(): diff --git a/src/api/ml/README b/src/api/ml/README index 925fced59..beee7d864 100644 --- a/src/api/ml/README +++ b/src/api/ml/README @@ -1,3 +1,8 @@ This directory is work in progress. We are currently working on a brand new ML API. + +On Windows, there are no less than four different ports of OCaml. The Z3 build +system assumes that either the win32 or the win64 port is installed. This means +that OCaml will use `cl' as the underlying C compiler and not the cygwin or +mingw compilers. \ No newline at end of file From 9d965b5fec5b4d28c86971d78b3391e39977e143 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 21:02:44 +0000 Subject: [PATCH 258/507] ML API: build system fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 9edbf2658..34a25781a 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -354,7 +354,10 @@ def check_ml(): raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler') os.remove('hello.cmi') os.remove('hello.cmo') + os.remove('hello.cmx') + os.remove('hello.obj') os.remove('a.out') + t.__del__() find_ml_lib() def find_ml_lib(): From b48c4449788a25bd4e14887614569516fae54d18 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 21:22:45 +0000 Subject: [PATCH 259/507] ML API: build system fix --- scripts/mk_util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 34a25781a..c1f899f6d 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -357,7 +357,6 @@ def check_ml(): os.remove('hello.cmx') os.remove('hello.obj') os.remove('a.out') - t.__del__() find_ml_lib() def find_ml_lib(): From 1865ca58c3b2b9dc4a33de0dd6537bdf0e0897e2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 21:34:40 +0000 Subject: [PATCH 260/507] ML API: build system fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c1f899f6d..75e2af52d 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -355,7 +355,6 @@ def check_ml(): os.remove('hello.cmi') os.remove('hello.cmo') os.remove('hello.cmx') - os.remove('hello.obj') os.remove('a.out') find_ml_lib() From be3fb0ef18a95ac75e3595872ab3698f37f93c34 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 10 Jan 2013 17:25:55 +0000 Subject: [PATCH 261/507] ML API: build system fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 75e2af52d..5530a7afd 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1339,23 +1339,26 @@ class MLComponent(Component): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) - out.write('z3.cmxa:') + out.write('libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s api/ml/z3native.c $(CXX_OUTFLAG) api/ml/z3native$(OBJ_EXT)\n' % get_component(API_COMPONENT).to_src_dir) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG) libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('api/ml/z3.cmxa: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) out.write('\n') - out.write('\tpushd %s && %s ' % (sub_dir, OCAMLOPT)) + out.write('\tcd %s && %s ' % (sub_dir, OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cmxa -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) - out.write('z3.cma:') + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cmxa -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) + out.write('api/ml/z3.cma: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\tpushd %s && %s ' % (sub_dir, OCAMLC)) + out.write('\tcd %s && %s ' % (sub_dir, OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-custom -ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cma -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) - out.write('ml: z3.cmxa z3.cma\n') + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cma -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) + out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') def main_component(self): @@ -1479,29 +1482,29 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: z3.cma ') + out.write('ml_example.byte: api/ml/z3.cma ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLC) if DEBUG_MODE: out.write('-g ') - out.write('-custom -o ml_example.byte -I . z3.cma -I api/ml') + out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" z3.cma') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example($EXE_EXT): z3.cmxa ml_example.byte') + out.write('ml_example$(EXE_EXT): api/ml/z3.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: out.write('-g ') - out.write('-o ml_example($EXE_EXT) -I . z3.cmxa -I api/ml') + out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" z3.cmxa') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('_ex_%s: ml_example.byte ml_example($EXE_EXT)\n\n' % self.name) + out.write('_ex_%s: ml_example.byte ml_example$(EXE_EXT)\n\n' % self.name) class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): From 381d552f9676bee85cd22e5cf0aa931066d57ea1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 10 Jan 2013 18:39:43 +0000 Subject: [PATCH 262/507] ML API: build system fixes --- scripts/mk_util.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5530a7afd..554bb4259 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -351,11 +351,11 @@ def check_ml(): print "Testing %s..." % OCAMLOPT r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml']) if r != 0: - raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler') - os.remove('hello.cmi') - os.remove('hello.cmo') - os.remove('hello.cmx') - os.remove('a.out') + raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler. Note that ocamlopt may require flexlink to be in your path.') + rmf('hello.cmi') + rmf('hello.cmo') + rmf('hello.cmx') + rmf('a.out') find_ml_lib() def find_ml_lib(): @@ -1340,8 +1340,8 @@ class MLComponent(Component): for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) out.write('libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s api/ml/z3native.c $(CXX_OUTFLAG) api/ml/z3native$(OBJ_EXT)\n' % get_component(API_COMPONENT).to_src_dir) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG) libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s api/ml/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, get_component(API_COMPONENT).to_src_dir)) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') out.write('api/ml/z3.cmxa: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) From 0e59d056298fc0eadeec20584f3c3d3cb31d5a26 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 11 Jan 2013 14:33:28 +0000 Subject: [PATCH 263/507] ML API: changed context from object to normal type. Removed optional array parameters. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 8 +- src/api/ml/z3.ml | 661 ++++++++++++++++++-------------------- 2 files changed, 323 insertions(+), 346 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 0e8122ae0..129f73d4d 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -38,7 +38,7 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ); ( - let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") None) g4 None) in + let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") [||]) g4 None) in if ((get_num_subgoals ar) == 1 && ((is_decided_sat (get_subgoal ar 0)) || (is_decided_unsat (get_subgoal ar 0)))) then @@ -49,7 +49,7 @@ let model_converter_test ( ctx : context ) = let solver = (mk_solver ctx None) in let f e = (Solver.assert_ solver [| e |]) in ignore (Array.map f (get_formulas (get_subgoal ar 0))) ; - let q = (check solver None) in + let q = (check solver [||]) in if q != SATISFIABLE then raise (TestFailedException "") else @@ -88,7 +88,7 @@ let basic_tests ( ctx : context ) = ( let solver = (mk_solver ctx None) in (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; - if (check solver None) != SATISFIABLE then + if (check solver [||]) != SATISFIABLE then raise (TestFailedException "") else Printf.printf "Test passed.\n" @@ -204,7 +204,7 @@ let _ = else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = (Some [("model", "true"); ("proof", "false")]) in + let cfg = [("model", "true"); ("proof", "false")] in let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in let ss = (Symbol.mk_string ctx "mySymbol") in diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c0711b4eb..c91d909bc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,46 +7,39 @@ open Z3enums +type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } + (**/**) +let context_dispose ctx = + if ctx.m_n_obj_cnt == 0 then ( + (* Printf.printf "Disposing context \n" ; *) + (Z3native.del_context ctx.m_n_ctx) + ) else ( + Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; + (* re-queue for finalization? *) + ) -class context settings = -object (self) - val mutable m_n_ctx : Z3native.z3_context = - let cfg = Z3native.mk_config in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - v - +let context_init settings = + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + (* Printf.printf "Installing finalizer on context \n" ; *) + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> context_dispose o in + Gc.finalise f res; + res (* CMW: Install error handler here! m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. Z3native.set_error_handler(m_ctx, m_n_err_handler); GC.SuppressFinalize(this); *) - val mutable m_obj_cnt : int = 0 - - initializer - (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) - let f = fun o -> o#dispose in - let v = self in - Gc.finalise f v; - - method dispose : unit = - if m_obj_cnt == 0 then ( - (* Printf.printf "Disposing context %d \n" (Oo.id self) ; *) - (Z3native.del_context m_n_ctx) - ) else ( - Printf.printf "NOT DISPOSING context %d because it still has %d objects alive\n" (Oo.id self) m_obj_cnt; - (* re-queue for finalization? *) - ) - - method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 - method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 - method gno = m_n_ctx -end +let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) +let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) +let context_gno ctx = ctx.m_n_ctx (**/**) @@ -70,10 +63,8 @@ the context, e.g., like so: (...) *) -let mk_context ( cfg : ( string * string ) list option ) = - match cfg with - | None -> new context [] - | Some(x) -> new context x +let mk_context ( cfg : ( string * string ) list ) = + context_init cfg (**/**) @@ -85,8 +76,8 @@ object (self) initializer (match m_n_obj with - | Some (x) -> self#incref m_ctx#gno x; - m_ctx#add_one_ctx_obj + | Some (x) -> self#incref (context_gno m_ctx) x; + (context_add1 m_ctx) | None -> () ); (* Printf.printf "Installing finalizer on z3object %d \n" (Oo.id self) ; *) @@ -101,8 +92,8 @@ object (self) (* Printf.printf "Disposing z3object %d \n" (Oo.id self) ; *) (match m_n_obj with | Some (x) -> - self#decref m_ctx#gno x; - m_ctx#sub_one_ctx_obj ; + self#decref (context_gno m_ctx) x; + (context_sub1 m_ctx) ; m_n_obj <- None; | None -> () ); @@ -112,16 +103,16 @@ object (self) | None -> raise (Z3native.Exception "Z3 object lost") method sno (ctx : context) o = - m_ctx#add_one_ctx_obj ; - self#incref ctx#gno o ; + (context_add1 m_ctx) ; + self#incref (context_gno ctx) o ; (match m_n_obj with - | Some(x) -> self#decref ctx#gno x ; m_ctx#sub_one_ctx_obj + | Some(x) -> self#decref (context_gno ctx) x ; (context_sub1 m_ctx) | None -> () ); m_n_obj <- Some o method gc = m_ctx - method gnc = m_ctx#gno + method gnc = (context_gno m_ctx) end @@ -134,37 +125,38 @@ object (self) method decref nc o = Z3native.params_dec_ref nc o end + (** Symbol objects *) -class symbol ctx = +class symbol ctx = object (self) - inherit z3object ctx None as super + inherit z3object ctx None as super method cnstr_obj obj = (self#sno ctx obj) ; self method incref nc o = () method decref nc o = () end +(** Int symbol objects *) +class int_symbol ctx = +object(self) + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol (context_gno ctx) i)) ; self +end + +(** String symbol objects *) +class string_symbol ctx = +object(self) + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol (context_gno ctx) name)) ; self +end + let symbolaton (a : symbol array) = let f (e : symbol) = e#gno in Array.map f a -(** Int symbol objects *) -class int_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol ctx#gno i)) ; self -end - -(** String symbol objects *) -class string_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol ctx#gno name)) ; self -end - let create_symbol ctx no = - match (symbol_kind_of_int (Z3native.get_symbol_kind ctx#gno no)) with + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) @@ -205,7 +197,7 @@ class array_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self + method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort (context_gno ctx) domain#gno range#gno)) ; self end (** Bit-vector sort objects *) @@ -241,7 +233,7 @@ class uninterpreted_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self + method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) s#gno)) ; self end (** Finite domain sort objects *) @@ -249,7 +241,7 @@ class finite_domain_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self + method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) s#gno sz)) ; self end (** Relation sort objects *) @@ -273,7 +265,7 @@ object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = - let (x,_,_) = (Z3native.mk_tuple_sort ctx#gno name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in + let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in (self#sno ctx x) ; self end @@ -284,8 +276,8 @@ class func_decl ctx = object (self) inherit ast ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self - method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (astaton domain) range#gno)) ; self method incref nc o = super#incref nc o method decref nc o = super#decref nc o @@ -341,7 +333,7 @@ object (self) val mutable _testerdecls : func_decl array option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (enum_names : symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in + let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) name#gno (Array.length enum_names) (symbolaton enum_names)) in _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; (self#sno ctx r) ; @@ -368,7 +360,7 @@ object (self) val mutable _taildecl : func_decl option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) name#gno elem_sort#gno) in _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; @@ -426,7 +418,7 @@ object (self) if m_n != (Array.length sort_refs) then raise (Z3native.Exception "Number of field names does not match number of sort refs") else - let o = (Z3native.mk_constructor ctx#gno name#gno recognizer#gno m_n (symbolaton field_names) + let o = (Z3native.mk_constructor (context_gno ctx) name#gno recognizer#gno m_n (symbolaton field_names) (sortaton sorts) sort_refs) in self#sno ctx o ; @@ -473,7 +465,7 @@ object (self) Gc.finalise f v method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ca ( c : constructor array ) = - self#sno ctx (Z3native.mk_constructor_list ctx#gno (Array.length c) (constructoraton c)) ; + self#sno ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (constructoraton c)) ; self end @@ -486,11 +478,11 @@ class datatype_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (constructoraton constructors)))) ; self + method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) name#gno (Array.length constructors) (constructoraton constructors)))) ; self end let create_sort ctx obj = - match (sort_kind_of_int (Z3native.get_sort_kind ctx#gno obj)) with + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) obj)) with | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) @@ -900,7 +892,7 @@ struct Create a new Boolean sort. *) let mk_bool ( ctx : context ) = - (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) + (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort (context_gno ctx)) (** Create a new uninterpreted sort. @@ -917,15 +909,15 @@ end (**/**) let create_expr ctx obj = - if ast_kind_of_int (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then (((new quantifier ctx)#cnstr_obj obj) :> expr) else - let s = Z3native.get_sort ctx#gno obj in - let sk = (sort_kind_of_int (Z3native.get_sort_kind ctx#gno s)) in - if (Z3native.is_algebraic_number ctx#gno obj) then + let s = Z3native.get_sort (context_gno ctx) obj in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) obj) then (((new algebraic_num ctx)#cnstr_obj obj) :> expr) else - if (Z3native.is_numeral_ast ctx#gno obj) && + if (Z3native.is_numeral_ast (context_gno ctx) obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) @@ -943,11 +935,11 @@ let create_expr ctx obj = | _ -> (new expr ctx)#cnstr_obj obj let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = - let o = Z3native.mk_app ctx#gno f#gno (Array.length args) (astaton args) in + let o = Z3native.mk_app (context_gno ctx) f#gno (Array.length args) (astaton args) in create_expr ctx o let create_ast ctx no = - match (ast_kind_of_int (Z3native.get_ast_kind ctx#gno no)) with + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) | SORT_AST -> ((create_sort ctx no) :> ast) @@ -1188,7 +1180,7 @@ struct @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = - (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) + (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno (context_gno to_ctx)) (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = @@ -1337,7 +1329,7 @@ struct if x#gc == to_ctx then x else - (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) + (create_ast to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx))) (** Wraps an AST. @@ -1383,13 +1375,13 @@ struct a string describing all available parameters to Expr.Simplify. *) let get_simplify_help ( ctx : context ) = - Z3native.simplify_get_help ctx#gno + Z3native.simplify_get_help (context_gno ctx) (** Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs ctx#gno) + (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. @@ -1462,7 +1454,7 @@ struct if x#gc == to_ctx then x else - create_expr to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno) + create_expr to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx)) (** Returns a string representation of the expression. @@ -1578,7 +1570,7 @@ struct Creates a new Constant of sort and named . *) let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = - create_expr ctx (Z3native.mk_const ctx#gno name#gno range#gno) + create_expr ctx (Z3native.mk_const (context_gno ctx) name#gno range#gno) (** @@ -1600,7 +1592,7 @@ struct name prefixed with . *) let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort) = - create_expr ctx (Z3native.mk_fresh_const ctx#gno prefix range#gno) + create_expr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix range#gno) (** Create a Boolean constant. @@ -1624,13 +1616,13 @@ struct The true Term. *) let mk_true ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_true ctx#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_true (context_gno ctx)) (** The false Term. *) let mk_false ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_false ctx#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_false (context_gno ctx)) (** Creates a Boolean value. @@ -1642,19 +1634,19 @@ struct Creates the equality = . *) let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq ctx#gno x#gno y#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq (context_gno ctx) x#gno y#gno) (** Creates a distinct term. *) let mk_distinct ( ctx : context ) ( args : expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct ctx#gno (Array.length args) (astaton args)) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct (context_gno ctx) (Array.length args) (astaton args)) (** Mk an expression representing not(a). *) let mk_not ( ctx : context ) ( a : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_not ctx#gno a#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_not (context_gno ctx) a#gno) (** Create an expression representing an if-then-else: ite(t1, t2, t3). @@ -1663,37 +1655,37 @@ struct @param t3 An expression with the same sort as *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create_expr ctx (Z3native.mk_ite ctx#gno t1#gno t2#gno t3#gno) + create_expr ctx (Z3native.mk_ite (context_gno ctx) t1#gno t2#gno t3#gno) (** Create an expression representing t1 iff t2. *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 -> t2. *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 xor t2. *) let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor (context_gno ctx) t1#gno t2#gno) (** Create an expression representing the AND of args *) let mk_and ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_and ctx#gno (Array.length args) (astaton args)) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_and (context_gno ctx) (Array.length args) (astaton args)) (** Create an expression representing the OR of args *) let mk_or ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_or ctx#gno (Array.length args) (astaton args)) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_or (context_gno ctx) (Array.length args) (astaton args)) (** Create a numeral of a given sort. @@ -1702,7 +1694,7 @@ struct @return A Term with value and sort *) let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - create_expr ctx (Z3native.mk_numeral ctx#gno v ty#gno) + create_expr ctx (Z3native.mk_numeral (context_gno ctx) v ty#gno) (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. @@ -1712,7 +1704,7 @@ struct @return A Term with value and type *) let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_int ctx#gno v ty#gno) + create_expr ctx (Z3native.mk_int (context_gno ctx) v ty#gno) end (** Quantifier expressions *) @@ -1845,7 +1837,7 @@ struct @param ty The sort of the variable *) let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) + create_expr ctx (Z3native.mk_bound (context_gno ctx) index ty#gno) (** Create a quantifier pattern. @@ -1854,7 +1846,7 @@ struct if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) + (new pattern ctx)#cnstr_obj (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (astaton terms)) (** Create a universal Quantifier. @@ -1875,27 +1867,24 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno true + else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno true + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) @@ -1903,51 +1892,45 @@ struct (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = - if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno true + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno true + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) body#gno) (** Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno false + else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno false + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) @@ -1955,31 +1938,28 @@ struct (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = - if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno false + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno false + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) body#gno) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -1989,7 +1969,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -2081,7 +2061,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - ((create_expr ctx (Z3native.mk_select ctx#gno a#gno i#gno)) :> array_expr) + ((create_expr ctx (Z3native.mk_select (context_gno ctx) a#gno i#gno)) :> array_expr) (** Array update. @@ -2100,7 +2080,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_store ctx#gno a#gno i#gno v#gno) + (new array_expr ctx)#cnstr_obj (Z3native.mk_store (context_gno ctx) a#gno i#gno v#gno) (** Create a constant array. @@ -2111,7 +2091,7 @@ struct *) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array ctx#gno domain#gno v#gno) + (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array (context_gno ctx) domain#gno v#gno) (** Maps f on the argument arrays. @@ -2124,7 +2104,7 @@ struct *) let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = - ((create_expr ctx (Z3native.mk_map ctx#gno f#gno (Array.length args) (astaton args))) :> array_expr) + ((create_expr ctx (Z3native.mk_map (context_gno ctx) f#gno (Array.length args) (astaton args))) :> array_expr) (** Access the array default value. @@ -2133,7 +2113,7 @@ struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - ((create_expr ctx (Z3native.mk_array_default ctx#gno arg#gno)) :> array_expr) + ((create_expr ctx (Z3native.mk_array_default (context_gno ctx) arg#gno)) :> array_expr) end (** Functions to manipulate Set expressions *) @@ -2174,61 +2154,61 @@ struct Create an empty set. *) let mk_empty ( ctx : context ) ( domain : sort ) = - (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) + (create_expr ctx (Z3native.mk_empty_set (context_gno ctx) domain#gno)) (** Create the full set. *) let mk_full ( ctx : context ) ( domain : sort ) = - create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) + create_expr ctx (Z3native.mk_full_set (context_gno ctx) domain#gno) (** Add an element to the set. *) let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) + create_expr ctx (Z3native.mk_set_add (context_gno ctx) set#gno element#gno) (** Remove an element from a set. *) let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) + create_expr ctx (Z3native.mk_set_del (context_gno ctx) set#gno element#gno) (** Take the union of a list of sets. *) let mk_union ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) + create_expr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (astaton args)) (** Take the intersection of a list of sets. *) let mk_intersection ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) + create_expr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (astaton args)) (** Take the difference between two sets. *) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) + create_expr ctx (Z3native.mk_set_difference (context_gno ctx) arg1#gno arg2#gno) (** Take the complement of a set. *) let mk_complement ( ctx : context ) ( arg : expr ) = - create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) + create_expr ctx (Z3native.mk_set_complement (context_gno ctx) arg#gno) (** Check for set membership. *) let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) + create_expr ctx (Z3native.mk_set_member (context_gno ctx) elem#gno set#gno) (** Check for subsetness of sets. *) let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) + create_expr ctx (Z3native.mk_set_subset (context_gno ctx) arg1#gno arg2#gno) end @@ -2458,7 +2438,7 @@ struct let n = (Array.length names) in let f e = ( (new constructor_list ctx)#cnstr_ca e ) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (symbolaton names) (constructor_listaton cla)) in let g e = ( (new datatype_sort ctx)#cnstr_obj e) in (Array.map g r) @@ -2592,13 +2572,13 @@ struct Create a new integer sort. *) let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) + (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort (context_gno ctx)) (** Create a real sort. *) let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) + (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort (context_gno ctx)) (** Indicates whether the term is of integer sort. @@ -2761,75 +2741,75 @@ struct Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_add ctx#gno (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_mul ctx#gno (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_sub ctx#gno (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - (create_expr ctx (Z3native.mk_unary_minus ctx#gno t#gno) :> arith_expr) + (create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) t#gno) :> arith_expr) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - (create_expr ctx (Z3native.mk_div ctx#gno t1#gno t2#gno) :> arith_expr) + (create_expr ctx (Z3native.mk_div (context_gno ctx) t1#gno t2#gno) :> arith_expr) (** Create an expression representing t1 mod t2. The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_mod ctx#gno t1#gno t2#gno) + (new int_expr ctx)#cnstr_obj (Z3native.mk_mod (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_rem ctx#gno t1#gno t2#gno) + (new int_expr ctx)#cnstr_obj (Z3native.mk_rem (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 ^ t2. *) let mk_Power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (create_expr ctx (Z3native.mk_power ctx#gno t1#gno t2#gno) :> arith_expr) + (create_expr ctx (Z3native.mk_power (context_gno ctx) t1#gno t2#gno) :> arith_expr) (** Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_le ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_le (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge (context_gno ctx) t1#gno t2#gno) (** Coerce an integer to a real. @@ -2842,7 +2822,7 @@ struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real ctx#gno t#gno) + (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real (context_gno ctx) t#gno) (** Coerce a real to an integer. @@ -2852,13 +2832,13 @@ struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int ctx#gno t#gno) + (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int (context_gno ctx) t#gno) (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int ctx#gno t#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int (context_gno ctx) t#gno) (** Return a upper bound for a given real algebraic number. @@ -2898,7 +2878,7 @@ struct raise (Z3native.Exception "Denominator is zero") else - (new rat_num ctx)#cnstr_obj (Z3native.mk_real ctx#gno num den) + (new rat_num ctx)#cnstr_obj (Z3native.mk_real (context_gno ctx) num den) (** Create a real numeral. @@ -2906,7 +2886,7 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_s ( ctx : context ) ( v : string ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_real_sort ctx)#gno) + (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create a real numeral. @@ -2915,14 +2895,14 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_i ( ctx : context ) ( v : int ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_real_sort ctx)#gno) + (new rat_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create an integer numeral. @param v A string representing the Term value in decimal notation. *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_int_sort ctx)#gno) + (new int_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) (** Create an integer numeral. @@ -2930,7 +2910,7 @@ struct @return A Term with value and sort Integer *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_int_sort ctx)#gno) + (new int_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -2944,7 +2924,7 @@ struct Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) + (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. @@ -3245,91 +3225,91 @@ struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) (** Unsigned division. @@ -3341,7 +3321,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) (** Signed division. @@ -3356,7 +3336,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) (** Unsigned remainder. @@ -3366,7 +3346,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) (** Signed remainder. @@ -3378,7 +3358,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) (** Two's complement signed remainder (sign follows divisor). @@ -3387,7 +3367,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) (** Unsigned less-than @@ -3395,7 +3375,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult (context_gno ctx) t1#gno t2#gno) (** Two's complement signed less-than @@ -3403,7 +3383,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt (context_gno ctx) t1#gno t2#gno) (** Unsigned less-than or equal to. @@ -3411,7 +3391,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule (context_gno ctx) t1#gno t2#gno) (** Two's complement signed less-than or equal to. @@ -3419,7 +3399,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle (context_gno ctx) t1#gno t2#gno) (** Unsigned greater than or equal to. @@ -3427,7 +3407,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge (context_gno ctx) t1#gno t2#gno) (** Two's complement signed greater than or equal to. @@ -3435,7 +3415,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge (context_gno ctx) t1#gno t2#gno) (** Unsigned greater-than. @@ -3443,7 +3423,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt (context_gno ctx) t1#gno t2#gno) (** Two's complement signed greater-than. @@ -3451,7 +3431,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt (context_gno ctx) t1#gno t2#gno) (** Bit-vector concatenation. @@ -3462,7 +3442,7 @@ struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat (context_gno ctx) t1#gno t2#gno) (** Bit-vector extraction. @@ -3473,7 +3453,7 @@ struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract ctx#gno high low t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) (** Bit-vector sign extension. @@ -3483,7 +3463,7 @@ struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext (context_gno ctx) i t#gno) (** Bit-vector zero extension. @@ -3494,7 +3474,7 @@ struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext (context_gno ctx) i t#gno) (** Bit-vector repetition. @@ -3502,7 +3482,7 @@ struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat (context_gno ctx) i t#gno) (** Shift left. @@ -3517,7 +3497,7 @@ struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl (context_gno ctx) t1#gno t2#gno) (** Logical shift right @@ -3531,7 +3511,7 @@ struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr (context_gno ctx) t1#gno t2#gno) (** Arithmetic shift right @@ -3547,7 +3527,7 @@ struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr (context_gno ctx) t1#gno t2#gno) (** Rotate Left. @@ -3556,7 +3536,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left (context_gno ctx) i t#gno) (** Rotate Right. @@ -3565,7 +3545,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right (context_gno ctx) i t#gno) (** Rotate Left. @@ -3574,7 +3554,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left (context_gno ctx) t1#gno t2#gno) (** Rotate Right. @@ -3584,7 +3564,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right (context_gno ctx) t1#gno t2#gno) (** Create an bit bit-vector from the integer argument . @@ -3597,7 +3577,7 @@ struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv ctx#gno n t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv (context_gno ctx) n t#gno) (** Create an integer from the bit-vector argument . @@ -3615,7 +3595,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno signed) + (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3623,7 +3603,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno signed) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow (context_gno ctx) t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3631,7 +3611,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow (context_gno ctx) t1#gno t2#gno) (** Create a predicate that checks that the bit-wise subtraction does not overflow. @@ -3639,7 +3619,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow (context_gno ctx) t1#gno t2#gno) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3647,7 +3627,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno signed) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow (context_gno ctx) t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3655,7 +3635,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) t1#gno t2#gno) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3663,7 +3643,7 @@ struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow ctx#gno t#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow (context_gno ctx) t#gno) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3671,7 +3651,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno signed) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow (context_gno ctx) t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3679,7 +3659,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow (context_gno ctx) t1#gno t2#gno) (** Create a bit-vector numeral. @@ -3688,7 +3668,7 @@ struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = - (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_sort ctx size)#gno) + (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) end (** Functions to manipulate proof expressions *) @@ -4248,7 +4228,7 @@ end Creates a new parameter set *) let mk_params ( ctx : context ) = - (new params ctx)#cnstr_obj (Z3native.mk_params ctx#gno) + (new params ctx)#cnstr_obj (Z3native.mk_params (context_gno ctx)) (** A string representation of the parameter set. @@ -4329,7 +4309,7 @@ struct (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = - (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno to_ctx#gno) + (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) let simplify ( x : goal ) ( p : params option ) = @@ -4360,7 +4340,7 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno models unsat_cores proofs) + (new goal ctx)#cnstr_obj (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno @@ -4429,14 +4409,14 @@ end (** The number of supported tactics. *) - let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics ctx#gno + let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) (** The names of all supported tactics. *) let get_tactic_names ( ctx : context ) = let n = (get_num_tactics ctx ) in - let f i = (Z3native.get_tactic_name ctx#gno i) in + let f i = (Z3native.get_tactic_name (context_gno ctx) i) in Array.init n f @@ -4444,39 +4424,34 @@ end Returns a string containing a description of the tactic with the given name. *) let get_tactic_description ( ctx : context ) ( name : string ) = - Z3native.tactic_get_descr ctx#gno name + Z3native.tactic_get_descr (context_gno ctx) name (** Creates a new Tactic. *) let mk_tactic ( ctx : context ) ( name : string ) = - (new tactic ctx)#cnstr_obj (Z3native.mk_tactic ctx#gno name) + (new tactic ctx)#cnstr_obj (Z3native.mk_tactic (context_gno ctx) name) (** Create a tactic that applies to a Goal and then to every subgoal produced by . *) - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array option ) = - match - match ts with - | None -> None - | Some(rts) -> ( - let f p c = (match p with - | None -> (Some c#gno) - | Some(x) -> (Some (Z3native.tactic_and_then ctx#gno c#gno x))) in - Array.fold_left f None rts) - with - | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno t2#gno) + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = + let f p c = (match p with + | None -> (Some c#gno) + | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) c#gno x))) in + match (Array.fold_left f None ts) with + | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno t2#gno) | Some(x) -> - let o = (Z3native.tactic_and_then ctx#gno t2#gno x) in - (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno o) + let o = (Z3native.tactic_and_then (context_gno ctx) t2#gno x) in + (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno o) (** Create a tactic that first applies to a Goal and if it fails then returns the result of applied to the Goal. *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else ctx#gno t1#gno t2#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else (context_gno ctx) t1#gno t2#gno) (** Create a tactic that applies to a goal for milliseconds. @@ -4484,7 +4459,7 @@ end If does not terminate within milliseconds, then it fails. *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for ctx#gno t#gno ms) + (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for (context_gno ctx) t#gno ms) (** Create a tactic that applies to a given goal if the probe @@ -4494,52 +4469,52 @@ end *) (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_when ctx#gno p#gno t#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) p#gno t#gno) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) p#gno t1#gno t2#gno) (** Create a tactic that keeps applying until the goal is not modified anymore or the maximum number of iterations is reached. *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat ctx#gno t#gno max) + (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat (context_gno ctx) t#gno max) (** Create a tactic that just returns the given goal. *) let skip ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_skip ctx#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_skip (context_gno ctx)) (** Create a tactic always fails. *) let fail ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail ctx#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail (context_gno ctx)) (** Create a tactic that fails if the probe evaluates to false. *) let fail_if ( ctx : context ) ( p : probe ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if ctx#gno p#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) p#gno) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) or trivially unsatisfiable (i.e., contains `false'). *) let fail_if_not_decided ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided ctx#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided (context_gno ctx)) (** Create a tactic that applies using the given set of parameters . *) let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params ctx#gno t#gno p#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params (context_gno ctx) t#gno p#gno) (** Create a tactic that applies using the given set of parameters . @@ -4552,21 +4527,21 @@ end Create a tactic that applies the given tactics in parallel. *) let par_or ( ctx : context ) ( t : tactic array ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or ctx#gno (Array.length t) (tacticaton t)) + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (tacticaton t)) (** Create a tactic that applies to a given goal and then to every subgoal produced by . The subgoals are processed in parallel. *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then (context_gno ctx) t1#gno t2#gno) (** Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers, simplifiers and tactics. *) let interrupt ( ctx : context ) = - Z3native.interrupt ctx#gno + Z3native.interrupt (context_gno ctx) end (** Probes @@ -4591,68 +4566,68 @@ struct The number of supported Probes. *) let get_num_probes ( ctx : context ) = - Z3native.get_num_probes ctx#gno + Z3native.get_num_probes (context_gno ctx) (** The names of all supported Probes. *) let get_probe_names ( ctx : context ) = let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name ctx#gno i) in + let f i = (Z3native.get_probe_name (context_gno ctx) i) in Array.init n f (** Returns a string containing a description of the probe with the given name. *) let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr ctx#gno name + Z3native.probe_get_descr (context_gno ctx) name (** Creates a new Probe. *) let mk_probe ( ctx : context ) ( name : string ) = - (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) + (new probe ctx)#cnstr_obj (Z3native.mk_probe (context_gno ctx) name) (** Create a probe that always evaluates to . *) let const ( ctx : context ) ( v : float ) = - (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) + (new probe ctx)#cnstr_obj (Z3native.probe_const (context_gno ctx) v) (** Create a probe that evaluates to "true" when the value returned by is less than the value returned by *) let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_lt (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is greater than the value returned by *) let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_gt (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is less than or equal the value returned by *) let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_le (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is greater than or equal the value returned by *) let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_ge (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is equal to the value returned by *) let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_eq (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value @@ -4660,7 +4635,7 @@ struct *) (* CMW: and is a keyword *) let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_and (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value @@ -4668,7 +4643,7 @@ struct *) (* CMW: or is a keyword *) let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_or (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value @@ -4676,7 +4651,7 @@ struct *) (* CMW: is not a keyword? *) let not_ ( ctx : context ) ( p : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_not (context_gno ctx) p#gno) end (** Solvers *) @@ -4836,11 +4811,12 @@ struct *) - let check ( x : solver ) ( assumptions : bool_expr array option) = + let check ( x : solver ) ( assumptions : bool_expr array) = let r = - match assumptions with - | None -> lbool_of_int (Z3native.solver_check x#gnc x#gno) - | Some (ass) -> lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length ass) (astaton ass)) + if ((Array.length assumptions) == 0) then + lbool_of_int (Z3native.solver_check x#gnc x#gno) + else + lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length assumptions) (astaton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -4907,8 +4883,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : symbol option) = match logic with - | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver ctx#gno) - | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic ctx#gno x#gno) + | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver (context_gno ctx)) + | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic (context_gno ctx) x#gno) (** Creates a new (incremental) solver. @@ -4921,7 +4897,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver ctx#gno) + (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver (context_gno ctx)) (** Creates a solver that is implemented using the given tactic. @@ -4930,7 +4906,7 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : tactic ) = - (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic ctx#gno t#gno) + (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno) (** A string representation of the solver. @@ -5333,7 +5309,7 @@ struct Create a Fixedpoint context. *) let mk_fixedpoint ( ctx : context ) = - (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint ctx#gno) + (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint (context_gno ctx)) end (** Global and context options @@ -5354,7 +5330,7 @@ struct *) let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value ctx#gno id value + Z3native.update_param_value (context_gno ctx) id value (** Get a configuration parameter. @@ -5363,7 +5339,7 @@ struct *) let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value ctx#gno id) in + let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in if not r then None else @@ -5385,7 +5361,7 @@ struct *) let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode ctx#gno (int_of_ast_print_mode value) + Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) (** Enable/disable printing of warning messages to the console. @@ -5412,7 +5388,7 @@ struct @return A string representation of the benchmark. *) let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = - Z3native.benchmark_to_smtlib_string ctx#gno name logic status attributes + Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes (Array.length assumptions) (astaton assumptions) formula#gno @@ -5425,92 +5401,93 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib_string ctx#gno str + Z3native.parse_smtlib_string (context_gno ctx) str cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib_file ctx#gno file_name + Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) + (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas ctx#gno + let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_formula ctx#gno i)) :> bool_expr) in + let f i = ((create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) :> bool_expr) in Array.init n f (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions ctx#gno + let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i)) :> bool_expr ) in + let f i = ((create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) :> bool_expr ) in Array.init n f (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls ctx#gno + let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl ctx#gno i) in + let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts ctx#gno + let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in - let f i = (create_sort ctx (Z3native.get_smtlib_sort ctx#gno i)) in + let f i = (create_sort ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f (** @@ -5519,41 +5496,41 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string ctx#gno str + Z3native.parse_smtlib2_string (context_gno ctx) str cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string ctx#gno file_name + Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) end (* From bbd1e465bb73b3dd8a757142b2c59c42552c2795 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 12 Jan 2013 00:01:50 +0000 Subject: [PATCH 264/507] ML API: bugfixes; starting to replace objects with normal types. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 3 +- scripts/update_api.py | 3 +- src/api/ml/z3.ml | 711 ++++++++++++++++++++------------------ 3 files changed, 382 insertions(+), 335 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 129f73d4d..97985a7bc 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -14,6 +14,7 @@ open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic +open Z3.Fixedpoints exception TestFailedException of string @@ -216,8 +217,8 @@ let _ = Printf.printf "bool sort: %s\n" (Sort.to_string bs); Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); - Printf.printf "Disposing...\n"; basic_tests ctx ; + Printf.printf "Disposing...\n"; Gc.full_major () ); Printf.printf "Exiting.\n"; diff --git a/scripts/update_api.py b/scripts/update_api.py index 1986f4a7e..c730a325e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1300,7 +1300,8 @@ def mk_ml(): ml_wrapper.write('extern "C" {\n') ml_wrapper.write('#endif\n\n') ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') - ml_wrapper.write(' return Val_bool(Data_custom_val(p) == 0);\n') + ml_wrapper.write(' void * t = * (void**) Data_custom_val(p);\n') + ml_wrapper.write(' return Val_bool(t == 0);\n') ml_wrapper.write('}\n\n') ml_wrapper.write('CAMLprim value n_mk_null( void ) {\n') ml_wrapper.write(' CAMLparam0();\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c91d909bc..1e8ffe92e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,9 +7,13 @@ open Z3enums -type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } + +(**/**) + +let null = Z3native.mk_null() +let is_null o = (Z3native.is_null o) -(**/**) let context_dispose ctx = if ctx.m_n_obj_cnt == 0 then ( (* Printf.printf "Disposing context \n" ; *) @@ -19,7 +23,7 @@ let context_dispose ctx = (* re-queue for finalization? *) ) -let context_init settings = +let context_cnstr settings = let cfg = Z3native.mk_config in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; @@ -50,7 +54,7 @@ require one such object, but power users may require more than one. To start usi Z3, do - let ctx = (mk_context None) in + let ctx = (mk_context []) in (...) @@ -58,17 +62,18 @@ where a list of pairs of strings may be passed to set options on the context, e.g., like so: - let cfg = (Some [("model", "true"); ("...", "...")]) in + let cfg = [("model", "true"); ("...", "...")] in let ctx = (mk_context cfg) in (...) *) let mk_context ( cfg : ( string * string ) list ) = - context_init cfg + context_cnstr cfg + + +(* type z3object = { m_ctx : context; m_n_obj : Z3native.ptr option; } *) (**/**) - -(** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) val mutable m_ctx : context = ctx_init @@ -669,15 +674,6 @@ object (self) method decref nc o = Z3native.func_interp_dec_ref nc o end -(** Model objects *) -class model ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.model_inc_ref nc o - method decref nc o = Z3native.model_dec_ref nc o -end - (** Tactic application result objects *) class apply_result ctx = object (self) @@ -724,32 +720,38 @@ object (self) method is_float = m_is_float end -(** Statistics objects *) -class statistics ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.stats_inc_ref nc o - method decref nc o = Z3native.stats_dec_ref nc o -end -(** Solver objects *) -class solver ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.solver_inc_ref nc o - method decref nc o = Z3native.solver_dec_ref nc o -end +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } -(** Fixedpoint objects *) -class fixedpoint ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.fixedpoint_inc_ref nc o - method decref nc o = Z3native.fixedpoint_dec_ref nc o -end +let z3obj_gc o = o.m_ctx +let z3obj_gnc o = (context_gno o.m_ctx) + +let z3obj_gno o = o.m_n_obj +let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + +let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + +let z3obj_cnstr o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o (**/**) @@ -1878,7 +1880,6 @@ struct (astaton names) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -1900,7 +1901,6 @@ struct (Array.length patterns) (patternaton patterns) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -1924,7 +1924,6 @@ struct (astaton names) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -1946,7 +1945,6 @@ struct (Array.length patterns) (patternaton patterns) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -4347,6 +4345,240 @@ struct end +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model = +struct + type model = z3_native_object + + (**/**) + let model_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : model = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.model_inc_ref ; + dec_ref = Z3native.model_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. + *) + module FuncInterp = + struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + + (** Retrieves the interpretation (the assignment) of in the model. + A function declaration of zero arity + An expression if the function has an interpretation in the model, null otherwise. *) + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + if (Z3native.is_null np) then + None + else + Some (create_expr (z3obj_gc x) np) + + (** Retrieves the interpretation (the assignment) of in the model. + A Constant + An expression if the constant has an interpretation in the model, null otherwise. + *) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + (** Retrieves the interpretation (the assignment) of a non-constant in the model. + A function declaration of non-zero arity + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range f#gnc f#gno))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if not (Z3native.is_as_array (z3obj_gnc x) n) then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in + get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in + if (Z3native.is_null n) then None else Some ((new func_interp (z3obj_gc x))#cnstr_obj n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) + + (** The function declarations of the constants in the model. *) + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + + (** The number of function interpretations in the model. *) + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) + + (** The function declarations of the function interpretations in the model. *) + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + (** All symbols that have an interpretation in the model. *) + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + Array.append (Array.init n_funcs f) (Array.init n_consts g) + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** + Evaluates the expression in the current model. + + + This function may fail if contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + + An expression + + When this flag is enabled, a model value will be assigned to any constant + or function that does not have an interpretation in the model. + + The evaluation of in the model. + *) + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) t#gno completion) in + if not r then + raise (ModelEvaluationFailedException "evaluation failed") + else + create_expr (z3obj_gc x) v + + (** Alias for eval. *) + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + + + *) + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (create_sort (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + Array.init n f + + + (** The finite set of distinct values that represent the interpretation for sort . + + An uninterpreted sort + An array of expressions, where each is an element of the universe of + *) + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in + Array.init n f + + (** Conversion of models to strings. + A string representation of the model. + *) + let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) +end + + (** Tactics Tactics are the basic building block for creating custom solvers for specific problem domains. @@ -4380,8 +4612,8 @@ struct goal g, that the ApplyResult was obtained from. #return A model for g *) - let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = - (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + Model.model_cnstr x#gc (Z3native.apply_result_convert_model x#gnc x#gno i (z3obj_gno m)) (** A string representation of the ApplyResult. *) let to_string ( x : apply_result ) = Z3native.apply_result_to_string x#gnc x#gno @@ -4401,11 +4633,6 @@ end | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) - (** creates a solver that is implemented using the given tactic. - *) - let get_solver ( x : tactic ) = - (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) - (** The number of supported tactics. *) @@ -4654,9 +4881,23 @@ struct (new probe ctx)#cnstr_obj (Z3native.probe_not (context_gno ctx) p#gno) end + (** Solvers *) module Solver = struct + type solver = z3_native_object + +(**/**) + let solver_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : solver = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.solver_inc_ref ; + dec_ref = Z3native.solver_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res +(**/**) + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE let string_of_status ( s : status) = match s with @@ -4667,6 +4908,18 @@ struct (** Objects that track statistical information about solvers. *) module Statistics = struct + type statistics = z3_native_object + + (**/**) + let statistics_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : statistics = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.stats_inc_ref ; + dec_ref = Z3native.stats_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) (** Statistical data is organized into pairs of [Key, Entry], where every @@ -4703,20 +4956,20 @@ struct end (** A string representation of the statistical data. *) - let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno + let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) (** The number of statistical data. *) - let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno + let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) (** The data entries. *) let get_entries ( x : statistics ) = let n = (get_size x ) in let f i = ( - let k = Z3native.stats_get_key x#gnc x#gno i in - if (Z3native.stats_is_uint x#gnc x#gno i) then - ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) + let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in + if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then + ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) + ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in Array.init n f @@ -4725,7 +4978,7 @@ struct *) let get_keys ( x : statistics ) = let n = (get_size x) in - let f i = (Z3native.stats_get_key x#gnc x#gno i) in + let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** @@ -4739,51 +4992,51 @@ struct (** A string that describes all available solver parameters. *) - let get_help ( x : solver ) = Z3native.solver_get_help x#gnc x#gno + let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) (** Sets the solver parameters. *) let set_parameters ( x : solver ) ( value : params )= - Z3native.solver_set_params x#gnc x#gno value#gno + Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) value#gno (** Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - (new param_descrs x#gc)#cnstr_obj (Z3native.solver_get_param_descrs x#gnc x#gno) + (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). *) - let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes x#gnc x#gno + let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) (** Creates a backtracking point. *) - let push ( x : solver ) = Z3native.solver_push x#gnc x#gno + let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) (** Backtracks backtracking points. Note that an exception is thrown if is not smaller than NumScopes *) - let pop ( x : solver ) ( n : int ) = Z3native.solver_pop x#gnc x#gno n + let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n (** Resets the Solver. This removes all assertions from the solver. *) - let reset ( x : solver ) = Z3native.solver_reset x#gnc x#gno + let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) (** Assert a constraint (or multiple) into the solver. *) let assert_ ( x : solver ) ( constraints : bool_expr array ) = - let f e = (Z3native.solver_assert x#gnc x#gno e#gno) in + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in ignore (Array.map f constraints) ; () @@ -4791,7 +5044,7 @@ struct The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -4799,9 +5052,9 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = ((new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get a i)#gno) in + let f i = ((new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get a i)#gno) in Array.init n f (** @@ -4814,9 +5067,9 @@ struct let check ( x : solver ) ( assumptions : bool_expr array) = let r = if ((Array.length assumptions) == 0) then - lbool_of_int (Z3native.solver_check x#gnc x#gno) + lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length assumptions) (astaton assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (astaton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -4830,11 +5083,11 @@ struct if its results was not SATISFIABLE, or if model production is not enabled. *) let get_model ( x : solver ) = - let q = Z3native.solver_get_model x#gnc x#gno in + let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then None else - Some ((new model x#gc)#cnstr_obj q) + Some (Model.model_cnstr (z3obj_gc x) q) (** The proof of the last Check. @@ -4843,11 +5096,11 @@ struct if its results was not UNSATISFIABLE, or if proof production is disabled. *) let get_proof ( x : solver ) = - let q = Z3native.solver_get_proof x#gnc x#gno in + let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then None else - Some (create_expr x#gc q) + Some (create_expr (z3obj_gc x) q) (** The unsat core of the last Check. @@ -4857,7 +5110,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_unsat_core x#gnc x#gno) in + let cn = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -4865,14 +5118,14 @@ struct (** A brief justification of why the last call to Check returned UNKNOWN. *) - let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown x#gnc x#gno + let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) (** Solver statistics. *) let get_statistics ( x : solver ) = - (new statistics x#gc)#cnstr_obj (Z3native.solver_get_statistics x#gnc x#gno) + (Statistics.statistics_cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) (** Creates a new (incremental) solver. @@ -4883,8 +5136,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : symbol option) = match logic with - | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver (context_gno ctx)) - | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic (context_gno ctx) x#gno) + | None -> (solver_cnstr ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (solver_cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) (** Creates a new (incremental) solver. @@ -4897,7 +5150,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver (context_gno ctx)) + (solver_cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) (** Creates a solver that is implemented using the given tactic. @@ -4906,261 +5159,54 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : tactic ) = - (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno) + (solver_cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) (** A string representation of the solver. *) - let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno + let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) -module Model = -struct - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. - *) - module FuncInterp = - struct - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) - module FuncEntry = - struct - (** - Return the (symbolic) value of this entry. - *) - let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) - - (** - The number of arguments of the entry. - *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno - - (** - The arguments of the function entry. - *) - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the function entry. - *) - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - (** - The number of entries in the function interpretation. - *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno - - (** - The entries in the function interpretation - *) - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in - Array.init n f - - (** - The (symbolic) `else' value of the function interpretation. - *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) - - (** - The arity of the function interpretation - *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno - - (** - A string representation of the function interpretation. - *) - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (Array.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - (** Retrieves the interpretation (the assignment) of in the model. - A function declaration of zero arity - An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null np) then - None - else - Some (create_expr x#gc np) - - (** Retrieves the interpretation (the assignment) of in the model. - A Constant - An expression if the constant has an interpretation in the model, null otherwise. - *) - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - (** Retrieves the interpretation (the assignment) of a non-constant in the model. - A function declaration of non-zero arity - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if not (Z3native.is_as_array x#gnc n) then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl x#gnc n in - get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in - if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno - - (** The function declarations of the constants in the model. *) - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.init n f - - - (** The number of function interpretations in the model. *) - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno - - (** The function declarations of the function interpretations in the model. *) - let get_func_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - Array.init n f - - (** All symbols that have an interpretation in the model. *) - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.append (Array.init n_funcs f) (Array.init n_consts g) - - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - - (** - Evaluates the expression in the current model. - - - This function may fail if contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - - An expression - - When this flag is enabled, a model value will be assigned to any constant - or function that does not have an interpretation in the model. - - The evaluation of in the model. - *) - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno completion) in - if not r then - raise (ModelEvaluationFailedException "evaluation failed") - else - create_expr x#gc v - - (** Alias for eval. *) - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - (** The number of uninterpreted sorts that the model has an interpretation for. *) - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - - - *) - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in - Array.init n f - - - (** The finite set of distinct values that represent the interpretation for sort . - - An uninterpreted sort - An array of expressions, where each is an element of the universe of - *) - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - Array.init n f - - (** Conversion of models to strings. - A string representation of the model. - *) - let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno -end - (** Fixedpoint solving *) module Fixedpoints = struct + type fixedpoint = z3_native_object + +(**/**) + let fixedpoint_cnstr ( ctx : context ) = + let res : fixedpoint = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.fixedpoint_inc_ref ; + dec_ref = Z3native.fixedpoint_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; + (z3obj_cnstr res) ; + res +(**/**) + (** A string that describes all available fixedpoint solver parameters. *) let get_help ( x : fixedpoint ) = - Z3native.fixedpoint_get_help x#gnc x#gno + Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) (** Sets the fixedpoint solver parameters. *) let set_params ( x : fixedpoint ) ( p : params )= - Z3native.fixedpoint_set_params x#gnc x#gno p#gno + Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) p#gno (** Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - (new param_descrs x#gc)#cnstr_obj (Z3native.fixedpoint_get_param_descrs x#gnc x#gno) + (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. *) let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = - let f e = (Z3native.fixedpoint_assert x#gnc x#gno e#gno) in + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in ignore (Array.map f constraints) ; () @@ -5168,21 +5214,21 @@ struct Register predicate as recursive relation. *) let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation x#gnc x#gno f#gno + Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) f#gno (** Add rule into the fixedpoint solver. *) let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno (Z3native.mk_null()) - | Some(y) -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno y#gno + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno y#gno (** Add table fact to the fixedpoint solver. *) let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = - Z3native.fixedpoint_add_fact x#gnc x#gno pred#gno (Array.length args) args + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) pred#gno (Array.length args) args (** Query the fixedpoint solver. @@ -5191,7 +5237,7 @@ struct The query is unsatisfiable if there are no derivations satisfying the query variables. *) let query ( x : fixedpoint ) ( query : bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query x#gnc x#gno query#gno)) with + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) query#gno)) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5203,7 +5249,7 @@ struct The query is unsatisfiable if there are no derivations satisfying any of the relations. *) let query_r ( x : fixedpoint ) ( relations : func_decl array ) = - match (lbool_of_int (Z3native.fixedpoint_query_relations x#gnc x#gno (Array.length relations) (func_declaton relations))) with + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (func_declaton relations))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5213,7 +5259,7 @@ struct *) let push ( x : fixedpoint ) = - Z3native.fixedpoint_push x#gnc x#gno + Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) (** Backtrack one backtracking point. @@ -5222,94 +5268,93 @@ struct *) let pop ( x : fixedpoint ) = - Z3native.fixedpoint_pop x#gnc x#gno + Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) (** Update named rule into in the fixedpoint solver. *) let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = - Z3native.fixedpoint_update_rule x#gnc x#gno rule#gno name#gno + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno name#gno (** Retrieve satisfying instance or instances of solver, or definitions for the recursive predicates that show unsatisfiability. *) let get_answer ( x : fixedpoint ) = - let q = (Z3native.fixedpoint_get_answer x#gnc x#gno) in + let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in if (Z3native.is_null q) then None else - Some (create_expr x#gc q) + Some (create_expr (z3obj_gc x) q) (** Retrieve explanation why fixedpoint engine returned status Unknown. *) let get_reason_unknown ( x : fixedpoint ) = - Z3native.fixedpoint_get_reason_unknown x#gnc x#gno + Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) (** Retrieve the number of levels explored for a given predicate. *) let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels x#gnc x#gno predicate#gno + Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) predicate#gno (** Retrieve the cover of a predicate. *) let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta x#gnc x#gno level predicate#gno) in + let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level predicate#gno) in if (Z3native.is_null q) then None else - Some (create_expr x#gc q) + Some (create_expr (z3obj_gc x) q) (** Add property about the predicate. The property is added at level. *) let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover x#gnc x#gno level predicate#gno, property#gno + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level predicate#gno property#gno (** Retrieve internal string representation of fixedpoint object. *) - let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string x#gnc x#gno 0 [||] + let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = - Z3native.fixedpoint_set_predicate_representation x#gnc x#gno f#gno (Array.length kinds) (symbolaton kinds) + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (symbolaton kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - Z3native.fixedpoint_to_string x#gnc x#gno (Array.length queries) (astaton queries) + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (astaton queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_rules x#gnc x#gno)) in + let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_assertions x#gnc x#gno)) in + let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Create a Fixedpoint context. *) - let mk_fixedpoint ( ctx : context ) = - (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint (context_gno ctx)) + let mk_fixedpoint ( ctx : context ) = fixedpoint_cnstr ctx end (** Global and context options From bcc0c14233fa0af46e95c945692726218d61eae3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 12 Jan 2013 01:15:23 +0000 Subject: [PATCH 265/507] ML API: moved more objects into normal types. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 1 - src/api/ml/z3.ml | 766 +++++++++++++++++++------------------- 2 files changed, 392 insertions(+), 375 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 97985a7bc..38b5fe642 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -14,7 +14,6 @@ open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic -open Z3.Fixedpoints exception TestFailedException of string diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 1e8ffe92e..545c7c227 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -20,7 +20,7 @@ let context_dispose ctx = (Z3native.del_context ctx.m_n_ctx) ) else ( Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; - (* re-queue for finalization? *) + (* re-queue for finalization? *) ) let context_cnstr settings = @@ -38,7 +38,7 @@ let context_cnstr settings = (* CMW: Install error handler here! m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); + GC.SuppressFinalize(this); *) let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) @@ -49,23 +49,23 @@ let context_gno ctx = ctx.m_n_ctx (** Create a context object. -Most interactions with Z3 are interpreted in some context; many users will only -require one such object, but power users may require more than one. To start using -Z3, do + Most interactions with Z3 are interpreted in some context; many users will only + require one such object, but power users may require more than one. To start using + Z3, do - + let ctx = (mk_context []) in (...) - + -where a list of pairs of strings may be passed to set options on -the context, e.g., like so: + where a list of pairs of strings may be passed to set options on + the context, e.g., like so: - + let cfg = [("model", "true"); ("...", "...")] in let ctx = (mk_context cfg) in (...) - + *) let mk_context ( cfg : ( string * string ) list ) = context_cnstr cfg @@ -656,70 +656,6 @@ let tacticaton (a : tactic array) = let f (e : tactic) = e#gno in Array.map f a -(** Function interpretation entry objects *) -class func_entry ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.func_entry_inc_ref nc o - method decref nc o = Z3native.func_entry_dec_ref nc o -end - -(** Function interpretation objects *) -class func_interp ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.func_interp_inc_ref nc o - method decref nc o = Z3native.func_interp_dec_ref nc o -end - -(** Tactic application result objects *) -class apply_result ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.apply_result_inc_ref nc o - method decref nc o = Z3native.apply_result_dec_ref nc o -end - -(** Probe objects *) -class probe ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.probe_inc_ref nc o - method decref nc o = Z3native.probe_dec_ref nc o -end - -(** Statistical value objects *) -class statistics_entry = -object (self) - val mutable m_key : string = "" - val mutable m_is_int = false - val mutable m_is_float = false - val mutable m_int = 0 - val mutable m_float = 0.0 - - method cnstr_si k v = - m_key <- k; - m_is_int <- true; - m_int <- v; - self - - method cnstr_sd k v = - m_key <- k; - m_is_float <- true; - m_float <- v; - self - - method key = m_key - method int = m_int - method float = m_float - method is_int = m_is_int - method is_float = m_is_float -end - type z3_native_object = { m_ctx : context ; @@ -1012,46 +948,46 @@ struct x#rational end - (** - Creates a new function declaration. - *) - let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name domain range + (** + Creates a new function declaration. + *) + let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name domain range - (** - Creates a new function declaration. - *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = - mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range + (** + Creates a new function declaration. + *) + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = + mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range - (** - Creates a fresh function declaration with a name prefixed with . - - - *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix domain range + (** + Creates a fresh function declaration with a name prefixed with . + + + *) + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix domain range - (** - Creates a new constant function declaration. - *) - let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name [||] range + (** + Creates a new constant function declaration. + *) + let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name [||] range - (** - Creates a new constant function declaration. - *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range + (** + Creates a new constant function declaration. + *) + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range - (** - Creates a fresh constant function declaration with a name prefixed with . - - - *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix [||] range + (** + Creates a fresh constant function declaration with a name prefixed with . + + + *) + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix [||] range (** @@ -1333,31 +1269,31 @@ struct else (create_ast to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx))) -(** - Wraps an AST. + (** + Wraps an AST. - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. -*) + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + *) let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - create_ast ctx ptr + create_ast ctx ptr -(** - Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. -*) + (** + Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + *) let unwrap_ast ( a : ast ) = a#gno end @@ -1373,17 +1309,17 @@ struct | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) -(** - a string describing all available parameters to Expr.Simplify. -*) + (** + a string describing all available parameters to Expr.Simplify. + *) let get_simplify_help ( ctx : context ) = Z3native.simplify_get_help (context_gno ctx) -(** - Retrieves parameter descriptions for simplifier. -*) - let get_simplify_parameter_descrs ( ctx : context ) = - (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) + (** + Retrieves parameter descriptions for simplifier. + *) + let get_simplify_parameter_descrs ( ctx : context ) = + (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. @@ -2691,7 +2627,7 @@ struct let (r, v) = Z3native.get_numeral_int x#gnc x#gno in if r then v else raise (Z3native.Exception "Conversion failed.") - + (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3202,7 +3138,7 @@ struct let (r, v) = Z3native.get_numeral_int x#gnc x#gno in if r then v else raise (Z3native.Exception "Conversion failed.") - + (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -4150,29 +4086,29 @@ end *) module Params = struct -(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) -module ParamDescrs = -struct + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs = + struct - (** Validate a set of parameters. *) - let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - (** Retrieve all names of parameters. *) - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size x#gnc x#gno in - let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in - Array.init n f + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size x#gnc x#gno in + let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - - (** Retrieves a string representation of the ParamDescrs. *) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno -end + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno + end (** Adds a parameter setting. @@ -4353,11 +4289,11 @@ struct type model = z3_native_object (**/**) - let model_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.model_inc_ref ; - dec_ref = Z3native.model_dec_ref } in + m_n_obj = null ; + inc_ref = Z3native.model_inc_ref ; + dec_ref = Z3native.model_dec_ref } in (z3obj_sno res ctx no) ; (z3obj_cnstr res) ; res @@ -4370,6 +4306,18 @@ struct *) module FuncInterp = struct + type func_interp = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_interp = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_interp_inc_ref ; + dec_ref = Z3native.func_interp_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) (** Function interpretations entries @@ -4377,23 +4325,36 @@ struct *) module FuncEntry = struct + type func_entry = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_entry = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_entry_inc_ref ; + dec_ref = Z3native.func_entry_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** Return the (symbolic) value of this entry. *) let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + create_expr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) (** The number of arguments of the entry. *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) (** The arguments of the function entry. *) let get_args ( x : func_entry ) = let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + let f i = (create_expr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4408,25 +4369,25 @@ struct (** The number of entries in the function interpretation. *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) (** The entries in the function interpretation *) let get_entries ( x : func_interp ) = let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + let f i = (FuncEntry.cnstr (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** The (symbolic) `else' value of the function interpretation. *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + let get_else ( x : func_interp ) = create_expr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) (** The arity of the function interpretation *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) (** A string representation of the function interpretation. @@ -4486,7 +4447,7 @@ struct | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in - if (Z3native.is_null n) then None else Some ((new func_interp (z3obj_gc x))#cnstr_obj n) + if (Z3native.is_null n) then None else Some (FuncInterp.cnstr (z3obj_gc x) n) (** The number of constants that have an interpretation in the model. *) let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) @@ -4579,6 +4540,130 @@ struct end +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe = +struct + type probe = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : probe = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.probe_inc_ref ; + dec_ref = Z3native.probe_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** + Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. + *) + let apply ( x : probe ) (g : goal) = + Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) g#gno + + (** + The number of supported Probes. + *) + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes (context_gno ctx) + + (** + The names of all supported Probes. + *) + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name (context_gno ctx) i) in + Array.init n f + + (** + Returns a string containing a description of the probe with the given name. + *) + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr (context_gno ctx) name + + (** + Creates a new Probe. + *) + let mk_probe ( ctx : context ) ( name : string ) = + (cnstr ctx (Z3native.mk_probe (context_gno ctx) name)) + + (** + Create a probe that always evaluates to . + *) + let const ( ctx : context ) ( v : float ) = + (cnstr ctx (Z3native.probe_const (context_gno ctx) v)) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by + *) + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by + *) + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by + *) + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by + *) + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by + *) + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value + and evaluate to "true". + *) + (* CMW: and is a keyword *) + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value + or evaluate to "true". + *) + (* CMW: or is a keyword *) + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". + *) + (* CMW: is not a keyword? *) + let not_ ( ctx : context ) ( p : probe ) = + (cnstr ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) +end + + (** Tactics Tactics are the basic building block for creating custom solvers for specific problem domains. @@ -4588,36 +4673,49 @@ end *) module Tactic = struct -(** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) -module ApplyResult = -struct - (** The number of Subgoals. *) - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals x#gnc x#gno + (** Tactic application results - (** Retrieves the subgoals from the apply_result. *) - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in - Array.init n f - - (** Retrieves the subgoals from the apply_result. *) - let get_subgoal ( x : apply_result ) ( i : int ) = - (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) - - (** Convert a model for the subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g - *) - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.model_cnstr x#gc (Z3native.apply_result_convert_model x#gnc x#gno i (z3obj_gno m)) - - (** A string representation of the ApplyResult. *) - let to_string ( x : apply_result ) = Z3native.apply_result_to_string x#gnc x#gno -end + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) + module ApplyResult = + struct + type apply_result = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : apply_result = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.apply_result_inc_ref ; + dec_ref = Z3native.apply_result_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** The number of Subgoals. *) + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoal ( x : apply_result ) ( i : int ) = + (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + + (** Convert a model for the subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g + *) + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + Model.cnstr (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) + + (** A string representation of the ApplyResult. *) + let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) + end (** A string containing a description of parameters accepted by the tactic. *) let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno @@ -4630,8 +4728,8 @@ end (** Apply the tactic to the goal. *) let apply ( x : tactic ) ( g : goal ) ( p : params option ) = match p with - | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) - | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) + | None -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply x#gnc x#gno g#gno)) + | Some (pn) -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno)) (** The number of supported tactics. @@ -4695,15 +4793,15 @@ end If evaluates to false, then the new tactic behaves like the skip tactic. *) (* CMW: when is a keyword *) - let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) p#gno t#gno) + let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) t#gno) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) - let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) p#gno t1#gno t2#gno) + let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) t1#gno t2#gno) (** Create a tactic that keeps applying until the goal is not @@ -4727,8 +4825,8 @@ end (** Create a tactic that fails if the probe evaluates to false. *) - let fail_if ( ctx : context ) ( p : probe ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) p#gno) + let fail_if ( ctx : context ) ( p : Probe.probe ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) @@ -4771,124 +4869,14 @@ end Z3native.interrupt (context_gno ctx) end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Probe = -struct - (** - Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - *) - let apply ( x : probe ) (g : goal) = - Z3native.probe_apply x#gnc x#gno g#gno - - (** - The number of supported Probes. - *) - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes (context_gno ctx) - - (** - The names of all supported Probes. - *) - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name (context_gno ctx) i) in - Array.init n f - - (** - Returns a string containing a description of the probe with the given name. - *) - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr (context_gno ctx) name - - (** - Creates a new Probe. - *) - let mk_probe ( ctx : context ) ( name : string ) = - (new probe ctx)#cnstr_obj (Z3native.mk_probe (context_gno ctx) name) - - (** - Create a probe that always evaluates to . - *) - let const ( ctx : context ) ( v : float ) = - (new probe ctx)#cnstr_obj (Z3native.probe_const (context_gno ctx) v) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by - *) - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_lt (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by - *) - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_gt (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by - *) - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_le (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by - *) - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_ge (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by - *) - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_eq (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". - *) - (* CMW: and is a keyword *) - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_and (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". - *) - (* CMW: or is a keyword *) - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_or (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". - *) - (* CMW: is not a keyword? *) - let not_ ( ctx : context ) ( p : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_not (context_gno ctx) p#gno) -end - (** Solvers *) module Solver = struct type solver = z3_native_object -(**/**) - let solver_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.solver_inc_ref ; @@ -4896,7 +4884,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_cnstr res) ; res -(**/**) + (**/**) type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE @@ -4911,7 +4899,7 @@ struct type statistics = z3_native_object (**/**) - let statistics_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.stats_inc_ref ; @@ -4919,28 +4907,58 @@ struct (z3obj_sno res ctx no) ; (z3obj_cnstr res) ; res - (**/**) + (**/**) (** - Statistical data is organized into pairs of [Key, Entry], where every - Entry is either a DoubleEntry or a UIntEntry + Statistical data is organized into pairs of \[Key, Entry\], where every + Entry is either a floating point or integer value. + *) module Entry = struct + type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } + + (**/**) + let cnstr_si k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = true ; + m_is_float = false ; + m_int = v ; + m_float = 0.0 + } in + res + + let cnstr_sd k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = false ; + m_is_float = true ; + m_int = 0 ; + m_float = v + } in + res + (**/**) + (** The key of the entry. *) - let get_key (x : statistics_entry) = x#key + let get_key (x : statistics_entry) = x.m_key (** The int-value of the entry. *) - let get_int (x : statistics_entry) = x#int + let get_int (x : statistics_entry) = x.m_int (** The float-value of the entry. *) - let get_float (x : statistics_entry) = x#float + let get_float (x : statistics_entry) = x.m_float (** True if the entry is uint-valued. *) - let is_int (x : statistics_entry) = x#is_int + let is_int (x : statistics_entry) = x.m_is_int (** True if the entry is double-valued. *) - let is_float (x : statistics_entry) = x#is_float + let is_float (x : statistics_entry) = x.m_is_float (** The string representation of the the entry's value. *) let to_string_value (x : statistics_entry) = @@ -4967,9 +4985,9 @@ struct let f i = ( let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in Array.init n f @@ -5087,7 +5105,7 @@ struct if (Z3native.is_null q) then None else - Some (Model.model_cnstr (z3obj_gc x) q) + Some (Model.cnstr (z3obj_gc x) q) (** The proof of the last Check. @@ -5125,7 +5143,7 @@ struct Solver statistics. *) let get_statistics ( x : solver ) = - (Statistics.statistics_cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) + (Statistics.cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) (** Creates a new (incremental) solver. @@ -5136,8 +5154,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : symbol option) = match logic with - | None -> (solver_cnstr ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (solver_cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) + | None -> (cnstr ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) (** Creates a new (incremental) solver. @@ -5150,7 +5168,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (solver_cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) + (cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) (** Creates a solver that is implemented using the given tactic. @@ -5159,7 +5177,7 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : tactic ) = - (solver_cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) + (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) (** A string representation of the solver. @@ -5169,12 +5187,12 @@ end (** Fixedpoint solving *) -module Fixedpoints = +module Fixedpoint = struct type fixedpoint = z3_native_object -(**/**) - let fixedpoint_cnstr ( ctx : context ) = + (**/**) + let cnstr ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.fixedpoint_inc_ref ; @@ -5182,7 +5200,7 @@ struct (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; (z3obj_cnstr res) ; res -(**/**) + (**/**) (** A string that describes all available fixedpoint solver parameters. @@ -5320,7 +5338,7 @@ struct Retrieve internal string representation of fixedpoint object. *) let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - + (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) @@ -5354,7 +5372,7 @@ struct (** Create a Fixedpoint context. *) - let mk_fixedpoint ( ctx : context ) = fixedpoint_cnstr ctx + let mk_fixedpoint ( ctx : context ) = cnstr ctx end (** Global and context options @@ -5365,24 +5383,24 @@ end module Options = struct -(** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - -*) + (** + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + + *) let update_param_value ( ctx : context ) ( id : string) ( value : string )= Z3native.update_param_value (context_gno ctx) id value -(** - Get a configuration parameter. - - Returns None if the parameter value does not exist. - -*) + (** + Get a configuration parameter. + + Returns None if the parameter value does not exist. + + *) let get_param_value ( ctx : context ) ( id : string ) = let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in if not r then @@ -5408,12 +5426,12 @@ struct let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) -(** - Enable/disable printing of warning messages to the console. + (** + Enable/disable printing of warning messages to the console. - Note that this function is static and effects the behaviour of - all contexts globally. -*) + Note that this function is static and effects the behaviour of + all contexts globally. + *) let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled end @@ -5581,17 +5599,17 @@ end (* (** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. *) - public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); + public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); - internal Z3native.error_handler m_n_err_handler = null; + internal Z3native.error_handler m_n_err_handler = null; - internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) + internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. *) From d0fea5e7404c9e99ace0930a80f8f207a67a25af Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 12 Jan 2013 23:18:05 +0000 Subject: [PATCH 266/507] ML API: moved more objects into normal types. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 734 ++++++++++++++++++++++++++--------------------- 1 file changed, 412 insertions(+), 322 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 545c7c227..8c0f24c4b 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,13 +7,30 @@ open Z3enums -type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } - -(**/**) - +(**/**) +(* Some helpers. *) + let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) +let mk_list ( f : int -> 'a ) ( n : int ) = + let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = + if (i >= n) then + tail + else + (mk_list' f (i+1) n ((f i) :: tail)) + in + mk_list' f 0 n [] +(**/**) + + +(**/**) +type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +(**/**) +type context = z3_native_context + +(**/**) + let context_dispose ctx = if ctx.m_n_obj_cnt == 0 then ( (* Printf.printf "Disposing context \n" ; *) @@ -71,8 +88,6 @@ let mk_context ( cfg : ( string * string ) list ) = context_cnstr cfg -(* type z3object = { m_ctx : context; m_n_obj : Z3native.ptr option; } *) - (**/**) class virtual z3object ctx_init obj_init = object (self) @@ -120,17 +135,6 @@ object (self) method gnc = (context_gno m_ctx) end - -(** Parameter set objects *) -class params ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.params_inc_ref nc o - method decref nc o = Z3native.params_dec_ref nc o -end - - (** Symbol objects *) class symbol ctx = object (self) @@ -292,44 +296,6 @@ let func_declaton (a : func_decl array) = let f (e : func_decl) = e#gno in Array.map f a -class parameter = -object (self) - val mutable m_kind : parameter_kind = PARAMETER_INT; - val mutable m_i : int = 0 - val mutable m_d : float = 0.0 - val mutable m_sym : symbol option = None - val mutable m_srt : sort option = None - val mutable m_ast : ast option = None - val mutable m_fd : func_decl option = None - val mutable m_r : string = "" - - method cnstr_int i = m_kind <- PARAMETER_INT; m_i <- i - method cnstr_double d = m_kind <- PARAMETER_DOUBLE; m_d <- d - method cnstr_symbol sym = m_kind <- PARAMETER_SYMBOL; m_sym <- sym - method cnstr_sort srt = m_kind <- PARAMETER_SORT; m_srt <- srt - method cnstr_ast ast = m_kind <- PARAMETER_AST; m_ast <- ast - method cnstr_func_decl fd = m_kind <- PARAMETER_FUNC_DECL; m_fd <- fd - method cnstr_rational r = m_kind <- PARAMETER_RATIONAL; m_r <- r - - method kind = m_kind - method int = m_i - method double = m_d - method symbol = match m_sym with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter symbol") - method sort = match m_srt with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter sort") - method ast = match m_ast with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter ast") - method func_decl = match m_fd with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter func_decl") - method rational = m_r -end - - (** Enum sort objects *) class enum_sort ctx = object (self) @@ -499,26 +465,6 @@ let create_sort ctx obj = | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") -(** AST vector objects *) -class ast_vector ctx = -object (self) - inherit z3object ctx None - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.ast_vector_inc_ref nc o - method decref nc o = Z3native.ast_vector_dec_ref nc o -end - - -(** AST map objects *) -class ast_map ctx = -object (self) - inherit z3object ctx None - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.ast_map_inc_ref nc o - method decref nc o = Z3native.ast_map_dec_ref nc o -end - - (** Expression objects *) class expr ctx = object(self) @@ -625,37 +571,6 @@ let patternaton (a : pattern array) = let f (e : pattern) = e#gno in Array.map f a -(** Parameter description objects *) -class param_descrs ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.param_descrs_inc_ref nc o - method decref nc o = Z3native.param_descrs_dec_ref nc o -end - -(** Goal objects *) -class goal ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.goal_inc_ref nc o - method decref nc o = Z3native.goal_dec_ref nc o -end - -(** Tactic objects *) -class tactic ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.tactic_inc_ref nc o - method decref nc o = Z3native.tactic_dec_ref nc o -end - -let tacticaton (a : tactic array) = - let f (e : tactic) = e#gno in - Array.map f a - type z3_native_object = { m_ctx : context ; @@ -689,6 +604,10 @@ let z3obj_cnstr o = let f = fun o -> (z3obj_dispose o) in Gc.finalise f o +let array_to_native a = + let f e = (z3obj_gno e) in + Array.map f a + (**/**) @@ -890,62 +809,153 @@ let create_ast ctx no = (** Function declarations *) module FuncDecl = struct + (** Parameters of Func_Decls *) module Parameter = struct + type parameter = { + m_kind : parameter_kind ; + m_i : int ; + m_d : float ; + m_sym : symbol option ; + m_srt : sort option ; + m_ast : ast option ; + m_fd : func_decl option ; + m_r : string ; + } + + (**/**) + let cnstr_int i = { + m_kind = PARAMETER_INT ; + m_i = i ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_double d = { + m_kind = PARAMETER_DOUBLE ; + m_i = 0 ; + m_d = d ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_symbol sym = { + m_kind = PARAMETER_SYMBOL ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = sym ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_sort srt = { + m_kind = PARAMETER_SORT ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = srt ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_ast ast = { + m_kind = PARAMETER_AST ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = ast ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_func_decl fd ={ + m_kind = PARAMETER_FUNC_DECL ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = fd ; + m_r = "" ; + } + + let cnstr_rational r = { + m_kind = PARAMETER_RATIONAL ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = r ; + } + (**/**) + (** The kind of the parameter. *) - let get_kind (x : parameter) = x#kind + let get_kind ( x : parameter ) = x.m_kind (**The int value of the parameter.*) - let get_int (x : parameter) = - if (x#kind != PARAMETER_INT) then + let get_int ( x : parameter ) = + if ((get_kind x) != PARAMETER_INT) then raise (Z3native.Exception "parameter is not an int") else - x#int + x.m_i (**The double value of the parameter.*) - let get_double (x : parameter) = - if (x#kind != PARAMETER_DOUBLE) then + let get_double ( x : parameter ) = + if ((get_kind x) != PARAMETER_DOUBLE) then raise (Z3native.Exception "parameter is not a double") else - x#double + x.m_d (**The Symbol value of the parameter.*) - let get_symbol (x : parameter) = - if (x#kind != PARAMETER_SYMBOL) then + let get_symbol ( x : parameter ) = + if ((get_kind x) != PARAMETER_SYMBOL) then raise (Z3native.Exception "parameter is not a symbol") else - x#symbol + x.m_sym (**The Sort value of the parameter.*) - let get_sort (x : parameter) = - if (x#kind != PARAMETER_SORT) then + let get_sort ( x : parameter ) = + if ((get_kind x) != PARAMETER_SORT) then raise (Z3native.Exception "parameter is not a sort") else - x#sort + x.m_srt (**The AST value of the parameter.*) - let get_ast (x : parameter) = - if (x#kind != PARAMETER_AST) then + let get_ast ( x : parameter ) = + if ((get_kind x) != PARAMETER_AST) then raise (Z3native.Exception "parameter is not an ast") else - x#ast + x.m_ast (**The FunctionDeclaration value of the parameter.*) - let get_ast (x : parameter) = - if (x#kind != PARAMETER_FUNC_DECL) then + let get_ast ( x : parameter ) = + if ((get_kind x) != PARAMETER_FUNC_DECL) then raise (Z3native.Exception "parameter is not an function declaration") else - x#func_decl + x.m_fd (**The rational string value of the parameter.*) - let get_rational (x : parameter) = - if (x#kind != PARAMETER_RATIONAL) then + let get_rational ( x : parameter ) = + if ((get_kind x) != PARAMETER_RATIONAL) then raise (Z3native.Exception "parameter is not a ratinoal string") else - x#rational + x.m_r end (** @@ -1051,7 +1061,7 @@ struct The number of parameters of the function declaration *) let get_num_parameters (x : func_decl) = (Z3native.get_decl_num_parameters x#gnc x#gno) - + (** The parameters of the function declaration *) @@ -1059,15 +1069,15 @@ struct let n = (get_num_parameters x) in let f i = ( match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with - | PARAMETER_INT -> (new parameter)#cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) - | PARAMETER_DOUBLE -> (new parameter)#cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) - | PARAMETER_SYMBOL-> (new parameter)#cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) - | PARAMETER_SORT -> (new parameter)#cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) - | PARAMETER_AST -> (new parameter)#cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) - | PARAMETER_FUNC_DECL -> (new parameter)#cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) - | PARAMETER_RATIONAL -> (new parameter)#cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) + | PARAMETER_INT -> Parameter.cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) + | PARAMETER_DOUBLE -> Parameter.cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) + | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) + | PARAMETER_SORT -> Parameter.cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) + | PARAMETER_AST -> Parameter.cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) + | PARAMETER_FUNC_DECL -> Parameter.cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) + | PARAMETER_RATIONAL -> Parameter.cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) ) in - Array.init n f + mk_list f n (** Create expression that applies function to arguments. @@ -1083,9 +1093,22 @@ struct (** Vectors of ASTs *) module ASTVector = struct + type ast_vector = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_vector = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_vector_inc_ref ; + dec_ref = Z3native.ast_vector_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** The size of the vector *) let get_size ( x : ast_vector ) = - Z3native.ast_vector_size x#gnc x#gno + Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) (** Retrieves the i-th object in the vector. @@ -1093,16 +1116,16 @@ struct @return An AST *) let get ( x : ast_vector ) ( i : int ) = - create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) + create_ast (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) (** Sets the i-th object in the vector. *) let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set x#gnc x#gno i value#gno + Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i value#gno (** Resize the vector to . @param newSize The new size of the vector. *) let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize x#gnc x#gno new_size + Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size (** Add the AST to the back of the vector. The size @@ -1110,7 +1133,7 @@ struct @param a An AST *) let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push x#gnc x#gno a#gno + Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) a#gno (** Translates all ASTs in the vector to . @@ -1118,60 +1141,73 @@ struct @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = - (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno (context_gno to_ctx)) + cnstr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string x#gnc x#gno + Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) end (** Map from AST to AST *) module ASTMap = struct + type ast_map = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_map = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_map_inc_ref ; + dec_ref = Z3native.ast_map_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** Checks whether the map contains the key . @param k An AST @return True if is a key in the map, false otherwise. *) - let contains ( m : ast_map ) ( key : ast ) = - (Z3native.ast_map_contains m#gnc m#gno key#gno) + let contains ( x : ast_map ) ( key : ast ) = + (Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) key#gno) (** Finds the value associated with the key . This function signs an error when is not a key in the map. @param k An AST *) - let find ( m : ast_map ) ( key : ast ) = - create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) + let find ( x : ast_map ) ( key : ast ) = + create_ast (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) key#gno) (** Stores or replaces a new key/value pair in the map. @param k The key AST @param v The value AST *) - let insert ( m : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert m#gnc m#gno key#gno value#gno + let insert ( x : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) key#gno value#gno (** Erases the key from the map. @param k An AST *) - let erase ( m : ast_map ) ( key : ast ) = - Z3native.ast_map_erase m#gnc m#gno key#gno + let erase ( x : ast_map ) ( key : ast ) = + Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) key#gno (** Removes all keys from the map. *) - let reset ( m : ast_map ) = - Z3native.ast_map_reset m#gnc m#gno + let reset ( x : ast_map ) = + Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) (** The size of the map *) - let get_size ( m : ast_map ) = - Z3native.ast_map_size m#gnc m#gno + let get_size ( x : ast_map ) = + Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) (** The keys stored in the map. *) - let get_keys ( m : ast_map ) = - (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) + let get_keys ( x : ast_map ) = + ASTVector.cnstr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) - let to_strnig ( m : ast_map ) = - Z3native.ast_map_to_string m#gnc m#gno + let to_string ( x : ast_map ) = + Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) end (** @@ -1297,6 +1333,125 @@ struct let unwrap_ast ( a : ast ) = a#gno end + +(** + Parameter sets (of Solvers, Tactics, ...) + + A Params objects represents a configuration in the form of symbol/value pairs. +*) +module Params = +struct + type params = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : params = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.params_inc_ref ; + dec_ref = Z3native.params_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs = + struct + type param_descrs = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : param_descrs = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.param_descrs_inc_ref ; + dec_ref = Z3native.param_descrs_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params ) = + Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) + + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in + let f i = create_symbol (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) + + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) + end + + (** + Adds a parameter setting. + *) + let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = + Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) name#gno value + + (** + Adds a parameter setting. + *) + let add_int ( x : params ) (name : symbol ) ( value : int ) = + Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) name#gno value + + (** + Adds a parameter setting. + *) + let add_double ( x : params ) ( name : symbol ) ( value : float ) = + Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) name#gno value + + (** + Adds a parameter setting. + *) + let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = + Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) name#gno value#gno + + (** + Adds a parameter setting. + *) + let add_s_bool ( x : params ) ( name : string) ( value : bool ) = + add_bool x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Adds a parameter setting. + *) + let add_s_int ( x : params) ( name : string ) ( value : int ) = + add_int x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Adds a parameter setting. + *) + let add_s_double ( x : params ) ( name : string ) ( value : float ) = + add_double x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Adds a parameter setting. + *) + let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = + add_symbol x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Creates a new parameter set + *) + let mk_params ( ctx : context ) = + cnstr ctx (Z3native.mk_params (context_gno ctx)) + + (** + A string representation of the parameter set. + *) + let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) +end + + (** General expressions (terms), including Boolean logic *) module Expr = struct @@ -1305,9 +1460,9 @@ struct @param p A set of parameters to configure the simplifier *) - let simplify ( x : expr ) ( p : params option ) = match p with + let simplify ( x : expr ) ( p : Params.params option ) = match p with | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) - | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) + | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno (z3obj_gno pp)) (** a string describing all available parameters to Expr.Simplify. @@ -1319,7 +1474,7 @@ struct Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) + Params.ParamDescrs.cnstr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. @@ -4079,96 +4234,6 @@ struct let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end -(** - Parameter sets (of Solvers, Tactics, ...) - - A Params objects represents a configuration in the form of symbol/value pairs. -*) -module Params = -struct - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs = - struct - - (** Validate a set of parameters. *) - let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) - - (** Retrieve all names of parameters. *) - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size x#gnc x#gno in - let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in - Array.init n f - - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - - (** Retrieves a string representation of the ParamDescrs. *) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno - end - - (** - Adds a parameter setting. - *) - let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_int (p : params) (name : symbol) (value : int) = - Z3native.params_set_uint p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_double (p : params) (name : symbol) (value : float) = - Z3native.params_set_double p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_symbol (p : params) (name : symbol) (value : symbol) = - Z3native.params_set_symbol p#gnc p#gno name#gno value#gno - - (** - Adds a parameter setting. - *) - let add_s_bool (p : params) (name : string) (value : bool) = - add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_int (p : params) (name : string) (value : int) = - add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_double (p : params) (name : string) (value : float) = - add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_symbol (p : params) (name : string) (value : symbol) = - add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Creates a new parameter set - *) - let mk_params ( ctx : context ) = - (new params ctx)#cnstr_obj (Z3native.mk_params (context_gno ctx)) - - (** - A string representation of the parameter set. - *) - let to_string (p : params) = Z3native.params_to_string p#gnc p#gno -end (** Goals @@ -4177,6 +4242,18 @@ end tactics and solvers. *) module Goal = struct + type goal = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : goal = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.goal_inc_ref ; + dec_ref = Z3native.goal_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) (** The precision of the goal. @@ -4185,7 +4262,7 @@ struct An over approximation is applied when the objective is to find a proof for a given goal. *) let get_precision ( x : goal ) = - goal_prec_of_int (Z3native.goal_precision x#gnc x#gno) + goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) (** Indicates whether the goal is precise. *) let is_precise ( x : goal ) = @@ -4206,62 +4283,62 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) let assert_ ( x : goal ) ( constraints : bool_expr array ) = - let f e = Z3native.goal_assert x#gnc x#gno e#gno in + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) e#gno in ignore (Array.map f constraints) ; () (** Indicates whether the goal contains `false'. *) let is_inconsistent ( x : goal ) = - Z3native.goal_inconsistent x#gnc x#gno + Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) (** The depth of the goal. This tracks how many transformations were applied to it. *) - let get_depth ( x : goal ) = Z3native.goal_depth x#gnc x#gno + let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) (** Erases all formulas from the given goal. *) - let reset ( x : goal ) = Z3native.goal_reset x#gnc x#gno + let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) (** The number of formulas in the goal. *) - let get_size ( x : goal ) = Z3native.goal_size x#gnc x#gno + let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (new bool_expr x#gc)#cnstr_obj (Z3native.goal_formula x#gnc x#gno i) in + let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) - let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs x#gnc x#gno + let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) let is_decided_sat ( x : goal ) = - Z3native.goal_is_decided_sat x#gnc x#gno + Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) let is_decided_unsat ( x : goal ) = - Z3native.goal_is_decided_unsat x#gnc x#gno + Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = - (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno (context_gno to_ctx)) + cnstr to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - let simplify ( x : goal ) ( p : params option ) = - let tn = Z3native.mk_tactic x#gnc "simplify" in - Z3native.tactic_inc_ref x#gnc tn ; + let simplify ( x : goal ) ( p : Params.params option ) = + let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in + Z3native.tactic_inc_ref (z3obj_gnc x) tn ; let arn = match p with - | None -> Z3native.tactic_apply x#gnc tn x#gno - | Some(pn) -> Z3native.tactic_apply_ex x#gnc tn x#gno pn#gno + | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) + | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) in - Z3native.apply_result_inc_ref x#gnc arn ; - let sg = Z3native.apply_result_get_num_subgoals x#gnc arn in + Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; + let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in let res = if sg == 0 then raise (Z3native.Exception "No subgoals") else - Z3native.apply_result_get_subgoal x#gnc arn 0 in - Z3native.apply_result_dec_ref x#gnc arn ; - Z3native.tactic_dec_ref x#gnc tn ; - (new goal x#gc)#cnstr_obj res + Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in + Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; + Z3native.tactic_dec_ref (z3obj_gnc x) tn ; + cnstr (z3obj_gc x) res (** @@ -4274,10 +4351,10 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - (new goal ctx)#cnstr_obj (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) + cnstr ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) (** A string representation of the Goal. *) - let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno + let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) end @@ -4326,7 +4403,7 @@ struct module FuncEntry = struct type func_entry = z3_native_object - + (**/**) let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; @@ -4528,7 +4605,7 @@ struct An array of expressions, where each is an element of the universe of *) let sort_universe ( x : model ) ( s : sort ) = - let n_univ = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in + let n_univ = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f @@ -4568,8 +4645,8 @@ struct A probe always produce a double value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let apply ( x : probe ) (g : goal) = - Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) g#gno + let apply ( x : probe ) (g : Goal.goal) = + Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (** The number of supported Probes. @@ -4673,6 +4750,19 @@ end *) module Tactic = struct + type tactic = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : tactic = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.tactic_inc_ref ; + dec_ref = Z3native.tactic_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** Tactic application results ApplyResult objects represent the result of an application of a @@ -4699,12 +4789,12 @@ struct (** Retrieves the subgoals from the apply_result. *) let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in - let f i = (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** Retrieves the subgoals from the apply_result. *) let get_subgoal ( x : apply_result ) ( i : int ) = - (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) (** Convert a model for the subgoal into a model for the original goal g, that the ApplyResult was obtained from. @@ -4718,18 +4808,17 @@ struct end (** A string containing a description of parameters accepted by the tactic. *) - let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno - + let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = - (new param_descrs x#gc)#cnstr_obj (Z3native.tactic_get_param_descrs x#gnc x#gno) + Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) - let apply ( x : tactic ) ( g : goal ) ( p : params option ) = + let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with - | None -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply x#gnc x#gno g#gno)) - | Some (pn) -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno)) + | None -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) + | Some (pn) -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) (** The number of supported tactics. @@ -4755,7 +4844,7 @@ struct Creates a new Tactic. *) let mk_tactic ( ctx : context ) ( name : string ) = - (new tactic ctx)#cnstr_obj (Z3native.mk_tactic (context_gno ctx) name) + cnstr ctx (Z3native.mk_tactic (context_gno ctx) name) (** Create a tactic that applies to a Goal and @@ -4763,20 +4852,21 @@ struct *) let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = let f p c = (match p with - | None -> (Some c#gno) - | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) c#gno x))) in + | None -> (Some (z3obj_gno c)) + | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in match (Array.fold_left f None ts) with - | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno t2#gno) + | None -> + cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) | Some(x) -> - let o = (Z3native.tactic_and_then (context_gno ctx) t2#gno x) in - (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno o) + let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in + cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) (** Create a tactic that first applies to a Goal and if it fails then returns the result of applied to the Goal. *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else (context_gno ctx) t1#gno t2#gno) + cnstr ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that applies to a goal for milliseconds. @@ -4784,7 +4874,7 @@ struct If does not terminate within milliseconds, then it fails. *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for (context_gno ctx) t#gno ms) + cnstr ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) (** Create a tactic that applies to a given goal if the probe @@ -4794,72 +4884,72 @@ struct *) (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) t#gno) + cnstr ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) t1#gno t2#gno) + cnstr ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that keeps applying until the goal is not modified anymore or the maximum number of iterations is reached. *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat (context_gno ctx) t#gno max) + cnstr ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) (** Create a tactic that just returns the given goal. *) let skip ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_skip (context_gno ctx)) + cnstr ctx (Z3native.tactic_skip (context_gno ctx)) (** Create a tactic always fails. *) let fail ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail (context_gno ctx)) + cnstr ctx (Z3native.tactic_fail (context_gno ctx)) (** Create a tactic that fails if the probe evaluates to false. *) let fail_if ( ctx : context ) ( p : Probe.probe ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) + cnstr ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) or trivially unsatisfiable (i.e., contains `false'). *) let fail_if_not_decided ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided (context_gno ctx)) + cnstr ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) (** Create a tactic that applies using the given set of parameters . *) - let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params (context_gno ctx) t#gno p#gno) + let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + cnstr ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . Alias for UsingParams*) (* CMW: with is a keyword *) - let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = + let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p (** Create a tactic that applies the given tactics in parallel. *) let par_or ( ctx : context ) ( t : tactic array ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (tacticaton t)) + cnstr ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) (** Create a tactic that applies to a given goal and then to every subgoal produced by . The subgoals are processed in parallel. *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then (context_gno ctx) t1#gno t2#gno) + cnstr ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Interrupt the execution of a Z3 procedure. @@ -5015,14 +5105,14 @@ struct (** Sets the solver parameters. *) - let set_parameters ( x : solver ) ( value : params )= - Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) value#gno + let set_parameters ( x : solver ) ( p : Params.params )= + Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). @@ -5062,7 +5152,7 @@ struct The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -5070,7 +5160,7 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = ((new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get a i)#gno) in Array.init n f @@ -5128,7 +5218,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -5176,8 +5266,8 @@ struct The solver supports the commands Push and Pop, but it will always solve each check from scratch. *) - let mk_solver_t ( ctx : context ) ( t : tactic ) = - (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) + let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = + (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** A string representation of the solver. @@ -5211,14 +5301,14 @@ struct (** Sets the fixedpoint solver parameters. *) - let set_params ( x : fixedpoint ) ( p : params )= - Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) p#gno + let set_params ( x : fixedpoint ) ( p : Params.params )= + Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. @@ -5355,7 +5445,7 @@ struct Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f @@ -5364,7 +5454,7 @@ struct Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f From 69138924e5fd834f2890dceea371e503215ae3f7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 13 Jan 2013 00:02:38 +0000 Subject: [PATCH 267/507] ML API: Symbols are now normal types with visible hierarchy. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 468 ++++++++++++++++++++++++----------------------- 1 file changed, 241 insertions(+), 227 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8c0f24c4b..378988d59 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -135,39 +135,145 @@ object (self) method gnc = (context_gno m_ctx) end -(** Symbol objects *) -class symbol ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = () - method decref nc o = () -end -(** Int symbol objects *) -class int_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol (context_gno ctx) i)) ; self -end -(** String symbol objects *) -class string_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol (context_gno ctx) name)) ; self -end +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } -let symbolaton (a : symbol array) = - let f (e : symbol) = e#gno in +let z3obj_gc o = o.m_ctx +let z3obj_gnc o = (context_gno o.m_ctx) + +let z3obj_gno o = o.m_n_obj +let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + +let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + +let z3obj_cnstr o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o + +let z3obj_nil_ref x y = () + +let array_to_native a = + let f e = (z3obj_gno e) in Array.map f a +(**/**) -let create_symbol ctx no = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) - | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) + +(** Symbols are used to name several term and type constructors *) +module Symbol = +struct + (** Int symbol objects *) + type int_symbol = z3_native_object + + (** String symbol objects *) + and string_symbol = z3_native_object + + and symbol = + | IntSymbol of int_symbol + | StringSymbol of string_symbol + + (**/**) + let cnstr_i ( ctx : context ) ( no : Z3native.ptr ) = + let res : int_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + let cnstr_s ( ctx : context ) ( no : Z3native.ptr ) = + let res : string_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + + let gnc ( x : symbol ) = + match x with + | IntSymbol(n) -> (z3obj_gnc n) + | StringSymbol(n) -> (z3obj_gnc n) + + let gno ( x : symbol ) = + match x with + | IntSymbol(n) -> (z3obj_gno n) + | StringSymbol(n) -> (z3obj_gno n) + + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with + | INT_SYMBOL -> IntSymbol (cnstr_i ctx no) + | STRING_SYMBOL -> StringSymbol (cnstr_s ctx no) + + let aton a = + let f e = (gno e) in + Array.map f a + (**/**) + + (** The kind of the symbol (int or string) *) + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) + + (** Indicates whether the symbol is of Int kind *) + let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL + + (** Indicates whether the symbol is of string kind. *) + let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL + + (** The int value of the symbol. *) + let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) + + (** The string value of the symbol. *) + let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) + + (** A string representation of the symbol. *) + let to_string ( o : symbol ) = + match (kind o) with + | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) + | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) + + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) + let mk_int ( ctx : context ) ( i : int ) = + IntSymbol (cnstr_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + + (** Creates a new symbol using a string. *) + let mk_string ( ctx : context ) ( s : string ) = + StringSymbol (cnstr_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + + (** Create an array of symbols. *) + let mk_ints ( ctx : context ) ( names : int array ) = + let f elem = mk_int ( ctx : context ) elem in + (Array.map f names) + + (** Create an array of symbols. *) + let mk_strings ( ctx : context ) ( names : string array ) = + let f elem = mk_string ( ctx : context ) elem in + (Array.map f names) +end + +(**/**) (** AST objects *) class ast ctx = @@ -242,7 +348,7 @@ class uninterpreted_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) s#gno)) ; self + method cnstr_s (s : Symbol.symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; self end (** Finite domain sort objects *) @@ -250,7 +356,7 @@ class finite_domain_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) s#gno sz)) ; self + method cnstr_si (s : Symbol.symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno s) sz)) ; self end (** Relation sort objects *) @@ -273,8 +379,8 @@ class tuple_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = - let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in + method cnstr_siss (name : Symbol.symbol) (num_fields: int) (field_names : Symbol.symbol array) (field_sorts : sort array) = + let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) num_fields (Symbol.aton field_names) (astaton field_sorts)) in (self#sno ctx x) ; self end @@ -285,7 +391,7 @@ class func_decl ctx = object (self) inherit ast ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_ndr (name : Symbol.symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (astaton domain) range#gno)) ; self method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (astaton domain) range#gno)) ; self method incref nc o = super#incref nc o @@ -303,8 +409,8 @@ object (self) val mutable _constdecls : func_decl array option = None val mutable _testerdecls : func_decl array option = None method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (enum_names : symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) name#gno (Array.length enum_names) (symbolaton enum_names)) in + method cnstr_ss (name : Symbol.symbol) (enum_names : Symbol.symbol array) = + let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; (self#sno ctx r) ; @@ -330,8 +436,8 @@ object (self) val mutable _headdecl : func_decl option = None val mutable _taildecl : func_decl option = None method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) name#gno elem_sort#gno) in + method cnstr_ss (name : Symbol.symbol) (elem_sort : sort) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) elem_sort#gno) in _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; @@ -381,7 +487,7 @@ object (self) let v = self in Gc.finalise f v - method cnstr_ssssi (name : symbol) (recognizer : symbol) (field_names : symbol array) (sorts : sort array) (sort_refs : int array) = + method cnstr_ssssi (name : Symbol.symbol) (recognizer : Symbol.symbol) (field_names : Symbol.symbol array) (sorts : sort array) (sort_refs : int array) = m_n <- (Array.length field_names) ; if m_n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -389,7 +495,7 @@ object (self) if m_n != (Array.length sort_refs) then raise (Z3native.Exception "Number of field names does not match number of sort refs") else - let o = (Z3native.mk_constructor (context_gno ctx) name#gno recognizer#gno m_n (symbolaton field_names) + let o = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) m_n (Symbol.aton field_names) (sortaton sorts) sort_refs) in self#sno ctx o ; @@ -449,7 +555,7 @@ class datatype_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) name#gno (Array.length constructors) (constructoraton constructors)))) ; self + method cnstr_sc (name : Symbol.symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (constructoraton constructors)))) ; self end let create_sort ctx obj = @@ -571,43 +677,6 @@ let patternaton (a : pattern array) = let f (e : pattern) = e#gno in Array.map f a - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - -let z3obj_gc o = o.m_ctx -let z3obj_gnc o = (context_gno o.m_ctx) - -let z3obj_gno o = o.m_n_obj -let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - -let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - -let z3obj_cnstr o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - -let array_to_native a = - let f e = (z3obj_gno e) in - Array.map f a - (**/**) @@ -656,58 +725,6 @@ struct string_of_int rev ^ "." end -(** Symbols are used to name several term and type constructors *) -module Symbol = -struct - (** The kind of the symbol (int or string) *) - let kind (o : symbol) = (symbol_kind_of_int (Z3native.get_symbol_kind o#gnc o#gno)) - - (** Indicates whether the symbol is of Int kind *) - let is_int_symbol (o : symbol) = (kind o) == INT_SYMBOL - - (** Indicates whether the symbol is of string kind. *) - let is_string_symbol (o : symbol) = (kind o) == STRING_SYMBOL - - (** The int value of the symbol. *) - let get_int (o : int_symbol) = Z3native.get_symbol_int o#gnc o#gno - - (** The string value of the symbol. *) - let get_string (o : string_symbol) = Z3native.get_symbol_string o#gnc o#gno - - (** A string representation of the symbol. *) - let to_string (o : symbol) = - match (kind o) with - | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int o#gnc o#gno)) - | STRING_SYMBOL -> (Z3native.get_symbol_string o#gnc o#gno) - - (** - Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) - let mk_int ( ctx : context ) i = - (new int_symbol ctx)#cnstr_int i - - (** Creates a new symbol using a string. *) - let mk_string ( ctx : context ) s = - (new string_symbol ctx)#cnstr_string s - - (** - Create an array of symbols. - *) - let mk_ints ( ctx : context ) ( names : int array ) = - let f elem = mk_int ( ctx : context ) elem in - (Array.map f names) - - (** - Create an array of symbols. - *) - let mk_strings ( ctx : context ) ( names : string array ) = - let f elem = mk_string ( ctx : context ) elem in - (Array.map f names) -end - (** The Sort module implements type information for ASTs *) module Sort = @@ -738,7 +755,7 @@ struct (** The name of the sort *) - let get_name (x : sort) = (create_symbol x#gc (Z3native.get_sort_name x#gnc x#gno)) + let get_name (x : sort) = (Symbol.create x#gc (Z3native.get_sort_name x#gnc x#gno)) (** A string representation of the sort. @@ -754,14 +771,14 @@ struct (** Create a new uninterpreted sort. *) - let mk_uninterpreted ( ctx : context ) (s : symbol) = + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = (new uninterpreted_sort ctx)#cnstr_s s (** Create a new uninterpreted sort. *) - let mk_uninterpreted_s ( ctx : context ) (s : string) = - mk_uninterpreted ctx ((Symbol.mk_string ( ctx : context ) s) :> symbol) + let mk_uninterpreted_s ( ctx : context ) ( s : string ) = + mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) end (**/**) @@ -817,7 +834,7 @@ struct m_kind : parameter_kind ; m_i : int ; m_d : float ; - m_sym : symbol option ; + m_sym : Symbol.symbol option ; m_srt : sort option ; m_ast : ast option ; m_fd : func_decl option ; @@ -961,14 +978,14 @@ struct (** Creates a new function declaration. *) - let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort) = (new func_decl ctx)#cnstr_ndr name domain range (** Creates a new function declaration. *) let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = - mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range + mk_func_decl ctx (Symbol.mk_string ctx name) domain range (** Creates a fresh function declaration with a name prefixed with . @@ -981,7 +998,7 @@ struct (** Creates a new constant function declaration. *) - let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort) = (new func_decl ctx)#cnstr_ndr name [||] range @@ -989,7 +1006,7 @@ struct Creates a new constant function declaration. *) let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range + (new func_decl ctx)#cnstr_ndr (Symbol.mk_string ctx name) [||] range (** Creates a fresh constant function declaration with a name prefixed with . @@ -1055,7 +1072,7 @@ struct (** The name of the function declaration *) - let get_name (x : func_decl) = (create_symbol x#gc (Z3native.get_decl_name x#gnc x#gno)) + let get_name (x : func_decl) = (Symbol.create x#gc (Z3native.get_decl_name x#gnc x#gno)) (** The number of parameters of the function declaration @@ -1071,7 +1088,7 @@ struct match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with | PARAMETER_INT -> Parameter.cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) | PARAMETER_DOUBLE -> Parameter.cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) - | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) + | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (Symbol.create x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) | PARAMETER_SORT -> Parameter.cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) | PARAMETER_AST -> Parameter.cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) | PARAMETER_FUNC_DECL -> Parameter.cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) @@ -1375,13 +1392,13 @@ struct Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) name#gno)) + let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) (** Retrieve all names of parameters. *) let get_names ( x : param_descrs ) = let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in - let f i = create_symbol (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The size of the ParamDescrs. *) @@ -1394,50 +1411,50 @@ struct (** Adds a parameter setting. *) - let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = - Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) name#gno value + let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = + Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_int ( x : params ) (name : symbol ) ( value : int ) = - Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) name#gno value + let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = + Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_double ( x : params ) ( name : symbol ) ( value : float ) = - Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) name#gno value + let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = - Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) name#gno value#gno + let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = + Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) (** Adds a parameter setting. *) - let add_s_bool ( x : params ) ( name : string) ( value : bool ) = - add_bool x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = + add_bool x (Symbol.mk_string (z3obj_gc x) name) value (** Adds a parameter setting. *) let add_s_int ( x : params) ( name : string ) ( value : int ) = - add_int x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + add_int x (Symbol.mk_string (z3obj_gc x) name) value (** Adds a parameter setting. *) let add_s_double ( x : params ) ( name : string ) ( value : float ) = - add_double x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + add_double x (Symbol.mk_string (z3obj_gc x) name) value (** Adds a parameter setting. *) - let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = - add_symbol x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = + add_symbol x (Symbol.mk_string (z3obj_gc x) name) value (** Creates a new parameter set @@ -1662,15 +1679,15 @@ struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = - create_expr ctx (Z3native.mk_const (context_gno ctx) name#gno range#gno) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + create_expr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) range#gno) (** Creates a new Constant of sort and named . *) let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx ((Symbol.mk_string ctx name) :> symbol) range + mk_const ctx (Symbol.mk_string ctx name)range (** @@ -1690,14 +1707,14 @@ struct (** Create a Boolean constant. *) - let mk_bool_const ( ctx : context ) ( name : symbol ) = + let mk_bool_const ( ctx : context ) ( name : Symbol.symbol ) = ((mk_const ctx name (Sort.mk_bool ctx)) :> bool_expr) (** Create a Boolean constant. *) let mk_bool_const_s ( ctx : context ) ( name : string ) = - mk_bool_const ctx ((Symbol.mk_string ctx name) :> symbol) + mk_bool_const ctx (Symbol.mk_string ctx name) (** Create a new function application. @@ -1907,7 +1924,7 @@ struct *) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + let f i = (Symbol.create x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in Array.init n f (** @@ -1960,7 +1977,7 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -1968,23 +1985,23 @@ struct (match weight with | None -> 1 | Some(x) -> x) (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) @@ -1994,8 +2011,8 @@ struct else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expraton bound_constants) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) @@ -2004,7 +2021,7 @@ struct Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -2012,23 +2029,23 @@ struct (match weight with | None -> 1 | Some(x) -> x) (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) @@ -2038,8 +2055,8 @@ struct else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expraton bound_constants) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) @@ -2048,7 +2065,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -2058,7 +2075,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -2128,14 +2145,14 @@ struct (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = ((Expr.mk_const ctx name ((mk_sort ctx domain range) :> sort)) :> array_expr) (** Create an array constant. *) let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = - mk_const ctx ((Symbol.mk_string ctx name) :> symbol) domain range + mk_const ctx (Symbol.mk_string ctx name) domain range (** Array read. @@ -2307,14 +2324,14 @@ struct (** Create a new finite domain sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) size = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) size = (new finite_domain_sort ctx)#cnstr_si name size (** Create a new finite domain sort. *) let mk_sort_s ( ctx : context ) ( name : string ) size = - (new finite_domain_sort ctx)#cnstr_si ((Symbol.mk_string ctx name) :> symbol) size + (new finite_domain_sort ctx)#cnstr_si (Symbol.mk_string ctx name) size (** @@ -2488,7 +2505,7 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array) = (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs @@ -2502,32 +2519,32 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - mk_constructor ctx ((Symbol.mk_string ctx name) :> symbol) recognizer field_names sorts sort_refs + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : constructor array) = (new datatype_sort ctx)#cnstr_sc name constructors (** Create a new datatype sort. *) let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = - mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) constructors + mk_sort ctx (Symbol.mk_string ctx name) constructors (** Create mutually recursive datatypes. @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : constructor array array ) = let n = (Array.length names) in let f e = ( (new constructor_list ctx)#cnstr_ca e ) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (symbolaton names) (constructor_listaton cla)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (constructor_listaton cla)) in let g e = ( (new datatype_sort ctx)#cnstr_obj e) in (Array.map g r) @@ -2535,7 +2552,7 @@ struct let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = mk_sorts ctx ( - let f e = ((Symbol.mk_string ctx e) :> symbol) in + let f e = (Symbol.mk_string ctx e) in Array.map f names ) c @@ -2581,10 +2598,8 @@ struct *) let mk_sort_s ( ctx : context ) name enum_names = (new enum_sort ctx)#cnstr_ss - ((Symbol.mk_string ( ctx : context ) name) :> symbol) - (let f e = (e :> symbol) in - (Array.map f (Symbol.mk_strings ( ctx : context ) enum_names)) - ) + (Symbol.mk_string ctx name) + (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) let get_const_decls (x : enum_sort) = x#const_decls @@ -2599,15 +2614,14 @@ struct (** Create a new list sort. *) - let mk_sort ( ctx : context ) (name : symbol) elem_sort = + let mk_sort ( ctx : context ) (name : Symbol.symbol) elem_sort = (new list_sort ctx)#cnstr_ss name elem_sort (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = - mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) elem_sort - + mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) let get_nil_decl (x : list_sort) = x#nil_decl @@ -2805,26 +2819,26 @@ struct (** Creates an integer constant. *) - let mk_int_const ( ctx : context ) ( name : symbol ) = + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = ((Expr.mk_const ctx name (mk_int_sort ctx)) :> int_expr) (** Creates an integer constant. *) let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx ((Symbol.mk_string ctx name) :> symbol) + mk_int_const ctx (Symbol.mk_string ctx name) (** Creates a real constant. *) - let mk_real_const ( ctx : context ) ( name : symbol ) = + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = ((Expr.mk_const ctx name (mk_real_sort ctx)) :> real_expr) (** Creates a real constant. *) let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx ((Symbol.mk_string ctx name) :> symbol) + mk_real_const ctx (Symbol.mk_string ctx name) (** Create an expression representing t[0] + t[1] + .... @@ -3300,14 +3314,14 @@ struct (** Creates a bit-vector constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = ((Expr.mk_const ctx name (mk_sort ctx size)) :> bitvec_expr) (** Creates a bit-vector constant. *) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_const ctx ((Symbol.mk_string ctx name) :> symbol) size + mk_const ctx (Symbol.mk_string ctx name) size (** Bitwise negation. @@ -5242,17 +5256,17 @@ struct check-sat command, and check-sat commands that take more than a given number of milliseconds to be solved. *) - let mk_solver ( ctx : context ) ( logic : symbol option) = + let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with | None -> (cnstr ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) + | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) (** Creates a new (incremental) solver. *) let mk_solver_s ( ctx : context ) ( logic : string ) = - mk_solver ctx (Some ((Symbol.mk_string ctx logic) :> symbol)) + mk_solver ctx (Some (Symbol.mk_string ctx logic)) (** Creates a new (incremental) solver. @@ -5327,10 +5341,10 @@ struct (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol option ) = match name with | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno y#gno + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno y) (** Add table fact to the fixedpoint solver. @@ -5381,8 +5395,8 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno name#gno + let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno name) (** Retrieve satisfying instance or instances of solver, @@ -5432,8 +5446,8 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (symbolaton kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (Symbol.aton kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. @@ -5554,7 +5568,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5564,17 +5578,17 @@ struct else Z3native.parse_smtlib_string (context_gno ctx) str cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5584,10 +5598,10 @@ struct else Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) (** @@ -5649,7 +5663,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5659,17 +5673,17 @@ struct else Z3native.parse_smtlib2_string (context_gno ctx) str cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5679,10 +5693,10 @@ struct else Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) end From 048e8c1a978101cb54654f95a92e30479015e1d8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Jan 2013 11:37:39 +0000 Subject: [PATCH 268/507] ML API: updated example Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 38b5fe642..3b13a2462 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -22,8 +22,8 @@ exception TestFailedException of string *) let model_converter_test ( ctx : context ) = Printf.printf "ModelConverterTest\n"; - let xr = ((mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_real_sort ctx )) :> arith_expr) in - let yr = ((mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_real_sort ctx )) :> arith_expr) in + let xr = ((mk_const ctx (Symbol.mk_string ctx "x") (mk_real_sort ctx )) :> arith_expr) in + let yr = ((mk_const ctx (Symbol.mk_string ctx "y") (mk_real_sort ctx )) :> arith_expr) in let g4 = (mk_goal ctx true false false ) in (Goal.assert_ g4 [| (mk_gt ctx xr (mk_real_numeral_nd ctx 10 1)) |]) ; (Goal.assert_ g4 [| (mk_eq ctx yr (mk_add ctx [| xr; (mk_real_numeral_nd ctx 1 1) |] )) |] ) ; @@ -68,9 +68,9 @@ let model_converter_test ( ctx : context ) = let basic_tests ( ctx : context ) = Printf.printf "BasicTests\n" ; let qi = (mk_int ctx 1) in - let fname = ((mk_string ctx "f") :> symbol) in - let x = ((mk_string ctx "x") :> symbol) in - let y = ((mk_string ctx "y") :> symbol) in + let fname = (mk_string ctx "f") in + let x = (mk_string ctx "x") in + let y = (mk_string ctx "y") in let bs = (Sort.mk_bool ctx) in let domain = [| bs; bs |] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in @@ -142,8 +142,8 @@ let basic_tests ( ctx : context ) = ); ( let g3 = (mk_goal ctx true true false) in - let xc = (mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_int_sort ctx)) in - let yc = (mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_int_sort ctx)) in + let xc = (mk_const ctx (Symbol.mk_string ctx "x") (mk_int_sort ctx)) in + let yc = (mk_const ctx (Symbol.mk_string ctx "y") (mk_int_sort ctx)) in (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (mk_int_sort ctx))) |]) ; (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (mk_int_sort ctx))) |]) ; let constr = (mk_eq ctx xc yc) in @@ -211,8 +211,8 @@ let _ = let bs = (Sort.mk_bool ctx) in let ints = (mk_int_sort ctx) in let rs = (mk_real_sort ctx) in - Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); - Printf.printf "string symbol: %s\n" (Symbol.to_string (ss :> symbol)); + Printf.printf "int symbol: %s\n" (Symbol.to_string is); + Printf.printf "string symbol: %s\n" (Symbol.to_string ss); Printf.printf "bool sort: %s\n" (Sort.to_string bs); Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); From 7befc262d13c02fe736fa49bf87dac2a777e84e2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Jan 2013 17:51:16 +0000 Subject: [PATCH 269/507] ML API: added functions for global parameter management. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 378988d59..0dfb173c4 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -5700,6 +5700,53 @@ struct (func_declaton decls) end + +(* Global functions *) + +(** + * Set a global (or module) parameter, which is shared by all Z3 contexts. + * + * When a Z3 module is initialized it will use the value of these parameters + * when Z3_params objects are not provided. + * The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + * The character '.' is a delimiter (more later). + * The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + * Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + * This function can be used to set parameters for a specific Z3 module. + * This can be done by using .. + * For example: + * (set_global_param "pp.decimal" "true") + * will set the parameter "decimal" in the module "pp" to true. +*) +let set_global_param ( id : string ) ( value : string ) = + (Z3native.global_param_set id value) + +(** + * Get a global (or module) parameter. + * + * Returns None if the parameter does not exist. + * The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + * This function cannot be invoked simultaneously from different threads without synchronization. + * The result string stored in param_value is stored in a shared location. +*) +let get_global_param ( id : string ) = + let (r, v) = (Z3native.global_param_get id) in + if not r then + None + else + Some v + +(** + * Restore the value of all global (and module) parameters. + * + * This command will not affect already created objects (such as tactics and solvers) + * +*) +let global_param_reset_all = + Z3native.global_param_reset_all + + + (* (** From 1eae7a6bacb962d7ad109f73e0c778255f6d48cb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Jan 2013 19:47:51 +0000 Subject: [PATCH 270/507] ML API: Added Solver.assert_and_track Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0dfb173c4..f5c3e3d82 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -5159,8 +5159,42 @@ struct *) let assert_ ( x : solver ) ( constraints : bool_expr array ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in - ignore (Array.map f constraints) ; - () + ignore (Array.map f constraints) + + (** + * Assert multiple constraints (cs) into the solver, and track them (in the + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using + * and the Boolean literals + * provided using with assumptions. + *) + let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = + if ((Array.length cs) != (Array.length ps)) then + raise (Z3native.Exception "Argument size mismatch") + else + let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) e#gno (Array.get ps i)#gno) in + ignore (Array.iteri f cs) + + (** + * Assert a constraint (c) into the solver, and track it (in the unsat) core + * using the Boolean constant p. + * + * This API is an alternative to with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using + * and the Boolean literals + * provided using with assumptions. + *) + let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) c#gno p#gno (** The number of assertions in the solver. From 49cd4e2d3542f00e5be5f6bdafe0a4b5daa9fc00 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 31 Jan 2013 12:51:31 +0000 Subject: [PATCH 271/507] ML build Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 554bb4259..bea2939b6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1335,29 +1335,30 @@ class MLComponent(Component): src_dir = self.to_src_dir sub_dir = os.path.join('api', 'ml') mk_dir(os.path.join(BUILD_DIR, sub_dir)) + api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) - out.write('libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s api/ml/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, get_component(API_COMPONENT).to_src_dir)) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') - out.write('api/ml/z3.cmxa: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, src_dir)) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) out.write('\n') - out.write('\tcd %s && %s ' % (sub_dir, OCAMLOPT)) + out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cmxa -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) - out.write('api/ml/z3.cma: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) + out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\tcd %s && %s ' % (sub_dir, OCAMLC)) + out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cma -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') From 7b51dc9bdd06e54b65229bdee9914367b665b23b Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 4 Feb 2013 21:18:25 +0000 Subject: [PATCH 272/507] Checkpoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2989 ++++++++++++++++++++++++---------------------- 1 file changed, 1544 insertions(+), 1445 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index f5c3e3d82..0e47912ae 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,6 +7,51 @@ open Z3enums +(** Interaction logging for Z3 + + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log = +struct + (** Open an interaction log file. + @param filename the name of the file to open. + @return True if opening the log file succeeds, false otherwise. + *) + (* CMW: "open" seems to be a reserved keyword? *) + let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) + + (** Closes the interaction log. *) + let close = Z3native.close_log + + (** Appends a user-provided string to the interaction log. + @param s the string to append*) + let append s = Z3native.append_log s +end + +(** Version information *) +module Version = +struct + (** The major version. *) + let major = let (x, _, _, _) = Z3native.get_version in x + + (** The minor version. *) + let minor = let (_, x, _, _) = Z3native.get_version in x + + (** The build version. *) + let build = let (_, _, x, _) = Z3native.get_version in x + + (** The revision. *) + let revision = let (_, _, _, x) = Z3native.get_version in x + + (** A string representation of the version information. *) + let to_string = + let (mj, mn, bld, rev) = Z3native.get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + (**/**) (* Some helpers. *) @@ -40,7 +85,7 @@ let context_dispose ctx = (* re-queue for finalization? *) ) -let context_cnstr settings = +let context_create settings = let cfg = Z3native.mk_config in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; @@ -85,7 +130,7 @@ let context_gno ctx = ctx.m_n_ctx *) let mk_context ( cfg : ( string * string ) list ) = - context_cnstr cfg + context_create cfg (**/**) @@ -165,7 +210,7 @@ let z3obj_dispose o = ) ; o.m_n_obj <- null -let z3obj_cnstr o = +let z3obj_create o = let f = fun o -> (z3obj_dispose o) in Gc.finalise f o @@ -184,44 +229,51 @@ struct type int_symbol = z3_native_object (** String symbol objects *) - and string_symbol = z3_native_object + type string_symbol = z3_native_object - and symbol = - | IntSymbol of int_symbol - | StringSymbol of string_symbol + (** Symbol Objects *) + type symbol = + | S_Int of int_symbol + | S_Str of string_symbol (**/**) - let cnstr_i ( ctx : context ) ( no : Z3native.ptr ) = + let create_i ( ctx : context ) ( no : Z3native.ptr ) = let res : int_symbol = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res - let cnstr_s ( ctx : context ) ( no : Z3native.ptr ) = + + let create_s ( ctx : context ) ( no : Z3native.ptr ) = let res : string_symbol = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res + + let gc ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gc n) + | S_Str(n) -> (z3obj_gc n) let gnc ( x : symbol ) = match x with - | IntSymbol(n) -> (z3obj_gnc n) - | StringSymbol(n) -> (z3obj_gnc n) + | S_Int(n) -> (z3obj_gnc n) + | S_Str(n) -> (z3obj_gnc n) let gno ( x : symbol ) = match x with - | IntSymbol(n) -> (z3obj_gno n) - | StringSymbol(n) -> (z3obj_gno n) + | S_Int(n) -> (z3obj_gno n) + | S_Str(n) -> (z3obj_gno n) let create ( ctx : context ) ( no : Z3native.ptr ) = match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> IntSymbol (cnstr_i ctx no) - | STRING_SYMBOL -> StringSymbol (cnstr_s ctx no) + | INT_SYMBOL -> S_Int (create_i ctx no) + | STRING_SYMBOL -> S_Str (create_s ctx no) let aton a = let f e = (gno e) in @@ -256,11 +308,11 @@ struct The legal range of unsigned integers is 0 to 2^30-1. *) let mk_int ( ctx : context ) ( i : int ) = - IntSymbol (cnstr_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) (** Creates a new symbol using a string. *) let mk_string ( ctx : context ) ( s : string ) = - StringSymbol (cnstr_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) (** Create an array of symbols. *) let mk_ints ( ctx : context ) ( names : int array ) = @@ -273,853 +325,47 @@ struct (Array.map f names) end -(**/**) - -(** AST objects *) -class ast ctx = -object (self) - inherit z3object ctx None as super (* CMW: derive from icomparable? *) - method cnstr_obj obj = (self#sno ctx obj) ; self - - method incref nc o = Z3native.inc_ref nc o - method decref nc o = Z3native.dec_ref nc o -end - -let astaton (a : ast array) = - let f (e : ast) = e#gno in - Array.map f a - -(** Sort objects *) -class sort ctx = -object (self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -let sortaton (a : sort array) = - let f (e : sort) = e#gno in - Array.map f a - -(** Arithmetic sort objects, i.e., Int or Real. *) -class arith_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Array sorts objects *) -class array_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort (context_gno ctx) domain#gno range#gno)) ; self -end - -(** Bit-vector sort objects *) -class bitvec_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Boolean sort objects *) -class bool_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Int sort objects *) -class int_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Real sort objects *) -class real_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Uninterpreted sort objects *) -class uninterpreted_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : Symbol.symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; self -end - -(** Finite domain sort objects *) -class finite_domain_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_si (s : Symbol.symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno s) sz)) ; self -end - -(** Relation sort objects *) -class relation_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Set sort objects *) -class set_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : sort) = (self#sno ctx s#gno) ; self -end - -(** Tuple sort objects *) -class tuple_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_siss (name : Symbol.symbol) (num_fields: int) (field_names : Symbol.symbol array) (field_sorts : sort array) = - let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) num_fields (Symbol.aton field_names) (astaton field_sorts)) in - (self#sno ctx x) ; - self -end - - -(** Function declaration objects *) -class func_decl ctx = -object (self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ndr (name : Symbol.symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (astaton domain) range#gno)) ; self - method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (astaton domain) range#gno)) ; self - - method incref nc o = super#incref nc o - method decref nc o = super#decref nc o -end - -let func_declaton (a : func_decl array) = - let f (e : func_decl) = e#gno in - Array.map f a - -(** Enum sort objects *) -class enum_sort ctx = -object (self) - inherit sort ctx as super - val mutable _constdecls : func_decl array option = None - val mutable _testerdecls : func_decl array option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : Symbol.symbol) (enum_names : Symbol.symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in - _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; - _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; - (self#sno ctx r) ; - self - - method const_decls = match _constdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing const decls") - - method tester_decls = match _testerdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tester decls") -end - -(** List sort objects *) -class list_sort ctx = -object (self) - inherit sort ctx as super - val mutable _nildecl : func_decl option = None - val mutable _is_nildecl : func_decl option = None - val mutable _consdecl : func_decl option = None - val mutable _is_consdecl : func_decl option = None - val mutable _headdecl : func_decl option = None - val mutable _taildecl : func_decl option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : Symbol.symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) elem_sort#gno) in - _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; - _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; - _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; - _is_consdecl <- Some ((new func_decl ctx)#cnstr_obj d) ; - _headdecl <- Some ((new func_decl ctx)#cnstr_obj e) ; - _taildecl <- Some ((new func_decl ctx)#cnstr_obj f) ; - (self#sno ctx r) ; - self - - method nil_decl = match _nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing nil decl") - - method is_nil_decl = match _is_nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_nil decl") - - method cons_decl = match _consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing cons decl") - - method is_cons_decl = match _is_consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_cons decl") - - method head_decl = match _headdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing head decl") - - method tail_decl = match _taildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tail decl") -end - -(** Constructor objects *) -class constructor ctx = -object (self) - inherit z3object ctx None as super - val mutable m_n : int = 0 - val mutable m_tester_decl : func_decl option = None - val mutable m_constructor_decl : func_decl option = None - val mutable m_accessor_decls : func_decl array option = None - method incref nc o = () - method decref nc o = () - initializer - let f = fun o -> Z3native.del_constructor o#gnc o#gno in - let v = self in - Gc.finalise f v - - method cnstr_ssssi (name : Symbol.symbol) (recognizer : Symbol.symbol) (field_names : Symbol.symbol array) (sorts : sort array) (sort_refs : int array) = - m_n <- (Array.length field_names) ; - if m_n != (Array.length sorts) then - raise (Z3native.Exception "Number of field names does not match number of sorts") - else - if m_n != (Array.length sort_refs) then - raise (Z3native.Exception "Number of field names does not match number of sort refs") - else - let o = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) m_n (Symbol.aton field_names) - (sortaton sorts) - sort_refs) in - self#sno ctx o ; - self - - method private init = - match m_tester_decl with - | None -> - let (a, b, c) = (Z3native.query_constructor self#gnc self#gno m_n) in - m_constructor_decl <- Some ((new func_decl ctx)#cnstr_obj a) ; - m_tester_decl <- Some ((new func_decl ctx)#cnstr_obj b) ; - m_accessor_decls <- Some (let f e = ((new func_decl ctx)#cnstr_obj e) in Array.map f c) ; - () - | _ -> () - - method get_n = m_n - - method tester_decl = match m_tester_decl with - | Some(x) -> x - | None -> self#init ; self#tester_decl - - method constructor_decl = match m_constructor_decl with - | Some(x) -> x - | None -> self#init ; self#constructor_decl - - method accessor_decls = match m_accessor_decls with - | Some(x) -> x - | None -> self#init ; self#accessor_decls -end - -let constructoraton (a : constructor array) = - let f (e : constructor) = e#gno in - Array.map f a - -(** Constructor list objects *) -class constructor_list ctx = -object (self) - inherit z3object ctx None - method incref nc o = () - method decref nc o = () - initializer - let f = fun o -> Z3native.del_constructor_list o#gnc o#gno in - let v = self in - Gc.finalise f v - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ca ( c : constructor array ) = - self#sno ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (constructoraton c)) ; - self -end - -let constructor_listaton (a : constructor_list array) = - let f (e : constructor_list) = e#gno in - Array.map f a - -(** Datatype sort objects *) -class datatype_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : Symbol.symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (constructoraton constructors)))) ; self -end - -let create_sort ctx obj = - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) obj)) with - | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) - | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) - | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) - | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) - | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) - | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) - | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) - | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) - | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - -(** Expression objects *) -class expr ctx = -object(self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -let expraton (a : expr array) = - let f (e : expr) = e#gno in - Array.map f a - -(** Boolean expression objects *) -class bool_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Arithmetic expression objects (int/real) *) -class arith_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Int expression objects *) -class int_expr ctx = -object (self) - inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Real expression objects *) -class real_expr ctx = -object (self) - inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Bit-vector expression objects *) -class bitvec_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Array expression objects *) -class array_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Datatype expression objects *) -class datatype_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Integer numeral expression objects *) -class int_num ctx = -object (self) - inherit int_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Rational numeral expression objects *) -class rat_num ctx = -object (self) - inherit real_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Bit-vector numeral expression objects *) -class bitvec_num ctx = -object (self) - inherit bitvec_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Algebraic numeral expression objects *) -class algebraic_num ctx = -object (self) - inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Quantifier objects *) -class quantifier ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Quantifier pattern objects *) -class pattern ctx = -object (self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -let patternaton (a : pattern array) = - let f (e : pattern) = e#gno in - Array.map f a - -(**/**) - - -(** Interaction logging for Z3 - - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) -module Log = -struct - (** Open an interaction log file. - @param filename the name of the file to open. - @return True if opening the log file succeeds, false otherwise. - *) - (* CMW: "open" seems to be a reserved keyword? *) - let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - - (** Closes the interaction log. *) - let close = Z3native.close_log - - (** Appends a user-provided string to the interaction log. - @param s the string to append*) - let append s = Z3native.append_log s -end - -(** Version information *) -module Version = -struct - (** The major version. *) - let major = let (x, _, _, _) = Z3native.get_version in x - - (** The minor version. *) - let minor = let (_, x, _, _) = Z3native.get_version in x - - (** The build version. *) - let build = let (_, _, x, _) = Z3native.get_version in x - - (** The revision. *) - let revision = let (_, _, _, x) = Z3native.get_version in x - - (** A string representation of the version information. *) - let to_string = - let (mj, mn, bld, rev) = Z3native.get_version in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev ^ "." -end - - -(** The Sort module implements type information for ASTs *) -module Sort = -struct - (** - Comparison operator. - @param a A sort - @param b A sort - @return True if and are from the same context - and represent the same sort; false otherwise. - *) - let ( = ) (a : sort) (b : sort) = (a == b) || - if a#gnc != b#gnc then - false - else - (Z3native.is_eq_sort a#gnc a#gno b#gno) - - (** - Returns a unique identifier for the sort. - *) - let get_id (x : sort) = Z3native.get_sort_id x#gnc x#gno - - (** - The kind of the sort. - *) - let get_sort_kind (x : sort) = (sort_kind_of_int (Z3native.get_sort_kind x#gnc x#gno)) - - (** - The name of the sort - *) - let get_name (x : sort) = (Symbol.create x#gc (Z3native.get_sort_name x#gnc x#gno)) - - (** - A string representation of the sort. - *) - let to_string (x : sort) = Z3native.sort_to_string x#gnc x#gno - - (** - Create a new Boolean sort. - *) - let mk_bool ( ctx : context ) = - (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort (context_gno ctx)) - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = - (new uninterpreted_sort ctx)#cnstr_s s - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted_s ( ctx : context ) ( s : string ) = - mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) -end - -(**/**) -let create_expr ctx obj = - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then - (((new quantifier ctx)#cnstr_obj obj) :> expr) - else - let s = Z3native.get_sort (context_gno ctx) obj in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (((new algebraic_num ctx)#cnstr_obj obj) :> expr) - else - if (Z3native.is_numeral_ast (context_gno ctx) obj) && - (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - match sk with - | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) - | REAL_SORT -> (((new rat_num ctx)#cnstr_obj obj) :> expr) - | BV_SORT -> (((new bitvec_num ctx)#cnstr_obj obj) :> expr) - | _ -> raise (Z3native.Exception "Unsupported numeral object") - else - match sk with - | BOOL_SORT -> (((new bool_expr ctx)#cnstr_obj obj) :> expr) - | INT_SORT -> (((new int_expr ctx)#cnstr_obj obj) :> expr) - | REAL_SORT -> (((new real_expr ctx)#cnstr_obj obj) :> expr) - | BV_SORT -> (((new bitvec_expr ctx)#cnstr_obj obj) :> expr) - | ARRAY_SORT -> (((new array_expr ctx)#cnstr_obj obj) :> expr) - | DATATYPE_SORT -> (((new datatype_expr ctx)#cnstr_obj obj) :> expr) - | _ -> (new expr ctx)#cnstr_obj obj - -let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = - let o = Z3native.mk_app (context_gno ctx) f#gno (Array.length args) (astaton args) in - create_expr ctx o - -let create_ast ctx no = - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) - | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) - | SORT_AST -> ((create_sort ctx no) :> ast) - | APP_AST - | NUMERAL_AST - | VAR_AST -> ((create_expr ctx no) :> ast) - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") -(**/**) - -(** Function declarations *) -module FuncDecl = -struct - - (** Parameters of Func_Decls *) - module Parameter = - struct - type parameter = { - m_kind : parameter_kind ; - m_i : int ; - m_d : float ; - m_sym : Symbol.symbol option ; - m_srt : sort option ; - m_ast : ast option ; - m_fd : func_decl option ; - m_r : string ; - } - - (**/**) - let cnstr_int i = { - m_kind = PARAMETER_INT ; - m_i = i ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_double d = { - m_kind = PARAMETER_DOUBLE ; - m_i = 0 ; - m_d = d ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_symbol sym = { - m_kind = PARAMETER_SYMBOL ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = sym ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_sort srt = { - m_kind = PARAMETER_SORT ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = srt ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_ast ast = { - m_kind = PARAMETER_AST ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = ast ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_func_decl fd ={ - m_kind = PARAMETER_FUNC_DECL ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = fd ; - m_r = "" ; - } - - let cnstr_rational r = { - m_kind = PARAMETER_RATIONAL ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = r ; - } - (**/**) - - (** - The kind of the parameter. - *) - let get_kind ( x : parameter ) = x.m_kind - - (**The int value of the parameter.*) - let get_int ( x : parameter ) = - if ((get_kind x) != PARAMETER_INT) then - raise (Z3native.Exception "parameter is not an int") - else - x.m_i - - (**The double value of the parameter.*) - let get_double ( x : parameter ) = - if ((get_kind x) != PARAMETER_DOUBLE) then - raise (Z3native.Exception "parameter is not a double") - else - x.m_d - - (**The Symbol value of the parameter.*) - let get_symbol ( x : parameter ) = - if ((get_kind x) != PARAMETER_SYMBOL) then - raise (Z3native.Exception "parameter is not a symbol") - else - x.m_sym - - (**The Sort value of the parameter.*) - let get_sort ( x : parameter ) = - if ((get_kind x) != PARAMETER_SORT) then - raise (Z3native.Exception "parameter is not a sort") - else - x.m_srt - - (**The AST value of the parameter.*) - let get_ast ( x : parameter ) = - if ((get_kind x) != PARAMETER_AST) then - raise (Z3native.Exception "parameter is not an ast") - else - x.m_ast - - (**The FunctionDeclaration value of the parameter.*) - let get_ast ( x : parameter ) = - if ((get_kind x) != PARAMETER_FUNC_DECL) then - raise (Z3native.Exception "parameter is not an function declaration") - else - x.m_fd - - (**The rational string value of the parameter.*) - let get_rational ( x : parameter ) = - if ((get_kind x) != PARAMETER_RATIONAL) then - raise (Z3native.Exception "parameter is not a ratinoal string") - else - x.m_r - end - - (** - Creates a new function declaration. - *) - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name domain range - - (** - Creates a new function declaration. - *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = - mk_func_decl ctx (Symbol.mk_string ctx name) domain range - - (** - Creates a fresh function declaration with a name prefixed with . - - - *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix domain range - - (** - Creates a new constant function declaration. - *) - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name [||] range - - - (** - Creates a new constant function declaration. - *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr (Symbol.mk_string ctx name) [||] range - - (** - Creates a fresh constant function declaration with a name prefixed with . - - - *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix [||] range - - - (** - Comparison operator. - @param a A func_decl - @param b A func_decl - @return True if and are from the same context - and represent the same func_decl; false otherwise. - *) - let ( = ) (a : func_decl) (b : func_decl) = (a == b) || - if a#gnc == a#gnc then - false - else - (Z3native.is_eq_func_decl a#gnc a#gno b#gno) - (** - A string representations of the function declaration. - *) - let to_string (x : func_decl) = Z3native.func_decl_to_string x#gnc x#gno - - (** - Returns a unique identifier for the function declaration. - *) - let get_id (x : func_decl) = Z3native.get_func_decl_id x#gnc x#gno - - (** - The arity of the function declaration - *) - let get_arity (x : func_decl) = Z3native.get_arity x#gnc x#gno - - (** - The size of the domain of the function declaration - - *) - let get_domain_size (x : func_decl) = Z3native.get_domain_size x#gnc x#gno - - (** - The domain of the function declaration - *) - let get_domain (x : func_decl) = - let n = (get_domain_size x) in - let f i = create_sort x#gc (Z3native.get_domain x#gnc x#gno i) in - Array.init n f - - (** - The range of the function declaration - *) - let get_range (x : func_decl) = - create_sort x#gc (Z3native.get_range x#gnc x#gno) - - (** - The kind of the function declaration. - *) - let get_decl_kind (x : func_decl) = (decl_kind_of_int (Z3native.get_decl_kind x#gnc x#gno)) - - (** - The name of the function declaration - *) - let get_name (x : func_decl) = (Symbol.create x#gc (Z3native.get_decl_name x#gnc x#gno)) - - (** - The number of parameters of the function declaration - *) - let get_num_parameters (x : func_decl) = (Z3native.get_decl_num_parameters x#gnc x#gno) - - (** - The parameters of the function declaration - *) - let get_parameters (x : func_decl) = - let n = (get_num_parameters x) in - let f i = ( - match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with - | PARAMETER_INT -> Parameter.cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) - | PARAMETER_DOUBLE -> Parameter.cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) - | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (Symbol.create x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) - | PARAMETER_SORT -> Parameter.cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) - | PARAMETER_AST -> Parameter.cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) - | PARAMETER_FUNC_DECL -> Parameter.cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) - | PARAMETER_RATIONAL -> Parameter.cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) - ) in - mk_list f n - - (** - Create expression that applies function to arguments. - @param args The arguments - *) - let apply (x : func_decl) (args : expr array) = create_expr_fa x#gc x args - -end (** The abstract syntax tree (AST) module *) -module AST = -struct +module rec AST : +sig + type ast = z3_native_object + + val create : context -> Z3native.ptr -> ast + val aton : ast array -> Z3native.ptr array + + val is_expr : ast -> bool + val is_var : ast -> bool +end = struct + type ast = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let aton (a : ast array) = + let f (e : ast) = (z3obj_gno e) in + Array.map f a + + (** Vectors of ASTs *) module ASTVector = struct type ast_vector = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_vector_inc_ref ; dec_ref = Z3native.ast_vector_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -1133,11 +379,11 @@ struct @return An AST *) let get ( x : ast_vector ) ( i : int ) = - create_ast (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) + create (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) (** Sets the i-th object in the vector. *) let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i value#gno + Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) (** Resize the vector to . @param newSize The new size of the vector. *) @@ -1150,7 +396,7 @@ struct @param a An AST *) let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) a#gno + Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) (** Translates all ASTs in the vector to . @@ -1158,7 +404,7 @@ struct @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = - cnstr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = @@ -1171,13 +417,13 @@ struct type ast_map = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_map_inc_ref ; dec_ref = Z3native.ast_map_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -1185,7 +431,7 @@ struct @param k An AST @return True if is a key in the map, false otherwise. *) let contains ( x : ast_map ) ( key : ast ) = - (Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) key#gno) + Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (** Finds the value associated with the key . @@ -1193,7 +439,7 @@ struct @param k An AST *) let find ( x : ast_map ) ( key : ast ) = - create_ast (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) key#gno) + create (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) (** Stores or replaces a new key/value pair in the map. @@ -1201,14 +447,14 @@ struct @param v The value AST *) let insert ( x : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) key#gno value#gno + Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) (** Erases the key from the map. @param k An AST *) let erase ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) key#gno + Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (** Removes all keys from the map. *) let reset ( x : ast_map ) = @@ -1220,7 +466,7 @@ struct (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVector.cnstr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = @@ -1231,23 +477,23 @@ struct The AST's hash code. @return A hash code *) - let get_hash_code ( x : ast) = Z3native.get_ast_hash x#gnc x#gno + let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) (** A unique identifier for the AST (unique among all ASTs). *) - let get_id ( x : ast) = Z3native.get_ast_id x#gnc x#gno + let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) (** The kind of the AST. *) - let get_ast_kind ( x : ast) = (ast_kind_of_int (Z3native.get_ast_kind x#gnc x#gno)) + let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) (** Indicates whether the AST is an Expr *) - let is_expr ( x : ast) = - match get_ast_kind ( x : ast) with + let is_expr ( x : ast ) = + match get_ast_kind ( x : ast ) with | APP_AST | NUMERAL_AST | QUANTIFIER_AST @@ -1257,33 +503,33 @@ struct (** Indicates whether the AST is a bound variable *) - let is_var ( x : ast) = (get_ast_kind x) == VAR_AST + let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST (** Indicates whether the AST is a Quantifier *) - let is_quantifier ( x : ast) = (get_ast_kind x) == QUANTIFIER_AST + let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST (** Indicates whether the AST is a Sort *) - let is_sort ( x : ast) = (get_ast_kind x) == SORT_AST + let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST (** Indicates whether the AST is a FunctionDeclaration *) - let is_func_decl ( x : ast) = (get_ast_kind x) == FUNC_DECL_AST + let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST (** A string representation of the AST. *) - let to_string ( x : ast) = Z3native.ast_to_string x#gnc x#gno + let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) (** A string representation of the AST in s-expression notation. *) - let to_sexpr ( x : ast) = Z3native.ast_to_string x#gnc x#gno + let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) (** Comparison operator. @@ -1292,11 +538,11 @@ struct @return True if and are from the same context and represent the same sort; false otherwise. *) - let ( = ) (a : expr) (b : expr) = (a == b) || - if a#gnc == b#gnc then + let ( = ) ( a : ast ) ( b : ast ) = (a == b) || + if (z3obj_gnc a) != (z3obj_gnc b) then false else - (Z3native.is_eq_ast a#gnc a#gno b#gno) + Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) (** Object Comparison. @@ -1316,11 +562,11 @@ struct @param ctx A context @return A copy of the AST which is associated with *) - let translate ( x : ast) to_ctx = - if x#gc == to_ctx then + let translate ( x : ast ) ( to_ctx : context ) = + if (z3obj_gnc x) == (context_gno to_ctx) then x else - (create_ast to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx))) + create to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Wraps an AST. @@ -1334,7 +580,7 @@ struct @param nativeObject The native pointer to wrap. *) let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - create_ast ctx ptr + create ctx ptr (** Unwraps an AST. @@ -1347,43 +593,413 @@ struct @param a The AST to unwrap. *) - let unwrap_ast ( a : ast ) = a#gno + let unwrap_ast ( x : ast ) = (z3obj_gno x) + + (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST -> (match (FuncDecl.create ctx no) with FuncDecl.FuncDecl(x) -> x) + | SORT_AST -> (match (Sort.create ctx no) with Sort.Sort(x) -> x) + | QUANTIFIER_AST -> (match (Quantifiers.create ctx no) with Quantifiers.Quantifier(Expr.Expr(x)) -> x) + | APP_AST + | NUMERAL_AST + | VAR_AST -> (match (Expr.create ctx no) with Expr.Expr(x) -> x) + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") +(**/**) end +(** The Sort module implements type information for ASTs *) +and Sort : +sig + type sort = Sort of AST.ast + type bitvec_sort = BitvecSort of sort + type uninterpreted_sort = UninterpretedSort of sort + + val create : context -> Z3native.ptr -> sort + val gno : sort -> Z3native.ptr + val gnc : sort -> Z3native.ptr + val aton : sort array -> Z3native.ptr array +end = struct + type sort = Sort of AST.ast + type bitvec_sort = BitvecSort of sort + type uninterpreted_sort = UninterpretedSort of sort + + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) + let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) + let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) + + let aton : sort array -> Z3native.ptr array = fun a -> + let f e = (gno e) in + Array.map f a + + let create : context -> Z3native.ptr -> sort = fun ctx no -> + let q : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno q ctx no) ; + (z3obj_create q) ; + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + + (** + Comparison operator. + @param a A sort + @param b A sort + @return True if and are from the same context + and represent the same sort; false otherwise. + *) + let ( = ) : sort -> sort -> bool = fun a b -> + (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) + + (** + Returns a unique identifier for the sort. + *) + let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) + + (** + The kind of the sort. + *) + let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) + + (** + The name of the sort + *) + let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) + + (** + A string representation of the sort. + *) + let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; + (z3obj_create res) ; + UninterpretedSort(Sort(res)) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_s ( ctx : context ) ( s : string ) = + mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) +end + + +(** Function declarations *) +and FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + + val create : context -> Z3native.ptr -> func_decl + val gno : func_decl -> Z3native.ptr + val gnc : func_decl -> Z3native.ptr + + val get_domain_size : func_decl -> int + val get_decl_kind : func_decl -> Z3enums.decl_kind +end = struct + open Sort + + type func_decl = FuncDecl of AST.ast + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + FuncDecl(res) + + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) + let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) + let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) + + let aton (a : func_decl array) = + let f (e : func_decl) = (gno e) in + Array.map f a + + (** Parameters of Func_Decls *) + module Parameter = + struct + type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + (** The kind of the parameter. *) + let get_kind ( x : parameter ) = + (match x with + | P_Int(_) -> PARAMETER_INT + | P_Dbl(_) -> PARAMETER_DOUBLE + | P_Sym(_) -> PARAMETER_SYMBOL + | P_Srt(_) -> PARAMETER_SORT + | P_Ast(_) -> PARAMETER_AST + | P_Fdl(_) -> PARAMETER_FUNC_DECL + | P_Rat(_) -> PARAMETER_RATIONAL) + + (**The int value of the parameter.*) + let get_int ( x : parameter ) = + match x with + | P_Int(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an int") + + (**The double value of the parameter.*) + let get_float ( x : parameter ) = + match x with + | P_Dbl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a double") + + (**The Symbol value of the parameter.*) + let get_symbol ( x : parameter ) = + match x with + | P_Sym(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a symbol") + + (**The Sort value of the parameter.*) + let get_sort ( x : parameter ) = + match x with + | P_Srt(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a sort") + + (**The AST value of the parameter.*) + let get_ast ( x : parameter ) = + match x with + | P_Ast(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an ast") + + (**The FunctionDeclaration value of the parameter.*) + let get_func_decl ( x : parameter ) = + match x with + | P_Fdl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a func_decl") + + (**The rational string value of the parameter.*) + let get_func_decl ( x : parameter ) = + match x with + | P_Rat(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a rational string") + end + + open Parameter + + (** + Creates a new function declaration. + *) + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + create_ndr ctx name domain range + + (** + Creates a new function declaration. + *) + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = + mk_func_decl ctx (Symbol.mk_string ctx name) domain range + + (** + Creates a fresh function declaration with a name prefixed with . + + + *) + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + create_pdr ctx prefix domain range + + (** + Creates a new constant function declaration. + *) + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + create_ndr ctx name [||] range + + (** + Creates a new constant function declaration. + *) + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = + create_ndr ctx (Symbol.mk_string ctx name) [||] range + + (** + Creates a fresh constant function declaration with a name prefixed with . + + + *) + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = + create_pdr ctx prefix [||] range + + + (** + Comparison operator. + @param a A func_decl + @param b A func_decl + @return True if and are from the same context + and represent the same func_decl; false otherwise. + *) + let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) + + (** + A string representations of the function declaration. + *) + let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) + + (** + Returns a unique identifier for the function declaration. + *) + let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) + + (** + The arity of the function declaration + *) + let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) + + (** + The size of the domain of the function declaration + + *) + let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) + + (** + The domain of the function declaration + *) + let get_domain ( x : func_decl ) = + let n = (get_domain_size x) in + let f i = Sort.create (gc x) (Z3native.get_domain (gnc x) (gno x) i) in + Array.init n f + + (** + The range of the function declaration + *) + let get_range ( x : func_decl ) = + Sort.create (gc x) (Z3native.get_range (gnc x) (gno x)) + + (** + The kind of the function declaration. + *) + let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) + + (** + The name of the function declaration + *) + let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) + + (** + The number of parameters of the function declaration + *) + let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) + + (** + The parameters of the function declaration + *) + let get_parameters ( x : func_decl ) = + let n = (get_num_parameters x) in + let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with + | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + ) in + mk_list f n + + (** + Create expression that applies function to arguments. + @param args The arguments + *) + let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.create_fa (gc x) x args +end + (** Parameter sets (of Solvers, Tactics, ...) A Params objects represents a configuration in the form of symbol/value pairs. *) -module Params = -struct +and Params : +sig + type params = z3_native_object + + val create : context -> Z3native.ptr -> params + + module ParamDescrs : sig + type param_descrs = z3_native_object + + val create : context -> Z3native.ptr -> param_descrs + end +end = struct type params = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : params = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.params_inc_ref ; dec_ref = Z3native.params_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs = - struct + module ParamDescrs : + sig + type param_descrs = z3_native_object + + val create : context -> Z3native.ptr -> param_descrs + end = struct type param_descrs = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : param_descrs = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.param_descrs_inc_ref ; dec_ref = Z3native.param_descrs_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -1449,7 +1065,6 @@ struct *) let add_s_double ( x : params ) ( name : string ) ( value : float ) = add_double x (Symbol.mk_string (z3obj_gc x) name) value - (** Adds a parameter setting. *) @@ -1460,7 +1075,7 @@ struct Creates a new parameter set *) let mk_params ( ctx : context ) = - cnstr ctx (Z3native.mk_params (context_gno ctx)) + create ctx (Z3native.mk_params (context_gno ctx)) (** A string representation of the parameter set. @@ -1468,18 +1083,69 @@ struct let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) end - (** General expressions (terms), including Boolean logic *) -module Expr = -struct +and Expr : +sig + type expr = Expr of AST.ast + + val create : context -> Z3native.ptr -> expr + val create_fa : context -> FuncDecl.func_decl -> expr array -> expr + val gc : expr -> context + val gno : expr -> Z3native.ptr + val gnc : expr -> Z3native.ptr + val aton : expr array -> Z3native.ptr array + + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val get_func_decl : expr -> FuncDecl.func_decl +end = struct + type expr = Expr of AST.ast + + let create ( ctx : context ) ( obj : Z3native.ptr ) = + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then + (match (Quantifiers.create ctx obj) with Quantifiers.Quantifier(e) -> e) + else + let s = Z3native.get_sort (context_gno ctx) obj in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) obj) then + (match (Arithmetic.create_algebraic_num ctx obj) with Arithmetic.AlgebraicNum(Arithmetic.Expr(e)) -> e) + else + if (Z3native.is_numeral_ast (context_gno ctx) obj) && + (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + match sk with + | INT_SORT -> (match (Arithmetic.create_int_num ctx obj) with Arithmetic.IntNum(Arithmetic.IntExpr(Arithmetic.Expr(e))) -> e) + | REAL_SORT -> (match (Arithmetic.create_rat_num ctx obj) with Arithmetic.RatNum(Arithmetic.RealExpr(Arithmetic.Expr(e))) -> e) + | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) + | _ -> raise (Z3native.Exception "Unsupported numeral object") + else + match sk with + | BOOL_SORT -> (match (Booleans.create ctx obj) with Booleans.BoolExpr(e) -> e) + | INT_SORT -> (match (Arithmetic.create_int_expr ctx obj) with Arithmetic.IntExpr(Arithmetic.Expr(e)) -> e) + | REAL_SORT -> (match (Arithmetic.create_real_expr ctx obj) with Arithmetic.RealExpr(Arithmetic.Expr(e)) -> e) + | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) + | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) + | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) + | _ -> Expr(AST.create ctx obj) + + let aton ( a : expr array ) = + let f ( e : expr ) = match e with Expr(a) -> (z3obj_gno a) in + Array.map f a + + let create_fa ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = + let o = Z3native.mk_app (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args) in + Expr.create ctx o + + let gc ( x : expr ) = match x with Expr(a) -> (z3obj_gc a) + let gnc ( x : expr ) = match x with Expr(a) -> (z3obj_gnc a) + let gno ( x : expr ) = match x with Expr(a) -> (z3obj_gno a) + (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier *) let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) - | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno (z3obj_gno pp)) + | None -> Expr.create (gc x) (Z3native.simplify (gnc x) (gno x)) + | Some pp -> Expr.create (gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) (** a string describing all available parameters to Expr.Simplify. @@ -1491,29 +1157,29 @@ struct Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.cnstr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) + Params.ParamDescrs.create ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. *) - let get_func_decl ( x : expr ) = (new func_decl x#gc)#cnstr_obj (Z3native.get_app_decl x#gnc x#gno) + let get_func_decl ( x : expr ) = FuncDecl.create (gc x) (Z3native.get_app_decl (gnc x) (gno x)) (** Indicates whether the expression is the true or false expression or something else (L_UNDEF). *) - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value x#gnc x#gno) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) (** The number of arguments of the expression. *) - let get_num_args ( x : expr ) = Z3native.get_app_num_args x#gnc x#gno + let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) (** The arguments of the expression. *) let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = create_expr x#gc (Z3native.get_app_arg x#gnc x#gno i) in + let f i = create (gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in Array.init n f (** @@ -1524,7 +1190,7 @@ struct if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - x#sno x#gc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) + create (gc x) (Z3native.update_term (gnc x) (gno x) (Array.length args) (aton args)) (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. @@ -1537,7 +1203,7 @@ struct if (Array.length from) <> (Array.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - create_expr x#gc (Z3native.substitute x#gnc x#gno (Array.length from) (expraton from) (expraton to_)) + create (gc x) (Z3native.substitute (gnc x) (gno x) (Array.length from) (aton from) (aton to_)) (** Substitute every occurrence of from in the expression with to. @@ -1552,7 +1218,7 @@ struct For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) let substitute_vars ( x : expr ) to_ = - create_expr x#gc (Z3native.substitute_vars x#gnc x#gno (Array.length to_) (expraton to_)) + create (gc x) (Z3native.substitute_vars (gnc x) (gno x) (Array.length to_) (aton to_)) (** @@ -1561,46 +1227,46 @@ struct @return A copy of the term which is associated with *) let translate ( x : expr ) to_ctx = - if x#gc == to_ctx then + if (gc x) == to_ctx then x else - create_expr to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx)) + create to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) (** Returns a string representation of the expression. *) - let to_string ( x : expr ) = Z3native.ast_to_string x#gnc x#gno + let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast x#gnc x#gno) + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted x#gnc x#gno + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) (** The Sort of the term. *) - let get_sort ( x : expr ) = create_sort x#gc (Z3native.get_sort x#gnc x#gno) + let get_sort ( x : expr ) = Sort.create (gc x) (Z3native.get_sort (gnc x) (gno x)) (** Indicates whether the term has Boolean sort. *) - let is_bool ( x : expr ) = (AST.is_expr x) && - (Z3native.is_eq_sort x#gnc - (Z3native.mk_bool_sort x#gnc) - (Z3native.get_sort x#gnc x#gno)) - + let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (Z3native.is_eq_sort (gnc x) + (Z3native.mk_bool_sort (gnc x)) + (Z3native.get_sort (gnc x) (gno x))) + (** Indicates whether the term represents a constant. *) - let is_const ( x : expr ) = (AST.is_expr x) && + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (get_num_args x) == 0 && - FuncDecl.get_domain_size(get_func_decl x) == 0 + (FuncDecl.get_domain_size (get_func_decl x)) == 0 (** Indicates whether the term is the constant true. @@ -1679,123 +1345,36 @@ struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_expr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) range#gno) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = + create ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) (** Creates a new Constant of sort and named . *) - let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name)range + let mk_const_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = + mk_const ctx (Symbol.mk_string ctx name) range (** Creates a constant from the func_decl . @param f An expression of a 0-arity function *) - let mk_const_f ( ctx : context ) ( f : func_decl ) = - create_expr_fa ctx f [||] + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = + create_fa ctx f [||] (** Creates a fresh constant of sort and a name prefixed with . *) - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort) = - create_expr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix range#gno) - - (** - Create a Boolean constant. - *) - let mk_bool_const ( ctx : context ) ( name : Symbol.symbol ) = - ((mk_const ctx name (Sort.mk_bool ctx)) :> bool_expr) - - (** - Create a Boolean constant. - *) - let mk_bool_const_s ( ctx : context ) ( name : string ) = - mk_bool_const ctx (Symbol.mk_string ctx name) + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = + create ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) (** Create a new function application. *) - let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = - create_expr_fa ctx f args - - (** - The true Term. - *) - let mk_true ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_true (context_gno ctx)) - - (** - The false Term. - *) - let mk_false ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_false (context_gno ctx)) - - (** - Creates a Boolean value. - *) - let mk_bool ( ctx : context ) ( value : bool) = - if value then mk_true ctx else mk_false ctx - - (** - Creates the equality = . - *) - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq (context_gno ctx) x#gno y#gno) - - (** - Creates a distinct term. - *) - let mk_distinct ( ctx : context ) ( args : expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct (context_gno ctx) (Array.length args) (astaton args)) - - (** - Mk an expression representing not(a). - *) - let mk_not ( ctx : context ) ( a : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_not (context_gno ctx) a#gno) - - (** - Create an expression representing an if-then-else: ite(t1, t2, t3). - @param t1 An expression with Boolean sort - @param t2 An expression - @param t3 An expression with the same sort as - *) - let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create_expr ctx (Z3native.mk_ite (context_gno ctx) t1#gno t2#gno t3#gno) - - (** - Create an expression representing t1 iff t2. - *) - let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff (context_gno ctx) t1#gno t2#gno) - - (** - Create an expression representing t1 -> t2. - *) - let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies (context_gno ctx) t1#gno t2#gno) - - (** - Create an expression representing t1 xor t2. - *) - let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor (context_gno ctx) t1#gno t2#gno) - - (** - Create an expression representing the AND of args - *) - let mk_and ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_and (context_gno ctx) (Array.length args) (astaton args)) - - (** - Create an expression representing the OR of args - *) - let mk_or ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_or (context_gno ctx) (Array.length args) (astaton args)) + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = + create_fa ctx f args (** Create a numeral of a given sort. @@ -1803,8 +1382,8 @@ struct @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. @return A Term with value and sort *) - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - create_expr ctx (Z3native.mk_numeral (context_gno ctx) v ty#gno) + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : Sort.sort ) = + create ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. @@ -1813,13 +1392,147 @@ struct @param ty Sort of the numeral @return A Term with value and type *) - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_int (context_gno ctx) v ty#gno) + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : Sort.sort ) = + create ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) + + let aton (a : expr array) = + let f (e : expr) = (gno e) in + Array.map f a +end + +(** Boolean expressions *) +and Booleans : +sig + type bool_expr = BoolExpr of Expr.expr + type bool_sort = BoolSort of Sort.sort + + val create : context -> Z3native.ptr -> bool_expr + val aton : bool_expr array -> Z3native.ptr array +end = struct + type bool_expr = BoolExpr of Expr.expr + type bool_sort = BoolSort of Sort.sort + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let a = (AST.create ctx no) in + BoolExpr(Expr.Expr(a)) + + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gc e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gnc e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gno e) + + let aton ( a : bool_expr array ) = + let f (e : bool_expr) = (gno e) in + Array.map f a + + let mk_sort ( ctx : context ) = + BoolSort(Sort.create ctx (Z3native.mk_bool_sort (context_gno ctx))) + + (** + Create a Boolean constant. + *) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = + let s = (match (mk_sort ctx) with BoolSort(q) -> q) in + BoolExpr(Expr.mk_const ctx name s) + + (** + Create a Boolean constant. + *) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) + + (** + The true Term. + *) + let mk_true ( ctx : context ) = + create ctx (Z3native.mk_true (context_gno ctx)) + + (** + The false Term. + *) + let mk_false ( ctx : context ) = + create ctx (Z3native.mk_false (context_gno ctx)) + + (** + Creates a Boolean value. + *) + let mk_val ( ctx : context ) ( value : bool ) = + if value then mk_true ctx else mk_false ctx + + (** + Creates the equality = . + *) + let mk_eq ( ctx : context ) ( x : Expr.expr ) ( y : Expr.expr ) = + create ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + + (** + Creates a distinct term. + *) + let mk_distinct ( ctx : context ) ( args : Expr.expr array ) = + create ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) + + (** + Mk an expression representing not(a). + *) + let mk_not ( ctx : context ) ( a : bool_expr ) = + create ctx (Z3native.mk_not (context_gno ctx) (gno a)) + + (** + Create an expression representing an if-then-else: ite(t1, t2, t3). + @param t1 An expression with Boolean sort + @param t2 An expression + @param t3 An expression with the same sort as + *) + let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = + create ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + + (** + Create an expression representing t1 iff t2. + *) + let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + create ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + + (** + Create an expression representing t1 -> t2. + *) + let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + create ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + (** + Create an expression representing t1 xor t2. + *) + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + create ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + + (** + Create an expression representing the AND of args + *) + let mk_and ( ctx : context ) ( args : bool_expr array ) = + create ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) + + (** + Create an expression representing the OR of args + *) + let mk_or ( ctx : context ) ( args : bool_expr array ) = + create ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) end (** Quantifier expressions *) -module Quantifiers = -struct +and Quantifiers : +sig + type quantifier = Quantifier of Expr.expr + + val create : context -> Z3native.ptr -> quantifier +end = struct + type quantifier = Quantifier of Expr.expr + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let a = (AST.create ctx no) in + Quantifier(Expr.Expr(a)) + + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) + + (** The de-Burijn index of a bound variable. @@ -1838,11 +1551,11 @@ struct on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its index. *) - let get_index ( x : expr ) = - if not (AST.is_var x) then + let get_index ( x : Expr.expr ) = + if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else - Z3native.get_index_value x#gnc x#gno + Z3native.get_index_value (Expr.gnc x) (Expr.gno x) (** Quantifier patterns @@ -1850,33 +1563,57 @@ struct non-empty. If the list comprises of more than one term, it is also called a multi-pattern. *) - module Pattern = - struct + module Patterns : + sig + type pattern = Pattern of AST.ast + + val create : context -> Z3native.ptr -> pattern + val aton : pattern array -> Z3native.ptr array + end = struct + type pattern = Pattern of AST.ast + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + Pattern(res) + + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) + let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) + let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) + (** The number of terms in the pattern. *) let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms x#gnc x#gno + Z3native.get_pattern_num_terms (gnc x) (gno x) (** The terms in the pattern. *) let get_terms ( x : pattern ) = let n = (get_num_terms x) in - let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in + let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in Array.init n f (** A string representation of the pattern. *) - let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno + let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) + + let aton (a : pattern array) = + let f (e : pattern) = (gno e) in + Array.map f a end (** Indicates whether the quantifier is universal. *) let is_universal ( x : quantifier ) = - Z3native.is_quantifier_forall x#gnc x#gno + Z3native.is_quantifier_forall (gnc x) (gno x) (** Indicates whether the quantifier is existential. @@ -1886,45 +1623,45 @@ struct (** The weight of the quantifier. *) - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) (** The number of patterns. *) - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) (** The patterns. *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in + let f i = (Patterns.create (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** The number of no-patterns. *) - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) (** The no-patterns. *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in + let f i = (Patterns.create (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** The number of bound variables. *) - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) (** The symbols for the bound variables. *) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (Symbol.create x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in Array.init n f (** @@ -1932,31 +1669,31 @@ struct *) let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in + let f i = (Sort.create (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in Array.init n f (** The body of the quantifier. *) let get_body ( x : quantifier ) = - (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) + Booleans.create (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) (** Creates a new bound variable. @param index The de-Bruijn index of the variable @param ty The sort of the variable *) - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_bound (context_gno ctx) index ty#gno) + let mk_bound ( ctx : context ) ( index : int ) ( ty : Sort.sort ) = + Expr.create ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) (** Create a quantifier pattern. *) - let mk_pattern ( ctx : context ) ( terms : expr array ) = + let mk_pattern ( ctx : context ) ( terms : Expr.expr array ) = if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - (new pattern ctx)#cnstr_obj (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (astaton terms)) + Patterns.create ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (Expr.aton terms)) (** Create a universal Quantifier. @@ -1977,95 +1714,96 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (patternaton patterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) + create ctx (Z3native.mk_quantifier (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (Patterns.aton patterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) + create ctx (Z3native.mk_quantifier_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - body#gno) + create ctx (Z3native.mk_quantifier_const (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - body#gno) + create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Expr.gno body)) + (** Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (patternaton patterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) + create ctx (Z3native.mk_quantifier (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (Patterns.aton patterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) - + create ctx (Z3native.mk_quantifier_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) + (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - body#gno) + create ctx (Z3native.mk_quantifier_const (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - body#gno) + create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Expr.gno body)) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -2075,7 +1813,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -2083,75 +1821,104 @@ struct end (** Functions to manipulate Array expressions *) -module Arrays = -struct +and Arrays : +sig + type array_expr = ArrayExpr of Expr.expr + type array_sort = ArraySort of Sort.sort + + val create_expr : context -> Z3native.ptr -> array_expr +end = struct + type array_expr = ArrayExpr of Expr.expr + type array_sort = ArraySort of Sort.sort + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (Expr.create ctx no) in + ArrayExpr(e) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + ArraySort(s) + + let sgc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gno s) + + let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gc e) + let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gnc e) + let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gno e) + + let aton (a : array_expr array) = + let f (e : array_expr) = (egno e) in + Array.map f a + + (** Create a new array sort. *) - let mk_sort ( ctx : context ) domain range = - (new array_sort ctx)#cnstr_dr domain range + let mk_sort ( ctx : context ) ( domain : Sort.sort ) ( range : Sort.sort ) = + create_sort ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) (** Indicates whether the term is an array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). Array store takes at least 3 arguments. *) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) (** Indicates whether the term is an array select. *) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) (** Indicates whether the term is a constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_constant_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) (** Indicates whether the term is a default array. For example default(const(v)) = v. The function is unary. *) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_default_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) (** Indicates whether the term is an array map. It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_array_map ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) (** Indicates whether the term is an as-array term. An as-array term is n array value that behaves as the function graph of the function passed as parameter. *) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_as_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) (** Indicates whether the term is of an array sort. *) - let is_array ( x : expr ) = - (Z3native.is_app x#gnc x#gno) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + let is_array ( x : Expr.expr ) = + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) (** The domain of the array sort. *) - let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) + let get_domain ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) (** The range of the array sort. *) - let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) + let get_range ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - ((Expr.mk_const ctx name ((mk_sort ctx domain range) :> sort)) :> array_expr) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort ) ( range : Sort.sort ) = + ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) (** Create an array constant. *) - let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = + let mk_const_s ( ctx : context ) ( name : string ) ( domain : Sort.sort ) ( range : Sort.sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range (** @@ -2166,8 +1933,8 @@ struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - ((create_expr ctx (Z3native.mk_select (context_gno ctx) a#gno i#gno)) :> array_expr) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) = + create_expr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) (** Array update. @@ -2185,8 +1952,8 @@ struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_store (context_gno ctx) a#gno i#gno v#gno) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) ( v : Expr.expr ) = + create_expr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) (** Create a constant array. @@ -2196,8 +1963,8 @@ struct *) - let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array (context_gno ctx) domain#gno v#gno) + let mk_const_array ( ctx : context ) ( domain : Sort.sort ) ( v : Expr.expr ) = + create_expr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) (** Maps f on the argument arrays. @@ -2209,8 +1976,8 @@ struct *) - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = - ((create_expr ctx (Z3native.mk_map (context_gno ctx) f#gno (Array.length args) (astaton args))) :> array_expr) + let mk_map ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : array_expr array ) = + create_expr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args)) (** Access the array default value. @@ -2219,149 +1986,184 @@ struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - ((create_expr ctx (Z3native.mk_array_default (context_gno ctx) arg#gno)) :> array_expr) + create_expr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end (** Functions to manipulate Set expressions *) -module Sets = -struct +and Sets : +sig + type set_sort = SetSort of Sort.sort + +end = struct + type set_sort = SetSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + SetSort(s) + (** Indicates whether the term is set union *) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) (** Indicates whether the term is set intersection *) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_intersect ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) (** Indicates whether the term is set difference *) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_difference ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) (** Indicates whether the term is set complement *) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) (** Indicates whether the term is set subset *) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + let is_subset ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) (** Create a set type. *) - let mk_sort ( ctx : context ) ( ty : sort) = - (new set_sort ctx)#cnstr_s ty + let mk_sort ( ctx : context ) ( ty : Sort.sort ) = + create_sort ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) (** Create an empty set. *) - let mk_empty ( ctx : context ) ( domain : sort ) = - (create_expr ctx (Z3native.mk_empty_set (context_gno ctx) domain#gno)) + let mk_empty ( ctx : context ) ( domain : Sort.sort ) = + (Expr.create ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) (** Create the full set. *) - let mk_full ( ctx : context ) ( domain : sort ) = - create_expr ctx (Z3native.mk_full_set (context_gno ctx) domain#gno) + let mk_full ( ctx : context ) ( domain : Sort.sort ) = + Expr.create ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) (** Add an element to the set. *) - let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_add (context_gno ctx) set#gno element#gno) + let mk_set_add ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) (** Remove an element from a set. *) - let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_del (context_gno ctx) set#gno element#gno) + let mk_del ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) (** Take the union of a list of sets. *) - let mk_union ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (astaton args)) + let mk_union ( ctx : context ) ( args : Expr.expr array ) = + Expr.create ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (Expr.aton args)) (** Take the intersection of a list of sets. *) - let mk_intersection ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (astaton args)) + let mk_intersection ( ctx : context ) ( args : Expr.expr array ) = + Expr.create ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (Expr.aton args)) (** Take the difference between two sets. *) - let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_difference (context_gno ctx) arg1#gno arg2#gno) + let mk_difference ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) (** Take the complement of a set. *) - let mk_complement ( ctx : context ) ( arg : expr ) = - create_expr ctx (Z3native.mk_set_complement (context_gno ctx) arg#gno) + let mk_complement ( ctx : context ) ( arg : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) (** Check for set membership. *) - let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - create_expr ctx (Z3native.mk_set_member (context_gno ctx) elem#gno set#gno) + let mk_membership ( ctx : context ) ( elem : Expr.expr ) ( set : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) (** Check for subsetness of sets. *) - let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_subset (context_gno ctx) arg1#gno arg2#gno) + let mk_subset ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) end (** Functions to manipulate Finite Domain expressions *) -module FiniteDomains = -struct - (** - Create a new finite domain sort. - *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) size = - (new finite_domain_sort ctx)#cnstr_si name size +and FiniteDomains : +sig + type finite_domain_sort = FiniteDomainSort of Sort.sort + +end = struct + type finite_domain_sort = FiniteDomainSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + FiniteDomainSort(s) + + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gc s) + let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gnc s) + let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s))-> (z3obj_gno s) (** Create a new finite domain sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) size = - (new finite_domain_sort ctx)#cnstr_si (Symbol.mk_string ctx name) size + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + create_sort ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size) + + (** + Create a new finite domain sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_sort ctx (Symbol.mk_string ctx name) size (** Indicates whether the term is of an array sort. *) - let is_finite_domain ( x : expr ) = - (Z3native.is_app x#gnc x#gno) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + let is_finite_domain ( x : Expr.expr ) = + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == FINITE_DOMAIN_SORT) (** Indicates whether the term is a less than predicate over a finite domain. *) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) (** The size of the finite domain sort. *) - let get_size (x : finite_domain_sort) = - let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in + let get_size ( x : finite_domain_sort ) = + let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in if r then v else raise (Z3native.Exception "Conversion failed.") end (** Functions to manipulate Relation expressions *) -module Relations = -struct +and Relations : +sig + type relation_sort = RelationSort of Sort.sort + +end = struct + type relation_sort = RelationSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + RelationSort(s) + + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gc s) + let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gnc s) + let gno ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s))-> (z3obj_gno s) + (** Indicates whether the term is of a relation sort. *) - let is_relation ( x : expr ) = - ((Z3native.is_app x#gnc x#gno) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT)) + let is_relation ( x : Expr.expr ) = + ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == RELATION_SORT)) (** Indicates whether the term is an relation store @@ -2370,40 +2172,40 @@ struct The function takes n+1 arguments, where the first argument is the relation and the remaining n elements correspond to the n columns of the relation. *) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) (** Indicates whether the term is an empty relation *) - let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) (** Indicates whether the term is a test for the emptiness of a relation *) - let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) (** Indicates whether the term is a relational join *) - let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_join ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) (** Indicates whether the term is the union or convex hull of two relations. The function takes two arguments. *) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) (** Indicates whether the term is the widening of two relations The function takes two arguments. *) - let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_widen ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). The function takes one argument. *) - let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_project ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) (** Indicates whether the term is a relation filter @@ -2414,7 +2216,7 @@ struct corresponding to the columns of the relation. So the first column in the relation has index 0. *) - let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) (** Indicates whether the term is an intersection of a relation with the negation of another. @@ -2429,7 +2231,7 @@ struct target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with ( x : expr ) on the columns c1, d1, .., cN, dN. *) - let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_negation_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) (** Indicates whether the term is the renaming of a column in a relation @@ -2437,12 +2239,12 @@ struct The function takes one argument. The parameters contain the renaming as a cycle. *) - let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_rename ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) (** Indicates whether the term is the complement of a relation *) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) (** Indicates whether the term is a relational select @@ -2451,7 +2253,7 @@ struct The function takes n+1 arguments, where the first argument is a relation, and the remaining n arguments correspond to a record. *) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) (** Indicates whether the term is a relational clone (copy) @@ -2462,38 +2264,153 @@ struct for terms of kind to perform destructive updates to the first argument. *) - let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + let is_clone ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) (** The arity of the relation sort. *) - let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno + let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) (** The sorts of the columns of the relation sort. *) - let get_column_sorts (x : relation_sort) = + let get_column_sorts ( x : relation_sort ) = let n = get_arity x in - let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in + let f i = (create_sort (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in Array.init n f end (** Functions to manipulate Datatype expressions *) -module Datatypes = -struct +and Datatypes : +sig + type datatype_expr = DatatypeExpr of Expr.expr + type datatype_sort = DatatypeSort of Sort.sort + + val create_expr : context -> Z3native.ptr -> datatype_expr +end = struct + type datatype_expr = DatatypeExpr of Expr.expr + type datatype_sort = DatatypeSort of Sort.sort + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (Expr.create ctx no) in + DatatypeExpr(e) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + DatatypeSort(s) + + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s))-> (z3obj_gno s) + + (** Constructors *) module Constructor = struct + type constructor_extra = { + m_n : int; + mutable m_tester_decl : FuncDecl.func_decl option; + mutable m_constructor_decl : FuncDecl.func_decl option ; + mutable m_accessor_decls : FuncDecl.func_decl array option} + type constructor = Constructor of (z3_native_object * constructor_extra) + + let create_ssssi ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + let n = (Array.length field_names) in + if n != (Array.length sorts) then + raise (Z3native.Exception "Number of field names does not match number of sorts") + else + if n != (Array.length sort_refs) then + raise (Z3native.Exception "Number of field names does not match number of sort refs") + else + let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) + (Symbol.gno recognizer) + n + (Symbol.aton field_names) + (Sort.aton sorts) + sort_refs) in + let no : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + let ex : constructor_extra = { m_n = n; + m_tester_decl = None; + m_constructor_decl = None; + m_accessor_decls = None} in + (z3obj_sno no ctx ptr) ; + (z3obj_create no) ; + let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f no ; + Constructor(no, ex) + + let init_extra ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_tester_decl with + | None -> + let (a, b, c) = (Z3native.query_constructor (z3obj_gnc no) (z3obj_gno no) ex.m_n) in + ex.m_constructor_decl <- Some (FuncDecl.create (z3obj_gc no) a) ; + ex.m_tester_decl <- Some (FuncDecl.create (z3obj_gc no) b) ; + ex.m_accessor_decls <- Some (let f e = (FuncDecl.create (z3obj_gc no) e) in Array.map f c) ; + () + | _ -> () + + let get_n ( x : constructor ) = + match x with Constructor(no, ex) -> + ex.m_n + + let rec tester_decl ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_tester_decl with + | Some(s) -> s + | None -> init_extra x ; tester_decl x + + let rec constructor_decl ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_constructor_decl with + | Some(s) -> s + | None -> init_extra x ; constructor_decl x + + let rec accessor_decls ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_accessor_decls with + | Some(s) -> s + | None -> init_extra x ; accessor_decls x + + let aton ( a : constructor array ) = + let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in + Array.map f a + + (** The number of fields of the constructor. *) - let get_num_fields ( x : constructor ) = x#get_n + let get_num_fields ( x : constructor ) = get_n x (** The function declaration of the constructor. *) - let get_constructor_decl ( x : constructor ) = x#constructor_decl + let get_constructor_decl ( x : constructor ) = constructor_decl x (** The function declaration of the tester. *) - let get_tester_decl ( x : constructor ) = x#tester_decl + let get_tester_decl ( x : constructor ) = tester_decl x (** The function declarations of the accessors *) - let get_accessor_decls ( x : constructor ) = x#accessor_decls + let get_accessor_decls ( x : constructor ) = accessor_decls x end + (** Constructor list objects *) + module ConstructorList = + struct + type constructor_list = z3_native_object + + let create ( ctx : context )( c : Constructor.constructor array ) = + let res : constructor_list = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Constructor.aton c))) ; + (z3obj_create res) ; + let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f res; + res + + let aton (a : constructor_list array) = + let f (e : constructor_list) = (z3obj_gno e) in + Array.map f a + end + (* DATATYPES *) (** Create a datatype constructor. @@ -2505,8 +2422,8 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array) = + Constructor.create_ssssi ctx name recognizer field_names sorts sort_refs (** @@ -2519,20 +2436,21 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : constructor array) = - (new datatype_sort ctx)#cnstr_sc name constructors + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array) = + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Constructor.aton constructors)) in + create_sort ctx x (** Create a new datatype sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors (** @@ -2540,16 +2458,16 @@ struct @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : constructor array array ) = + let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = let n = (Array.length names) in - let f e = ( (new constructor_list ctx)#cnstr_ca e ) in + let f e = (ConstructorList.create ctx e) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (constructor_listaton cla)) in - let g e = ( (new datatype_sort ctx)#cnstr_obj e) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (ConstructorList.aton cla)) in + let g e = (create_sort ctx e) in (Array.map g r) (** Create mutually recursive data-types. *) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in @@ -2558,130 +2476,230 @@ struct c (** The number of constructors of the datatype sort. *) - let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno + let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) (** The range of the array sort. *) - let get_constructors (x : datatype_sort) = + let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in + let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in Array.init n f (** The recognizers. *) - let get_recognizers (x : datatype_sort) = + let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in + let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in Array.init n f (** The constructor accessors. *) - let get_accessors (x : datatype_sort) = + let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = ( - let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in - let ds = (Z3native.get_domain_size fd#gnc fd#gno) in - let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in + let fd = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in + let g j = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in Array.init ds g ) in Array.init n f end (** Functions to manipulate Enumeration expressions *) -module Enumerations = -struct - (** - Create a new enumeration sort. - *) - let mk_sort ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss name enum_names +and Enumerations : +sig + type enum_sort_data + type enum_sort = EnumSort of (Sort.sort * enum_sort_data) +end = struct + type enum_sort_data = { mutable _constdecls : FuncDecl.func_decl array ; + mutable _testerdecls : FuncDecl.func_decl array } + type enum_sort = EnumSort of (Sort.sort * enum_sort_data) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = + let s = (Sort.create ctx no) in + let e = { _constdecls = (let f e = FuncDecl.create ctx e in (Array.map f cdecls)) ; + _testerdecls = (let f e = FuncDecl.create ctx e in (Array.map f tdecls)) } in + EnumSort(s, e) + + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gc s) + let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gnc s) + let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_)-> (z3obj_gno s) + (** Create a new enumeration sort. *) - let mk_sort_s ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss - (Symbol.mk_string ctx name) - (Symbol.mk_strings ctx enum_names) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in + create_sort ctx a b c + + (** + Create a new enumeration sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string array ) = + mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) - let get_const_decls (x : enum_sort) = x#const_decls + let get_const_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._constdecls (** The test predicates for the constants in the enumeration. *) - let get_tester_decls (x : enum_sort) = x#tester_decls + let get_tester_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._testerdecls end (** Functions to manipulate List expressions *) -module Lists = -struct - (** - Create a new list sort. - *) - let mk_sort ( ctx : context ) (name : Symbol.symbol) elem_sort = - (new list_sort ctx)#cnstr_ss name elem_sort +and Lists : +sig + type list_sort_data + type list_sort = ListSort of (Sort.sort * list_sort_data) - (** - Create a new list sort. - *) +end = struct + type list_sort_data = { _nildecl : FuncDecl.func_decl ; + _is_nildecl : FuncDecl.func_decl ; + _consdecl : FuncDecl.func_decl ; + _is_consdecl : FuncDecl.func_decl ; + _headdecl : FuncDecl.func_decl ; + _taildecl : FuncDecl.func_decl } + type list_sort = ListSort of (Sort.sort * list_sort_data) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = + let s = (Sort.create ctx no) in + let e = {_nildecl = FuncDecl.create ctx nildecl; + _is_nildecl = FuncDecl.create ctx is_nildecl; + _consdecl = FuncDecl.create ctx consdecl; + _is_consdecl = FuncDecl.create ctx is_consdecl; + _headdecl = FuncDecl.create ctx headdecl; + _taildecl = FuncDecl.create ctx taildecl} in + ListSort(s, e) + + let sgc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gc s) + let sgnc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gnc s) + let sgno ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_)-> (z3obj_gno s) + + + (** Create a new list sort. *) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : Sort.sort ) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in + create_sort ctx r a b c d e f + + (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) - let get_nil_decl (x : list_sort) = x#nil_decl + let get_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._nildecl (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl (x : list_sort) = x#is_nil_decl + let get_is_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_nildecl (** The declaration of the cons function of this list sort. *) - let get_cons_decl (x : list_sort) = x#cons_decl + let get_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._consdecl (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl (x : list_sort) = x#is_cons_decl + let get_is_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_consdecl (** The declaration of the head function of this list sort. *) - let get_head_decl (x : list_sort) = x#head_decl + let get_head_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._headdecl (** The declaration of the tail function of this list sort. *) - let get_tail_decl (x : list_sort) = x#tail_decl + let get_tail_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._taildecl (** The empty list. *) - let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] + let nil ( x : list_sort ) = Expr.create_fa (sgc x) (get_nil_decl x) [||] end (** Functions to manipulate Tuple expressions *) -module Tuples = -struct - (** - Create a new tuple sort. - *) - let mk_sort ( ctx : context ) name field_names field_sorts = - (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts +and Tuples : +sig + type tuple_sort = TupleSort of Sort.sort +end = struct + type tuple_sort = TupleSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + TupleSort(s) + + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s))-> (z3obj_gno s) + + (** Create a new tuple sort. *) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : Sort.sort array ) = + let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Symbol.aton field_names) (Sort.aton field_sorts)) in + (* CMW: leaks a,b? *) + create_sort ctx r (** The constructor function of the tuple. *) - let get_mk_decl (x : tuple_sort) = - (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) + let get_mk_decl ( x : tuple_sort ) = + FuncDecl.create (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) (** The number of fields in the tuple. *) - let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno + let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) (** The field declarations. *) - let get_field_decls (x : tuple_sort) = + let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in - let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in + let f i = FuncDecl.create (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in Array.init n f end (** Functions to manipulate arithmetic expressions *) -module Arithmetic = -struct +and Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type int_sort = IntSort of Sort.sort + type real_sort = RealSort of Sort.sort + + type arith_expr = Expr of Expr.expr + type int_expr = IntExpr of arith_expr + type real_expr = RealExpr of arith_expr + + type int_num = IntNum of int_expr + type rat_num = RatNum of real_expr + type algebraic_num = AlgebraicNum of arith_expr + + + val create_arith_expr : context -> Z3native.ptr -> arith_expr + val create_int_expr : context -> Z3native.ptr -> int_expr + val create_real_expr : context -> Z3native.ptr -> real_expr + val create_int_num : context -> Z3native.ptr -> int_num + val create_rat_num : context -> Z3native.ptr -> rat_num + val create_algebraic_num : context -> Z3native.ptr -> algebraic_num +end = struct + type arith_sort = ArithSort of Sort.sort + type int_sort = IntSort of Sort.sort + type real_sort = RealSort of Sort.sort + + type arith_expr = ArithExpr of Expr.expr + type int_expr = IntExpr of arith_expr + type real_expr = RealExpr of arith_expr + + type int_num = IntNum of int_expr + type rat_num = RatNum of real_expr + type algebraic_num = AlgebraicNum of arith_expr + + let create_arith_expr ( ctx : context ) ( no : Z3native.ptr ) = + ArithExpr(Expr.create ctx no) + + let create_int_expr ( ctx : context ) ( no : Z3native.ptr ) = + IntExpr(create_arith_expr ctx no) + + let create_real_expr ( ctx : context ) ( no : Z3native.ptr ) = + RealExpr(create_arith_expr ctx no) + + let create_int_num ( ctx : context ) ( no : Z3native.ptr ) = + IntNum(create_int_expr ctx no) + + let create_rat_num ( ctx : context ) ( no : Z3native.ptr ) = + RatNum(create_real_expr ctx no) + (** Create a new integer sort. *) let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort (context_gno ctx)) + (new int_sort ctx)#create_obj (Z3native.mk_int_sort (context_gno ctx)) (** Create a real sort. *) let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort (context_gno ctx)) + (new real_sort ctx)#create_obj (Z3native.mk_real_sort (context_gno ctx)) (** Indicates whether the term is of integer sort. @@ -2802,11 +2820,11 @@ struct (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) + (new int_num x#gc)#create_obj (Z3native.get_numerator x#gnc x#gno) (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) + (new int_num x#gc)#create_obj (Z3native.get_denominator x#gnc x#gno) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2844,75 +2862,92 @@ struct Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - (create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) t#gno) :> arith_expr) + ArithExpr(create ctx (Z3native.mk_unary_minus (context_gno ctx) + (gno (match t with ArithExpr(b) -> b)))) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - (create_expr ctx (Z3native.mk_div (context_gno ctx) t1#gno t2#gno) :> arith_expr) + ArithExpr(create ctx (Z3native.mk_div (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 mod t2. The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_mod (context_gno ctx) t1#gno t2#gno) + IntExpr(create ctx (Z3native.mk_mod (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_rem (context_gno ctx) t1#gno t2#gno) + IntExpr(create ctx (Z3native.mk_rem (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 ^ t2. *) - let mk_Power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (create_expr ctx (Z3native.mk_power (context_gno ctx) t1#gno t2#gno) :> arith_expr) + let mk_power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + ArithExpr(create_expr ctx (Z3native.mk_power (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_lt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_le (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_le (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_gt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_ge (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Coerce an integer to a real. @@ -2925,7 +2960,8 @@ struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real (context_gno ctx) t#gno) + RealExpr(create (Z3native.mk_int2real (context_gno ctx) + (gno (match t with BoolExpr(b) -> b)))) (** Coerce a real to an integer. @@ -2935,14 +2971,14 @@ struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int (context_gno ctx) t#gno) + (new int_expr ctx)#create_obj (Z3native.mk_real2int (context_gno ctx) t#gno) (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int (context_gno ctx) t#gno) - + BoolExpr(create ctx (Z3native.mk_is_int (context_gno ctx) + (gno (match t with BoolExpr(b) -> b)))) (** Return a upper bound for a given real algebraic number. The interval isolating the number is smaller than 1/10^. @@ -2951,7 +2987,7 @@ struct @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) + (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) (** Return a lower bound for the given real algebraic number. @@ -2961,7 +2997,7 @@ struct @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2981,7 +3017,7 @@ struct raise (Z3native.Exception "Denominator is zero") else - (new rat_num ctx)#cnstr_obj (Z3native.mk_real (context_gno ctx) num den) + (new rat_num ctx)#create_obj (Z3native.mk_real (context_gno ctx) num den) (** Create a real numeral. @@ -2989,7 +3025,7 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_s ( ctx : context ) ( v : string ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) + (new rat_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create a real numeral. @@ -2998,14 +3034,14 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_i ( ctx : context ) ( v : int ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) + (new rat_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create an integer numeral. @param v A string representing the Term value in decimal notation. *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) + (new int_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) (** Create an integer numeral. @@ -3013,7 +3049,7 @@ struct @return A Term with value and sort Integer *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) + (new int_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3021,13 +3057,30 @@ end (** Functions to manipulate bit-vector expressions *) -module BitVectors = -struct +and BitVectors : +sig + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val create_expr : context -> Z3native.ptr -> bitvec_expr + val create_num : context -> Z3native.ptr -> bitvec_num +end = struct + type bitvec_expr = Expr of Expr.expr + type bitvec_num = BitVecExpr of bitvec_expr + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (Expr.create ctx no) in + BitVecExpr(e) + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + let e = (create_expr ctx no) in + BitVecNum(e) + (** Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort (context_gno ctx) size) + (new bitvec_sort ctx)#create_obj (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. @@ -3328,91 +3381,91 @@ struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) (** Unsigned division. @@ -3424,7 +3477,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) (** Signed division. @@ -3439,7 +3492,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) (** Unsigned remainder. @@ -3449,7 +3502,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) (** Signed remainder. @@ -3461,7 +3514,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) (** Two's complement signed remainder (sign follows divisor). @@ -3470,7 +3523,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) (** Unsigned less-than @@ -3478,7 +3531,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvult (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed less-than @@ -3486,7 +3541,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvslt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Unsigned less-than or equal to. @@ -3494,7 +3551,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvule (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed less-than or equal to. @@ -3502,7 +3561,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsle (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Unsigned greater than or equal to. @@ -3510,7 +3571,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvuge (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed greater than or equal to. @@ -3518,7 +3581,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsge (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Unsigned greater-than. @@ -3526,7 +3591,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvugt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed greater-than. @@ -3534,7 +3601,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsgt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Bit-vector concatenation. @@ -3545,7 +3614,9 @@ struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat (context_gno ctx) t1#gno t2#gno) + BitVectors.BitVecExpr(create ctx (Z3native.mk_concat (context_gno ctx) + (gno (match t1 with BitVecExpr(b) -> b)) + (gno (match t2 with BitVecExpr(b) -> b)))) (** Bit-vector extraction. @@ -3556,7 +3627,7 @@ struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) (** Bit-vector sign extension. @@ -3566,7 +3637,7 @@ struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_sign_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) (** Bit-vector zero extension. @@ -3577,7 +3648,7 @@ struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_zero_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) (** Bit-vector repetition. @@ -3585,7 +3656,7 @@ struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_repeat (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) (** Shift left. @@ -3600,7 +3671,9 @@ struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_bvshl (context_gno ctx) + (gno (match t1 with BitVecExpr(b) -> b)) + (gno (match t2 with BitVecExpr(b) -> b)))) (** Logical shift right @@ -3614,7 +3687,9 @@ struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_bvlshr (context_gno ctx) + (gno (match t1 with BitVecExpr(b) -> b)) + (gno (match t2 with BitVecExpr(b) -> b)))) (** Arithmetic shift right @@ -3630,7 +3705,9 @@ struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_bvashr (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Rotate Left. @@ -3639,7 +3716,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_rotate_left (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) (** Rotate Right. @@ -3648,7 +3725,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_rotate_right (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) (** Rotate Left. @@ -3657,7 +3734,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_ext_rotate_left (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Rotate Right. @@ -3667,7 +3746,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_ext_rotate_right (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an bit bit-vector from the integer argument . @@ -3680,7 +3761,7 @@ struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv (context_gno ctx) n t#gno) + BitVecExpr(create ctx (Z3native.mk_int2bv (context_gno ctx) n (gno (match t with IntExpr(b) -> b)))) (** Create an integer from the bit-vector argument . @@ -3698,7 +3779,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) + (new int_expr ctx)#create_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3706,7 +3787,10 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow (context_gno ctx) t1#gno t2#gno signed) + BoolExpr(create ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)) + signed)) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3714,23 +3798,30 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow (context_gno ctx) t1#gno t2#gno) - + BoolExpr(create ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) + (** Create a predicate that checks that the bit-wise subtraction does not overflow. The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow (context_gno ctx) t1#gno t2#gno) - + BoolExpr(create ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) + (** Create a predicate that checks that the bit-wise subtraction does not underflow. The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow (context_gno ctx) t1#gno t2#gno signed) + BoolExpr(create ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)) + signed)) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3738,7 +3829,9 @@ struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3746,7 +3839,7 @@ struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow (context_gno ctx) t#gno) + BoolExpr(create ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (gno (match t with BitVecExpr(b) -> b)))) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3754,7 +3847,10 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow (context_gno ctx) t1#gno t2#gno signed) + BoolExpr(create ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)) + signed)) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3762,7 +3858,9 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create a bit-vector numeral. @@ -3771,12 +3869,13 @@ struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = - (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) + (new bitvec_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) end (** Functions to manipulate proof expressions *) -module Proofs = -struct +and Proofs : +sig +end = struct (** Indicates whether the term is a Proof for the expression 'true'. *) @@ -4259,13 +4358,13 @@ struct type goal = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : goal = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.goal_inc_ref ; dec_ref = Z3native.goal_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4318,7 +4417,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new bool_expr (z3obj_gc x))#create_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) @@ -4334,7 +4433,7 @@ struct (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = - cnstr to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) let simplify ( x : goal ) ( p : Params.params option ) = @@ -4352,7 +4451,7 @@ struct Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; Z3native.tactic_dec_ref (z3obj_gnc x) tn ; - cnstr (z3obj_gc x) res + create (z3obj_gc x) res (** @@ -4365,7 +4464,7 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - cnstr ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) + create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) @@ -4380,13 +4479,13 @@ struct type model = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.model_inc_ref ; dec_ref = Z3native.model_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4400,13 +4499,13 @@ struct type func_interp = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_interp = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.func_interp_inc_ref ; dec_ref = Z3native.func_interp_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4419,13 +4518,13 @@ struct type func_entry = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.func_entry_inc_ref ; dec_ref = Z3native.func_entry_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4467,7 +4566,7 @@ struct *) let get_entries ( x : func_interp ) = let n = (get_num_entries x) in - let f i = (FuncEntry.cnstr (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4534,11 +4633,11 @@ struct raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + get_func_interp x ((new func_decl f#gc)#create_obj fd) | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in - if (Z3native.is_null n) then None else Some (FuncInterp.cnstr (z3obj_gc x) n) + if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) (** The number of constants that have an interpretation in the model. *) let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) @@ -4546,7 +4645,7 @@ struct (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f @@ -4556,15 +4655,15 @@ struct (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in - let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) @@ -4619,7 +4718,7 @@ struct An array of expressions, where each is an element of the universe of *) let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in + let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f @@ -4644,13 +4743,13 @@ struct type probe = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : probe = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.probe_inc_ref ; dec_ref = Z3native.probe_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4686,48 +4785,48 @@ struct Creates a new Probe. *) let mk_probe ( ctx : context ) ( name : string ) = - (cnstr ctx (Z3native.mk_probe (context_gno ctx) name)) + (create ctx (Z3native.mk_probe (context_gno ctx) name)) (** Create a probe that always evaluates to . *) let const ( ctx : context ) ( v : float ) = - (cnstr ctx (Z3native.probe_const (context_gno ctx) v)) + (create ctx (Z3native.probe_const (context_gno ctx) v)) (** Create a probe that evaluates to "true" when the value returned by is less than the value returned by *) let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is greater than the value returned by *) let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is less than or equal the value returned by *) let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is greater than or equal the value returned by *) let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is equal to the value returned by *) let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value @@ -4735,7 +4834,7 @@ struct *) (* CMW: and is a keyword *) let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value @@ -4743,7 +4842,7 @@ struct *) (* CMW: or is a keyword *) let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value @@ -4751,7 +4850,7 @@ struct *) (* CMW: is not a keyword? *) let not_ ( ctx : context ) ( p : probe ) = - (cnstr ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) + (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) end @@ -4767,13 +4866,13 @@ struct type tactic = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : tactic = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.tactic_inc_ref ; dec_ref = Z3native.tactic_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4786,13 +4885,13 @@ struct type apply_result = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : apply_result = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.apply_result_inc_ref ; dec_ref = Z3native.apply_result_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4803,19 +4902,19 @@ struct (** Retrieves the subgoals from the apply_result. *) let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in - let f i = Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** Retrieves the subgoals from the apply_result. *) let get_subgoal ( x : apply_result ) ( i : int ) = - Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) (** Convert a model for the subgoal into a model for the original goal g, that the ApplyResult was obtained from. #return A model for g *) let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.cnstr (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) + Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) (** A string representation of the ApplyResult. *) let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) @@ -4826,13 +4925,13 @@ struct (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.create (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with - | None -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) - | Some (pn) -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) + | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) + | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) (** The number of supported tactics. @@ -4858,7 +4957,7 @@ struct Creates a new Tactic. *) let mk_tactic ( ctx : context ) ( name : string ) = - cnstr ctx (Z3native.mk_tactic (context_gno ctx) name) + create ctx (Z3native.mk_tactic (context_gno ctx) name) (** Create a tactic that applies to a Goal and @@ -4870,17 +4969,17 @@ struct | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in match (Array.fold_left f None ts) with | None -> - cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) | Some(x) -> let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in - cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) (** Create a tactic that first applies to a Goal and if it fails then returns the result of applied to the Goal. *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - cnstr ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that applies to a goal for milliseconds. @@ -4888,7 +4987,7 @@ struct If does not terminate within milliseconds, then it fails. *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - cnstr ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) + create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) (** Create a tactic that applies to a given goal if the probe @@ -4898,52 +4997,52 @@ struct *) (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - cnstr ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) + create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - cnstr ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that keeps applying until the goal is not modified anymore or the maximum number of iterations is reached. *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - cnstr ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) + create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) (** Create a tactic that just returns the given goal. *) let skip ( ctx : context ) = - cnstr ctx (Z3native.tactic_skip (context_gno ctx)) + create ctx (Z3native.tactic_skip (context_gno ctx)) (** Create a tactic always fails. *) let fail ( ctx : context ) = - cnstr ctx (Z3native.tactic_fail (context_gno ctx)) + create ctx (Z3native.tactic_fail (context_gno ctx)) (** Create a tactic that fails if the probe evaluates to false. *) let fail_if ( ctx : context ) ( p : Probe.probe ) = - cnstr ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) + create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) or trivially unsatisfiable (i.e., contains `false'). *) let fail_if_not_decided ( ctx : context ) = - cnstr ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) + create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) (** Create a tactic that applies using the given set of parameters . *) let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - cnstr ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) + create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . @@ -4956,14 +5055,14 @@ struct Create a tactic that applies the given tactics in parallel. *) let par_or ( ctx : context ) ( t : tactic array ) = - cnstr ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) + create ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) (** Create a tactic that applies to a given goal and then to every subgoal produced by . The subgoals are processed in parallel. *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - cnstr ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Interrupt the execution of a Z3 procedure. @@ -4980,13 +5079,13 @@ struct type solver = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.solver_inc_ref ; dec_ref = Z3native.solver_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -5003,13 +5102,13 @@ struct type statistics = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.stats_inc_ref ; dec_ref = Z3native.stats_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -5028,7 +5127,7 @@ struct mutable m_float : float } (**/**) - let cnstr_si k v = + let create_si k v = let res : statistics_entry = { m_key = k ; m_is_int = true ; @@ -5038,7 +5137,7 @@ struct } in res - let cnstr_sd k v = + let create_sd k v = let res : statistics_entry = { m_key = k ; m_is_int = false ; @@ -5089,9 +5188,9 @@ struct let f i = ( let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - (Entry.cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - (Entry.cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in Array.init n f @@ -5126,7 +5225,7 @@ struct Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.create (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). @@ -5200,7 +5299,7 @@ struct The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -5208,9 +5307,9 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = ((new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get a i)#gno) in + let f i = ((new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get a i)#gno) in Array.init n f (** @@ -5225,7 +5324,7 @@ struct if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (astaton assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (AST.aton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -5243,7 +5342,7 @@ struct if (Z3native.is_null q) then None else - Some (Model.cnstr (z3obj_gc x) q) + Some (Model.create (z3obj_gc x) q) (** The proof of the last Check. @@ -5266,7 +5365,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -5281,7 +5380,7 @@ struct Solver statistics. *) let get_statistics ( x : solver ) = - (Statistics.cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) + (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) (** Creates a new (incremental) solver. @@ -5292,8 +5391,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with - | None -> (cnstr ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) + | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) (** Creates a new (incremental) solver. @@ -5306,7 +5405,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) + (create ctx (Z3native.mk_simple_solver (context_gno ctx))) (** Creates a solver that is implemented using the given tactic. @@ -5315,7 +5414,7 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = - (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) + (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** A string representation of the solver. @@ -5330,13 +5429,13 @@ struct type fixedpoint = z3_native_object (**/**) - let cnstr ( ctx : context ) = + let create ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.fixedpoint_inc_ref ; dec_ref = Z3native.fixedpoint_dec_ref } in (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -5356,7 +5455,7 @@ struct Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.create (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. @@ -5487,30 +5586,30 @@ struct Convert benchmark given as set of axioms, rules and queries to a string. *) let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (astaton queries) + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (AST.aton queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Create a Fixedpoint context. *) - let mk_fixedpoint ( ctx : context ) = cnstr ctx + let mk_fixedpoint ( ctx : context ) = create ctx end (** Global and context options @@ -5590,7 +5689,7 @@ struct *) let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (astaton assumptions) + (Array.length assumptions) (AST.aton assumptions) formula#gno (** @@ -5613,7 +5712,7 @@ struct Z3native.parse_smtlib_string (context_gno ctx) str cs (Symbol.aton sort_names) - (astaton sorts) + (AST.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) @@ -5633,7 +5732,7 @@ struct Z3native.parse_smtlib_file (context_gno ctx) file_name cs (Symbol.aton sort_names) - (astaton sorts) + (AST.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) @@ -5675,7 +5774,7 @@ struct *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in + let f i = (new func_decl ctx)#create_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** @@ -5708,7 +5807,7 @@ struct Z3native.parse_smtlib2_string (context_gno ctx) str cs (Symbol.aton sort_names) - (astaton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) @@ -5728,7 +5827,7 @@ struct Z3native.parse_smtlib2_string (context_gno ctx) file_name cs (Symbol.aton sort_names) - (astaton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) From 0138d0c11c283c1d3457055975df69fdac9b5410 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 4 Feb 2013 23:18:55 +0000 Subject: [PATCH 273/507] Checkpoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 643 ++++++++++++++++++++++++++--------------------- 1 file changed, 355 insertions(+), 288 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0e47912ae..58c319d4d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1097,6 +1097,7 @@ sig val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val get_func_decl : expr -> FuncDecl.func_decl + val is_numeral : expr -> bool end = struct type expr = Expr of AST.ast @@ -1107,20 +1108,20 @@ end = struct let s = Z3native.get_sort (context_gno ctx) obj in let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (match (Arithmetic.create_algebraic_num ctx obj) with Arithmetic.AlgebraicNum(Arithmetic.Expr(e)) -> e) + (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.Expr(e)) -> e) else if (Z3native.is_numeral_ast (context_gno ctx) obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with - | INT_SORT -> (match (Arithmetic.create_int_num ctx obj) with Arithmetic.IntNum(Arithmetic.IntExpr(Arithmetic.Expr(e))) -> e) - | REAL_SORT -> (match (Arithmetic.create_rat_num ctx obj) with Arithmetic.RatNum(Arithmetic.RealExpr(Arithmetic.Expr(e))) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.Expr(e))) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.Expr(e))) -> e) | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) | _ -> raise (Z3native.Exception "Unsupported numeral object") else match sk with - | BOOL_SORT -> (match (Booleans.create ctx obj) with Booleans.BoolExpr(e) -> e) - | INT_SORT -> (match (Arithmetic.create_int_expr ctx obj) with Arithmetic.IntExpr(Arithmetic.Expr(e)) -> e) - | REAL_SORT -> (match (Arithmetic.create_real_expr ctx obj) with Arithmetic.RealExpr(Arithmetic.Expr(e)) -> e) + | BOOL_SORT -> (match (Booleans.create_expr ctx obj) with Booleans.BoolExpr(e) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.Expr(e)) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.Expr(e)) -> e) | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) @@ -1406,16 +1407,20 @@ sig type bool_expr = BoolExpr of Expr.expr type bool_sort = BoolSort of Sort.sort - val create : context -> Z3native.ptr -> bool_expr + val create_expr : context -> Z3native.ptr -> bool_expr + val create_sort : context -> Z3native.ptr -> bool_sort val aton : bool_expr array -> Z3native.ptr array end = struct type bool_expr = BoolExpr of Expr.expr type bool_sort = BoolSort of Sort.sort - let create ( ctx : context ) ( no : Z3native.ptr ) = + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let a = (AST.create ctx no) in BoolExpr(Expr.Expr(a)) + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + BoolSort(Sort.create ctx no) + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gc e) let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gnc e) let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gno e) @@ -1444,13 +1449,13 @@ end = struct The true Term. *) let mk_true ( ctx : context ) = - create ctx (Z3native.mk_true (context_gno ctx)) + create_expr ctx (Z3native.mk_true (context_gno ctx)) (** The false Term. *) let mk_false ( ctx : context ) = - create ctx (Z3native.mk_false (context_gno ctx)) + create_expr ctx (Z3native.mk_false (context_gno ctx)) (** Creates a Boolean value. @@ -1462,19 +1467,19 @@ end = struct Creates the equality = . *) let mk_eq ( ctx : context ) ( x : Expr.expr ) ( y : Expr.expr ) = - create ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + create_expr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) (** Creates a distinct term. *) let mk_distinct ( ctx : context ) ( args : Expr.expr array ) = - create ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) + create_expr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) (** Mk an expression representing not(a). *) let mk_not ( ctx : context ) ( a : bool_expr ) = - create ctx (Z3native.mk_not (context_gno ctx) (gno a)) + create_expr ctx (Z3native.mk_not (context_gno ctx) (gno a)) (** Create an expression representing an if-then-else: ite(t1, t2, t3). @@ -1483,36 +1488,36 @@ end = struct @param t3 An expression with the same sort as *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + create_expr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) (** Create an expression representing t1 iff t2. *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + create_expr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 -> t2. *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + create_expr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 xor t2. *) let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + create_expr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing the AND of args *) let mk_and ( ctx : context ) ( args : bool_expr array ) = - create ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) + create_expr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) (** Create an expression representing the OR of args *) let mk_or ( ctx : context ) ( args : bool_expr array ) = - create ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) + create_expr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) end (** Quantifier expressions *) @@ -1676,7 +1681,7 @@ end = struct The body of the quantifier. *) let get_body ( x : quantifier ) = - Booleans.create (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + Booleans.create_expr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) (** Creates a new bound variable. @@ -2643,416 +2648,478 @@ end and Arithmetic : sig type arith_sort = ArithSort of Sort.sort - type int_sort = IntSort of Sort.sort - type real_sort = RealSort of Sort.sort - type arith_expr = Expr of Expr.expr - type int_expr = IntExpr of arith_expr - type real_expr = RealExpr of arith_expr - - type int_num = IntNum of int_expr - type rat_num = RatNum of real_expr - type algebraic_num = AlgebraicNum of arith_expr - - val create_arith_expr : context -> Z3native.ptr -> arith_expr - val create_int_expr : context -> Z3native.ptr -> int_expr - val create_real_expr : context -> Z3native.ptr -> real_expr - val create_int_num : context -> Z3native.ptr -> int_num - val create_rat_num : context -> Z3native.ptr -> rat_num - val create_algebraic_num : context -> Z3native.ptr -> algebraic_num + val create_expr : context -> Z3native.ptr -> arith_expr + val aton : arith_expr array -> Z3native.ptr array + + module Integers : sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val create_sort : context -> Z3native.ptr -> int_sort + val create_expr : context -> Z3native.ptr -> int_expr + val create_num : context -> Z3native.ptr -> int_num + end + + module Reals : sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val create_sort : context -> Z3native.ptr -> real_sort + val create_expr : context -> Z3native.ptr -> real_expr + val create_num : context -> Z3native.ptr -> rat_num + end + + module AlgebraicNumbers : sig + type algebraic_num = AlgebraicNum of arith_expr + + val create_num : context -> Z3native.ptr -> algebraic_num + end + end = struct type arith_sort = ArithSort of Sort.sort - type int_sort = IntSort of Sort.sort - type real_sort = RealSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - type int_expr = IntExpr of arith_expr - type real_expr = RealExpr of arith_expr - - type int_num = IntNum of int_expr - type rat_num = RatNum of real_expr - type algebraic_num = AlgebraicNum of arith_expr let create_arith_expr ( ctx : context ) ( no : Z3native.ptr ) = ArithExpr(Expr.create ctx no) - let create_int_expr ( ctx : context ) ( no : Z3native.ptr ) = - IntExpr(create_arith_expr ctx no) + let create_arith_sort ( ctx : context ) ( no : Z3native.ptr ) = + ArithSort(Sort.create ctx no) - let create_real_expr ( ctx : context ) ( no : Z3native.ptr ) = - RealExpr(create_arith_expr ctx no) + let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gno s) + let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) + let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) + let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) - let create_int_num ( ctx : context ) ( no : Z3native.ptr ) = - IntNum(create_int_expr ctx no) - let create_rat_num ( ctx : context ) ( no : Z3native.ptr ) = - RatNum(create_real_expr ctx no) - - (** - Create a new integer sort. - *) - let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#create_obj (Z3native.mk_int_sort (context_gno ctx)) + module rec Integers : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr - (** - Create a real sort. - *) - let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#create_obj (Z3native.mk_real_sort (context_gno ctx)) + val create_sort : context -> Z3native.ptr -> int_sort + val create_expr : context -> Z3native.ptr -> int_expr + val create_num : context -> Z3native.ptr -> int_num + end = struct + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + IntSort(create_arith_sort ctx no) + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + IntExpr(create_arith_expr ctx no) + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + IntNum(create_expr ctx no) + + let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) + let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) + let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) + let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) + let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) + let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) + let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) + let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) + let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) + + (** Create a new integer sort. *) + let mk_sort ( ctx : context ) = + create_sort ctx (Z3native.mk_int_sort (context_gno ctx)) + + (** Retrieve the int value. *) + let get_int ( x : int_num ) = + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + if r then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + (** + Creates an integer constant. + *) + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) + + (** + Creates an integer constant. + *) + let mk_int_const_s ( ctx : context ) ( name : string ) = + mk_int_const ctx (Symbol.mk_string ctx name) + + (** + Create an expression representing t1 mod t2. + The arguments must have int type. + *) + let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + create_expr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + + (** + Create an expression representing t1 rem t2. + The arguments must have int type. + *) + let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + create_expr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + + (** + Create an integer numeral. + @param v A string representing the Term value in decimal notation. + *) + let mk_int_numeral_s ( ctx : context ) ( v : string ) = + create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + (** + Create an integer numeral. + @param v value of the numeral. + @return A Term with value and sort Integer + *) + let mk_int_numeral_i ( ctx : context ) ( v : int ) = + create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + (** + Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. + *) + let mk_int2real ( ctx : context ) ( t : int_expr ) = + Reals.create_expr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)) + end + + and Reals : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val create_sort : context -> Z3native.ptr -> real_sort + val create_expr : context -> Z3native.ptr -> real_expr + val create_num : context -> Z3native.ptr -> rat_num + end = struct + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + RealSort(create_arith_sort ctx no) + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + RealExpr(create_arith_expr ctx no) + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + RatNum(create_expr ctx no) + + let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) + let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) + let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) + let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) + let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) + let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) + let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) + let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) + let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) + + (** Create a real sort. *) + let mk_sort ( ctx : context ) = + create_sort ctx (Z3native.mk_real_sort (context_gno ctx)) + + (** The numerator of a rational numeral. *) + let get_numerator ( x : rat_num ) = + Integers.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + + (** The denominator of a rational numeral. *) + let get_denominator ( x : rat_num ) = + Integers.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : rat_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + (** Creates a real constant. *) + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) + + (** Creates a real constant. *) + let mk_real_const_s ( ctx : context ) ( name : string ) = + mk_real_const ctx (Symbol.mk_string ctx name) + + (** + Create a real from a fraction. + + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + *) + let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + if (den == 0) then + raise (Z3native.Exception "Denominator is zero") + else + create_num ctx (Z3native.mk_real (context_gno ctx) num den) + + (** + Create a real numeral. + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + *) + let mk_numeral_s ( ctx : context ) ( v : string ) = + create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + (** + Create a real numeral. + + @param v value of the numeral. + @return A Term with value and sort Real + *) + let mk_numeral_i ( ctx : context ) ( v : int ) = + create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + (** Creates an expression that checks whether a real number is an integer. *) + let mk_is_integer ( ctx : context ) ( t : real_expr ) = + Booleans.create_expr ctx (Z3native.mk_is_int (context_gno ctx) (egno t)) + + (** + Coerce a real to an integer. + + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. + *) + let mk_real2int ( ctx : context ) ( t : real_expr ) = + Integers.create_expr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)) + end + + and AlgebraicNumbers : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val create_num : context -> Z3native.ptr -> algebraic_num + end = struct + type algebraic_num = AlgebraicNum of arith_expr + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + AlgebraicNum(create_arith_expr ctx no) + + let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) + let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) + let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) + + (** + Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_upper ( x : algebraic_num ) ( precision : int ) = + Reals.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + + (** + Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_lower ( x : algebraic_num ) precision = + Reals.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + end + + let aton (a : arith_expr array) = + let f (e : arith_expr) = (egno e) in + Array.map f a (** Indicates whether the term is of integer sort. *) - let is_int ( x : expr ) = - (Z3native.is_numeral_ast x#gnc x#gno) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + let is_int ( x : Expr.expr ) = + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) (** Indicates whether the term is an arithmetic numeral. *) - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + let is_arithmetic_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) (** Indicates whether the term is a less-than-or-equal *) - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + let is_le ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) (** Indicates whether the term is a greater-than-or-equal *) - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + let is_ge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) (** Indicates whether the term is a less-than *) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) (** Indicates whether the term is a greater-than *) - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + let is_gt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) (** Indicates whether the term is addition (binary) *) - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + let is_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) (** Indicates whether the term is subtraction (binary) *) - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + let is_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) (** Indicates whether the term is a unary minus *) - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + let is_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) (** Indicates whether the term is multiplication (binary) *) - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + let is_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) (** Indicates whether the term is division (binary) *) - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + let is_div ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) (** Indicates whether the term is integer division (binary) *) - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + let is_idiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) (** Indicates whether the term is remainder (binary) *) - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + let is_remainder ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) (** Indicates whether the term is modulus (binary) *) - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + let is_modulus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) (** Indicates whether the term is a coercion of integer to real (unary) *) - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_inttoreal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) (** Indicates whether the term is a coercion of real to integer (unary) *) - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + let is_real_is_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) (** Indicates whether the term is of sort real. *) - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + let is_real ( x : Expr.expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) (** Indicates whether the term is an integer numeral. *) - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + let is_int_numeral ( x : Expr.expr ) = (Expr.is_numeral x) && (is_int x) (** Indicates whether the term is a real numeral. *) - let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) + let is_rat_num ( x : Expr.expr ) = (Expr.is_numeral x) && (is_real x) (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number x#gnc x#gno - - (** Retrieve the int value. *) - let get_int ( x : int_num ) = - let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if r then v - else raise (Z3native.Exception "Conversion failed.") - - (** Returns a string representation of the numeral. *) - let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno - - (** The numerator of a rational numeral. *) - let get_numerator ( x : rat_num ) = - (new int_num x#gc)#create_obj (Z3native.get_numerator x#gnc x#gno) - - (** The denominator of a rational numeral. *) - let get_denominator ( x : rat_num ) = - (new int_num x#gc)#create_obj (Z3native.get_denominator x#gnc x#gno) - - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : rat_num ) (precision : int) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision - - (** Returns a string representation of the numeral. *) - let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno - - (** - Creates an integer constant. - *) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = - ((Expr.mk_const ctx name (mk_int_sort ctx)) :> int_expr) - - (** - Creates an integer constant. - *) - let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx (Symbol.mk_string ctx name) - - (** - Creates a real constant. - *) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = - ((Expr.mk_const ctx name (mk_real_sort ctx)) :> real_expr) - - (** - Creates a real constant. - *) - let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx (Symbol.mk_string ctx name) + let is_algebraic_number ( x : Expr.expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) (** Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) + Arithmetic.create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Arithmetic.aton t)) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) + Arithmetic.create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Arithmetic.aton t)) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) + Arithmetic.create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Arithmetic.aton t)) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - ArithExpr(create ctx (Z3native.mk_unary_minus (context_gno ctx) - (gno (match t with ArithExpr(b) -> b)))) + Arithmetic.create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t)) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - ArithExpr(create ctx (Z3native.mk_div (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Create an expression representing t1 mod t2. - The arguments must have int type. - *) - let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - IntExpr(create ctx (Z3native.mk_mod (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Create an expression representing t1 rem t2. - The arguments must have int type. - *) - let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - IntExpr(create ctx (Z3native.mk_rem (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Arithmetic.create_expr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 ^ t2. *) - let mk_power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - ArithExpr(create_expr ctx (Z3native.mk_power (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Arithmetic.create_expr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 < t2 *) - let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_lt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 <= t2 *) - let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_le (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 > t2 *) - let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_gt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 >= t2 *) - let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_ge (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. - *) - let mk_int2real ( ctx : context ) ( t : int_expr ) = - RealExpr(create (Z3native.mk_int2real (context_gno ctx) - (gno (match t with BoolExpr(b) -> b)))) - - (** - Coerce a real to an integer. - - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. - *) - let mk_real2int ( ctx : context ) ( t : real_expr ) = - (new int_expr ctx)#create_obj (Z3native.mk_real2int (context_gno ctx) t#gno) - - (** - Creates an expression that checks whether a real number is an integer. - *) - let mk_is_integer ( ctx : context ) ( t : real_expr ) = - BoolExpr(create ctx (Z3native.mk_is_int (context_gno ctx) - (gno (match t with BoolExpr(b) -> b)))) - (** - Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) - let to_upper ( x : algebraic_num ) ( precision : int ) = - (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) - - (** - Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) - let to_lower ( x : algebraic_num ) precision = - (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) - - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision - - (** - Create a real from a fraction. - - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - *) - let mk_real_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = - if (den == 0) then - raise (Z3native.Exception "Denominator is zero") - else - - (new rat_num ctx)#create_obj (Z3native.mk_real (context_gno ctx) num den) - - (** - Create a real numeral. - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - *) - let mk_real_numeral_s ( ctx : context ) ( v : string ) = - (new rat_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) - - (** - Create a real numeral. - - @param v value of the numeral. - @return A Term with value and sort Real - *) - let mk_real_numeral_i ( ctx : context ) ( v : int ) = - (new rat_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) - - (** - Create an integer numeral. - @param v A string representing the Term value in decimal notation. - *) - let mk_int_numeral_s ( ctx : context ) ( v : string ) = - (new int_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) - - (** - Create an integer numeral. - @param v value of the numeral. - @return A Term with value and sort Integer - *) - let mk_int_numeral_i ( ctx : context ) ( v : int ) = - (new int_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) - - (** Returns a string representation of the numeral. *) - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno + let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2)) end From 276c5a5cdcab12fe3df8eb8b2aacceeed117d74f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 5 Feb 2013 00:19:06 +0000 Subject: [PATCH 274/507] ML API: No more objects; type hierarchy exposed; clean separation into modules. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 691 ++++++++++++++++++++++++----------------------- 1 file changed, 357 insertions(+), 334 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 58c319d4d..4cf41f420 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -334,6 +334,13 @@ sig val create : context -> Z3native.ptr -> ast val aton : ast array -> Z3native.ptr array + module ASTVectors : sig + type ast_vector + val create : context -> Z3native.ptr -> ast_vector + val get_size : ast_vector -> int + val get : ast_vector -> int -> ast + end + val is_expr : ast -> bool val is_var : ast -> bool end = struct @@ -354,7 +361,7 @@ end = struct (** Vectors of ASTs *) - module ASTVector = + module ASTVectors = struct type ast_vector = z3_native_object @@ -401,7 +408,7 @@ end = struct (** Translates all ASTs in the vector to . @param to_ctx A context - @return A new ASTVector + @return A new ASTVectors *) let translate ( x : ast_vector ) ( to_ctx : context ) = create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) @@ -466,7 +473,7 @@ end = struct (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVectors.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = @@ -613,16 +620,15 @@ end and Sort : sig type sort = Sort of AST.ast - type bitvec_sort = BitvecSort of sort type uninterpreted_sort = UninterpretedSort of sort val create : context -> Z3native.ptr -> sort - val gno : sort -> Z3native.ptr + val gc : sort -> context val gnc : sort -> Z3native.ptr + val gno : sort -> Z3native.ptr val aton : sort array -> Z3native.ptr array end = struct type sort = Sort of AST.ast - type bitvec_sort = BitvecSort of sort type uninterpreted_sort = UninterpretedSort of sort let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) @@ -713,11 +719,14 @@ sig type func_decl = FuncDecl of AST.ast val create : context -> Z3native.ptr -> func_decl + val gc : func_decl -> context val gno : func_decl -> Z3native.ptr val gnc : func_decl -> Z3native.ptr + val aton : func_decl array -> Z3native.ptr array val get_domain_size : func_decl -> int val get_decl_kind : func_decl -> Z3enums.decl_kind + val get_arity : func_decl -> int end = struct open Sort @@ -1098,6 +1107,7 @@ sig val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val get_func_decl : expr -> FuncDecl.func_decl val is_numeral : expr -> bool + val to_string : expr -> string end = struct type expr = Expr of AST.ast @@ -1108,20 +1118,20 @@ end = struct let s = Z3native.get_sort (context_gno ctx) obj in let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.Expr(e)) -> e) + (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.ArithExpr(e)) -> e) else if (Z3native.is_numeral_ast (context_gno ctx) obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with - | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.Expr(e))) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.Expr(e))) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e))) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e))) -> e) | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) | _ -> raise (Z3native.Exception "Unsupported numeral object") else match sk with | BOOL_SORT -> (match (Booleans.create_expr ctx obj) with Booleans.BoolExpr(e) -> e) - | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.Expr(e)) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.Expr(e)) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e)) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e)) -> e) | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) @@ -1409,6 +1419,9 @@ sig val create_expr : context -> Z3native.ptr -> bool_expr val create_sort : context -> Z3native.ptr -> bool_sort + val gc : bool_expr -> context + val gnc : bool_expr -> Z3native.ptr + val gno : bool_expr -> Z3native.ptr val aton : bool_expr array -> Z3native.ptr array end = struct type bool_expr = BoolExpr of Expr.expr @@ -2648,9 +2661,10 @@ end and Arithmetic : sig type arith_sort = ArithSort of Sort.sort - type arith_expr = Expr of Expr.expr + type arith_expr = ArithExpr of Expr.expr val create_expr : context -> Z3native.ptr -> arith_expr + val create_sort : context -> Z3native.ptr -> arith_sort val aton : arith_expr array -> Z3native.ptr array module Integers : sig @@ -2679,14 +2693,53 @@ sig val create_num : context -> Z3native.ptr -> algebraic_num end + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool + val mk_add : context -> arith_expr array -> Arithmetic.arith_expr + val mk_mul : context -> arith_expr array -> Arithmetic.arith_expr + val mk_sub : context -> arith_expr array -> Arithmetic.arith_expr + val mk_unary_minus : + context -> arith_expr -> Arithmetic.arith_expr + val mk_div : + context -> arith_expr -> arith_expr -> Arithmetic.arith_expr + val mk_power : + context -> arith_expr -> arith_expr -> Arithmetic.arith_expr + val mk_lt : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + val mk_le : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + val mk_gt : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + val mk_ge : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + end = struct type arith_sort = ArithSort of Sort.sort type arith_expr = ArithExpr of Expr.expr - let create_arith_expr ( ctx : context ) ( no : Z3native.ptr ) = + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = ArithExpr(Expr.create ctx no) - let create_arith_sort ( ctx : context ) ( no : Z3native.ptr ) = + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = ArithSort(Sort.create ctx no) let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gc s) @@ -2712,10 +2765,10 @@ end = struct type int_num = IntNum of int_expr let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - IntSort(create_arith_sort ctx no) + IntSort(Arithmetic.create_sort ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - IntExpr(create_arith_expr ctx no) + IntExpr(Arithmetic.create_expr ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = IntNum(create_expr ctx no) @@ -2796,6 +2849,19 @@ end = struct *) let mk_int2real ( ctx : context ) ( t : int_expr ) = Reals.create_expr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)) + + (** + Create an bit bit-vector from the integer argument . + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. + *) + let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = + BitVectors.create_expr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t)) end and Reals : @@ -2813,10 +2879,10 @@ end = struct type rat_num = RatNum of real_expr let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - RealSort(create_arith_sort ctx no) + RealSort(Arithmetic.create_sort ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - RealExpr(create_arith_expr ctx no) + RealExpr(Arithmetic.create_expr ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = RatNum(create_expr ctx no) @@ -2914,7 +2980,7 @@ end = struct type algebraic_num = AlgebraicNum of arith_expr let create_num ( ctx : context ) ( no : Z3native.ptr ) = - AlgebraicNum(create_arith_expr ctx no) + AlgebraicNum(Arithmetic.create_expr ctx no) let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) @@ -3126,316 +3192,330 @@ end (** Functions to manipulate bit-vector expressions *) and BitVectors : sig + type bitvec_sort = BitVecSort of Sort.sort type bitvec_expr = BitVecExpr of Expr.expr type bitvec_num = BitVecNum of bitvec_expr + val create_sort : context -> Z3native.ptr -> bitvec_sort val create_expr : context -> Z3native.ptr -> bitvec_expr val create_num : context -> Z3native.ptr -> bitvec_num end = struct - type bitvec_expr = Expr of Expr.expr - type bitvec_num = BitVecExpr of bitvec_expr + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + BitVecSort(Sort.create ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (Expr.create ctx no) in - BitVecExpr(e) + BitVecExpr(Expr.create ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = - let e = (create_expr ctx no) in - BitVecNum(e) + BitVecNum(create_expr ctx no) + + let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) + let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) + let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) + let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) + let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) + let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) + let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) + let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) + let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) (** Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - (new bitvec_sort ctx)#create_obj (Z3native.mk_bv_sort (context_gno ctx) size) + create_sort ctx (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. *) - let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) + let is_bv ( x : Expr.expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) (** Indicates whether the term is a bit-vector numeral *) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) (** Indicates whether the term is a one-bit bit-vector with value one *) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit1 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) (** Indicates whether the term is a one-bit bit-vector with value zero *) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_bit0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) (** Indicates whether the term is a bit-vector unary minus *) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) (** Indicates whether the term is a bit-vector addition (binary) *) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) (** Indicates whether the term is a bit-vector subtraction (binary) *) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) (** Indicates whether the term is a bit-vector multiplication (binary) *) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) (** Indicates whether the term is a bit-vector signed division (binary) *) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_sdiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) (** Indicates whether the term is a bit-vector unsigned division (binary) *) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_udiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) (** Indicates whether the term is a bit-vector signed remainder (binary) *) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_SRem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_urem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) (** Indicates whether the term is a bit-vector signed modulus *) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_smod ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) (** Indicates whether the term is a bit-vector signed division by zero *) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_sdiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) (** Indicates whether the term is a bit-vector unsigned division by zero *) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_udiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) (** Indicates whether the term is a bit-vector signed remainder by zero *) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_srem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_urem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) (** Indicates whether the term is a bit-vector signed modulus by zero *) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_smod0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_ule ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_sle ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_uge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_sge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) (** Indicates whether the term is an unsigned bit-vector less-than *) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_ult ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) (** Indicates whether the term is a signed bit-vector less-than *) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_slt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) (** Indicates whether the term is an unsigned bit-vector greater-than *) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_ugt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) (** Indicates whether the term is a signed bit-vector greater-than *) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_sgt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) (** Indicates whether the term is a bit-wise AND *) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_and ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) (** Indicates whether the term is a bit-wise OR *) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_or ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) (** Indicates whether the term is a bit-wise NOT *) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_not ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) (** Indicates whether the term is a bit-wise XOR *) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_xor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) (** Indicates whether the term is a bit-wise NAND *) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) (** Indicates whether the term is a bit-wise NOR *) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_nor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) (** Indicates whether the term is a bit-wise XNOR *) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_xnor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) (** Indicates whether the term is a bit-vector concatenation (binary) *) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_concat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) (** Indicates whether the term is a bit-vector sign extension *) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_signextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) (** Indicates whether the term is a bit-vector zero extension *) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_zeroextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) (** Indicates whether the term is a bit-vector extraction *) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_extract ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) (** Indicates whether the term is a bit-vector repetition *) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_repeat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) (** Indicates whether the term is a bit-vector reduce OR *) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) (** Indicates whether the term is a bit-vector reduce AND *) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_reduceand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) (** Indicates whether the term is a bit-vector comparison *) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_comp ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) (** Indicates whether the term is a bit-vector shift left *) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) (** Indicates whether the term is a bit-vector logical shift right *) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightlogical ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) (** Indicates whether the term is a bit-vector arithmetic shift left *) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_shiftrightarithmetic ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) (** Indicates whether the term is a bit-vector rotate left *) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right *) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateright ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) (** Indicates whether the term is a bit-vector rotate left (extended) Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotateleftextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right (extended) Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_bv_rotaterightextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_int_to_bv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_carry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) (** Indicates whether the term is a bit-vector ternary XOR The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let is_bv_xor3 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) (** The size of a bit-vector sort. *) - let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno + let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = - let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in if r then v else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) (** Creates a bit-vector constant. *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - ((Expr.mk_const ctx name (mk_sort ctx size)) :> bitvec_expr) + BitVecExpr(Expr.mk_const ctx name (match (mk_sort ctx size) with BitVecSort(s) -> s)) (** Creates a bit-vector constant. @@ -3448,91 +3528,91 @@ end = struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) (** Unsigned division. @@ -3544,7 +3624,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) (** Signed division. @@ -3559,7 +3639,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) (** Unsigned remainder. @@ -3569,7 +3649,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) (** Signed remainder. @@ -3581,7 +3661,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed remainder (sign follows divisor). @@ -3590,7 +3670,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than @@ -3598,9 +3678,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvult (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed less-than @@ -3608,9 +3686,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvslt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than or equal to. @@ -3618,9 +3694,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvule (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed less-than or equal to. @@ -3628,9 +3702,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsle (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2)) (** Unsigned greater than or equal to. @@ -3638,19 +3710,15 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvuge (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed greater than or equal to. The arguments must have the same bit-vector sort. *) - let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsge (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Booleans.create_expr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2)) (** Unsigned greater-than. @@ -3658,9 +3726,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvugt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed greater-than. @@ -3668,9 +3734,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsgt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector concatenation. @@ -3681,9 +3745,7 @@ end = struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVectors.BitVecExpr(create ctx (Z3native.mk_concat (context_gno ctx) - (gno (match t1 with BitVecExpr(b) -> b)) - (gno (match t2 with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector extraction. @@ -3694,7 +3756,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) + create_expr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) (** Bit-vector sign extension. @@ -3704,7 +3766,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_sign_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) (** Bit-vector zero extension. @@ -3715,7 +3777,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_zero_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) (** Bit-vector repetition. @@ -3723,7 +3785,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_repeat (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) (** Shift left. @@ -3738,9 +3800,8 @@ end = struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_bvshl (context_gno ctx) - (gno (match t1 with BitVecExpr(b) -> b)) - (gno (match t2 with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + (** Logical shift right @@ -3754,9 +3815,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_bvlshr (context_gno ctx) - (gno (match t1 with BitVecExpr(b) -> b)) - (gno (match t2 with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) (** Arithmetic shift right @@ -3772,9 +3831,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_bvashr (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) (** Rotate Left. @@ -3783,7 +3840,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_rotate_left (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) (** Rotate Right. @@ -3792,7 +3849,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_rotate_right (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) (** Rotate Left. @@ -3801,9 +3858,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_ext_rotate_left (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) (** Rotate Right. @@ -3813,22 +3868,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_ext_rotate_right (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Create an bit bit-vector from the integer argument . - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. - *) - let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVecExpr(create ctx (Z3native.mk_int2bv (context_gno ctx) n (gno (match t with IntExpr(b) -> b)))) + create_expr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) (** Create an integer from the bit-vector argument . @@ -3845,8 +3885,8 @@ end = struct The argument must be of bit-vector sort. *) - let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#create_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) + let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = + Arithmetic.Integers.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3854,10 +3894,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - BoolExpr(create ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)) - signed)) + Booleans.create_expr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3865,19 +3902,15 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - + Booleans.create_expr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2)) + (** Create a predicate that checks that the bit-wise subtraction does not overflow. The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2)) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3885,10 +3918,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - BoolExpr(create ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)) - signed)) + Booleans.create_expr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3896,17 +3926,15 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2)) (** Create a predicate that checks that the bit-wise negation does not overflow. The arguments must be of bit-vector sort. *) - let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = - BoolExpr(create ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (gno (match t with BitVecExpr(b) -> b)))) + let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = + Booleans.create_expr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t)) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3914,10 +3942,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - BoolExpr(create ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)) - signed)) + Booleans.create_expr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3925,9 +3950,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2)) (** Create a bit-vector numeral. @@ -3936,7 +3959,7 @@ end = struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = - (new bitvec_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) + create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx size))) end (** Functions to manipulate proof expressions *) @@ -3946,17 +3969,17 @@ end = struct (** Indicates whether the term is a Proof for the expression 'true'. *) - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) (** Indicates whether the term is a proof for a fact asserted by the user. *) - let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_asserted ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_goal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) (** Indicates whether the term is proof via modus ponens @@ -3967,7 +3990,7 @@ end = struct [mp T1 T2]: q The second antecedents may also be a proof for (iff p q). *) - let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_modus_ponens ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. @@ -3976,7 +3999,7 @@ end = struct equivalence modulo namings, equality and equivalence. That is, R is either '~', '=' or 'iff'. *) - let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_reflexivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) (** Indicates whether the term is proof by symmetricity of a relation @@ -3986,7 +4009,7 @@ end = struct [symmetry T1]: (R s t) T1 is the antecedent of this proof object. *) - let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_symmetry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) (** Indicates whether the term is a proof by transitivity of a relation @@ -3997,7 +4020,7 @@ end = struct T2: (R s u) [trans T1 T2]: (R t u) *) - let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_transitivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) (** Indicates whether the term is a proof by condensed transitivity of a relation @@ -4017,7 +4040,7 @@ end = struct if there is a path from s to t, if we view every antecedent (R a b) as an edge between a and b. *) - let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_Transitivity_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) (** @@ -4030,7 +4053,7 @@ end = struct Remark: if t_i == s_i, then the antecedent Ti is suppressed. That is, reflexivity proofs are supressed to save space. *) - let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_monotonicity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) (** Indicates whether the term is a quant-intro proof @@ -4039,7 +4062,7 @@ end = struct T1: (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_quant_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) (** Indicates whether the term is a distributivity proof object. @@ -4056,7 +4079,7 @@ end = struct Remark. This rule is used by the CNF conversion pass and instantiated by f = or, and g = and. *) - let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_distributivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) (** Indicates whether the term is a proof by elimination of AND @@ -4065,7 +4088,7 @@ end = struct T1: (and l_1 ... l_n) [and-elim T1]: l_i *) - let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_and_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) (** Indicates whether the term is a proof by eliminiation of not-or @@ -4074,7 +4097,7 @@ end = struct T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) *) - let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_or_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) (** Indicates whether the term is a proof by rewriting @@ -4088,11 +4111,11 @@ end = struct Remark: if f is bool, then = is iff. Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) + (= (+ ( x : Expr.expr ) 0) x) + (= (+ ( x : Expr.expr ) 1 2) (+ 3 x)) + (iff (or ( x : Expr.expr ) false) x) *) - let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) (** Indicates whether the term is a proof by rewriting @@ -4107,14 +4130,14 @@ end = struct - When converting bit-vectors to Booleans (BIT2BOOL=true) - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_rewrite_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) (** Indicates whether the term is a proof for pulling quantifiers out. A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) (** Indicates whether the term is a proof for pulling quantifiers out. @@ -4123,7 +4146,7 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object has no antecedents *) - let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_pull_quant_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) (** Indicates whether the term is a proof for pushing quantifiers in. @@ -4136,7 +4159,7 @@ end = struct This proof object has no antecedents *) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_push_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) (** Indicates whether the term is a proof for elimination of unused variables. @@ -4148,34 +4171,34 @@ end = struct This proof object has no antecedents. *) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_elim_unused_vars ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) (** Indicates whether the term is a proof for destructive equality resolution A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. + (iff (forall (x) (or (not (= ( x : Expr.expr ) t)) P[x])) P[t]) + if ( x : Expr.expr ) does not occur in t. This proof object has no antecedents. Several variables can be eliminated simultaneously. *) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_der ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) (** Indicates whether the term is a proof for quantifier instantiation A proof of (or (not (forall (x) (P x))) (P a)) *) - let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_quant_inst ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) (** Indicates whether the term is a hypthesis marker. Mark a hypothesis in a natural deduction style proof. *) - let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_hypothesis ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) (** Indicates whether the term is a proof by lemma @@ -4187,7 +4210,7 @@ end = struct It converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 contains the hypotheses: l_1, ..., l_n. *) - let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) (** Indicates whether the term is a proof by unit resolution @@ -4198,7 +4221,7 @@ end = struct T(n+1): (not l_n) [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_unit_resolution ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) (** Indicates whether the term is a proof by iff-true @@ -4206,7 +4229,7 @@ end = struct T1: p [iff-true T1]: (iff p true) *) - let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) (** Indicates whether the term is a proof by iff-false @@ -4214,7 +4237,7 @@ end = struct T1: (not p) [iff-false T1]: (iff p false) *) - let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_iff_false ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) (** Indicates whether the term is a proof by commutativity @@ -4226,7 +4249,7 @@ end = struct This proof object has no antecedents. Remark: if f is bool, then = is iff. *) - let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_commutativity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) (** Indicates whether the term is a proof for Tseitin-like axioms @@ -4261,7 +4284,7 @@ end = struct unfolding the Boolean connectives in the axioms a small bounded number of steps (=3). *) - let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_axiom ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) (** Indicates whether the term is a proof for introduction of a name @@ -4283,7 +4306,7 @@ end = struct Otherwise: [def-intro]: (= n e) *) - let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_def_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) (** Indicates whether the term is a proof for application of a definition @@ -4292,7 +4315,7 @@ end = struct F is 'equivalent' to n, given that T1 is a proof that n is a name for F. *) - let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_apply_def ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) (** Indicates whether the term is a proof iff-oeq @@ -4300,7 +4323,7 @@ end = struct T1: (iff p q) [iff~ T1]: (~ p q) *) - let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_iff_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) (** Indicates whether the term is a proof for a positive NNF step @@ -4327,7 +4350,7 @@ end = struct NNF_NEG furthermore handles the case where negation is pushed over Boolean connectives 'and' and 'or'. *) - let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_pos ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) (** Indicates whether the term is a proof for a negative NNF step @@ -4351,7 +4374,7 @@ end = struct [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 r_2) (or r_1' r_2'))) *) - let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_neg ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. @@ -4362,7 +4385,7 @@ end = struct This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_nnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. @@ -4371,19 +4394,19 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_cnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) (** Indicates whether the term is a proof for a Skolemization step Proof for: - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + [sk]: (~ (not (forall ( x : Expr.expr ) (p ( x : Expr.expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : Expr.expr ) (p ( x : Expr.expr ) y)) (p (sk y) y)) This proof object has no antecedents. *) - let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_skolemize ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. @@ -4393,7 +4416,7 @@ end = struct T2: (~ p q) [mp~ T1 T2]: q *) - let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_modus_ponens_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) (** Indicates whether the term is a proof for theory lemma @@ -4411,7 +4434,7 @@ end = struct (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) + let is_theory_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end @@ -4462,8 +4485,8 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) - let assert_ ( x : goal ) ( constraints : bool_expr array ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) e#gno in + let assert_ ( x : goal ) ( constraints : Booleans.bool_expr array ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) in ignore (Array.map f constraints) ; () @@ -4484,7 +4507,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (new bool_expr (z3obj_gc x))#create_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Booleans.create_expr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) @@ -4599,7 +4622,7 @@ struct Return the (symbolic) value of this entry. *) let get_value ( x : func_entry ) = - create_expr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) + Expr.create (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) (** The number of arguments of the entry. @@ -4611,7 +4634,7 @@ struct *) let get_args ( x : func_entry ) = let n = (get_num_args x) in - let f i = (create_expr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (Expr.create (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4639,7 +4662,7 @@ struct (** The (symbolic) `else' value of the function interpretation. *) - let get_else ( x : func_interp ) = create_expr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) + let get_else ( x : func_interp ) = Expr.create (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) (** The arity of the function interpretation @@ -4666,31 +4689,31 @@ struct (** Retrieves the interpretation (the assignment) of in the model. A function declaration of zero arity An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : func_decl ) = + let get_const_interp ( x : model ) ( f : FuncDecl.func_decl ) = if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") else - let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in if (Z3native.is_null np) then None else - Some (create_expr (z3obj_gc x) np) + Some (Expr.create (z3obj_gc x) np) (** Retrieves the interpretation (the assignment) of in the model. A Constant An expression if the constant has an interpretation in the model, null otherwise. *) - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + let get_const_interp_e ( x : model ) ( a : Expr.expr ) = get_const_interp x (Expr.get_func_decl a) (** Retrieves the interpretation (the assignment) of a non-constant in the model. A function declaration of non-zero arity A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range f#gnc f#gno))) in + let rec get_func_interp ( x : model ) ( f : FuncDecl.func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in if (Z3native.is_null n) then None else @@ -4700,10 +4723,10 @@ struct raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x ((new func_decl f#gc)#create_obj fd) + get_func_interp x (FuncDecl.create (z3obj_gc x) fd) | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else - let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in + let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) (** The number of constants that have an interpretation in the model. *) @@ -4712,7 +4735,7 @@ struct (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f @@ -4722,15 +4745,15 @@ struct (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in - let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) @@ -4751,15 +4774,15 @@ struct The evaluation of in the model. *) - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) t#gno completion) in + let eval ( x : model ) ( t : Expr.expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then raise (ModelEvaluationFailedException "evaluation failed") else - create_expr (z3obj_gc x) v + Expr.create (z3obj_gc x) v (** Alias for eval. *) - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + let evaluate ( x : model ) ( t : Expr.expr ) ( completion : bool ) = eval x t completion (** The number of uninterpreted sorts that the model has an interpretation for. *) @@ -4775,7 +4798,7 @@ struct *) let get_sorts ( x : model ) = let n = (get_num_sorts x) in - let f i = (create_sort (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (Sort.create (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f @@ -4784,10 +4807,10 @@ struct An uninterpreted sort An array of expressions, where each is an element of the universe of *) - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in + let sort_universe ( x : model ) ( s : Sort.sort ) = + let n_univ = AST.ASTVectors.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n = (AST.ASTVectors.get_size n_univ) in + let f i = (AST.ASTVectors.get n_univ i) in Array.init n f (** Conversion of models to strings. @@ -5323,8 +5346,8 @@ struct (** Assert a constraint (or multiple) into the solver. *) - let assert_ ( x : solver ) ( constraints : bool_expr array ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in + let assert_ ( x : solver ) ( constraints : Booleans.bool_expr array ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in ignore (Array.map f constraints) (** @@ -5340,11 +5363,11 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = + let assert_and_track ( x : solver ) ( cs : Booleans.bool_expr array ) ( ps : Booleans.bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) e#gno (Array.get ps i)#gno) in + let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) (Booleans.gno (Array.get ps i))) in ignore (Array.iteri f cs) (** @@ -5359,24 +5382,24 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) c#gno p#gno + let assert_and_track ( x : solver ) ( c : Booleans.bool_expr ) ( p : Booleans.bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno c) (Booleans.gno p) (** The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVector.get_size a) + let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + (AST.ASTVectors.get_size a) (** The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size a) in - let f i = ((new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get a i)#gno) in + let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVectors.get_size a) in + let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get a i)) in Array.init n f (** @@ -5386,12 +5409,12 @@ struct *) - let check ( x : solver ) ( assumptions : bool_expr array) = + let check ( x : solver ) ( assumptions : Booleans.bool_expr array) = let r = if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (AST.aton assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Booleans.aton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -5422,7 +5445,7 @@ struct if (Z3native.is_null q) then None else - Some (create_expr (z3obj_gc x) q) + Some (Expr.create (z3obj_gc x) q) (** The unsat core of the last Check. @@ -5432,9 +5455,9 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size cn) in - let f i = (AST.ASTVector.get cn i) in + let cn = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVectors.get_size cn) in + let f i = (AST.ASTVectors.get cn i) in Array.init n f (** @@ -5527,30 +5550,30 @@ struct (** Assert a constraints into the fixedpoint solver. *) - let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in + let assert_ ( x : fixedpoint ) ( constraints : Booleans.bool_expr array ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in ignore (Array.map f constraints) ; () (** Register predicate as recursive relation. *) - let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) f#gno + let register_relation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) = + Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno y) + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno y) (** Add table fact to the fixedpoint solver. *) - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) pred#gno (Array.length args) args + let add_fact ( x : fixedpoint ) ( pred : FuncDecl.func_decl ) ( args : int array ) = + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args (** Query the fixedpoint solver. @@ -5558,8 +5581,8 @@ struct The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - let query ( x : fixedpoint ) ( query : bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) query#gno)) with + let query ( x : fixedpoint ) ( query : Booleans.bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Booleans.gno query))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5570,8 +5593,8 @@ struct The query is satisfiable if there is an instance of some relation that is non-empty. The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - let query_r ( x : fixedpoint ) ( relations : func_decl array ) = - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (func_declaton relations))) with + let query_r ( x : fixedpoint ) ( relations : FuncDecl.func_decl array ) = + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (FuncDecl.aton relations))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5595,8 +5618,8 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno name) + let update_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno name) (** Retrieve satisfying instance or instances of solver, @@ -5607,7 +5630,7 @@ struct if (Z3native.is_null q) then None else - Some (create_expr (z3obj_gc x) q) + Some (Expr.create (z3obj_gc x) q) (** Retrieve explanation why fixedpoint engine returned status Unknown. @@ -5618,25 +5641,25 @@ struct (** Retrieve the number of levels explored for a given predicate. *) - let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) predicate#gno + let get_num_levels ( x : fixedpoint ) ( predicate : FuncDecl.func_decl ) = + Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) (** Retrieve the cover of a predicate. *) - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level predicate#gno) in + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) = + let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in if (Z3native.is_null q) then None else - Some (create_expr (z3obj_gc x) q) + Some (Expr.create (z3obj_gc x) q) (** Add property about the predicate. The property is added at level. *) - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level predicate#gno property#gno + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) ( property : Expr.expr ) = + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) (** Retrieve internal string representation of fixedpoint object. @@ -5646,31 +5669,31 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (Symbol.aton kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) ( kinds : Symbol.symbol array ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Symbol.aton kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) - let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (AST.aton queries) + let to_string_q ( x : fixedpoint ) ( queries : Booleans.bool_expr array ) = + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Booleans.aton queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in + let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVectors.get_size v) in + let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in + let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVectors.get_size v) in + let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in Array.init n f (** @@ -5754,10 +5777,10 @@ struct @param formula Formula to be checked for consistency in conjunction with assumptions. @return A string representation of the benchmark. *) - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Booleans.bool_expr array ) ( formula : Booleans.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (AST.aton assumptions) - formula#gno + (Array.length assumptions) (Booleans.aton assumptions) + (Booleans.gno formula) (** Parse the given string using the SMT-LIB parser. @@ -5768,7 +5791,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5779,16 +5802,16 @@ struct Z3native.parse_smtlib_string (context_gno ctx) str cs (Symbol.aton sort_names) - (AST.aton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5799,10 +5822,10 @@ struct Z3native.parse_smtlib_file (context_gno ctx) file_name cs (Symbol.aton sort_names) - (AST.aton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. @@ -5814,7 +5837,7 @@ struct *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) :> bool_expr) in + let f i = Booleans.create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i) in Array.init n f @@ -5828,7 +5851,7 @@ struct *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) :> bool_expr ) in + let f i = Booleans.create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i) in Array.init n f (** @@ -5841,7 +5864,7 @@ struct *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = (new func_decl ctx)#create_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in + let f i = FuncDecl.create ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** @@ -5854,7 +5877,7 @@ struct *) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in - let f i = (create_sort ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in + let f i = (Sort.create ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f (** @@ -5863,7 +5886,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5877,13 +5900,13 @@ struct (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5897,7 +5920,7 @@ struct (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) end From 34a72942bfbf752e7eb02e81672539fd31252620 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 5 Feb 2013 00:51:20 +0000 Subject: [PATCH 275/507] ML API: documentation fixes. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 246 +++++++++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 105 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 4cf41f420..aeb9c0d03 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -331,8 +331,10 @@ module rec AST : sig type ast = z3_native_object +(**/**) val create : context -> Z3native.ptr -> ast val aton : ast array -> Z3native.ptr array +(**/**) module ASTVectors : sig type ast_vector @@ -346,6 +348,7 @@ sig end = struct type ast = z3_native_object + (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let res : z3_native_object = { m_ctx = ctx ; m_n_obj = null ; @@ -358,7 +361,7 @@ end = struct let aton (a : ast array) = let f (e : ast) = (z3obj_gno e) in Array.map f a - + (**/**) (** Vectors of ASTs *) module ASTVectors = @@ -615,7 +618,6 @@ end = struct (**/**) end - (** The Sort module implements type information for ASTs *) and Sort : sig @@ -631,6 +633,7 @@ end = struct type sort = Sort of AST.ast type uninterpreted_sort = UninterpretedSort of sort + (**/**) let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) @@ -657,6 +660,7 @@ end = struct | FINITE_DOMAIN_SORT | RELATION_SORT -> Sort(q) | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + (**/**) (** @@ -728,10 +732,9 @@ sig val get_decl_kind : func_decl -> Z3enums.decl_kind val get_arity : func_decl -> int end = struct - open Sort - type func_decl = FuncDecl of AST.ast + (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let res = { m_ctx = ctx ; m_n_obj = null ; @@ -741,7 +744,7 @@ end = struct (z3obj_create res) ; FuncDecl(res) - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -750,7 +753,7 @@ end = struct (z3obj_create res) ; FuncDecl(res) - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let create_pdr ( ctx : context) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -766,7 +769,8 @@ end = struct let aton (a : func_decl array) = let f (e : func_decl) = (gno e) in Array.map f a - + (**/**) + (** Parameters of Func_Decls *) module Parameter = struct @@ -833,18 +837,16 @@ end = struct | _ -> raise (Z3native.Exception "parameter is not a rational string") end - open Parameter - (** Creates a new function declaration. *) - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = create_ndr ctx name domain range (** Creates a new function declaration. *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range (** @@ -852,19 +854,19 @@ end = struct *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = create_pdr ctx prefix domain range (** Creates a new constant function declaration. *) - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = create_ndr ctx name [||] range (** Creates a new constant function declaration. *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = create_ndr ctx (Symbol.mk_string ctx name) [||] range (** @@ -872,7 +874,7 @@ end = struct *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = create_pdr ctx prefix [||] range @@ -945,13 +947,13 @@ end = struct let get_parameters ( x : func_decl ) = let n = (get_num_parameters x) in let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> Parameter.P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> Parameter.P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) ) in mk_list f n @@ -977,6 +979,7 @@ sig type param_descrs = z3_native_object val create : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit end end = struct type params = z3_native_object @@ -998,6 +1001,7 @@ end = struct type param_descrs = z3_native_object val create : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit end = struct type param_descrs = z3_native_object @@ -1025,7 +1029,7 @@ end = struct let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - + (** The size of the ParamDescrs. *) let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) @@ -1092,7 +1096,7 @@ end = struct let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) end -(** General expressions (terms), including Boolean logic *) +(** General expressions (terms) *) and Expr : sig type expr = Expr of AST.ast @@ -1111,6 +1115,7 @@ sig end = struct type expr = Expr of AST.ast + (**/**) let create ( ctx : context ) ( obj : Z3native.ptr ) = if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then (match (Quantifiers.create ctx obj) with Quantifiers.Quantifier(e) -> e) @@ -1148,7 +1153,12 @@ end = struct let gc ( x : expr ) = match x with Expr(a) -> (z3obj_gc a) let gnc ( x : expr ) = match x with Expr(a) -> (z3obj_gnc a) let gno ( x : expr ) = match x with Expr(a) -> (z3obj_gno a) - + + let aton (a : expr array) = + let f (e : expr) = (gno e) in + Array.map f a + (**/**) + (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier @@ -1405,10 +1415,6 @@ end = struct *) let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : Sort.sort ) = create ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) - - let aton (a : expr array) = - let f (e : expr) = (gno e) in - Array.map f a end (** Boolean expressions *) @@ -1427,6 +1433,7 @@ end = struct type bool_expr = BoolExpr of Expr.expr type bool_sort = BoolSort of Sort.sort + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let a = (AST.create ctx no) in BoolExpr(Expr.Expr(a)) @@ -1441,6 +1448,7 @@ end = struct let aton ( a : bool_expr array ) = let f (e : bool_expr) = (gno e) in Array.map f a + (**/**) let mk_sort ( ctx : context ) = BoolSort(Sort.create ctx (Z3native.mk_bool_sort (context_gno ctx))) @@ -1542,6 +1550,7 @@ sig end = struct type quantifier = Quantifier of Expr.expr + (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let a = (AST.create ctx no) in Quantifier(Expr.Expr(a)) @@ -1549,7 +1558,61 @@ end = struct let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - + (**/**) + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. + *) + module Patterns : + sig + type pattern = Pattern of AST.ast + + val create : context -> Z3native.ptr -> pattern + val aton : pattern array -> Z3native.ptr array + end = struct + type pattern = Pattern of AST.ast + + (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + Pattern(res) + + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) + let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) + let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) + + let aton (a : pattern array) = + let f (e : pattern) = (gno e) in + Array.map f a + (**/**) + + (** + The number of terms in the pattern. + *) + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms (gnc x) (gno x) + + (** + The terms in the pattern. + *) + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in + Array.init n f + + (** + A string representation of the pattern. + *) + let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) + end (** The de-Burijn index of a bound variable. @@ -1575,58 +1638,6 @@ end = struct else Z3native.get_index_value (Expr.gnc x) (Expr.gno x) - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. - *) - module Patterns : - sig - type pattern = Pattern of AST.ast - - val create : context -> Z3native.ptr -> pattern - val aton : pattern array -> Z3native.ptr array - end = struct - type pattern = Pattern of AST.ast - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - Pattern(res) - - let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) - let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) - let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - - (** - The number of terms in the pattern. - *) - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - - (** - The terms in the pattern. - *) - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - Array.init n f - - (** - A string representation of the pattern. - *) - let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) - - let aton (a : pattern array) = - let f (e : pattern) = (gno e) in - Array.map f a - end - (** Indicates whether the quantifier is universal. *) @@ -1849,6 +1860,7 @@ end = struct type array_expr = ArrayExpr of Expr.expr type array_sort = ArraySort of Sort.sort + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let e = (Expr.create ctx no) in ArrayExpr(e) @@ -1868,7 +1880,7 @@ end = struct let aton (a : array_expr array) = let f (e : array_expr) = (egno e) in Array.map f a - + (**/**) (** Create a new array sort. @@ -2120,6 +2132,7 @@ sig end = struct type finite_domain_sort = FiniteDomainSort of Sort.sort + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = let s = (Sort.create ctx no) in FiniteDomainSort(s) @@ -2127,7 +2140,8 @@ end = struct let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gc s) let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gnc s) let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s))-> (z3obj_gno s) - + (**/**) + (** Create a new finite domain sort. *) @@ -2168,6 +2182,7 @@ sig end = struct type relation_sort = RelationSort of Sort.sort + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = let s = (Sort.create ctx no) in RelationSort(s) @@ -2175,7 +2190,8 @@ end = struct let gc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gc s) let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gnc s) let gno ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s))-> (z3obj_gno s) - + (**/**) + (** Indicates whether the term is of a relation sort. *) @@ -2306,6 +2322,7 @@ end = struct type datatype_expr = DatatypeExpr of Expr.expr type datatype_sort = DatatypeSort of Sort.sort + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let e = (Expr.create ctx no) in DatatypeExpr(e) @@ -2317,19 +2334,24 @@ end = struct let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gc s) let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gnc s) let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s))-> (z3obj_gno s) - + (**/**) (** Constructors *) - module Constructor = - struct + module Constructor : sig + type constructor + val create : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> constructor + val aton : constructor array -> Z3native.ptr array + end = struct type constructor_extra = { m_n : int; mutable m_tester_decl : FuncDecl.func_decl option; mutable m_constructor_decl : FuncDecl.func_decl option ; mutable m_accessor_decls : FuncDecl.func_decl array option} + type constructor = Constructor of (z3_native_object * constructor_extra) - let create_ssssi ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + (**/**) + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -2356,6 +2378,10 @@ end = struct let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; Constructor(no, ex) + + let aton ( a : constructor array ) = + let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in + Array.map f a let init_extra ( x : constructor ) = match x with Constructor(no, ex) -> @@ -2367,7 +2393,8 @@ end = struct ex.m_accessor_decls <- Some (let f e = (FuncDecl.create (z3obj_gc no) e) in Array.map f c) ; () | _ -> () - + (**/**) + let get_n ( x : constructor ) = match x with Constructor(no, ex) -> ex.m_n @@ -2389,12 +2416,7 @@ end = struct match ex.m_accessor_decls with | Some(s) -> s | None -> init_extra x ; accessor_decls x - - let aton ( a : constructor array ) = - let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in - Array.map f a - - + (** The number of fields of the constructor. *) let get_num_fields ( x : constructor ) = get_n x @@ -2413,6 +2435,7 @@ end = struct struct type constructor_list = z3_native_object + (**/**) let create ( ctx : context )( c : Constructor.constructor array ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; @@ -2427,6 +2450,7 @@ end = struct let aton (a : constructor_list array) = let f (e : constructor_list) = (z3obj_gno e) in Array.map f a + (**/**) end (* DATATYPES *) @@ -2441,7 +2465,7 @@ end = struct referring to one of the recursive datatypes that is declared. *) let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array) = - Constructor.create_ssssi ctx name recognizer field_names sorts sort_refs + Constructor.create ctx name recognizer field_names sorts sort_refs (** @@ -2530,6 +2554,7 @@ end = struct mutable _testerdecls : FuncDecl.func_decl array } type enum_sort = EnumSort of (Sort.sort * enum_sort_data) + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = let s = (Sort.create ctx no) in let e = { _constdecls = (let f e = FuncDecl.create ctx e in (Array.map f cdecls)) ; @@ -2539,7 +2564,7 @@ end = struct let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gc s) let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_)-> (z3obj_gno s) - + (**/**) (** Create a new enumeration sort. @@ -2576,6 +2601,7 @@ end = struct _taildecl : FuncDecl.func_decl } type list_sort = ListSort of (Sort.sort * list_sort_data) + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = let s = (Sort.create ctx no) in let e = {_nildecl = FuncDecl.create ctx nildecl; @@ -2589,7 +2615,7 @@ end = struct let sgc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gc s) let sgnc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gnc s) let sgno ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_)-> (z3obj_gno s) - + (**/**) (** Create a new list sort. *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : Sort.sort ) = @@ -2629,6 +2655,7 @@ sig end = struct type tuple_sort = TupleSort of Sort.sort + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = let s = (Sort.create ctx no) in TupleSort(s) @@ -2636,6 +2663,7 @@ end = struct let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gc s) let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s))-> (z3obj_gno s) + (**/**) (** Create a new tuple sort. *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : Sort.sort array ) = @@ -2736,6 +2764,7 @@ end = struct type arith_sort = ArithSort of Sort.sort type arith_expr = ArithExpr of Expr.expr + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = ArithExpr(Expr.create ctx no) @@ -2749,6 +2778,10 @@ end = struct let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) + let aton (a : arith_expr array) = + let f (e : arith_expr) = (egno e) in + Array.map f a + (**/**) module rec Integers : sig @@ -2764,6 +2797,7 @@ end = struct type int_expr = IntExpr of arith_expr type int_num = IntNum of int_expr + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = IntSort(Arithmetic.create_sort ctx no) @@ -2782,6 +2816,7 @@ end = struct let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) + (**/**) (** Create a new integer sort. *) let mk_sort ( ctx : context ) = @@ -2878,6 +2913,7 @@ end = struct type real_expr = RealExpr of arith_expr type rat_num = RatNum of real_expr + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = RealSort(Arithmetic.create_sort ctx no) @@ -2896,7 +2932,8 @@ end = struct let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - + (**/**) + (** Create a real sort. *) let mk_sort ( ctx : context ) = create_sort ctx (Z3native.mk_real_sort (context_gno ctx)) @@ -2979,12 +3016,14 @@ end = struct end = struct type algebraic_num = AlgebraicNum of arith_expr + (**/**) let create_num ( ctx : context ) ( no : Z3native.ptr ) = AlgebraicNum(Arithmetic.create_expr ctx no) let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) + (**/**) (** Return a upper bound for a given real algebraic number. @@ -3015,10 +3054,6 @@ end = struct let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) end - let aton (a : arith_expr array) = - let f (e : arith_expr) = (egno e) in - Array.map f a - (** Indicates whether the term is of integer sort. *) @@ -3188,7 +3223,6 @@ end = struct Booleans.create_expr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2)) end - (** Functions to manipulate bit-vector expressions *) and BitVectors : sig @@ -3204,6 +3238,7 @@ end = struct type bitvec_expr = BitVecExpr of Expr.expr type bitvec_num = BitVecNum of bitvec_expr + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = BitVecSort(Sort.create ctx no) @@ -3222,6 +3257,7 @@ end = struct let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) + (**/**) (** Create a new bit-vector sort. From 23febf13c40b56d7e7fe3fa4bd071c1b8c57c87d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 19:49:27 +0000 Subject: [PATCH 276/507] ML API: basic structure and interface Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 81 +- scripts/update_api.py | 30 +- src/api/ml/Makefile | 2 +- src/api/ml/z3.ml | 2714 +++++++++++++++++++---------------------- 4 files changed, 1380 insertions(+), 1447 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index bea2939b6..a187bf9cb 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1340,10 +1340,17 @@ class MLComponent(Component): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + cmis = '%s/z3enums.cmi %s/z3native.cmi %s/z3.cmi' % (src_dir,src_dir,src_dir) + out.write('%s/z3enums.cmi: %s/z3enums.mli\n' % (src_dir,src_dir)) + out.write('\t%s -I %s -c %s/z3enums.mli\n' % (OCAMLC,src_dir,src_dir)) + out.write('%s/z3native.cmi: %s/z3native.mli\n' % (src_dir,src_dir)) + out.write('\t%s -I %s -c %s/z3native.mli\n' % (OCAMLC,src_dir,src_dir)) + out.write('%s/z3.cmi: %s/z3.mli\n' % (src_dir,src_dir)) + out.write('\t%s -I %s -c %s/z3.mli\n' % (OCAMLC,src_dir,src_dir)) out.write('api/ml/libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, src_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') - out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) out.write('\n') @@ -1351,7 +1358,7 @@ class MLComponent(Component): if DEBUG_MODE: out.write('-g ') out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) - out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') @@ -2716,6 +2723,76 @@ def mk_z3consts_ml(api_files): linenum = linenum + 1 if VERBOSE: print "Generated '%s/z3enums.ml'" % ('%s' % gendir) + efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') + efile.write('(* Automatically generated file *)\n\n') + efile.write('(** The enumeration types of Z3. *)\n\n') + for api_file in api_files: + api_file_c = ml.find_file(api_file, ml.name) + api_file = os.path.join(api_file_c.src_dir, api_file) + + api = open(api_file, 'r') + + SEARCHING = 0 + FOUND_ENUM = 1 + IN_ENUM = 2 + + mode = SEARCHING + decls = {} + idx = 0 + + linenum = 1 + for line in api: + m1 = blank_pat.match(line) + m2 = comment_pat.match(line) + if m1 or m2: + # skip blank lines and comments + linenum = linenum + 1 + elif mode == SEARCHING: + m = typedef_pat.match(line) + if m: + mode = FOUND_ENUM + m = typedef2_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + elif mode == FOUND_ENUM: + m = openbrace_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + else: + assert False, "Invalid %s, line: %s" % (api_file, linenum) + else: + assert mode == IN_ENUM + words = re.split('[^\-a-zA-Z0-9_]+', line) + m = closebrace_pat.match(line) + if m: + name = words[1] + if name not in DeprecatedEnums: + efile.write('(** %s *)\n' % name[3:]) + efile.write('type %s =\n' % name[3:]) # strip Z3_ + for k, i in decls.iteritems(): + efile.write(' | %s \n' % k[3:]) # strip Z3_ + efile.write('\n') + efile.write('(** Convert %s to int*)\n' % name[3:]) + efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_ + efile.write('(** Convert int to %s*)\n' % name[3:]) + efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_ + efile.write('\n') + mode = SEARCHING + else: + if words[2] != '': + if len(words[2]) > 1 and words[2][1] == 'x': + idx = int(words[2], 16) + else: + idx = int(words[2]) + decls[words[1]] = idx + idx = idx + 1 + linenum = linenum + 1 + if VERBOSE: + print "Generated '%s/z3enums.mli'" % ('%s' % gendir) def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index c730a325e..6e9c14355 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1147,49 +1147,66 @@ def mk_ml(): return ml_dir = get_component('ml').src_dir ml_nativef = os.path.join(ml_dir, 'z3native.ml') + ml_nativefi = os.path.join(ml_dir, 'z3native.mli') ml_wrapperf = os.path.join(ml_dir, 'z3native.c') ml_native = open(ml_nativef, 'w') + ml_i = open(ml_nativefi, 'w') ml_native.write('(* Automatically generated file *)\n\n') ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') + ml_i.write('(* Automatically generated file *)\n\n') + ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_native.write('open Z3enums\n\n') ml_native.write('(**/**)\n') ml_native.write('type ptr\n') + ml_i.write('type ptr\n') ml_native.write('and z3_symbol = ptr\n') + ml_i.write('and z3_symbol = ptr\n') for k, v in Type2Str.iteritems(): if is_obj(k): ml_native.write('and %s = ptr\n' % v.lower()) + ml_i.write('and %s = ptr\n' % v.lower()) ml_native.write('\n') - ml_native.write('external is_null : ptr -> bool\n') - ml_native.write(' = "n_is_null"\n\n') - ml_native.write('external mk_null : unit -> ptr\n') - ml_native.write(' = "n_mk_null"\n\n') + ml_i.write('\n') + ml_native.write('external is_null : ptr -> bool\n = "n_is_null"\n\n') + ml_native.write('external mk_null : unit -> ptr\n = "n_mk_null"\n\n') ml_native.write('exception Exception of string\n\n') + ml_i.write('val is_null : ptr -> bool\n') + ml_i.write('val mk_null : unit -> ptr\n') + ml_i.write('exception Exception of string\n\n') # ML declarations - ml_native.write(' module ML2C = struct\n\n') + ml_native.write('module ML2C = struct\n\n') for name, result, params in _dotnet_decls: ml_native.write(' external n_%s : ' % ml_method_name(name)) + ml_i.write('val %s : ' % ml_method_name(name)) ip = inparams(params) op = outparams(params) if len(ip) == 0: - ml_native.write(' unit -> ') + ml_native.write(' unit -> ') for p in ip: ml_native.write('%s -> ' % param2ml(p)) + ml_i.write('%s -> ' % param2ml(p)) if len(op) > 0: ml_native.write('(') + ml_i.write('(') first = True if result != VOID or len(op) == 0: ml_native.write('%s' % type2ml(result)) + ml_i.write('%s' % type2ml(result)) first = False for p in op: if first: first = False else: ml_native.write(' * ') + ml_i.write(' * ') ml_native.write('%s' % param2ml(p)) + ml_i.write('%s' % param2ml(p)) if len(op) > 0: ml_native.write(')') + ml_i.write(')') ml_native.write('\n') + ml_i.write('\n') ml_native.write(' = "n_%s"\n' % ml_method_name(name)) if len(ip) > 5: ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) @@ -1201,6 +1218,7 @@ def mk_ml(): ip = inparams(params) op = outparams(params) ml_native.write(' let %s ' % ml_method_name(name)) + first = True i = 0; for p in params: diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index ad5442327..abcefa4af 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -7,4 +7,4 @@ all: doc: *.ml mkdir -p doc - ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.ml -hide Z3 + ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.mli -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index aeb9c0d03..ea8c9576e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,8 +7,479 @@ open Z3enums -(** Interaction logging for Z3 +(* Some helpers. *) +let null = Z3native.mk_null() +let is_null o = (Z3native.is_null o) + +(* Internal types *) +type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +type context = z3_native_context + + + +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } + + +(* Symbol types *) +type int_symbol = z3_native_object +type string_symbol = z3_native_object + +type symbol = + | S_Int of int_symbol + | S_Str of string_symbol + +(* AST types *) +type ast = z3_native_object +type ast_vector = z3_native_object +type ast_map = z3_native_object + +(* FuncDecl types *) +type func_decl = FuncDecl of ast + +(* Sort types *) +type sort = Sort of ast +type uninterpreted_sort = UninterpretedSort of sort +type bool_sort = BoolSort of sort +type array_sort = ArraySort of sort +type set_sort = SetSort of sort +type datatype_sort = DatatypeSort of sort +type relation_sort = RelationSort of sort +type finite_domain_sort = FiniteDomainSort of sort +type enum_sort = EnumSort of sort +type list_sort = ListSort of sort +type tuple_sort = TupleSort of sort +type arith_sort = ArithSort of sort +type bitvec_sort = BitVecSort of sort + +type int_sort = IntSort of arith_sort +type real_sort = RealSort of arith_sort + +(* FuncDecl parameters *) +type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of symbol + | P_Srt of sort + | P_Ast of ast + | P_Fdl of func_decl + | P_Rat of string +type params = z3_native_object +type param_descrs = z3_native_object + +(* Expr types *) +type expr = Expr of ast + +type bool_expr = BoolExpr of expr +type arith_expr = ArithExpr of expr +type int_expr = IntExpr of arith_expr +type real_expr = RealExpr of arith_expr +type bitvec_expr = BitVecExpr of expr +type array_expr = ArrayExpr of expr +type datatype_expr = DatatypeExpr of expr + +(* Numerals *) +type int_num = IntNum of int_expr +type rat_num = RatNum of real_expr +type algebraic_num = AlgebraicNum of arith_expr +type bitvec_num = BitVecNum of bitvec_expr + +(* Quantifier stuff *) +type quantifier = Quantifier of expr +type pattern = Pattern of ast + +(* Datatype stuff *) +type constructor_extra = { + m_n : int; + mutable m_tester_decl : func_decl option; + mutable m_constructor_decl : func_decl option ; + mutable m_accessor_decls : func_decl array option} + +type constructor = Constructor of (z3_native_object * constructor_extra) +type constructor_list = z3_native_object + +(* Tactical interface *) +type goal = z3_native_object +type model = z3_native_object +type func_interp = z3_native_object +type func_entry = z3_native_object +type probe = z3_native_object +type tactic = z3_native_object +type apply_result = z3_native_object +type solver = z3_native_object +type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE +type statistics = z3_native_object +type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } +type fixedpoint = z3_native_object + + +(** Internal stuff *) +module Internal = +struct + let dispose_context ctx = + if ctx.m_n_obj_cnt == 0 then ( + (* Printf.printf "Disposing context \n" ; *) + (Z3native.del_context ctx.m_n_ctx) + ) else ( + Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; + (* re-queue for finalization? *) + ) + + let create_context settings = + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + (* Printf.printf "Installing finalizer on context \n" ; *) + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> dispose_context o in + Gc.finalise f res; + res + (* CMW: Install error handler here! + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); + *) + + let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) + let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) + let context_gno ctx = ctx.m_n_ctx + + + let z3obj_gc o = o.m_ctx + let z3obj_gnc o = (context_gno o.m_ctx) + + let z3obj_gno o = o.m_n_obj + let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + + let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + + let z3obj_create o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o + + let z3obj_nil_ref x y = () + + let array_to_native a = + let f e = (z3obj_gno e) in + Array.map f a + + (* Internal coercions *) + let context_of_ast ( x : ast ) = (z3obj_gc x) + let nc_of_ast ( x : ast ) = (z3obj_gnc x) + let ptr_of_ast ( x : ast ) = (z3obj_gno x) + + let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) + let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) + let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + + + let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> + let res : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> + let q = (z3_native_object_of_ast_ptr ctx no) in + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then + raise (Z3native.Exception "Invalid coercion") + else + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + FuncDecl(z3_native_object_of_ast_ptr ctx no) + + let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST + | SORT_AST + | QUANTIFIER_AST + | APP_AST + | NUMERAL_AST + | VAR_AST -> z3_native_object_of_ast_ptr ctx no + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") + + and expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then + Expr(z3_native_object_of_ast_ptr ctx no) + else + let s = Z3native.get_sort (context_gno ctx) no in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) no) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + if (Z3native.is_numeral_ast (context_gno ctx) no) then + if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + raise (Z3native.Exception "Unsupported numeral object") + else + Expr(z3_native_object_of_ast_ptr ctx no) + + let expr_aton ( a : expr array ) = + let f ( e : expr ) = match e with Expr(a) -> (ptr_of_ast a) in + Array.map f a + + let expr_of_func_app : context -> func_decl -> expr array -> expr = fun ctx f args -> + match f with FuncDecl(fa) -> + let o = Z3native.mk_app (context_gno ctx) (ptr_of_ast fa) (Array.length args) (expr_aton args) in + expr_of_ptr ctx o +end + + +open Internal + + + +(* Sort coercions *) +let ast_of_sort s = match s with Sort(x) -> x +let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x +let sort_of_bool_sort s = match s with BoolSort(x) -> x +let sort_of_array_sort s = match s with ArraySort(x) -> x +let sort_of_set_sort s = match s with SetSort(x) -> x +let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x +let sort_of_relation_sort s = match s with RelationSort(x) -> x +let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x +let sort_of_enum_sort s = match s with EnumSort(x) -> x +let sort_of_list_sort s = match s with ListSort(x) -> x +let sort_of_tuple_sort s = match s with TupleSort(x) -> x +let sort_of_arith_sort s = match s with ArithSort(x) -> x +let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x +let arith_sort_of_int_sort s = match s with IntSort(x) -> x +let arith_sort_of_real_sort s = match s with RealSort(x) -> x + +let uninterpreted_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + UninterpretedSort(s) + +let bool_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolSort(s) + +let array_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArraySort(s) + +let datatype_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeSort(s) + +let relation_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RelationSort(s) + +let finite_domain_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + FiniteDomainSort(s) + +let arith_sort_of_sort s = match s with Sort(a) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithSort(s) + +let bitvec_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecSort(s) + +let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntSort(s) + +let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealSort(s) + +(* FuncDecl coercions *) +let ast_of_func_decl f = match f with FuncDecl(x) -> x + +(* Expr coercions *) +let ast_of_expr e = match e with Expr(a) -> a +let expr_of_bool_expr e = match e with BoolExpr(x) -> x +let expr_of_arith_expr e = match e with ArithExpr(x) -> x +let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x +let expr_of_array_expr e = match e with ArrayExpr(x) -> x +let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x + +let arith_expr_of_int_expr e = match e with IntExpr(x) -> x +let arith_expr_of_real_expr e = match e with RealExpr(x) -> x + +let int_expr_of_int_num e = match e with IntNum(x) -> x +let real_expr_of_rat_num e = match e with RatNum(x) -> x +let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x +let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x + +let expr_of_quantifier e = match e with Quantifier(x) -> x +let ast_of_pattern e = match e with Pattern(x) -> x + + +let expr_of_ast a = + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Expr(a) + +let bool_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolExpr(e) + +let arith_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithExpr(e) + +let bitvec_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecExpr(e) + +let array_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArrayExpr(e) + +let datatype_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeExpr(e) + +let int_expr_of_arith_expr e = + match e with ArithExpr(Expr(no)) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntExpr(e) + +let real_expr_of_arith_expr e = + match e with ArithExpr(Expr(no)) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealExpr(e) + +let int_num_of_int_expr e = + match e with IntExpr(ArithExpr(Expr(no))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + IntNum(e) + +let rat_num_of_real_expr e = + match e with RealExpr(ArithExpr(Expr(no))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + RatNum(e) + +let algebraic_num_of_arith_expr e = + match e with ArithExpr(Expr(no)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + AlgebraicNum(e) + +let bitvec_num_of_bitvec_expr e = + match e with BitVecExpr(Expr(no)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecNum(e) + +let quantifier_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.QUANTIFIER_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Quantifier(e) + +let pattern_of_ast a = + (* CMW: Unchecked ok? *) + Pattern(a) + + + +(** Interaction logging for Z3 Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) module Log = @@ -28,6 +499,7 @@ struct let append s = Z3native.append_log s end + (** Version information *) module Version = struct @@ -52,11 +524,6 @@ struct string_of_int rev ^ "." end -(**/**) -(* Some helpers. *) - -let null = Z3native.mk_null() -let is_null o = (Z3native.is_null o) let mk_list ( f : int -> 'a ) ( n : int ) = let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = @@ -66,49 +533,8 @@ let mk_list ( f : int -> 'a ) ( n : int ) = (mk_list' f (i+1) n ((f i) :: tail)) in mk_list' f 0 n [] -(**/**) -(**/**) -type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } -(**/**) -type context = z3_native_context - -(**/**) - -let context_dispose ctx = - if ctx.m_n_obj_cnt == 0 then ( - (* Printf.printf "Disposing context \n" ; *) - (Z3native.del_context ctx.m_n_ctx) - ) else ( - Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; - (* re-queue for finalization? *) - ) - -let context_create settings = - let cfg = Z3native.mk_config in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - (* Printf.printf "Installing finalizer on context \n" ; *) - let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in - let f = fun o -> context_dispose o in - Gc.finalise f res; - res -(* CMW: Install error handler here! - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); -*) - -let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) -let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) -let context_gno ctx = ctx.m_n_ctx - -(**/**) - (** Create a context object. Most interactions with Z3 are interpreted in some context; many users will only @@ -130,113 +556,14 @@ let context_gno ctx = ctx.m_n_ctx *) let mk_context ( cfg : ( string * string ) list ) = - context_create cfg + create_context cfg -(**/**) -class virtual z3object ctx_init obj_init = -object (self) - val mutable m_ctx : context = ctx_init - val mutable m_n_obj : Z3native.ptr option = obj_init - - initializer - (match m_n_obj with - | Some (x) -> self#incref (context_gno m_ctx) x; - (context_add1 m_ctx) - | None -> () - ); - (* Printf.printf "Installing finalizer on z3object %d \n" (Oo.id self) ; *) - let f = fun o -> o#dispose in - let v = self in - Gc.finalise f v - - method virtual incref : Z3native.ptr -> Z3native.ptr -> unit - method virtual decref : Z3native.ptr -> Z3native.ptr -> unit - - method dispose = - (* Printf.printf "Disposing z3object %d \n" (Oo.id self) ; *) - (match m_n_obj with - | Some (x) -> - self#decref (context_gno m_ctx) x; - (context_sub1 m_ctx) ; - m_n_obj <- None; - | None -> () - ); - - method gno = match m_n_obj with - | Some(x) -> x - | None -> raise (Z3native.Exception "Z3 object lost") - - method sno (ctx : context) o = - (context_add1 m_ctx) ; - self#incref (context_gno ctx) o ; - (match m_n_obj with - | Some(x) -> self#decref (context_gno ctx) x ; (context_sub1 m_ctx) - | None -> () - ); - m_n_obj <- Some o - - method gc = m_ctx - method gnc = (context_gno m_ctx) -end - - - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - -let z3obj_gc o = o.m_ctx -let z3obj_gnc o = (context_gno o.m_ctx) - -let z3obj_gno o = o.m_n_obj -let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - -let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - -let z3obj_create o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - -let z3obj_nil_ref x y = () - -let array_to_native a = - let f e = (z3obj_gno e) in - Array.map f a -(**/**) (** Symbols are used to name several term and type constructors *) module Symbol = -struct - (** Int symbol objects *) - type int_symbol = z3_native_object - - (** String symbol objects *) - type string_symbol = z3_native_object - - (** Symbol Objects *) - type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - - (**/**) +struct let create_i ( ctx : context ) ( no : Z3native.ptr ) = let res : int_symbol = { m_ctx = ctx ; m_n_obj = null ; @@ -255,6 +582,11 @@ struct (z3obj_create res) ; res + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with + | INT_SYMBOL -> S_Int (create_i ctx no) + | STRING_SYMBOL -> S_Str (create_s ctx no) + let gc ( x : symbol ) = match x with | S_Int(n) -> (z3obj_gc n) @@ -269,17 +601,7 @@ struct match x with | S_Int(n) -> (z3obj_gno n) | S_Str(n) -> (z3obj_gno n) - - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> S_Int (create_i ctx no) - | STRING_SYMBOL -> S_Str (create_s ctx no) - - let aton a = - let f e = (gno e) in - Array.map f a - (**/**) - + (** The kind of the symbol (int or string) *) let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) @@ -327,48 +649,11 @@ end (** The abstract syntax tree (AST) module *) -module rec AST : -sig - type ast = z3_native_object - -(**/**) - val create : context -> Z3native.ptr -> ast - val aton : ast array -> Z3native.ptr array -(**/**) - - module ASTVectors : sig - type ast_vector - val create : context -> Z3native.ptr -> ast_vector - val get_size : ast_vector -> int - val get : ast_vector -> int -> ast - end - - val is_expr : ast -> bool - val is_var : ast -> bool -end = struct - type ast = z3_native_object - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let aton (a : ast array) = - let f (e : ast) = (z3obj_gno e) in - Array.map f a - (**/**) - +module AST = +struct (** Vectors of ASTs *) - module ASTVectors = + module ASTVector = struct - type ast_vector = z3_native_object - - (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; @@ -377,7 +662,7 @@ end = struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** The size of the vector *) let get_size ( x : ast_vector ) = @@ -411,7 +696,7 @@ end = struct (** Translates all ASTs in the vector to . @param to_ctx A context - @return A new ASTVectors + @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) @@ -423,10 +708,8 @@ end = struct (** Map from AST to AST *) module ASTMap = - struct - type ast_map = z3_native_object - - (**/**) + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; @@ -435,7 +718,7 @@ end = struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Checks whether the map contains the key . @param k An AST @@ -476,7 +759,7 @@ end = struct (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVectors.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = @@ -576,7 +859,7 @@ end = struct if (z3obj_gnc x) == (context_gno to_ctx) then x else - create to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Wraps an AST. @@ -590,7 +873,7 @@ end = struct @param nativeObject The native pointer to wrap. *) let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - create ctx ptr + ast_of_ptr ctx ptr (** Unwraps an AST. @@ -603,66 +886,17 @@ end = struct @param a The AST to unwrap. *) - let unwrap_ast ( x : ast ) = (z3obj_gno x) - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST -> (match (FuncDecl.create ctx no) with FuncDecl.FuncDecl(x) -> x) - | SORT_AST -> (match (Sort.create ctx no) with Sort.Sort(x) -> x) - | QUANTIFIER_AST -> (match (Quantifiers.create ctx no) with Quantifiers.Quantifier(Expr.Expr(x)) -> x) - | APP_AST - | NUMERAL_AST - | VAR_AST -> (match (Expr.create ctx no) with Expr.Expr(x) -> x) - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") -(**/**) + let unwrap_ast ( x : ast ) = (z3obj_gno x) end (** The Sort module implements type information for ASTs *) -and Sort : -sig - type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort - - val create : context -> Z3native.ptr -> sort - val gc : sort -> context - val gnc : sort -> Z3native.ptr - val gno : sort -> Z3native.ptr - val aton : sort array -> Z3native.ptr array -end = struct - type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort - - (**/**) +module Sort = +struct + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - let aton : sort array -> Z3native.ptr array = fun a -> - let f e = (gno e) in - Array.map f a - - let create : context -> Z3native.ptr -> sort = fun ctx no -> - let q : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno q ctx no) ; - (z3obj_create q) ; - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - (**/**) - - (** Comparison operator. @param a A sort @@ -700,7 +934,7 @@ end = struct (** Create a new uninterpreted sort. *) - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = + let mk_uninterpreted ( ctx : context ) ( s : symbol ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -718,71 +952,37 @@ end (** Function declarations *) -and FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - - val create : context -> Z3native.ptr -> func_decl - val gc : func_decl -> context - val gno : func_decl -> Z3native.ptr - val gnc : func_decl -> Z3native.ptr - val aton : func_decl array -> Z3native.ptr array - - val get_domain_size : func_decl -> int - val get_decl_kind : func_decl -> Z3enums.decl_kind - val get_arity : func_decl -> int -end = struct - type func_decl = FuncDecl of AST.ast - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - FuncDecl(res) - - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = +module FuncDecl = +struct + (**/**) + let create_ndr ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + let f x = (ptr_of_ast (ast_of_sort x)) in + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) - let create_pdr ( ctx : context) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + let f x = (ptr_of_ast (ast_of_sort x)) in + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - - let aton (a : func_decl array) = - let f (e : func_decl) = (gno e) in - Array.map f a - (**/**) + (**/**) (** Parameters of Func_Decls *) module Parameter = - struct - type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - + struct (** The kind of the parameter. *) let get_kind ( x : parameter ) = (match x with @@ -840,13 +1040,13 @@ end = struct (** Creates a new function declaration. *) - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = create_ndr ctx name domain range (** Creates a new function declaration. *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range (** @@ -854,19 +1054,19 @@ end = struct *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = create_pdr ctx prefix domain range (** Creates a new constant function declaration. *) - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = + let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort ) = create_ndr ctx name [||] range (** Creates a new constant function declaration. *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = create_ndr ctx (Symbol.mk_string ctx name) [||] range (** @@ -874,7 +1074,7 @@ end = struct *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = create_pdr ctx prefix [||] range @@ -917,14 +1117,14 @@ end = struct *) let get_domain ( x : func_decl ) = let n = (get_domain_size x) in - let f i = Sort.create (gc x) (Z3native.get_domain (gnc x) (gno x) i) in + let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in Array.init n f (** The range of the function declaration *) let get_range ( x : func_decl ) = - Sort.create (gc x) (Z3native.get_range (gnc x) (gno x)) + sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) (** The kind of the function declaration. @@ -947,13 +1147,13 @@ end = struct let get_parameters ( x : func_decl ) = let n = (get_num_parameters x) in let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> Parameter.P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> Parameter.P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> P_Ast (ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) ) in mk_list f n @@ -961,7 +1161,7 @@ end = struct Create expression that applies function to arguments. @param args The arguments *) - let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.create_fa (gc x) x args + let apply ( x : func_decl ) ( args : expr array ) = expr_of_func_app (gc x) x args end (** @@ -969,43 +1169,12 @@ end A Params objects represents a configuration in the form of symbol/value pairs. *) -and Params : -sig - type params = z3_native_object - - val create : context -> Z3native.ptr -> params - - module ParamDescrs : sig - type param_descrs = z3_native_object - - val create : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - end -end = struct - type params = z3_native_object - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : params = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.params_inc_ref ; - dec_ref = Z3native.params_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - (**/**) - +module Params = +struct (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs : - sig - type param_descrs = z3_native_object - - val create : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - end = struct - type param_descrs = z3_native_object - - (**/**) + module ParamDescrs = + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : param_descrs = { m_ctx = ctx ; m_n_obj = null ; @@ -1014,14 +1183,14 @@ end = struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Validate a set of parameters. *) let validate ( x : param_descrs ) ( p : params ) = Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = + let get_kind ( x : param_descrs ) ( name : symbol ) = (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) (** Retrieve all names of parameters. *) @@ -1040,25 +1209,25 @@ end = struct (** Adds a parameter setting. *) - let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = + let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = + let add_int ( x : params ) (name : symbol ) ( value : int ) = Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + let add_double ( x : params ) ( name : symbol ) ( value : float ) = Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = + let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) (** @@ -1081,14 +1250,20 @@ end = struct (** Adds a parameter setting. *) - let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = + let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = add_symbol x (Symbol.mk_string (z3obj_gc x) name) value (** Creates a new parameter set *) let mk_params ( ctx : context ) = - create ctx (Z3native.mk_params (context_gno ctx)) + let res : params = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.params_inc_ref ; + dec_ref = Z3native.params_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; + (z3obj_create res) ; + res (** A string representation of the parameter set. @@ -1097,76 +1272,16 @@ end = struct end (** General expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - - val create : context -> Z3native.ptr -> expr - val create_fa : context -> FuncDecl.func_decl -> expr array -> expr - val gc : expr -> context - val gno : expr -> Z3native.ptr - val gnc : expr -> Z3native.ptr - val aton : expr array -> Z3native.ptr array - - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - val get_func_decl : expr -> FuncDecl.func_decl - val is_numeral : expr -> bool - val to_string : expr -> string -end = struct - type expr = Expr of AST.ast - - (**/**) - let create ( ctx : context ) ( obj : Z3native.ptr ) = - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then - (match (Quantifiers.create ctx obj) with Quantifiers.Quantifier(e) -> e) - else - let s = Z3native.get_sort (context_gno ctx) obj in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.ArithExpr(e)) -> e) - else - if (Z3native.is_numeral_ast (context_gno ctx) obj) && - (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - match sk with - | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e))) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e))) -> e) - | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) - | _ -> raise (Z3native.Exception "Unsupported numeral object") - else - match sk with - | BOOL_SORT -> (match (Booleans.create_expr ctx obj) with Booleans.BoolExpr(e) -> e) - | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e)) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e)) -> e) - | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) - | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) - | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) - | _ -> Expr(AST.create ctx obj) - - let aton ( a : expr array ) = - let f ( e : expr ) = match e with Expr(a) -> (z3obj_gno a) in - Array.map f a - - let create_fa ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = - let o = Z3native.mk_app (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args) in - Expr.create ctx o - - let gc ( x : expr ) = match x with Expr(a) -> (z3obj_gc a) - let gnc ( x : expr ) = match x with Expr(a) -> (z3obj_gnc a) - let gno ( x : expr ) = match x with Expr(a) -> (z3obj_gno a) - - let aton (a : expr array) = - let f (e : expr) = (gno e) in - Array.map f a - (**/**) - +module Expr = +struct (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier *) - let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> Expr.create (gc x) (Z3native.simplify (gnc x) (gno x)) - | Some pp -> Expr.create (gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) + let simplify ( x : expr ) ( p : params option ) = match p with + | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) + | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) (** a string describing all available parameters to Expr.Simplify. @@ -1183,24 +1298,24 @@ end = struct (** The function declaration of the function that is applied in this expression. *) - let get_func_decl ( x : expr ) = FuncDecl.create (gc x) (Z3native.get_app_decl (gnc x) (gno x)) + let get_func_decl ( x : expr ) = func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the expression is the true or false expression or something else (L_UNDEF). *) - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (nc_of_expr x) (ptr_of_expr x)) (** The number of arguments of the expression. *) - let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) + let get_num_args ( x : expr ) = Z3native.get_app_num_args (nc_of_expr x) (ptr_of_expr x) (** The arguments of the expression. *) let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = create (gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in + let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in Array.init n f (** @@ -1211,7 +1326,7 @@ end = struct if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - create (gc x) (Z3native.update_term (gnc x) (gno x) (Array.length args) (aton args)) + expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (Array.length args) (expr_aton args)) (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. @@ -1224,7 +1339,7 @@ end = struct if (Array.length from) <> (Array.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - create (gc x) (Z3native.substitute (gnc x) (gno x) (Array.length from) (aton from) (aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (Array.length from) (expr_aton from) (expr_aton to_)) (** Substitute every occurrence of from in the expression with to. @@ -1239,48 +1354,47 @@ end = struct For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) let substitute_vars ( x : expr ) to_ = - create (gc x) (Z3native.substitute_vars (gnc x) (gno x) (Array.length to_) (aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (Array.length to_) (expr_aton to_)) - (** Translates (copies) the term to the Context . @param ctx A context @return A copy of the term which is associated with *) let translate ( x : expr ) to_ctx = - if (gc x) == to_ctx then + if (c_of_expr x) == to_ctx then x else - create to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) + expr_of_ptr to_ctx (Z3native.translate (nc_of_expr x) (ptr_of_expr x) (context_gno to_ctx)) (** Returns a string representation of the expression. *) - let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) + let to_string ( x : expr ) = Z3native.ast_to_string (nc_of_expr x) (ptr_of_expr x) (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (nc_of_expr x) (ptr_of_expr x) (** The Sort of the term. *) - let get_sort ( x : expr ) = Sort.create (gc x) (Z3native.get_sort (gnc x) (gno x)) + let get_sort ( x : expr ) = sort_of_ptr (c_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the term has Boolean sort. *) let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (gnc x) - (Z3native.mk_bool_sort (gnc x)) - (Z3native.get_sort (gnc x) (gno x))) + (Z3native.is_eq_sort (nc_of_expr x) + (Z3native.mk_bool_sort (nc_of_expr x)) + (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x))) (** Indicates whether the term represents a constant. @@ -1366,14 +1480,14 @@ end = struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = - create ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) + let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) (** Creates a new Constant of sort and named . *) - let mk_const_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = + let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) range @@ -1381,21 +1495,21 @@ end = struct Creates a constant from the func_decl . @param f An expression of a 0-arity function *) - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = - create_fa ctx f [||] + let mk_const_f ( ctx : context ) ( f : func_decl ) = + expr_of_func_app ctx f [||] (** Creates a fresh constant of sort and a name prefixed with . *) - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = - create ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) (** Create a new function application. *) - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = - create_fa ctx f args + let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = + expr_of_func_app ctx f args (** Create a numeral of a given sort. @@ -1403,8 +1517,8 @@ end = struct @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. @return A Term with value and sort *) - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : Sort.sort ) = - create ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. @@ -1413,50 +1527,31 @@ end = struct @param ty Sort of the numeral @return A Term with value and type *) - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : Sort.sort ) = - create ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) end (** Boolean expressions *) -and Booleans : -sig - type bool_expr = BoolExpr of Expr.expr - type bool_sort = BoolSort of Sort.sort +module Boolean = +struct + let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let a = (ast_of_ptr ctx no) in + BoolExpr(Expr(a)) - val create_expr : context -> Z3native.ptr -> bool_expr - val create_sort : context -> Z3native.ptr -> bool_sort - val gc : bool_expr -> context - val gnc : bool_expr -> Z3native.ptr - val gno : bool_expr -> Z3native.ptr - val aton : bool_expr array -> Z3native.ptr array -end = struct - type bool_expr = BoolExpr of Expr.expr - type bool_sort = BoolSort of Sort.sort - - (**/**) - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.create ctx no) in - BoolExpr(Expr.Expr(a)) + let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + BoolSort(sort_of_ptr ctx no) - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - BoolSort(Sort.create ctx no) - - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gc e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gnc e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gno e) - - let aton ( a : bool_expr array ) = - let f (e : bool_expr) = (gno e) in - Array.map f a - (**/**) + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (c_of_expr e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (nc_of_expr e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (ptr_of_expr e) let mk_sort ( ctx : context ) = - BoolSort(Sort.create ctx (Z3native.mk_bool_sort (context_gno ctx))) + BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) (** Create a Boolean constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : symbol ) = let s = (match (mk_sort ctx) with BoolSort(q) -> q) in BoolExpr(Expr.mk_const ctx name s) @@ -1470,13 +1565,13 @@ end = struct The true Term. *) let mk_true ( ctx : context ) = - create_expr ctx (Z3native.mk_true (context_gno ctx)) + bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) (** The false Term. *) let mk_false ( ctx : context ) = - create_expr ctx (Z3native.mk_false (context_gno ctx)) + bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) (** Creates a Boolean value. @@ -1487,20 +1582,20 @@ end = struct (** Creates the equality = . *) - let mk_eq ( ctx : context ) ( x : Expr.expr ) ( y : Expr.expr ) = - create_expr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) (** Creates a distinct term. *) - let mk_distinct ( ctx : context ) ( args : Expr.expr array ) = - create_expr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) + let mk_distinct ( ctx : context ) ( args : expr array ) = + bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (expr_aton args)) (** Mk an expression representing not(a). *) let mk_not ( ctx : context ) ( a : bool_expr ) = - create_expr ctx (Z3native.mk_not (context_gno ctx) (gno a)) + bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) (** Create an expression representing an if-then-else: ite(t1, t2, t3). @@ -1509,103 +1604,70 @@ end = struct @param t3 An expression with the same sort as *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create_expr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) (** Create an expression representing t1 iff t2. *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create_expr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 -> t2. *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create_expr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 xor t2. *) let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create_expr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing the AND of args *) let mk_and ( ctx : context ) ( args : bool_expr array ) = - create_expr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) + let f x = (ptr_of_expr (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (Array.map f args)) (** Create an expression representing the OR of args *) let mk_or ( ctx : context ) ( args : bool_expr array ) = - create_expr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) + let f x = (ptr_of_expr (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (Array.map f args)) end (** Quantifier expressions *) -and Quantifiers : -sig - type quantifier = Quantifier of Expr.expr - - val create : context -> Z3native.ptr -> quantifier -end = struct - type quantifier = Quantifier of Expr.expr - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.create ctx no) in - Quantifier(Expr.Expr(a)) - - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - (**/**) - +module Quantifier = +struct + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (c_of_expr e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) + (** Quantifier patterns Patterns comprise a list of terms. The list should be non-empty. If the list comprises of more than one term, it is also called a multi-pattern. *) - module Patterns : - sig - type pattern = Pattern of AST.ast - - val create : context -> Z3native.ptr -> pattern - val aton : pattern array -> Z3native.ptr array - end = struct - type pattern = Pattern of AST.ast - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - Pattern(res) - + module Pattern = struct let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - let aton (a : pattern array) = - let f (e : pattern) = (gno e) in - Array.map f a - (**/**) - (** The number of terms in the pattern. *) let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - + Z3native.get_pattern_num_terms (gnc x) (gno x) + (** The terms in the pattern. *) let get_terms ( x : pattern ) = let n = (get_num_terms x) in - let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in + let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in Array.init n f (** @@ -1632,11 +1694,11 @@ end = struct on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its index. *) - let get_index ( x : Expr.expr ) = - if not (AST.is_var (match x with Expr.Expr(a) -> a)) then + let get_index ( x : expr ) = + if not (AST.is_var (match x with Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else - Z3native.get_index_value (Expr.gnc x) (Expr.gno x) + Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) (** Indicates whether the quantifier is universal. @@ -1664,7 +1726,7 @@ end = struct *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = (Patterns.create (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1677,7 +1739,7 @@ end = struct *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = (Patterns.create (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1698,31 +1760,31 @@ end = struct *) let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (Sort.create (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in + let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in Array.init n f (** The body of the quantifier. *) let get_body ( x : quantifier ) = - Booleans.create_expr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) (** Creates a new bound variable. @param index The de-Bruijn index of the variable @param ty The sort of the variable *) - let mk_bound ( ctx : context ) ( index : int ) ( ty : Sort.sort ) = - Expr.create ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) (** Create a quantifier pattern. *) - let mk_pattern ( ctx : context ) ( terms : Expr.expr array ) = + let mk_pattern ( ctx : context ) ( terms : expr array ) = if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - Patterns.create ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (Expr.aton terms)) + Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) (** Create a universal Quantifier. @@ -1743,96 +1805,96 @@ end = struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (Patterns.aton patterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) - + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) + (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (ptr_of_expr body))) (** Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (Patterns.aton patterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) - + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) + (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (ptr_of_expr body))) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -1842,7 +1904,7 @@ end = struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -1850,42 +1912,29 @@ end = struct end (** Functions to manipulate Array expressions *) -and Arrays : -sig - type array_expr = ArrayExpr of Expr.expr - type array_sort = ArraySort of Sort.sort - - val create_expr : context -> Z3native.ptr -> array_expr -end = struct - type array_expr = ArrayExpr of Expr.expr - type array_sort = ArraySort of Sort.sort - - (**/**) +module Array_ = +struct + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (Expr.create ctx no) in + let e = (expr_of_ptr ctx no) in ArrayExpr(e) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in ArraySort(s) - let sgc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gno s) + let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) - let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gc e) - let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gnc e) - let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gno e) + let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) + let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) + let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - let aton (a : array_expr array) = - let f (e : array_expr) = (egno e) in - Array.map f a - (**/**) - (** Create a new array sort. *) - let mk_sort ( ctx : context ) ( domain : Sort.sort ) ( range : Sort.sort ) = + let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = create_sort ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) (** @@ -1893,62 +1942,62 @@ end = struct It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). Array store takes at least 3 arguments. *) - let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) (** Indicates whether the term is an array select. *) - let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) (** Indicates whether the term is a constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - let is_constant_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) (** Indicates whether the term is a default array. For example default(const(v)) = v. The function is unary. *) - let is_default_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) (** Indicates whether the term is an array map. It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - let is_array_map ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) (** Indicates whether the term is an as-array term. An as-array term is n array value that behaves as the function graph of the function passed as parameter. *) - let is_as_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) (** Indicates whether the term is of an array sort. *) - let is_array ( x : Expr.expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) + let is_array ( x : expr ) = + (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) (** The domain of the array sort. *) - let get_domain ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) + let get_domain ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) (** The range of the array sort. *) - let get_range ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) + let get_range ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort ) ( range : Sort.sort ) = + let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) (** Create an array constant. *) - let mk_const_s ( ctx : context ) ( name : string ) ( domain : Sort.sort ) ( range : Sort.sort ) = + let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range (** @@ -1963,8 +2012,8 @@ end = struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) = - create_expr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = + expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) (** Array update. @@ -1982,8 +2031,8 @@ end = struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) ( v : Expr.expr ) = - create_expr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = + expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) (** Create a constant array. @@ -1993,8 +2042,8 @@ end = struct *) - let mk_const_array ( ctx : context ) ( domain : Sort.sort ) ( v : Expr.expr ) = - create_expr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) + let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = + expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) (** Maps f on the argument arrays. @@ -2006,8 +2055,9 @@ end = struct *) - let mk_map ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : array_expr array ) = - create_expr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args)) + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = + let m x = (ptr_of_expr (expr_of_array_expr x)) in + expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) (** Access the array default value. @@ -2016,137 +2066,122 @@ end = struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - create_expr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) + expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end (** Functions to manipulate Set expressions *) -and Sets : -sig - type set_sort = SetSort of Sort.sort - -end = struct - type set_sort = SetSort of Sort.sort - +module Set = +struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in SetSort(s) (** Indicates whether the term is set union *) - let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) (** Indicates whether the term is set intersection *) - let is_intersect ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) (** Indicates whether the term is set difference *) - let is_difference ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) (** Indicates whether the term is set complement *) - let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) (** Indicates whether the term is set subset *) - let is_subset ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) (** Create a set type. *) - let mk_sort ( ctx : context ) ( ty : Sort.sort ) = + let mk_sort ( ctx : context ) ( ty : sort ) = create_sort ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) (** Create an empty set. *) - let mk_empty ( ctx : context ) ( domain : Sort.sort ) = - (Expr.create ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) + let mk_empty ( ctx : context ) ( domain : sort ) = + (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) (** Create the full set. *) - let mk_full ( ctx : context ) ( domain : Sort.sort ) = - Expr.create ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) + let mk_full ( ctx : context ) ( domain : sort ) = + expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) (** Add an element to the set. *) - let mk_set_add ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) + let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) (** Remove an element from a set. *) - let mk_del ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) + let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) (** Take the union of a list of sets. *) - let mk_union ( ctx : context ) ( args : Expr.expr array ) = - Expr.create ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (Expr.aton args)) + let mk_union ( ctx : context ) ( args : expr array ) = + expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (expr_aton args)) (** Take the intersection of a list of sets. *) - let mk_intersection ( ctx : context ) ( args : Expr.expr array ) = - Expr.create ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (Expr.aton args)) + let mk_intersection ( ctx : context ) ( args : expr array ) = + expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (expr_aton args)) (** Take the difference between two sets. *) - let mk_difference ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) (** Take the complement of a set. *) - let mk_complement ( ctx : context ) ( arg : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) + let mk_complement ( ctx : context ) ( arg : expr ) = + expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (ptr_of_expr arg)) (** Check for set membership. *) - let mk_membership ( ctx : context ) ( elem : Expr.expr ) ( set : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) + let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (ptr_of_expr elem) (ptr_of_expr set)) (** Check for subsetness of sets. *) - let mk_subset ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) end (** Functions to manipulate Finite Domain expressions *) -and FiniteDomains : -sig - type finite_domain_sort = FiniteDomainSort of Sort.sort - -end = struct - type finite_domain_sort = FiniteDomainSort of Sort.sort - - (**/**) - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in - FiniteDomainSort(s) - - let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gc s) - let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gnc s) - let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) - +module FiniteDomain = +struct + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) + (** Create a new finite domain sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - create_sort ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size) + let mk_sort ( ctx : context ) ( name : symbol ) ( size : int ) = + let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in + FiniteDomainSort(s) (** Create a new finite domain sort. @@ -2158,14 +2193,15 @@ end = struct (** Indicates whether the term is of an array sort. *) - let is_finite_domain ( x : Expr.expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == FINITE_DOMAIN_SORT) + let is_finite_domain ( x : expr ) = + let nc = (nc_of_expr x) in + (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == FINITE_DOMAIN_SORT) (** Indicates whether the term is a less than predicate over a finite domain. *) - let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) (** The size of the finite domain sort. *) let get_size ( x : finite_domain_sort ) = @@ -2175,29 +2211,25 @@ end = struct end (** Functions to manipulate Relation expressions *) -and Relations : -sig - type relation_sort = RelationSort of Sort.sort - -end = struct - type relation_sort = RelationSort of Sort.sort - - (**/**) +module Relation = +struct + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in RelationSort(s) - let gc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gc s) - let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gnc s) - let gno ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) + (** Indicates whether the term is of a relation sort. *) - let is_relation ( x : Expr.expr ) = - ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == RELATION_SORT)) + let is_relation ( x : expr ) = + let nc = (nc_of_expr x) in + ((Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == RELATION_SORT)) (** Indicates whether the term is an relation store @@ -2206,40 +2238,40 @@ end = struct The function takes n+1 arguments, where the first argument is the relation and the remaining n elements correspond to the n columns of the relation. *) - let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) (** Indicates whether the term is an empty relation *) - let is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) (** Indicates whether the term is a test for the emptiness of a relation *) - let is_is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) (** Indicates whether the term is a relational join *) - let is_join ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) (** Indicates whether the term is the union or convex hull of two relations. The function takes two arguments. *) - let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) (** Indicates whether the term is the widening of two relations The function takes two arguments. *) - let is_widen ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). The function takes one argument. *) - let is_project ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) (** Indicates whether the term is a relation filter @@ -2250,7 +2282,7 @@ end = struct corresponding to the columns of the relation. So the first column in the relation has index 0. *) - let is_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) (** Indicates whether the term is an intersection of a relation with the negation of another. @@ -2265,7 +2297,7 @@ end = struct target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with ( x : expr ) on the columns c1, d1, .., cN, dN. *) - let is_negation_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) (** Indicates whether the term is the renaming of a column in a relation @@ -2273,12 +2305,12 @@ end = struct The function takes one argument. The parameters contain the renaming as a cycle. *) - let is_rename ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) (** Indicates whether the term is the complement of a relation *) - let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) (** Indicates whether the term is a relational select @@ -2287,7 +2319,7 @@ end = struct The function takes n+1 arguments, where the first argument is a relation, and the remaining n arguments correspond to a record. *) - let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) (** Indicates whether the term is a relational clone (copy) @@ -2298,7 +2330,7 @@ end = struct for terms of kind to perform destructive updates to the first argument. *) - let is_clone ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) (** The arity of the relation sort. *) let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) @@ -2312,46 +2344,22 @@ end = struct end (** Functions to manipulate Datatype expressions *) -and Datatypes : -sig - type datatype_expr = DatatypeExpr of Expr.expr - type datatype_sort = DatatypeSort of Sort.sort - - val create_expr : context -> Z3native.ptr -> datatype_expr -end = struct - type datatype_expr = DatatypeExpr of Expr.expr - type datatype_sort = DatatypeSort of Sort.sort - - (**/**) - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (Expr.create ctx no) in - DatatypeExpr(e) - +module Datatype = +struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in DatatypeSort(s) - let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) + (** Constructors *) - module Constructor : sig - type constructor - val create : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> constructor - val aton : constructor array -> Z3native.ptr array - end = struct - type constructor_extra = { - m_n : int; - mutable m_tester_decl : FuncDecl.func_decl option; - mutable m_constructor_decl : FuncDecl.func_decl option ; - mutable m_accessor_decls : FuncDecl.func_decl array option} - - type constructor = Constructor of (z3_native_object * constructor_extra) - - (**/**) - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + module Constructor = + struct + + let create ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -2362,8 +2370,8 @@ end = struct let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) n - (Symbol.aton field_names) - (Sort.aton sorts) + (let f x = (Symbol.gno x) in (Array.map f field_names)) + (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) sort_refs) in let no : z3_native_object = { m_ctx = ctx ; m_n_obj = null ; @@ -2379,21 +2387,17 @@ end = struct Gc.finalise f no ; Constructor(no, ex) - let aton ( a : constructor array ) = - let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in - Array.map f a - let init_extra ( x : constructor ) = match x with Constructor(no, ex) -> match ex.m_tester_decl with | None -> let (a, b, c) = (Z3native.query_constructor (z3obj_gnc no) (z3obj_gno no) ex.m_n) in - ex.m_constructor_decl <- Some (FuncDecl.create (z3obj_gc no) a) ; - ex.m_tester_decl <- Some (FuncDecl.create (z3obj_gc no) b) ; - ex.m_accessor_decls <- Some (let f e = (FuncDecl.create (z3obj_gc no) e) in Array.map f c) ; + ex.m_constructor_decl <- Some (func_decl_of_ptr (z3obj_gc no) a) ; + ex.m_tester_decl <- Some (func_decl_of_ptr (z3obj_gc no) b) ; + ex.m_accessor_decls <- Some (let f e = (func_decl_of_ptr (z3obj_gc no) e) in Array.map f c) ; () | _ -> () - (**/**) + let get_n ( x : constructor ) = match x with Constructor(no, ex) -> @@ -2433,24 +2437,18 @@ end = struct (** Constructor list objects *) module ConstructorList = struct - type constructor_list = z3_native_object - - (**/**) - let create ( ctx : context )( c : Constructor.constructor array ) = + + let create ( ctx : context ) ( c : constructor array ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Constructor.aton c))) ; + let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Array.map f c))) ; (z3obj_create res) ; let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f res; res - - let aton (a : constructor_list array) = - let f (e : constructor_list) = (z3obj_gno e) in - Array.map f a - (**/**) end (* DATATYPES *) @@ -2464,7 +2462,7 @@ end = struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array) = + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = Constructor.create ctx name recognizer field_names sorts sort_refs @@ -2478,21 +2476,22 @@ end = struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array) = - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Constructor.aton constructors)) in + let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in create_sort ctx x (** Create a new datatype sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors (** @@ -2500,16 +2499,17 @@ end = struct @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = + let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = let n = (Array.length names) in - let f e = (ConstructorList.create ctx e) in + let f e = (ptr_of_ast (ConstructorList.create ctx e)) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (ConstructorList.aton cla)) in + let f2 x = (Symbol.gno x) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Array.map f2 names) cla) in let g e = (create_sort ctx e) in (Array.map g r) (** Create mutually recursive data-types. *) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in @@ -2523,54 +2523,50 @@ end = struct (** The range of the array sort. *) let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in Array.init n f (** The recognizers. *) let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in Array.init n f (** The constructor accessors. *) let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = ( - let fd = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in + let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in Array.init ds g ) in Array.init n f end (** Functions to manipulate Enumeration expressions *) -and Enumerations : -sig - type enum_sort_data - type enum_sort = EnumSort of (Sort.sort * enum_sort_data) -end = struct - type enum_sort_data = { mutable _constdecls : FuncDecl.func_decl array ; - mutable _testerdecls : FuncDecl.func_decl array } - type enum_sort = EnumSort of (Sort.sort * enum_sort_data) - - (**/**) +module Enumeration = +struct + let _constdecls = Hashtbl.create 0 + let _testerdecls = Hashtbl.create 0 + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = - let s = (Sort.create ctx no) in - let e = { _constdecls = (let f e = FuncDecl.create ctx e in (Array.map f cdecls)) ; - _testerdecls = (let f e = FuncDecl.create ctx e in (Array.map f tdecls)) } in - EnumSort(s, e) + let s = (sort_of_ptr ctx no) in + let res = EnumSort(s) in + Hashtbl.add _constdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f cdecls)) ; + Hashtbl.add _testerdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f tdecls)) ; + res - let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gc s) - let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gnc s) - let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_)-> (z3obj_gno s) - (**/**) + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) (** Create a new enumeration sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in + let mk_sort ( ctx : context ) ( name : symbol ) ( enum_names : symbol array ) = + let f x = Symbol.gno x in + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in create_sort ctx a b c (** @@ -2580,45 +2576,40 @@ end = struct mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) - let get_const_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._constdecls + let get_const_decls ( x : enum_sort ) = Hashtbl.find _constdecls x (** The test predicates for the constants in the enumeration. *) - let get_tester_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._testerdecls + let get_tester_decls ( x : enum_sort ) = Hashtbl.find _testerdecls x end (** Functions to manipulate List expressions *) -and Lists : -sig - type list_sort_data - type list_sort = ListSort of (Sort.sort * list_sort_data) - -end = struct - type list_sort_data = { _nildecl : FuncDecl.func_decl ; - _is_nildecl : FuncDecl.func_decl ; - _consdecl : FuncDecl.func_decl ; - _is_consdecl : FuncDecl.func_decl ; - _headdecl : FuncDecl.func_decl ; - _taildecl : FuncDecl.func_decl } - type list_sort = ListSort of (Sort.sort * list_sort_data) - - (**/**) +module List_ = +struct + let _nildecls = Hashtbl.create 0 + let _is_nildecls = Hashtbl.create 0 + let _consdecls = Hashtbl.create 0 + let _is_consdecls = Hashtbl.create 0 + let _headdecls = Hashtbl.create 0 + let _taildecls = Hashtbl.create 0 + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = - let s = (Sort.create ctx no) in - let e = {_nildecl = FuncDecl.create ctx nildecl; - _is_nildecl = FuncDecl.create ctx is_nildecl; - _consdecl = FuncDecl.create ctx consdecl; - _is_consdecl = FuncDecl.create ctx is_consdecl; - _headdecl = FuncDecl.create ctx headdecl; - _taildecl = FuncDecl.create ctx taildecl} in - ListSort(s, e) + let s = (sort_of_ptr ctx no) in + let res = ListSort(s) in + Hashtbl.add _nildecls res (func_decl_of_ptr ctx nildecl) ; + Hashtbl.add _is_nildecls res (func_decl_of_ptr ctx is_nildecl) ; + Hashtbl.add _consdecls res (func_decl_of_ptr ctx consdecl) ; + Hashtbl.add _is_consdecls res (func_decl_of_ptr ctx is_consdecl) ; + Hashtbl.add _headdecls res (func_decl_of_ptr ctx headdecl) ; + Hashtbl.add _taildecls res (func_decl_of_ptr ctx taildecl) ; + res - let sgc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gc s) - let sgnc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gnc s) - let sgno ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_)-> (z3obj_gno s) - (**/**) + let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) + (** Create a new list sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : Sort.sort ) = + let mk_sort ( ctx : context ) ( name : symbol ) ( elem_sort : sort ) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in create_sort ctx r a b c d e f @@ -2627,53 +2618,51 @@ end = struct mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) - let get_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._nildecl + let get_nil_decl ( x : list_sort ) = (Hashtbl.find _nildecls x) (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_nildecl + let get_is_nil_decl ( x : list_sort ) = (Hashtbl.find _is_nildecls x) (** The declaration of the cons function of this list sort. *) - let get_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._consdecl + let get_cons_decl ( x : list_sort ) = (Hashtbl.find _consdecls x) (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_consdecl + let get_is_cons_decl ( x : list_sort ) = (Hashtbl.find _is_consdecls x) (** The declaration of the head function of this list sort. *) - let get_head_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._headdecl + let get_head_decl ( x : list_sort ) = (Hashtbl.find _headdecls x) (** The declaration of the tail function of this list sort. *) - let get_tail_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._taildecl + let get_tail_decl ( x : list_sort ) = (Hashtbl.find _taildecls x) (** The empty list. *) - let nil ( x : list_sort ) = Expr.create_fa (sgc x) (get_nil_decl x) [||] + let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] end (** Functions to manipulate Tuple expressions *) -and Tuples : -sig - type tuple_sort = TupleSort of Sort.sort -end = struct - type tuple_sort = TupleSort of Sort.sort - - (**/**) +module Tuple = +struct + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in TupleSort(s) - let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) + (** Create a new tuple sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : Sort.sort array ) = - let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Symbol.aton field_names) (Sort.aton field_sorts)) in + let mk_sort ( ctx : context ) ( name : symbol ) ( field_names : symbol array ) ( field_sorts : sort array ) = + let f x = Symbol.gno x in + let f2 x = ptr_of_ast (ast_of_sort x) in + let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in (* CMW: leaks a,b? *) create_sort ctx r (** The constructor function of the tuple. *) let get_mk_decl ( x : tuple_sort ) = - FuncDecl.create (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) + func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) (** The number of fields in the tuple. *) let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) @@ -2681,131 +2670,37 @@ end = struct (** The field declarations. *) let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in - let f i = FuncDecl.create (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in Array.init n f end (** Functions to manipulate arithmetic expressions *) -and Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val create_expr : context -> Z3native.ptr -> arith_expr - val create_sort : context -> Z3native.ptr -> arith_sort - val aton : arith_expr array -> Z3native.ptr array - - module Integers : sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val create_sort : context -> Z3native.ptr -> int_sort - val create_expr : context -> Z3native.ptr -> int_expr - val create_num : context -> Z3native.ptr -> int_num - end - - module Reals : sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val create_sort : context -> Z3native.ptr -> real_sort - val create_expr : context -> Z3native.ptr -> real_expr - val create_num : context -> Z3native.ptr -> rat_num - end - - module AlgebraicNumbers : sig - type algebraic_num = AlgebraicNum of arith_expr - - val create_num : context -> Z3native.ptr -> algebraic_num - end - - val is_int : Expr.expr -> bool - val is_arithmetic_numeral : Expr.expr -> bool - val is_le : Expr.expr -> bool - val is_ge : Expr.expr -> bool - val is_lt : Expr.expr -> bool - val is_gt : Expr.expr -> bool - val is_add : Expr.expr -> bool - val is_sub : Expr.expr -> bool - val is_uminus : Expr.expr -> bool - val is_mul : Expr.expr -> bool - val is_div : Expr.expr -> bool - val is_idiv : Expr.expr -> bool - val is_remainder : Expr.expr -> bool - val is_modulus : Expr.expr -> bool - val is_inttoreal : Expr.expr -> bool - val is_real_to_int : Expr.expr -> bool - val is_real_is_int : Expr.expr -> bool - val is_real : Expr.expr -> bool - val is_int_numeral : Expr.expr -> bool - val is_rat_num : Expr.expr -> bool - val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr array -> Arithmetic.arith_expr - val mk_mul : context -> arith_expr array -> Arithmetic.arith_expr - val mk_sub : context -> arith_expr array -> Arithmetic.arith_expr - val mk_unary_minus : - context -> arith_expr -> Arithmetic.arith_expr - val mk_div : - context -> arith_expr -> arith_expr -> Arithmetic.arith_expr - val mk_power : - context -> arith_expr -> arith_expr -> Arithmetic.arith_expr - val mk_lt : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - val mk_le : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - val mk_gt : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - val mk_ge : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - -end = struct - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - (**/**) +module Arithmetic = +struct + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - ArithExpr(Expr.create ctx no) + arith_expr_of_expr (expr_of_ptr ctx no) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - ArithSort(Sort.create ctx no) + arith_sort_of_sort (sort_of_ptr ctx no) - let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gno s) - let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) - let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) - let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) + let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) + let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (c_of_expr e) + let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (nc_of_expr e) + let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (ptr_of_expr e) - let aton (a : arith_expr array) = - let f (e : arith_expr) = (egno e) in - Array.map f a - (**/**) - - module rec Integers : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val create_sort : context -> Z3native.ptr -> int_sort - val create_expr : context -> Z3native.ptr -> int_expr - val create_num : context -> Z3native.ptr -> int_num - end = struct - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - (**/**) + module Integer = + struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - IntSort(Arithmetic.create_sort ctx no) + int_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - IntExpr(Arithmetic.create_expr ctx no) + int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) let create_num ( ctx : context ) ( no : Z3native.ptr ) = - IntNum(create_expr ctx no) + int_num_of_int_expr (create_expr ctx no) let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) @@ -2816,7 +2711,7 @@ end = struct let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - (**/**) + (** Create a new integer sort. *) let mk_sort ( ctx : context ) = @@ -2834,7 +2729,7 @@ end = struct (** Creates an integer constant. *) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_int_const ( ctx : context ) ( name : symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) (** @@ -2848,14 +2743,14 @@ end = struct The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - create_expr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - create_expr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) (** Create an integer numeral. @@ -2883,7 +2778,7 @@ end = struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - Reals.create_expr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)) + real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) (** Create an bit bit-vector from the integer argument . @@ -2896,32 +2791,19 @@ end = struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVectors.create_expr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t)) + bitvec_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) end - and Reals : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val create_sort : context -> Z3native.ptr -> real_sort - val create_expr : context -> Z3native.ptr -> real_expr - val create_num : context -> Z3native.ptr -> rat_num - end = struct - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - (**/**) + module Real = + struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - RealSort(Arithmetic.create_sort ctx no) + real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - RealExpr(Arithmetic.create_expr ctx no) - + real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + let create_num ( ctx : context ) ( no : Z3native.ptr ) = - RatNum(create_expr ctx no) + rat_num_of_real_expr (create_expr ctx no) let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) @@ -2932,7 +2814,7 @@ end = struct let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - (**/**) + (** Create a real sort. *) let mk_sort ( ctx : context ) = @@ -2940,11 +2822,11 @@ end = struct (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = - Integers.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + Integer.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = - Integers.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + Integer.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2955,7 +2837,7 @@ end = struct let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) (** Creates a real constant. *) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_real_const ( ctx : context ) ( name : symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) (** Creates a real constant. *) @@ -2995,7 +2877,7 @@ end = struct (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - Booleans.create_expr ctx (Z3native.mk_is_int (context_gno ctx) (egno t)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) (** Coerce a real to an integer. @@ -3005,25 +2887,18 @@ end = struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - Integers.create_expr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)) + int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) end - and AlgebraicNumbers : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val create_num : context -> Z3native.ptr -> algebraic_num - end = struct - type algebraic_num = AlgebraicNum of arith_expr - - (**/**) + module AlgebraicNumber = + struct let create_num ( ctx : context ) ( no : Z3native.ptr ) = - AlgebraicNum(Arithmetic.create_expr ctx no) + algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - (**/**) + (** Return a upper bound for a given real algebraic number. @@ -3033,7 +2908,7 @@ end = struct @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = - Reals.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + Real.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) (** Return a lower bound for the given real algebraic number. @@ -3043,7 +2918,7 @@ end = struct @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = - Reals.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + Real.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -3057,207 +2932,197 @@ end = struct (** Indicates whether the term is of integer sort. *) - let is_int ( x : Expr.expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) + let is_int ( x : expr ) = + (Z3native.is_numeral_ast (nc_of_expr x) (nc_of_expr x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == INT_SORT) (** Indicates whether the term is an arithmetic numeral. *) - let is_arithmetic_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) (** Indicates whether the term is a less-than-or-equal *) - let is_le ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) (** Indicates whether the term is a greater-than-or-equal *) - let is_ge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) (** Indicates whether the term is a less-than *) - let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) (** Indicates whether the term is a greater-than *) - let is_gt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) (** Indicates whether the term is addition (binary) *) - let is_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) (** Indicates whether the term is subtraction (binary) *) - let is_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) (** Indicates whether the term is a unary minus *) - let is_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) (** Indicates whether the term is multiplication (binary) *) - let is_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) (** Indicates whether the term is division (binary) *) - let is_div ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) (** Indicates whether the term is integer division (binary) *) - let is_idiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) (** Indicates whether the term is remainder (binary) *) - let is_remainder ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) (** Indicates whether the term is modulus (binary) *) - let is_modulus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) (** Indicates whether the term is a coercion of integer to real (unary) *) - let is_inttoreal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) (** Indicates whether the term is a coercion of real to integer (unary) *) - let is_real_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - let is_real_is_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) (** Indicates whether the term is of sort real. *) - let is_real ( x : Expr.expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == REAL_SORT) (** Indicates whether the term is an integer numeral. *) - let is_int_numeral ( x : Expr.expr ) = (Expr.is_numeral x) && (is_int x) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) (** Indicates whether the term is a real numeral. *) - let is_rat_num ( x : Expr.expr ) = (Expr.is_numeral x) && (is_real x) + let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : Expr.expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) (** Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - Arithmetic.create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Arithmetic.aton t)) + let f x = (ptr_of_expr (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Array.map f t))) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - Arithmetic.create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Arithmetic.aton t)) + let f x = (ptr_of_expr (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Array.map f t))) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - Arithmetic.create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Arithmetic.aton t)) + let f x = (ptr_of_expr (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Array.map f t))) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - Arithmetic.create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t)) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Arithmetic.create_expr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2)) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 ^ t2. *) let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Arithmetic.create_expr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2)) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) end (** Functions to manipulate bit-vector expressions *) -and BitVectors : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val create_sort : context -> Z3native.ptr -> bitvec_sort - val create_expr : context -> Z3native.ptr -> bitvec_expr - val create_num : context -> Z3native.ptr -> bitvec_num -end = struct - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - (**/**) +module BitVector = +struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - BitVecSort(Sort.create ctx no) + bitvec_sort_of_sort (sort_of_ptr ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - BitVecExpr(Expr.create ctx no) + bitvec_expr_of_expr (expr_of_ptr ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = - BitVecNum(create_expr ctx no) + bitvec_num_of_bitvec_expr (create_expr ctx no) let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) - let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) - let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) - let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) + let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (c_of_expr e) + let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (nc_of_expr e) + let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (ptr_of_expr e) let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - (**/**) + (** Create a new bit-vector sort. @@ -3268,272 +3133,272 @@ end = struct (** Indicates whether the terms is of bit-vector sort. *) - let is_bv ( x : Expr.expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) + let is_bv ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == BV_SORT) (** Indicates whether the term is a bit-vector numeral *) - let is_bv_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) (** Indicates whether the term is a one-bit bit-vector with value one *) - let is_bv_bit1 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) (** Indicates whether the term is a one-bit bit-vector with value zero *) - let is_bv_bit0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) (** Indicates whether the term is a bit-vector unary minus *) - let is_bv_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) (** Indicates whether the term is a bit-vector addition (binary) *) - let is_bv_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) (** Indicates whether the term is a bit-vector subtraction (binary) *) - let is_bv_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) (** Indicates whether the term is a bit-vector multiplication (binary) *) - let is_bv_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) (** Indicates whether the term is a bit-vector signed division (binary) *) - let is_bv_sdiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) (** Indicates whether the term is a bit-vector unsigned division (binary) *) - let is_bv_udiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) (** Indicates whether the term is a bit-vector signed remainder (binary) *) - let is_bv_SRem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - let is_bv_urem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) (** Indicates whether the term is a bit-vector signed modulus *) - let is_bv_smod ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) (** Indicates whether the term is a bit-vector signed division by zero *) - let is_bv_sdiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) (** Indicates whether the term is a bit-vector unsigned division by zero *) - let is_bv_udiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) (** Indicates whether the term is a bit-vector signed remainder by zero *) - let is_bv_srem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - let is_bv_urem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) (** Indicates whether the term is a bit-vector signed modulus by zero *) - let is_bv_smod0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - let is_bv_ule ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - let is_bv_sle ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - let is_bv_uge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - let is_bv_sge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) (** Indicates whether the term is an unsigned bit-vector less-than *) - let is_bv_ult ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) (** Indicates whether the term is a signed bit-vector less-than *) - let is_bv_slt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) (** Indicates whether the term is an unsigned bit-vector greater-than *) - let is_bv_ugt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) (** Indicates whether the term is a signed bit-vector greater-than *) - let is_bv_sgt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) (** Indicates whether the term is a bit-wise AND *) - let is_bv_and ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) (** Indicates whether the term is a bit-wise OR *) - let is_bv_or ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) (** Indicates whether the term is a bit-wise NOT *) - let is_bv_not ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) (** Indicates whether the term is a bit-wise XOR *) - let is_bv_xor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) (** Indicates whether the term is a bit-wise NAND *) - let is_bv_nand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) (** Indicates whether the term is a bit-wise NOR *) - let is_bv_nor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) (** Indicates whether the term is a bit-wise XNOR *) - let is_bv_xnor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) (** Indicates whether the term is a bit-vector concatenation (binary) *) - let is_bv_concat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) (** Indicates whether the term is a bit-vector sign extension *) - let is_bv_signextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) (** Indicates whether the term is a bit-vector zero extension *) - let is_bv_zeroextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) (** Indicates whether the term is a bit-vector extraction *) - let is_bv_extract ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) (** Indicates whether the term is a bit-vector repetition *) - let is_bv_repeat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) (** Indicates whether the term is a bit-vector reduce OR *) - let is_bv_reduceor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) (** Indicates whether the term is a bit-vector reduce AND *) - let is_bv_reduceand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) (** Indicates whether the term is a bit-vector comparison *) - let is_bv_comp ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) (** Indicates whether the term is a bit-vector shift left *) - let is_bv_shiftleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) (** Indicates whether the term is a bit-vector logical shift right *) - let is_bv_shiftrightlogical ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) (** Indicates whether the term is a bit-vector arithmetic shift left *) - let is_bv_shiftrightarithmetic ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) (** Indicates whether the term is a bit-vector rotate left *) - let is_bv_rotateleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right *) - let is_bv_rotateright ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) (** Indicates whether the term is a bit-vector rotate left (extended) Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotateleftextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right (extended) Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotaterightextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_int_to_bv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_bv_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - let is_bv_carry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) (** Indicates whether the term is a bit-vector ternary XOR The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - let is_bv_xor3 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) (** The size of a bit-vector sort. *) let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) @@ -3550,7 +3415,7 @@ end = struct (** Creates a bit-vector constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = BitVecExpr(Expr.mk_const ctx name (match (mk_sort ctx size) with BitVecSort(s) -> s)) (** @@ -3564,91 +3429,91 @@ end = struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - create_expr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - create_expr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - create_expr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) (** Unsigned division. @@ -3660,7 +3525,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) (** Signed division. @@ -3675,7 +3540,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) (** Unsigned remainder. @@ -3685,7 +3550,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) (** Signed remainder. @@ -3697,7 +3562,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed remainder (sign follows divisor). @@ -3706,7 +3571,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than @@ -3714,7 +3579,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than @@ -3722,7 +3587,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) (** Unsigned less-than or equal to. @@ -3730,7 +3595,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than or equal to. @@ -3738,7 +3603,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater than or equal to. @@ -3746,7 +3611,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater than or equal to. @@ -3754,7 +3619,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater-than. @@ -3762,7 +3627,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater-than. @@ -3770,7 +3635,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) (** Bit-vector concatenation. @@ -3781,7 +3646,7 @@ end = struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector extraction. @@ -3792,7 +3657,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) + expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) (** Bit-vector sign extension. @@ -3802,7 +3667,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) (** Bit-vector zero extension. @@ -3813,7 +3678,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) (** Bit-vector repetition. @@ -3821,7 +3686,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) (** Shift left. @@ -3836,7 +3701,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) (** @@ -3851,7 +3716,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) (** Arithmetic shift right @@ -3867,7 +3732,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) (** Rotate Left. @@ -3876,7 +3741,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) (** Rotate Right. @@ -3885,7 +3750,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) (** Rotate Left. @@ -3894,7 +3759,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) (** Rotate Right. @@ -3904,7 +3769,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) (** Create an integer from the bit-vector argument . @@ -3922,7 +3787,7 @@ end = struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integers.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) + Arithmetic.Integer.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3930,7 +3795,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Booleans.create_expr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3938,7 +3803,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not overflow. @@ -3946,7 +3811,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3954,7 +3819,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Booleans.create_expr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3962,7 +3827,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3970,7 +3835,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3978,7 +3843,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Booleans.create_expr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3986,7 +3851,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a bit-vector numeral. @@ -3994,28 +3859,27 @@ end = struct @param v A string representing the value in decimal notation. @param size the size of the bit-vector *) - let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = + let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx size))) end (** Functions to manipulate proof expressions *) -and Proofs : -sig -end = struct +module Proof = +struct (** Indicates whether the term is a Proof for the expression 'true'. *) - let is_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) (** Indicates whether the term is a proof for a fact asserted by the user. *) - let is_asserted ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - let is_goal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) (** Indicates whether the term is proof via modus ponens @@ -4026,7 +3890,7 @@ end = struct [mp T1 T2]: q The second antecedents may also be a proof for (iff p q). *) - let is_modus_ponens ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. @@ -4035,7 +3899,7 @@ end = struct equivalence modulo namings, equality and equivalence. That is, R is either '~', '=' or 'iff'. *) - let is_reflexivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) (** Indicates whether the term is proof by symmetricity of a relation @@ -4045,7 +3909,7 @@ end = struct [symmetry T1]: (R s t) T1 is the antecedent of this proof object. *) - let is_symmetry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) (** Indicates whether the term is a proof by transitivity of a relation @@ -4056,7 +3920,7 @@ end = struct T2: (R s u) [trans T1 T2]: (R t u) *) - let is_transitivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) (** Indicates whether the term is a proof by condensed transitivity of a relation @@ -4076,7 +3940,7 @@ end = struct if there is a path from s to t, if we view every antecedent (R a b) as an edge between a and b. *) - let is_Transitivity_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) (** @@ -4089,7 +3953,7 @@ end = struct Remark: if t_i == s_i, then the antecedent Ti is suppressed. That is, reflexivity proofs are supressed to save space. *) - let is_monotonicity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) (** Indicates whether the term is a quant-intro proof @@ -4098,7 +3962,7 @@ end = struct T1: (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - let is_quant_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) (** Indicates whether the term is a distributivity proof object. @@ -4115,7 +3979,7 @@ end = struct Remark. This rule is used by the CNF conversion pass and instantiated by f = or, and g = and. *) - let is_distributivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) (** Indicates whether the term is a proof by elimination of AND @@ -4124,7 +3988,7 @@ end = struct T1: (and l_1 ... l_n) [and-elim T1]: l_i *) - let is_and_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) (** Indicates whether the term is a proof by eliminiation of not-or @@ -4133,7 +3997,7 @@ end = struct T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) *) - let is_or_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) (** Indicates whether the term is a proof by rewriting @@ -4147,11 +4011,11 @@ end = struct Remark: if f is bool, then = is iff. Examples: - (= (+ ( x : Expr.expr ) 0) x) - (= (+ ( x : Expr.expr ) 1 2) (+ 3 x)) - (iff (or ( x : Expr.expr ) false) x) + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) - let is_rewrite ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) (** Indicates whether the term is a proof by rewriting @@ -4166,14 +4030,14 @@ end = struct - When converting bit-vectors to Booleans (BIT2BOOL=true) - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - let is_rewrite_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) (** Indicates whether the term is a proof for pulling quantifiers out. A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - let is_pull_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) (** Indicates whether the term is a proof for pulling quantifiers out. @@ -4182,7 +4046,7 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object has no antecedents *) - let is_pull_quant_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) (** Indicates whether the term is a proof for pushing quantifiers in. @@ -4195,7 +4059,7 @@ end = struct This proof object has no antecedents *) - let is_push_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) (** Indicates whether the term is a proof for elimination of unused variables. @@ -4207,34 +4071,34 @@ end = struct This proof object has no antecedents. *) - let is_elim_unused_vars ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) (** Indicates whether the term is a proof for destructive equality resolution A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : Expr.expr ) t)) P[x])) P[t]) - if ( x : Expr.expr ) does not occur in t. + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. This proof object has no antecedents. Several variables can be eliminated simultaneously. *) - let is_der ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) (** Indicates whether the term is a proof for quantifier instantiation A proof of (or (not (forall (x) (P x))) (P a)) *) - let is_quant_inst ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) (** Indicates whether the term is a hypthesis marker. Mark a hypothesis in a natural deduction style proof. *) - let is_hypothesis ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) (** Indicates whether the term is a proof by lemma @@ -4246,7 +4110,7 @@ end = struct It converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 contains the hypotheses: l_1, ..., l_n. *) - let is_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) (** Indicates whether the term is a proof by unit resolution @@ -4257,7 +4121,7 @@ end = struct T(n+1): (not l_n) [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - let is_unit_resolution ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) (** Indicates whether the term is a proof by iff-true @@ -4265,7 +4129,7 @@ end = struct T1: p [iff-true T1]: (iff p true) *) - let is_iff_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) (** Indicates whether the term is a proof by iff-false @@ -4273,7 +4137,7 @@ end = struct T1: (not p) [iff-false T1]: (iff p false) *) - let is_iff_false ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) (** Indicates whether the term is a proof by commutativity @@ -4285,7 +4149,7 @@ end = struct This proof object has no antecedents. Remark: if f is bool, then = is iff. *) - let is_commutativity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) (** Indicates whether the term is a proof for Tseitin-like axioms @@ -4320,7 +4184,7 @@ end = struct unfolding the Boolean connectives in the axioms a small bounded number of steps (=3). *) - let is_def_axiom ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) (** Indicates whether the term is a proof for introduction of a name @@ -4342,7 +4206,7 @@ end = struct Otherwise: [def-intro]: (= n e) *) - let is_def_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) (** Indicates whether the term is a proof for application of a definition @@ -4351,7 +4215,7 @@ end = struct F is 'equivalent' to n, given that T1 is a proof that n is a name for F. *) - let is_apply_def ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) (** Indicates whether the term is a proof iff-oeq @@ -4359,7 +4223,7 @@ end = struct T1: (iff p q) [iff~ T1]: (~ p q) *) - let is_iff_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) (** Indicates whether the term is a proof for a positive NNF step @@ -4386,7 +4250,7 @@ end = struct NNF_NEG furthermore handles the case where negation is pushed over Boolean connectives 'and' and 'or'. *) - let is_nnf_pos ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) (** Indicates whether the term is a proof for a negative NNF step @@ -4410,7 +4274,7 @@ end = struct [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 r_2) (or r_1' r_2'))) *) - let is_nnf_neg ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. @@ -4421,7 +4285,7 @@ end = struct This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_nnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. @@ -4430,19 +4294,19 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_cnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) (** Indicates whether the term is a proof for a Skolemization step Proof for: - [sk]: (~ (not (forall ( x : Expr.expr ) (p ( x : Expr.expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : Expr.expr ) (p ( x : Expr.expr ) y)) (p (sk y) y)) + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) This proof object has no antecedents. *) - let is_skolemize ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. @@ -4452,7 +4316,7 @@ end = struct T2: (~ p q) [mp~ T1 T2]: q *) - let is_modus_ponens_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) (** Indicates whether the term is a proof for theory lemma @@ -4470,7 +4334,7 @@ end = struct (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - let is_theory_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) + let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end @@ -4480,10 +4344,8 @@ end of formulas, that can be solved and/or transformed using tactics and solvers. *) module Goal = -struct - type goal = z3_native_object - - (**/**) +struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : goal = { m_ctx = ctx ; m_n_obj = null ; @@ -4492,7 +4354,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** The precision of the goal. @@ -4521,8 +4383,8 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) - let assert_ ( x : goal ) ( constraints : Booleans.bool_expr array ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) in + let assert_ ( x : goal ) ( constraints : bool_expr array ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in ignore (Array.map f constraints) ; () @@ -4543,7 +4405,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = Booleans.create_expr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) @@ -4562,7 +4424,7 @@ struct create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - let simplify ( x : goal ) ( p : Params.params option ) = + let simplify ( x : goal ) ( p : params option ) = let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in Z3native.tactic_inc_ref (z3obj_gnc x) tn ; let arn = match p with @@ -4602,9 +4464,7 @@ end A Model contains interpretations (assignments) of constants and functions. *) module Model = struct - type model = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; m_n_obj = null ; @@ -4613,7 +4473,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Function interpretations @@ -4622,9 +4482,7 @@ struct *) module FuncInterp = struct - type func_interp = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_interp = { m_ctx = ctx ; m_n_obj = null ; @@ -4633,17 +4491,15 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Function interpretations entries An Entry object represents an element in the finite map used to a function interpretation. *) module FuncEntry = - struct - type func_entry = z3_native_object - - (**/**) + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; m_n_obj = null ; @@ -4652,13 +4508,13 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Return the (symbolic) value of this entry. *) let get_value ( x : func_entry ) = - Expr.create (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) + expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) (** The number of arguments of the entry. @@ -4670,7 +4526,7 @@ struct *) let get_args ( x : func_entry ) = let n = (get_num_args x) in - let f i = (Expr.create (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4698,7 +4554,7 @@ struct (** The (symbolic) `else' value of the function interpretation. *) - let get_else ( x : func_interp ) = Expr.create (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) + let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) (** The arity of the function interpretation @@ -4725,7 +4581,7 @@ struct (** Retrieves the interpretation (the assignment) of in the model. A function declaration of zero arity An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : FuncDecl.func_decl ) = + let get_const_interp ( x : model ) ( f : func_decl ) = if (FuncDecl.get_arity f) != 0 || (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") @@ -4734,19 +4590,19 @@ struct if (Z3native.is_null np) then None else - Some (Expr.create (z3obj_gc x) np) + Some (expr_of_ptr (z3obj_gc x) np) (** Retrieves the interpretation (the assignment) of in the model. A Constant An expression if the constant has an interpretation in the model, null otherwise. *) - let get_const_interp_e ( x : model ) ( a : Expr.expr ) = get_const_interp x (Expr.get_func_decl a) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) (** Retrieves the interpretation (the assignment) of a non-constant in the model. A function declaration of non-zero arity A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : FuncDecl.func_decl ) = + let rec get_func_interp ( x : model ) ( f : func_decl ) = let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in if (FuncDecl.get_arity f) == 0 then let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in @@ -4759,7 +4615,7 @@ struct raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x (FuncDecl.create (z3obj_gc x) fd) + get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in @@ -4771,7 +4627,7 @@ struct (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in - let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f @@ -4781,15 +4637,15 @@ struct (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in - let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in - let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) @@ -4810,15 +4666,15 @@ struct The evaluation of in the model. *) - let eval ( x : model ) ( t : Expr.expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (ptr_of_expr t) completion) in if not r then raise (ModelEvaluationFailedException "evaluation failed") else - Expr.create (z3obj_gc x) v + expr_of_ptr (z3obj_gc x) v (** Alias for eval. *) - let evaluate ( x : model ) ( t : Expr.expr ) ( completion : bool ) = + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = eval x t completion (** The number of uninterpreted sorts that the model has an interpretation for. *) @@ -4834,7 +4690,7 @@ struct *) let get_sorts ( x : model ) = let n = (get_num_sorts x) in - let f i = (Sort.create (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f @@ -4843,10 +4699,10 @@ struct An uninterpreted sort An array of expressions, where each is an element of the universe of *) - let sort_universe ( x : model ) ( s : Sort.sort ) = - let n_univ = AST.ASTVectors.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in - let n = (AST.ASTVectors.get_size n_univ) in - let f i = (AST.ASTVectors.get n_univ i) in + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in Array.init n f (** Conversion of models to strings. @@ -4866,9 +4722,7 @@ end *) module Probe = struct - type probe = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : probe = { m_ctx = ctx ; m_n_obj = null ; @@ -4877,14 +4731,14 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Execute the probe over the goal. A probe always produce a double value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let apply ( x : probe ) (g : Goal.goal) = + let apply ( x : probe ) (g : goal) = Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (** @@ -4988,10 +4842,8 @@ end It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. *) module Tactic = -struct - type tactic = z3_native_object - - (**/**) +struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : tactic = { m_ctx = ctx ; m_n_obj = null ; @@ -5000,7 +4852,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Tactic application results @@ -5008,9 +4860,7 @@ struct tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult = struct - type apply_result = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : apply_result = { m_ctx = ctx ; m_n_obj = null ; @@ -5019,7 +4869,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** The number of Subgoals. *) let get_num_subgoals ( x : apply_result ) = @@ -5039,7 +4889,7 @@ struct goal g, that the ApplyResult was obtained from. #return A model for g *) - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) (** A string representation of the ApplyResult. *) @@ -5054,7 +4904,7 @@ struct Params.ParamDescrs.create (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) - let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = + let apply ( x : tactic ) ( g : goal ) ( p : params option ) = match p with | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) @@ -5122,14 +4972,14 @@ struct If evaluates to false, then the new tactic behaves like the skip tactic. *) (* CMW: when is a keyword *) - let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = + let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) - let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = + let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** @@ -5154,7 +5004,7 @@ struct (** Create a tactic that fails if the probe evaluates to false. *) - let fail_if ( ctx : context ) ( p : Probe.probe ) = + let fail_if ( ctx : context ) ( p : probe ) = create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** @@ -5167,14 +5017,14 @@ struct (** Create a tactic that applies using the given set of parameters . *) - let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . Alias for UsingParams*) (* CMW: with is a keyword *) - let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = using_params ctx t p (** @@ -5201,10 +5051,8 @@ end (** Solvers *) module Solver = -struct - type solver = z3_native_object - - (**/**) +struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; @@ -5213,9 +5061,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) - - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + let string_of_status ( s : status) = match s with | UNSATISFIABLE -> "unsatisfiable" @@ -5224,10 +5070,8 @@ struct (** Objects that track statistical information about solvers. *) module Statistics = - struct - type statistics = z3_native_object - - (**/**) + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; @@ -5236,7 +5080,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Statistical data is organized into pairs of \[Key, Entry\], where every @@ -5245,14 +5089,7 @@ struct *) module Entry = struct - type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } - - (**/**) + let create_si k v = let res : statistics_entry = { m_key = k ; @@ -5272,7 +5109,7 @@ struct m_float = v } in res - (**/**) + (** The key of the entry. *) let get_key (x : statistics_entry) = x.m_key @@ -5344,7 +5181,7 @@ struct (** Sets the solver parameters. *) - let set_parameters ( x : solver ) ( p : Params.params )= + let set_parameters ( x : solver ) ( p : params )= Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** @@ -5382,8 +5219,8 @@ struct (** Assert a constraint (or multiple) into the solver. *) - let assert_ ( x : solver ) ( constraints : Booleans.bool_expr array ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in + let assert_ ( x : solver ) ( constraints : bool_expr array ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) (** @@ -5399,11 +5236,11 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( cs : Booleans.bool_expr array ) ( ps : Booleans.bool_expr array ) = + let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) (Booleans.gno (Array.get ps i))) in + let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) (Boolean.gno (Array.get ps i))) in ignore (Array.iteri f cs) (** @@ -5418,24 +5255,24 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( c : Booleans.bool_expr ) ( p : Booleans.bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno c) (Booleans.gno p) + let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) (** The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVectors.get_size a) + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + (AST.ASTVector.get_size a) (** The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVectors.get_size a) in - let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get a i)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size a) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in Array.init n f (** @@ -5445,12 +5282,13 @@ struct *) - let check ( x : solver ) ( assumptions : Booleans.bool_expr array) = + let check ( x : solver ) ( assumptions : bool_expr array) = let r = if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Booleans.aton assumptions)) + let f x = (ptr_of_expr (expr_of_bool_expr x)) in + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Array.map f assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -5481,7 +5319,7 @@ struct if (Z3native.is_null q) then None else - Some (Expr.create (z3obj_gc x) q) + Some (expr_of_ptr (z3obj_gc x) q) (** The unsat core of the last Check. @@ -5491,9 +5329,9 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVectors.get_size cn) in - let f i = (AST.ASTVectors.get cn i) in + let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size cn) in + let f i = (AST.ASTVector.get cn i) in Array.init n f (** @@ -5515,7 +5353,7 @@ struct check-sat command, and check-sat commands that take more than a given number of milliseconds to be solved. *) - let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = + let mk_solver ( ctx : context ) ( logic : symbol option ) = match logic with | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) @@ -5539,7 +5377,7 @@ struct The solver supports the commands Push and Pop, but it will always solve each check from scratch. *) - let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = + let mk_solver_t ( ctx : context ) ( t : tactic ) = (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** @@ -5551,10 +5389,7 @@ end (** Fixedpoint solving *) module Fixedpoint = -struct - type fixedpoint = z3_native_object - - (**/**) +struct let create ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; @@ -5563,7 +5398,7 @@ struct (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; (z3obj_create res) ; res - (**/**) + (** A string that describes all available fixedpoint solver parameters. @@ -5574,7 +5409,7 @@ struct (** Sets the fixedpoint solver parameters. *) - let set_params ( x : fixedpoint ) ( p : Params.params )= + let set_params ( x : fixedpoint ) ( p : params )= Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** @@ -5586,29 +5421,29 @@ struct (** Assert a constraints into the fixedpoint solver. *) - let assert_ ( x : fixedpoint ) ( constraints : Booleans.bool_expr array ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in + let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) ; () (** Register predicate as recursive relation. *) - let register_relation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) = + let register_relation ( x : fixedpoint ) ( f : func_decl ) = Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno y) + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) (** Add table fact to the fixedpoint solver. *) - let add_fact ( x : fixedpoint ) ( pred : FuncDecl.func_decl ) ( args : int array ) = + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args (** @@ -5617,11 +5452,11 @@ struct The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - let query ( x : fixedpoint ) ( query : Booleans.bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Booleans.gno query))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN + let query ( x : fixedpoint ) ( query : bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN (** Query the fixedpoint solver. @@ -5629,11 +5464,12 @@ struct The query is satisfiable if there is an instance of some relation that is non-empty. The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - let query_r ( x : fixedpoint ) ( relations : FuncDecl.func_decl array ) = - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (FuncDecl.aton relations))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN + let query_r ( x : fixedpoint ) ( relations : func_decl array ) = + let f x = ptr_of_ast (ast_of_func_decl x) in + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN (** Creates a backtracking point. @@ -5654,8 +5490,8 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno name) + let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) (** Retrieve satisfying instance or instances of solver, @@ -5666,7 +5502,7 @@ struct if (Z3native.is_null q) then None else - Some (Expr.create (z3obj_gc x) q) + Some (expr_of_ptr (z3obj_gc x) q) (** Retrieve explanation why fixedpoint engine returned status Unknown. @@ -5677,25 +5513,25 @@ struct (** Retrieve the number of levels explored for a given predicate. *) - let get_num_levels ( x : fixedpoint ) ( predicate : FuncDecl.func_decl ) = + let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) (** Retrieve the cover of a predicate. *) - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) = + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in if (Z3native.is_null q) then None else - Some (Expr.create (z3obj_gc x) q) + Some (expr_of_ptr (z3obj_gc x) q) (** Add property about the predicate. The property is added at level. *) - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) ( property : Expr.expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (ptr_of_expr property) (** Retrieve internal string representation of fixedpoint object. @@ -5705,31 +5541,33 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) ( kinds : Symbol.symbol array ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Symbol.aton kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = + let f2 x = (Symbol.gno x) in + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) - let to_string_q ( x : fixedpoint ) ( queries : Booleans.bool_expr array ) = - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Booleans.aton queries) + let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = + let f x = ptr_of_expr (expr_of_bool_expr x) in + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVectors.get_size v) in - let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVectors.get_size v) in - let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** @@ -5813,10 +5651,10 @@ struct @param formula Formula to be checked for consistency in conjunction with assumptions. @return A string representation of the benchmark. *) - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Booleans.bool_expr array ) ( formula : Booleans.bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (Booleans.aton assumptions) - (Booleans.gno formula) + (Array.length assumptions) (let f x = ptr_of_expr (expr_of_bool_expr x) in (Array.map f assumptions)) + (Boolean.gno formula) (** Parse the given string using the SMT-LIB parser. @@ -5827,7 +5665,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5837,17 +5675,17 @@ struct else Z3native.parse_smtlib_string (context_gno ctx) str cs - (Symbol.aton sort_names) - (Sort.aton sorts) + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5857,11 +5695,11 @@ struct else Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (Symbol.aton sort_names) - (Sort.aton sorts) + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)) (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. @@ -5873,7 +5711,7 @@ struct *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = Booleans.create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i) in + let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in Array.init n f @@ -5887,7 +5725,7 @@ struct *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = Booleans.create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i) in + let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in Array.init n f (** @@ -5900,7 +5738,7 @@ struct *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = FuncDecl.create ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in + let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** @@ -5913,7 +5751,7 @@ struct *) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in - let f i = (Sort.create ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in + let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f (** @@ -5922,7 +5760,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5930,19 +5768,19 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.aton sort_names) - (Sort.aton sorts) - cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) + cd + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5950,13 +5788,13 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string (context_gno ctx) file_name + bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (Symbol.aton sort_names) - (Sort.aton sorts) + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) end From a27945f297c20a5af0794d3c8bbff1b1612c7268 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 20:04:11 +0000 Subject: [PATCH 277/507] ML API: got rid of "extra" objects on types. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 73 +++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 50 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index ea8c9576e..aa919e7fc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -93,13 +93,7 @@ type quantifier = Quantifier of expr type pattern = Pattern of ast (* Datatype stuff *) -type constructor_extra = { - m_n : int; - mutable m_tester_decl : func_decl option; - mutable m_constructor_decl : func_decl option ; - mutable m_accessor_decls : func_decl array option} - -type constructor = Constructor of (z3_native_object * constructor_extra) +type constructor = z3_native_object type constructor_list = z3_native_object (* Tactical interface *) @@ -2358,7 +2352,8 @@ struct (** Constructors *) module Constructor = struct - + let _counts = Hashtbl.create 0 + let create ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then @@ -2373,53 +2368,31 @@ struct (let f x = (Symbol.gno x) in (Array.map f field_names)) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) sort_refs) in - let no : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - let ex : constructor_extra = { m_n = n; - m_tester_decl = None; - m_constructor_decl = None; - m_accessor_decls = None} in + let no : constructor = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + Hashtbl.add _counts no n ; (z3obj_sno no ctx ptr) ; (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; - Constructor(no, ex) + no - let init_extra ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_tester_decl with - | None -> - let (a, b, c) = (Z3native.query_constructor (z3obj_gnc no) (z3obj_gno no) ex.m_n) in - ex.m_constructor_decl <- Some (func_decl_of_ptr (z3obj_gc no) a) ; - ex.m_tester_decl <- Some (func_decl_of_ptr (z3obj_gc no) b) ; - ex.m_accessor_decls <- Some (let f e = (func_decl_of_ptr (z3obj_gc no) e) in Array.map f c) ; - () - | _ -> () - - - let get_n ( x : constructor ) = - match x with Constructor(no, ex) -> - ex.m_n + let get_n ( x : constructor ) = (Hashtbl.find _counts x) - let rec tester_decl ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_tester_decl with - | Some(s) -> s - | None -> init_extra x ; tester_decl x - let rec constructor_decl ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_constructor_decl with - | Some(s) -> s - | None -> init_extra x ; constructor_decl x + let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + func_decl_of_ptr (z3obj_gc x) a + + let rec tester_decl ( x : constructor ) = + let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + func_decl_of_ptr (z3obj_gc x) b let rec accessor_decls ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_accessor_decls with - | Some(s) -> s - | None -> init_extra x ; accessor_decls x + let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + let f y = func_decl_of_ptr (z3obj_gc x) y in + Array.map f c (** The number of fields of the constructor. *) let get_num_fields ( x : constructor ) = get_n x @@ -2443,7 +2416,7 @@ struct m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in - let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + let f x =(z3obj_gno x) in (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Array.map f c))) ; (z3obj_create res) ; let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in @@ -2462,7 +2435,7 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = Constructor.create ctx name recognizer field_names sorts sort_refs @@ -2483,8 +2456,8 @@ struct (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = - let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array ) = + let f x = (z3obj_gno x) in let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in create_sort ctx x From 5f41a40a63eb31a823628b7b77f73b17b1e9bcbf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 22:49:19 +0000 Subject: [PATCH 278/507] ML API: build system fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index a187bf9cb..e32ca14f9 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1332,40 +1332,49 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): + CP_CMD = "cp" + if IS_WINDOWS: + CP_CMD = "copy" src_dir = self.to_src_dir sub_dir = os.path.join('api', 'ml') mk_dir(os.path.join(BUILD_DIR, sub_dir)) api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): - shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) + out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): - shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) - cmis = '%s/z3enums.cmi %s/z3native.cmi %s/z3.cmi' % (src_dir,src_dir,src_dir) - out.write('%s/z3enums.cmi: %s/z3enums.mli\n' % (src_dir,src_dir)) - out.write('\t%s -I %s -c %s/z3enums.mli\n' % (OCAMLC,src_dir,src_dir)) - out.write('%s/z3native.cmi: %s/z3native.mli\n' % (src_dir,src_dir)) - out.write('\t%s -I %s -c %s/z3native.mli\n' % (OCAMLC,src_dir,src_dir)) - out.write('%s/z3.cmi: %s/z3.mli\n' % (src_dir,src_dir)) - out.write('\t%s -I %s -c %s/z3.mli\n' % (OCAMLC,src_dir,src_dir)) - out.write('api/ml/libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, src_dir)) + out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) + out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) + modules = ["z3enums", "z3native", "z3"] # dependencies in this order! + prev = '' + for m in modules: + out.write('%s/%s.mli: %s/%s.ml %s\n' % (sub_dir,m,sub_dir,m,prev)) + out.write('\t%s -I %s -i -c %s/%s.ml > %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m,sub_dir,m)) + prev = prev + ' ' + sub_dir + '/' + m + '.mli' + cmis = '' + for m in modules: + out.write('%s/%s.cmi: %s/%s.mli\n' % (sub_dir,m,sub_dir,m)) + out.write('\t%s -I %s -c %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m)) + cmis = cmis + ' ' + sub_dir + '/' + m + '.cmi' + out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(src_dir, mlfile)) + out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) + out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) + out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) + out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') From fd2ae5f60e28c8523be6dac66b41a7e1d9e67421 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 23:42:50 +0000 Subject: [PATCH 279/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 54 +++++++++++++++++++++-------------- src/api/ml/z3.ml | 60 ++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 3b13a2462..49db6fb50 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -7,6 +7,7 @@ open Z3 open Z3.Symbol open Z3.Sort open Z3.Expr +open Z3.Boolean open Z3.FuncDecl open Z3.Goal open Z3.Tactic @@ -22,12 +23,20 @@ exception TestFailedException of string *) let model_converter_test ( ctx : context ) = Printf.printf "ModelConverterTest\n"; - let xr = ((mk_const ctx (Symbol.mk_string ctx "x") (mk_real_sort ctx )) :> arith_expr) in - let yr = ((mk_const ctx (Symbol.mk_string ctx "y") (mk_real_sort ctx )) :> arith_expr) in + let xr = (arith_expr_of_expr + (Expr.mk_const ctx (Symbol.mk_string ctx "x") + (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in + let yr = (arith_expr_of_expr + (Expr.mk_const ctx (Symbol.mk_string ctx "y") + (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [| (mk_gt ctx xr (mk_real_numeral_nd ctx 10 1)) |]) ; - (Goal.assert_ g4 [| (mk_eq ctx yr (mk_add ctx [| xr; (mk_real_numeral_nd ctx 1 1) |] )) |] ) ; - (Goal.assert_ g4 [| (mk_gt ctx yr (mk_real_numeral_nd ctx 1 1)) |]) ; + (Goal.assert_ g4 [| (mk_gt ctx xr + (arith_expr_of_real_expr (real_expr_of_rat_num + (Real.mk_numeral_nd ctx 10 1)))) |]) ; + (Goal.assert_ g4 [| (mk_eq ctx + (expr_of_arith_expr yr) + (expr_of_arith_expr (mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |] ))) |] ) ; + (Goal.assert_ g4 [| (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) |]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -67,15 +76,15 @@ let model_converter_test ( ctx : context ) = *) let basic_tests ( ctx : context ) = Printf.printf "BasicTests\n" ; - let qi = (mk_int ctx 1) in +(* let qi = (mk_int ctx 1) in *) let fname = (mk_string ctx "f") in let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in - let bs = (Sort.mk_bool ctx) in + let bs = (sort_of_bool_sort (Boolean.mk_sort ctx)) in let domain = [| bs; bs |] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in let fapp = (mk_app ctx f - [| (mk_const ctx x bs); (mk_const ctx y bs) |]) in + [| (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) |]) in let fargs2 = [| (mk_fresh_const ctx "cp" bs) |] in let domain2 = [| bs |] in let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in @@ -110,8 +119,11 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ); - (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) - (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) + (Goal.assert_ g [| (mk_eq ctx + (mk_numeral_int ctx 1 + (sort_of_bitvec_sort (BitVector.mk_sort ctx 32))) + (mk_numeral_int ctx 2 + (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) |] ) ; ( let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in @@ -132,7 +144,7 @@ let basic_tests ( ctx : context ) = ); ( let g2 = (mk_goal ctx true true false) in - (Goal.assert_ g2 [| (mk_false ctx) |]) ; + (Goal.assert_ g2 [| (Boolean.mk_false ctx) |]) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then @@ -142,10 +154,10 @@ let basic_tests ( ctx : context ) = ); ( let g3 = (mk_goal ctx true true false) in - let xc = (mk_const ctx (Symbol.mk_string ctx "x") (mk_int_sort ctx)) in - let yc = (mk_const ctx (Symbol.mk_string ctx "y") (mk_int_sort ctx)) in - (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (mk_int_sort ctx))) |]) ; - (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (mk_int_sort ctx))) |]) ; + let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in + let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in + (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; + (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; let constr = (mk_eq ctx xc yc) in (Goal.assert_ g3 [| constr |] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in @@ -208,14 +220,14 @@ let _ = let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in let ss = (Symbol.mk_string ctx "mySymbol") in - let bs = (Sort.mk_bool ctx) in - let ints = (mk_int_sort ctx) in - let rs = (mk_real_sort ctx) in + let bs = (Boolean.mk_sort ctx) in + let ints = (Integer.mk_sort ctx) in + let rs = (Real.mk_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string is); Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string bs); - Printf.printf "int sort: %s\n" (Sort.to_string ints); - Printf.printf "real sort: %s\n" (Sort.to_string rs); + Printf.printf "bool sort: %s\n" (Sort.to_string (sort_of_bool_sort bs)); + Printf.printf "int sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_int_sort ints))); + Printf.printf "real sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_real_sort rs))); basic_tests ctx ; Printf.printf "Disposing...\n"; Gc.full_major () diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index aa919e7fc..651102bc8 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -240,7 +240,7 @@ struct Expr(z3_native_object_of_ast_ptr ctx no) else let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in if (Z3native.is_algebraic_number (context_gno ctx) no) then Expr(z3_native_object_of_ast_ptr ctx no) else @@ -376,92 +376,99 @@ let expr_of_ast a = Expr(a) let bool_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.BOOL_SORT) then raise (Z3native.Exception "Invalid coercion") else BoolExpr(e) let arith_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then raise (Z3native.Exception "Invalid coercion") else ArithExpr(e) let bitvec_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.BV_SORT) then raise (Z3native.Exception "Invalid coercion") else BitVecExpr(e) let array_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.ARRAY_SORT) then raise (Z3native.Exception "Invalid coercion") else ArrayExpr(e) let datatype_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.DATATYPE_SORT) then raise (Z3native.Exception "Invalid coercion") else DatatypeExpr(e) let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(no)) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.INT_SORT) then raise (Z3native.Exception "Invalid coercion") else IntExpr(e) let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(no)) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.REAL_SORT) then raise (Z3native.Exception "Invalid coercion") else RealExpr(e) let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(no))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + match e with IntExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else IntNum(e) let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(no))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + match e with RealExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else RatNum(e) let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(no)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc no) (z3obj_gno no))) then + match e with ArithExpr(Expr(a)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else AlgebraicNum(e) let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(no)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + match e with BitVecExpr(Expr(a)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else BitVecNum(e) let quantifier_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in if (q != Z3enums.QUANTIFIER_AST) then raise (Z3native.Exception "Invalid coercion") else @@ -4378,7 +4385,8 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) From 09aa02759f3501492f0f710ae50848687f4eb22a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 11:49:00 +0000 Subject: [PATCH 280/507] ML API: Build system and error handling fixes. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 8 ++++++-- scripts/update_api.py | 12 ++++++++++++ src/api/ml/z3.ml | 6 +----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index e32ca14f9..a30e074b0 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1341,10 +1341,14 @@ class MLComponent(Component): api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) + str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) + if IS_WINDOWS: str = str.replace('/','\\') + out.write(str) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) + str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) + if IS_WINDOWS: str = str.replace('/','\\') + out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: diff --git a/scripts/update_api.py b/scripts/update_api.py index 6e9c14355..e5c66dd39 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1169,9 +1169,11 @@ def mk_ml(): ml_i.write('\n') ml_native.write('external is_null : ptr -> bool\n = "n_is_null"\n\n') ml_native.write('external mk_null : unit -> ptr\n = "n_mk_null"\n\n') + ml_native.write('external set_internal_error_handler : ptr -> unit\n = "n_set_internal_error_handler"\n\n') ml_native.write('exception Exception of string\n\n') ml_i.write('val is_null : ptr -> bool\n') ml_i.write('val mk_null : unit -> ptr\n') + ml_i.write('val set_internal_error_handler : ptr -> unit\n\n') ml_i.write('exception Exception of string\n\n') # ML declarations @@ -1329,6 +1331,16 @@ def mk_ml(): ml_wrapper.write(' memcpy( Data_custom_val(result), &z3_result, sizeof(void*));\n') ml_wrapper.write(' CAMLreturn (result);\n') ml_wrapper.write('}\n\n') + ml_wrapper.write('void MLErrorHandler(Z3_context c, Z3_error_code e)\n') + ml_wrapper.write('{\n') + ml_wrapper.write(' // Internal do-nothing error handler. This is required to avoid that Z3 calls exit()\n') + ml_wrapper.write(' // upon errors, but the actual error handling is done by throwing exceptions in the\n') + ml_wrapper.write(' // wrappers below.\n') + ml_wrapper.write('}\n\n') + ml_wrapper.write('void n_set_internal_error_handler(Z3_context c)\n') + ml_wrapper.write('{\n') + ml_wrapper.write(' Z3_set_error_handler(c, MLErrorHandler);\n') + ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 651102bc8..45faae468 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -135,16 +135,12 @@ struct let v = Z3native.mk_context_rc cfg in Z3native.del_config(cfg) ; Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + Z3native.set_internal_error_handler v ; (* Printf.printf "Installing finalizer on context \n" ; *) let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in let f = fun o -> dispose_context o in Gc.finalise f res; res - (* CMW: Install error handler here! - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); - *) let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) From 2af1f81ae17a42801384c5e543edcdbc16b4dcfd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 18:37:52 +0000 Subject: [PATCH 281/507] ML API: Cleanup Signed-off-by: Christoph M. Wintersteiger --- examples/ml/Makefile | 4 +- examples/ml/ml_example.ml | 5 +- scripts/update_api.py | 2 + src/api/ml/z3.ml | 2247 +++++++++++++++++++------------------ 4 files changed, 1159 insertions(+), 1099 deletions(-) diff --git a/examples/ml/Makefile b/examples/ml/Makefile index 4b3e7c4d2..a7f8e6ee0 100644 --- a/examples/ml/Makefile +++ b/examples/ml/Makefile @@ -3,5 +3,5 @@ # in the top-level build directory. all: - OCAML_COMPAT=c ocamlc -g -annot -o ml_example.byte -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cma ml_example.ml - ocamlopt -g -annot -o ml_example -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cmxa ml_example.ml + OCAML_COMPAT=c C:/ocamlw32/bin/ocamlc -g -annot -o ml_example.byte -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cma ml_example.ml + C:/ocamlw32/bin/ocamlopt -g -annot -o ml_example -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cmxa ml_example.ml diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 49db6fb50..6dfe11623 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -15,6 +15,9 @@ open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic +open Z3.Arithmetic.Integer +open Z3.Arithmetic.Real +open Z3.BitVector exception TestFailedException of string @@ -35,7 +38,7 @@ let model_converter_test ( ctx : context ) = (Real.mk_numeral_nd ctx 10 1)))) |]) ; (Goal.assert_ g4 [| (mk_eq ctx (expr_of_arith_expr yr) - (expr_of_arith_expr (mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |] ))) |] ) ; + (expr_of_arith_expr (Arithmetic.mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |]) ) ) |] ) ; (Goal.assert_ g4 [| (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) |]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in diff --git a/scripts/update_api.py b/scripts/update_api.py index e5c66dd39..a0b7e6250 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1155,6 +1155,7 @@ def mk_ml(): ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_i.write('(* Automatically generated file *)\n\n') ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') + ml_i.write('(**/**)\n\n'); ml_native.write('open Z3enums\n\n') ml_native.write('(**/**)\n') ml_native.write('type ptr\n') @@ -1214,6 +1215,7 @@ def mk_ml(): ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) ml_native.write('\n') ml_native.write(' end\n\n') + ml_i.write('\n(**/**)\n'); # Exception wrappers for name, result, params in _dotnet_decls: diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 45faae468..c261fce05 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -16,104 +16,11 @@ let is_null o = (Z3native.is_null o) type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } type context = z3_native_context - - type z3_native_object = { m_ctx : context ; mutable m_n_obj : Z3native.ptr ; inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - - -(* Symbol types *) -type int_symbol = z3_native_object -type string_symbol = z3_native_object - -type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - -(* AST types *) -type ast = z3_native_object -type ast_vector = z3_native_object -type ast_map = z3_native_object - -(* FuncDecl types *) -type func_decl = FuncDecl of ast - -(* Sort types *) -type sort = Sort of ast -type uninterpreted_sort = UninterpretedSort of sort -type bool_sort = BoolSort of sort -type array_sort = ArraySort of sort -type set_sort = SetSort of sort -type datatype_sort = DatatypeSort of sort -type relation_sort = RelationSort of sort -type finite_domain_sort = FiniteDomainSort of sort -type enum_sort = EnumSort of sort -type list_sort = ListSort of sort -type tuple_sort = TupleSort of sort -type arith_sort = ArithSort of sort -type bitvec_sort = BitVecSort of sort - -type int_sort = IntSort of arith_sort -type real_sort = RealSort of arith_sort - -(* FuncDecl parameters *) -type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of symbol - | P_Srt of sort - | P_Ast of ast - | P_Fdl of func_decl - | P_Rat of string -type params = z3_native_object -type param_descrs = z3_native_object - -(* Expr types *) -type expr = Expr of ast - -type bool_expr = BoolExpr of expr -type arith_expr = ArithExpr of expr -type int_expr = IntExpr of arith_expr -type real_expr = RealExpr of arith_expr -type bitvec_expr = BitVecExpr of expr -type array_expr = ArrayExpr of expr -type datatype_expr = DatatypeExpr of expr - -(* Numerals *) -type int_num = IntNum of int_expr -type rat_num = RatNum of real_expr -type algebraic_num = AlgebraicNum of arith_expr -type bitvec_num = BitVecNum of bitvec_expr - -(* Quantifier stuff *) -type quantifier = Quantifier of expr -type pattern = Pattern of ast - -(* Datatype stuff *) -type constructor = z3_native_object -type constructor_list = z3_native_object - -(* Tactical interface *) -type goal = z3_native_object -type model = z3_native_object -type func_interp = z3_native_object -type func_entry = z3_native_object -type probe = z3_native_object -type tactic = z3_native_object -type apply_result = z3_native_object -type solver = z3_native_object -type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE -type statistics = z3_native_object -type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } -type fixedpoint = z3_native_object (** Internal stuff *) @@ -121,11 +28,9 @@ module Internal = struct let dispose_context ctx = if ctx.m_n_obj_cnt == 0 then ( - (* Printf.printf "Disposing context \n" ; *) (Z3native.del_context ctx.m_n_ctx) ) else ( - Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; - (* re-queue for finalization? *) + Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; ) let create_context settings = @@ -136,7 +41,6 @@ struct Z3native.del_config(cfg) ; Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; Z3native.set_internal_error_handler v ; - (* Printf.printf "Installing finalizer on context \n" ; *) let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in let f = fun o -> dispose_context o in Gc.finalise f res; @@ -178,16 +82,6 @@ struct let array_to_native a = let f e = (z3obj_gno e) in Array.map f a - - (* Internal coercions *) - let context_of_ast ( x : ast ) = (z3obj_gc x) - let nc_of_ast ( x : ast ) = (z3obj_gnc x) - let ptr_of_ast ( x : ast ) = (z3obj_gno x) - - let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) - let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) - let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> let res : z3_native_object = { m_ctx = ctx ; @@ -196,323 +90,25 @@ struct dec_ref = Z3native.dec_ref } in (z3obj_sno res ctx no) ; (z3obj_create res) ; - res - - let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> - let q = (z3_native_object_of_ast_ptr ctx no) in - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then - raise (Z3native.Exception "Invalid coercion") - else - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - - let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - FuncDecl(z3_native_object_of_ast_ptr ctx no) - - let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST - | SORT_AST - | QUANTIFIER_AST - | APP_AST - | NUMERAL_AST - | VAR_AST -> z3_native_object_of_ast_ptr ctx no - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") - - and expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then - Expr(z3_native_object_of_ast_ptr ctx no) - else - let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) no) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - raise (Z3native.Exception "Unsupported numeral object") - else - Expr(z3_native_object_of_ast_ptr ctx no) - - let expr_aton ( a : expr array ) = - let f ( e : expr ) = match e with Expr(a) -> (ptr_of_ast a) in - Array.map f a - - let expr_of_func_app : context -> func_decl -> expr array -> expr = fun ctx f args -> - match f with FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (ptr_of_ast fa) (Array.length args) (expr_aton args) in - expr_of_ptr ctx o + res end - open Internal - - -(* Sort coercions *) -let ast_of_sort s = match s with Sort(x) -> x -let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x -let sort_of_bool_sort s = match s with BoolSort(x) -> x -let sort_of_array_sort s = match s with ArraySort(x) -> x -let sort_of_set_sort s = match s with SetSort(x) -> x -let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x -let sort_of_relation_sort s = match s with RelationSort(x) -> x -let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x -let sort_of_enum_sort s = match s with EnumSort(x) -> x -let sort_of_list_sort s = match s with ListSort(x) -> x -let sort_of_tuple_sort s = match s with TupleSort(x) -> x -let sort_of_arith_sort s = match s with ArithSort(x) -> x -let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x -let arith_sort_of_int_sort s = match s with IntSort(x) -> x -let arith_sort_of_real_sort s = match s with RealSort(x) -> x - -let uninterpreted_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - UninterpretedSort(s) - -let bool_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolSort(s) - -let array_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArraySort(s) - -let datatype_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeSort(s) - -let relation_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RelationSort(s) - -let finite_domain_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - FiniteDomainSort(s) - -let arith_sort_of_sort s = match s with Sort(a) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithSort(s) - -let bitvec_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecSort(s) - -let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntSort(s) - -let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealSort(s) - -(* FuncDecl coercions *) -let ast_of_func_decl f = match f with FuncDecl(x) -> x - -(* Expr coercions *) -let ast_of_expr e = match e with Expr(a) -> a -let expr_of_bool_expr e = match e with BoolExpr(x) -> x -let expr_of_arith_expr e = match e with ArithExpr(x) -> x -let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x -let expr_of_array_expr e = match e with ArrayExpr(x) -> x -let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x - -let arith_expr_of_int_expr e = match e with IntExpr(x) -> x -let arith_expr_of_real_expr e = match e with RealExpr(x) -> x - -let int_expr_of_int_num e = match e with IntNum(x) -> x -let real_expr_of_rat_num e = match e with RatNum(x) -> x -let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x -let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x - -let expr_of_quantifier e = match e with Quantifier(x) -> x -let ast_of_pattern e = match e with Pattern(x) -> x - - -let expr_of_ast a = - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Expr(a) - -let bool_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolExpr(e) - -let arith_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithExpr(e) - -let bitvec_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecExpr(e) - -let array_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArrayExpr(e) - -let datatype_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeExpr(e) - -let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntExpr(e) - -let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealExpr(e) - -let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - IntNum(e) - -let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - RatNum(e) - -let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - AlgebraicNum(e) - -let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(a)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecNum(e) - -let quantifier_of_expr e = - match e with Expr(a) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.QUANTIFIER_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Quantifier(e) - -let pattern_of_ast a = - (* CMW: Unchecked ok? *) - Pattern(a) - - - -(** Interaction logging for Z3 - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) module Log = struct - (** Open an interaction log file. - @param filename the name of the file to open. - @return True if opening the log file succeeds, false otherwise. - *) - (* CMW: "open" seems to be a reserved keyword? *) let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - - (** Closes the interaction log. *) let close = Z3native.close_log - - (** Appends a user-provided string to the interaction log. - @param s the string to append*) let append s = Z3native.append_log s end -(** Version information *) module Version = struct - (** The major version. *) let major = let (x, _, _, _) = Z3native.get_version in x - - (** The minor version. *) let minor = let (_, x, _, _) = Z3native.get_version in x - - (** The build version. *) let build = let (_, _, x, _) = Z3native.get_version in x - - (** The revision. *) let revision = let (_, _, _, x) = Z3native.get_version in x - - (** A string representation of the version information. *) let to_string = let (mj, mn, bld, rev) = Z3native.get_version in string_of_int mj ^ "." ^ @@ -532,35 +128,21 @@ let mk_list ( f : int -> 'a ) ( n : int ) = mk_list' f 0 n [] -(** Create a context object. - - Most interactions with Z3 are interpreted in some context; many users will only - require one such object, but power users may require more than one. To start using - Z3, do - - - let ctx = (mk_context []) in - (...) - - - where a list of pairs of strings may be passed to set options on - the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (mk_context cfg) in - (...) - -*) let mk_context ( cfg : ( string * string ) list ) = create_context cfg - - -(** Symbols are used to name several term and type constructors *) module Symbol = -struct +struct + (* Symbol types *) + type int_symbol = z3_native_object + type string_symbol = z3_native_object + + type symbol = + | S_Int of int_symbol + | S_Str of string_symbol + + let create_i ( ctx : context ) ( no : Z3native.ptr ) = let res : int_symbol = { m_ctx = ctx ; m_n_obj = null ; @@ -588,7 +170,7 @@ struct match x with | S_Int(n) -> (z3obj_gc n) | S_Str(n) -> (z3obj_gc n) - + let gnc ( x : symbol ) = match x with | S_Int(n) -> (z3obj_gnc n) @@ -599,59 +181,55 @@ struct | S_Int(n) -> (z3obj_gno n) | S_Str(n) -> (z3obj_gno n) - (** The kind of the symbol (int or string) *) - let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) - - (** Indicates whether the symbol is of Int kind *) + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL - - (** Indicates whether the symbol is of string kind. *) let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - - (** The int value of the symbol. *) let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - - (** The string value of the symbol. *) let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) - - (** A string representation of the symbol. *) let to_string ( o : symbol ) = match (kind o) with | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) - (** - Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) let mk_int ( ctx : context ) ( i : int ) = S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) - (** Creates a new symbol using a string. *) let mk_string ( ctx : context ) ( s : string ) = S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - (** Create an array of symbols. *) let mk_ints ( ctx : context ) ( names : int array ) = let f elem = mk_int ( ctx : context ) elem in (Array.map f names) - (** Create an array of symbols. *) let mk_strings ( ctx : context ) ( names : string array ) = let f elem = mk_string ( ctx : context ) elem in (Array.map f names) end -(** The abstract syntax tree (AST) module *) module AST = -struct - (** Vectors of ASTs *) +struct + type ast = z3_native_object + + let context_of_ast ( x : ast ) = (z3obj_gc x) + let nc_of_ast ( x : ast ) = (z3obj_gnc x) + let ptr_of_ast ( x : ast ) = (z3obj_gno x) + + let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST + | SORT_AST + | QUANTIFIER_AST + | APP_AST + | NUMERAL_AST + | VAR_AST -> z3_native_object_of_ast_ptr ctx no + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") + module ASTVector = struct - let create ( ctx : context ) ( no : Z3native.ptr ) = + type ast_vector = z3_native_object + + let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_vector_inc_ref ; @@ -659,55 +237,34 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - - - (** The size of the vector *) + let get_size ( x : ast_vector ) = Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) - (** - Retrieves the i-th object in the vector. - @param i Index - @return An AST - *) let get ( x : ast_vector ) ( i : int ) = - create (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) + ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) - (** Sets the i-th object in the vector. *) let set ( x : ast_vector ) ( i : int ) ( value : ast ) = Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) - (** Resize the vector to . - @param newSize The new size of the vector. *) let resize ( x : ast_vector ) ( new_size : int ) = Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size - (** - Add the AST to the back of the vector. The size - is increased by 1. - @param a An AST - *) let push ( x : ast_vector ) ( a : ast ) = Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) - (** - Translates all ASTs in the vector to . - @param to_ctx A context - @return A new ASTVector - *) let translate ( x : ast_vector ) ( to_ctx : context ) = - create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) end - (** Map from AST to AST *) module ASTMap = struct + type ast_map = z3_native_object - let create ( ctx : context ) ( no : Z3native.ptr ) = + let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_map_inc_ref ; @@ -715,73 +272,36 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - - - (** Checks whether the map contains the key . - @param k An AST - @return True if is a key in the map, false otherwise. *) + let contains ( x : ast_map ) ( key : ast ) = Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - (** Finds the value associated with the key . - - This function signs an error when is not a key in the map. - @param k An AST - *) let find ( x : ast_map ) ( key : ast ) = - create (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) + ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - (** - Stores or replaces a new key/value pair in the map. - @param k The key AST - @param v The value AST - *) let insert ( x : ast_map ) ( key : ast ) ( value : ast) = Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) - (** - Erases the key from the map. - @param k An AST - *) let erase ( x : ast_map ) ( key : ast ) = Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - (** Removes all keys from the map. *) let reset ( x : ast_map ) = Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) - (** The size of the map *) let get_size ( x : ast_map ) = Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) - (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) - (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) end - (** - The AST's hash code. - @return A hash code - *) let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) - - (** - A unique identifier for the AST (unique among all ASTs). - *) let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) - - (** - The kind of the AST. - *) let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) - (** - Indicates whether the AST is an Expr - *) let is_expr ( x : ast ) = match get_ast_kind ( x : ast ) with | APP_AST @@ -790,117 +310,77 @@ struct | VAR_AST -> true | _ -> false - (** - Indicates whether the AST is a bound variable - *) let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST - - (** - Indicates whether the AST is a Quantifier - *) let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST - - - (** - Indicates whether the AST is a Sort - *) let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST - - (** - Indicates whether the AST is a FunctionDeclaration - *) let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST - (** - A string representation of the AST. - *) let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - - (** - A string representation of the AST in s-expression notation. - *) let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - (** - Comparison operator. - @param a An AST - @param b An AST - @return True if and are from the same context - and represent the same sort; false otherwise. - *) + let ( = ) ( a : ast ) ( b : ast ) = (a == b) || if (z3obj_gnc a) != (z3obj_gnc b) then false else Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) - (** - Object Comparison. - @param other Another ast - @return Negative if the object should be sorted before , positive if after else zero. - *) let compare a b = if (get_id a) < (get_id b) then -1 else if (get_id a) > (get_id b) then 1 else 0 - (** Operator < *) let ( < ) (a : ast) (b : ast) = (compare a b) - (** - Translates (copies) the AST to the Context . - @param ctx A context - @return A copy of the AST which is associated with - *) let translate ( x : ast ) ( to_ctx : context ) = if (z3obj_gnc x) == (context_gno to_ctx) then x else ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - (** - Wraps an AST. - - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - *) - let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - ast_of_ptr ctx ptr - - (** - Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - *) + let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr let unwrap_ast ( x : ast ) = (z3obj_gno x) end -(** The Sort module implements type information for ASTs *) +open AST + + module Sort = struct - + type sort = Sort of AST.ast + type uninterpreted_sort = UninterpretedSort of sort + + let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> + let q = (z3_native_object_of_ast_ptr ctx no) in + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then + raise (Z3native.Exception "Invalid coercion") + else + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + let ast_of_sort s = match s with Sort(x) -> x + let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x + + let uninterpreted_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + UninterpretedSort(s) + + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - - (** - Comparison operator. - @param a A sort - @param b A sort - @return True if and are from the same context - and represent the same sort; false otherwise. - *) + let ( = ) : sort -> sort -> bool = fun a b -> (a == b) || if (gnc a) != (gnc b) then @@ -908,30 +388,13 @@ struct else (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) - (** - Returns a unique identifier for the sort. - *) + let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) - - (** - The kind of the sort. - *) let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) - - (** - The name of the sort - *) let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) - - (** - A string representation of the sort. - *) let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted ( ctx : context ) ( s : symbol ) = + + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -940,24 +403,76 @@ struct (z3obj_create res) ; UninterpretedSort(Sort(res)) - (** - Create a new uninterpreted sort. - *) let mk_uninterpreted_s ( ctx : context ) ( s : string ) = mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) end +open Sort -(** Function declarations *) -module FuncDecl = -struct - (**/**) - let create_ndr ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = + +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + val func_decl_of_ptr : context -> Z3native.ptr -> func_decl + val gc : func_decl -> context + val gnc : func_decl -> Z3native.ptr + val gno : func_decl -> Z3native.ptr + module Parameter : + sig + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + val get_kind : parameter -> Z3enums.parameter_kind + val get_int : parameter -> int + val get_float : parameter -> float + val get_symbol : parameter -> Symbol.symbol + val get_sort : parameter -> Sort.sort + val get_ast : parameter -> AST.ast + val get_func_decl : parameter -> func_decl + val get_rational : parameter -> string + end + val mk_func_decl : context -> Symbol.symbol -> Sort.sort array -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + val ( = ) : func_decl -> func_decl -> bool + val to_string : func_decl -> string + val get_id : func_decl -> int + val get_arity : func_decl -> int + val get_domain_size : func_decl -> int + val get_domain : func_decl -> Sort.sort array + val get_range : func_decl -> Sort.sort + val get_decl_kind : func_decl -> Z3enums.decl_kind + val get_name : func_decl -> Symbol.symbol + val get_num_parameters : func_decl -> int + val get_parameters : func_decl -> Parameter.parameter list + val apply : func_decl -> Expr.expr array -> Expr.expr +end = struct + type func_decl = FuncDecl of AST.ast + + let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + FuncDecl(z3_native_object_of_ast_ptr ctx no) + + let ast_of_func_decl f = match f with FuncDecl(x) -> x + + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (ptr_of_ast (ast_of_sort x)) in + let f x = (AST.ptr_of_ast (ast_of_sort x)) in (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) @@ -967,20 +482,26 @@ struct m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (ptr_of_ast (ast_of_sort x)) in + let f x = (AST.ptr_of_ast (ast_of_sort x)) in (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) - let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - (**/**) + let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - (** Parameters of Func_Decls *) module Parameter = - struct - (** The kind of the parameter. *) + struct + type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + let get_kind ( x : parameter ) = (match x with | P_Int(_) -> PARAMETER_INT @@ -991,188 +512,137 @@ struct | P_Fdl(_) -> PARAMETER_FUNC_DECL | P_Rat(_) -> PARAMETER_RATIONAL) - (**The int value of the parameter.*) let get_int ( x : parameter ) = match x with | P_Int(x) -> x | _ -> raise (Z3native.Exception "parameter is not an int") - - (**The double value of the parameter.*) + let get_float ( x : parameter ) = match x with | P_Dbl(x) -> x | _ -> raise (Z3native.Exception "parameter is not a double") - - (**The Symbol value of the parameter.*) + let get_symbol ( x : parameter ) = match x with | P_Sym(x) -> x | _ -> raise (Z3native.Exception "parameter is not a symbol") - (**The Sort value of the parameter.*) let get_sort ( x : parameter ) = match x with | P_Srt(x) -> x | _ -> raise (Z3native.Exception "parameter is not a sort") - (**The AST value of the parameter.*) let get_ast ( x : parameter ) = match x with | P_Ast(x) -> x | _ -> raise (Z3native.Exception "parameter is not an ast") - (**The FunctionDeclaration value of the parameter.*) let get_func_decl ( x : parameter ) = match x with | P_Fdl(x) -> x | _ -> raise (Z3native.Exception "parameter is not a func_decl") - (**The rational string value of the parameter.*) - let get_func_decl ( x : parameter ) = + let get_rational ( x : parameter ) = match x with | P_Rat(x) -> x | _ -> raise (Z3native.Exception "parameter is not a rational string") end - (** - Creates a new function declaration. - *) - let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = create_ndr ctx name domain range - (** - Creates a new function declaration. - *) let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range - (** - Creates a fresh function declaration with a name prefixed with . - - - *) let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = create_pdr ctx prefix domain range - (** - Creates a new constant function declaration. - *) - let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort ) = + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = create_ndr ctx name [||] range - (** - Creates a new constant function declaration. - *) let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = create_ndr ctx (Symbol.mk_string ctx name) [||] range - (** - Creates a fresh constant function declaration with a name prefixed with . - - - *) let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = create_pdr ctx prefix [||] range - (** - Comparison operator. - @param a A func_decl - @param b A func_decl - @return True if and are from the same context - and represent the same func_decl; false otherwise. - *) let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || if (gnc a) != (gnc b) then false else (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) - (** - A string representations of the function declaration. - *) let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) - (** - Returns a unique identifier for the function declaration. - *) let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) - (** - The arity of the function declaration - *) let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) - (** - The size of the domain of the function declaration - - *) let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) - (** - The domain of the function declaration - *) let get_domain ( x : func_decl ) = let n = (get_domain_size x) in let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in Array.init n f - (** - The range of the function declaration - *) let get_range ( x : func_decl ) = sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) - (** - The kind of the function declaration. - *) let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) - (** - The name of the function declaration - *) let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) - (** - The number of parameters of the function declaration - *) let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) - (** - The parameters of the function declaration - *) let get_parameters ( x : func_decl ) = let n = (get_num_parameters x) in let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> P_Ast (ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) ) in mk_list f n - (** - Create expression that applies function to arguments. - @param args The arguments - *) - let apply ( x : func_decl ) ( args : expr array ) = expr_of_func_app (gc x) x args + let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.expr_of_func_app (gc x) x args end -(** - Parameter sets (of Solvers, Tactics, ...) - A Params objects represents a configuration in the form of symbol/value pairs. -*) -module Params = -struct - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) +and Params : +sig + type params = z3_native_object + module ParamDescrs : + sig + type param_descrs + val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + val get_names : param_descrs -> Symbol.symbol array + val get_size : param_descrs -> int + val to_string : param_descrs -> string + end + val add_bool : params -> Symbol.symbol -> bool -> unit + val add_int : params -> Symbol.symbol -> int -> unit + val add_double : params -> Symbol.symbol -> float -> unit + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + val add_s_bool : params -> string -> bool -> unit + val add_s_int : params -> string -> int -> unit + val add_s_double : params -> string -> float -> unit + val add_s_symbol : params -> string -> Symbol.symbol -> unit + val mk_params : context -> params + val to_string : params -> string +end = struct + type params = z3_native_object + module ParamDescrs = - struct - - let create ( ctx : context ) ( no : Z3native.ptr ) = + struct + type param_descrs = z3_native_object + + let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : param_descrs = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.param_descrs_inc_ref ; @@ -1180,79 +650,46 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - - - (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params ) = Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = + let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) - (** Retrieve all names of parameters. *) let get_names ( x : param_descrs ) = let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) - - (** Retrieves a string representation of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) end - (** - Adds a parameter setting. - *) - let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = + let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - (** - Adds a parameter setting. - *) - let add_int ( x : params ) (name : symbol ) ( value : int ) = + let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - (** - Adds a parameter setting. - *) - let add_double ( x : params ) ( name : symbol ) ( value : float ) = + let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - (** - Adds a parameter setting. - *) - let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = + let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - (** - Adds a parameter setting. - *) let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = add_bool x (Symbol.mk_string (z3obj_gc x) name) value - (** - Adds a parameter setting. - *) let add_s_int ( x : params) ( name : string ) ( value : int ) = add_int x (Symbol.mk_string (z3obj_gc x) name) value - (** - Adds a parameter setting. - *) let add_s_double ( x : params ) ( name : string ) ( value : float ) = add_double x (Symbol.mk_string (z3obj_gc x) name) value - (** - Adds a parameter setting. - *) - let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = + + let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = add_symbol x (Symbol.mk_string (z3obj_gc x) name) value - (** - Creates a new parameter set - *) let mk_params ( ctx : context ) = let res : params = { m_ctx = ctx ; m_n_obj = null ; @@ -1262,21 +699,107 @@ struct (z3obj_create res) ; res - (** - A string representation of the parameter set. - *) let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) end (** General expressions (terms) *) -module Expr = -struct +and Expr : +sig + type expr = Expr of AST.ast + val expr_of_ptr : context -> Z3native.ptr -> expr + val c_of_expr : expr -> context + val nc_of_expr : expr -> Z3native.ptr + val ptr_of_expr : expr -> Z3native.ptr + val expr_aton : expr array -> Z3native.ptr array + val ast_of_expr : expr -> AST.ast + val expr_of_ast : AST.ast -> expr + val expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr + val simplify : expr -> Params.params option -> expr + val get_simplify_help : context -> string + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + val get_func_decl : expr -> FuncDecl.func_decl + val get_bool_value : expr -> Z3enums.lbool + val get_num_args : expr -> int + val get_args : expr -> expr array + val update : expr -> expr array -> expr + val substitute : expr -> expr array -> expr array -> expr + val substitute_one : expr -> expr -> expr -> expr + val substitute_vars : expr -> expr array -> expr + val translate : expr -> context -> expr + val to_string : expr -> string + val is_numeral : expr -> bool + val is_well_sorted : expr -> bool + val get_sort : expr -> Sort.sort + val is_bool : expr -> bool + val is_const : expr -> bool + val is_true : expr -> bool + val is_false : expr -> bool + val is_eq : expr -> bool + val is_distinct : expr -> bool + val is_ite : expr -> bool + val is_and : expr -> bool + val is_or : expr -> bool + val is_iff : expr -> bool + val is_xor : expr -> bool + val is_not : expr -> bool + val is_implies : expr -> bool + val is_label : expr -> bool + val is_oeq : expr -> bool + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val mk_const_s : context -> string -> Sort.sort -> expr + val mk_const_f : context -> FuncDecl.func_decl -> expr + val mk_fresh_const : context -> string -> Sort.sort -> expr + val mk_app : context -> FuncDecl.func_decl -> expr array -> expr + val mk_numeral_string : context -> string -> Sort.sort -> expr + val mk_numeral_int : context -> int -> Sort.sort -> expr +end = struct + type expr = Expr of AST.ast + + let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) + let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) + let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + + let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then + Expr(z3_native_object_of_ast_ptr ctx no) + else + let s = Z3native.get_sort (context_gno ctx) no in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) no) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + if (Z3native.is_numeral_ast (context_gno ctx) no) then + if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + raise (Z3native.Exception "Unsupported numeral object") + else + Expr(z3_native_object_of_ast_ptr ctx no) + + let expr_of_ast a = + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Expr(a) + + let ast_of_expr e = match e with Expr(a) -> a + + let expr_aton ( a : expr array ) = + let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in + Array.map f a + + let expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr = fun ctx f args -> + match f with FuncDecl.FuncDecl(fa) -> + let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (Array.length args) (expr_aton args) in + expr_of_ptr ctx o + (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier *) - let simplify ( x : expr ) ( p : params option ) = match p with + let simplify ( x : expr ) ( p : Params.params option ) = match p with | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) @@ -1290,12 +813,12 @@ struct Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.create ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) + Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. *) - let get_func_decl ( x : expr ) = func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the expression is the true or false expression @@ -1477,7 +1000,7 @@ struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -1492,8 +1015,7 @@ struct Creates a constant from the func_decl . @param f An expression of a 0-arity function *) - let mk_const_f ( ctx : context ) ( f : func_decl ) = - expr_of_func_app ctx f [||] + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [||] (** Creates a fresh constant of sort and a @@ -1505,8 +1027,7 @@ struct (** Create a new function application. *) - let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = - expr_of_func_app ctx f args + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = expr_of_func_app ctx f args (** Create a numeral of a given sort. @@ -1528,19 +1049,44 @@ struct expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) end +open FuncDecl +open Expr + (** Boolean expressions *) module Boolean = -struct +struct + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (ast_of_ptr ctx no) in - BoolExpr(Expr(a)) + let a = (AST.ast_of_ptr ctx no) in + BoolExpr(Expr.Expr(a)) + + let bool_expr_of_expr e = + match e with Expr.Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolExpr(e) let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = BoolSort(sort_of_ptr ctx no) - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (c_of_expr e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (nc_of_expr e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (ptr_of_expr e) + let sort_of_bool_sort s = match s with BoolSort(x) -> x + + let bool_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolSort(s) + + let expr_of_bool_expr e = match e with BoolExpr(x) -> x + + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) let mk_sort ( ctx : context ) = BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) @@ -1548,7 +1094,7 @@ struct (** Create a Boolean constant. *) - let mk_const ( ctx : context ) ( name : symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = let s = (match (mk_sort ctx) with BoolSort(q) -> q) in BoolExpr(Expr.mk_const ctx name s) @@ -1638,17 +1184,38 @@ end (** Quantifier expressions *) module Quantifier = struct + type quantifier = Quantifier of expr + + let expr_of_quantifier e = match e with Quantifier(x) -> x + + let quantifier_of_expr e = + match e with Expr.Expr(a) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.QUANTIFIER_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Quantifier(e) + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (c_of_expr e) let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) - + (** Quantifier patterns Patterns comprise a list of terms. The list should be non-empty. If the list comprises of more than one term, it is also called a multi-pattern. *) - module Pattern = struct + module Pattern = + struct + type pattern = Pattern of ast + + let ast_of_pattern e = match e with Pattern(x) -> x + + let pattern_of_ast a = + (* CMW: Unchecked ok? *) + Pattern(a) + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) @@ -1692,7 +1259,7 @@ struct index. *) let get_index ( x : expr ) = - if not (AST.is_var (match x with Expr(a) -> a)) then + if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) @@ -1723,7 +1290,7 @@ struct *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1736,7 +1303,7 @@ struct *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1781,7 +1348,7 @@ struct if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) + Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) (** Create a universal Quantifier. @@ -1802,14 +1369,14 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) else @@ -1817,21 +1384,21 @@ struct (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true @@ -1839,7 +1406,7 @@ struct (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) @@ -1847,14 +1414,14 @@ struct Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) else @@ -1862,21 +1429,21 @@ struct (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) - + (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false @@ -1884,14 +1451,14 @@ struct (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -1901,7 +1468,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -1911,14 +1478,35 @@ end (** Functions to manipulate Array expressions *) module Array_ = struct + type array_sort = ArraySort of sort + type array_expr = ArrayExpr of expr - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let e = (expr_of_ptr ctx no) in ArrayExpr(e) - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in - ArraySort(s) + ArraySort(s) + + let sort_of_array_sort s = match s with ArraySort(x) -> x + + let array_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArraySort(s) + + let array_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArrayExpr(e) + + let expr_of_array_expr e = match e with ArrayExpr(x) -> x let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) @@ -1932,7 +1520,7 @@ struct Create a new array sort. *) let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - create_sort ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) + array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) (** Indicates whether the term is an array store. @@ -1979,16 +1567,15 @@ struct ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) (** The domain of the array sort. *) - let get_domain ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) + let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) (** The range of the array sort. *) - let get_range ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) - + let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) (** @@ -2010,7 +1597,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) + array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) (** Array update. @@ -2029,7 +1616,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = - expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) + array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) (** Create a constant array. @@ -2040,7 +1627,7 @@ struct *) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) + array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) (** Maps f on the argument arrays. @@ -2054,7 +1641,7 @@ struct *) let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = let m x = (ptr_of_expr (expr_of_array_expr x)) in - expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) + array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) (** Access the array default value. @@ -2063,16 +1650,20 @@ struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) + array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end (** Functions to manipulate Set expressions *) module Set = struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + type set_sort = SetSort of sort + + let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in SetSort(s) + let sort_of_set_sort s = match s with SetSort(x) -> x + (** Indicates whether the term is set union *) @@ -2102,7 +1693,7 @@ struct Create a set type. *) let mk_sort ( ctx : context ) ( ty : sort ) = - create_sort ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) + set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) (** Create an empty set. @@ -2169,14 +1760,24 @@ end (** Functions to manipulate Finite Domain expressions *) module FiniteDomain = struct + type finite_domain_sort = FiniteDomainSort of sort + + let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x + + let finite_domain_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + FiniteDomainSort(s) + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - + (** Create a new finite domain sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( size : int ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in FiniteDomainSort(s) @@ -2210,15 +1811,24 @@ end (** Functions to manipulate Relation expressions *) module Relation = struct - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + type relation_sort = RelationSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in RelationSort(s) + let sort_of_relation_sort s = match s with RelationSort(x) -> x + + let relation_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RelationSort(s) + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - + (** Indicates whether the term is of a relation sort. @@ -2335,29 +1945,53 @@ struct (** The sorts of the columns of the relation sort. *) let get_column_sorts ( x : relation_sort ) = let n = get_arity x in - let f i = (create_sort (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in + let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in Array.init n f end (** Functions to manipulate Datatype expressions *) module Datatype = -struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = +struct + type datatype_sort = DatatypeSort of sort + type datatype_expr = DatatypeExpr of expr + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in DatatypeSort(s) + let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x + + let datatype_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeSort(s) + + let datatype_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeExpr(e) + + let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - + (** Constructors *) module Constructor = struct + type constructor = z3_native_object + let _counts = Hashtbl.create 0 - let create ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -2366,11 +2000,11 @@ struct raise (Z3native.Exception "Number of field names does not match number of sort refs") else let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) - (Symbol.gno recognizer) - n - (let f x = (Symbol.gno x) in (Array.map f field_names)) - (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - sort_refs) in + (Symbol.gno recognizer) + n + (let f x = (Symbol.gno x) in (Array.map f field_names)) + (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + sort_refs) in let no : constructor = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; @@ -2383,7 +2017,7 @@ struct no let get_n ( x : constructor ) = (Hashtbl.find _counts x) - + let rec constructor_decl ( x : constructor ) = let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in func_decl_of_ptr (z3obj_gc x) a @@ -2391,12 +2025,12 @@ struct let rec tester_decl ( x : constructor ) = let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in func_decl_of_ptr (z3obj_gc x) b - + let rec accessor_decls ( x : constructor ) = let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in let f y = func_decl_of_ptr (z3obj_gc x) y in Array.map f c - + (** The number of fields of the constructor. *) let get_num_fields ( x : constructor ) = get_n x @@ -2413,8 +2047,9 @@ struct (** Constructor list objects *) module ConstructorList = struct - - let create ( ctx : context ) ( c : constructor array ) = + type constructor_list = z3_native_object + + let create ( ctx : context ) ( c : Constructor.constructor array ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; @@ -2438,7 +2073,7 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = Constructor.create ctx name recognizer field_names sorts sort_refs @@ -2452,22 +2087,22 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array ) = let f x = (z3obj_gno x) in let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in - create_sort ctx x + sort_of_ptr ctx x (** Create a new datatype sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors (** @@ -2475,17 +2110,17 @@ struct @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = let n = (Array.length names) in - let f e = (ptr_of_ast (ConstructorList.create ctx e)) in + let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in let cla = (Array.map f c) in let f2 x = (Symbol.gno x) in let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Array.map f2 names) cla) in - let g e = (create_sort ctx e) in + let g e = (sort_of_ptr ctx e) in (Array.map g r) (** Create mutually recursive data-types. *) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in @@ -2522,17 +2157,21 @@ end (** Functions to manipulate Enumeration expressions *) module Enumeration = -struct +struct + type enum_sort = EnumSort of sort + let _constdecls = Hashtbl.create 0 let _testerdecls = Hashtbl.create 0 - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = let s = (sort_of_ptr ctx no) in let res = EnumSort(s) in Hashtbl.add _constdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f cdecls)) ; Hashtbl.add _testerdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f tdecls)) ; res + let sort_of_enum_sort s = match s with EnumSort(x) -> x + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) @@ -2540,10 +2179,10 @@ struct (** Create a new enumeration sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( enum_names : symbol array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = let f x = Symbol.gno x in let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in - create_sort ctx a b c + sort_of_ptr ctx a b c (** Create a new enumeration sort. @@ -2561,14 +2200,16 @@ end (** Functions to manipulate List expressions *) module List_ = struct + type list_sort = ListSort of sort + let _nildecls = Hashtbl.create 0 let _is_nildecls = Hashtbl.create 0 let _consdecls = Hashtbl.create 0 let _is_consdecls = Hashtbl.create 0 let _headdecls = Hashtbl.create 0 let _taildecls = Hashtbl.create 0 - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in let res = ListSort(s) in Hashtbl.add _nildecls res (func_decl_of_ptr ctx nildecl) ; @@ -2578,16 +2219,18 @@ struct Hashtbl.add _headdecls res (func_decl_of_ptr ctx headdecl) ; Hashtbl.add _taildecls res (func_decl_of_ptr ctx taildecl) ; res + + let sort_of_list_sort s = match s with ListSort(x) -> x let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - - + + (** Create a new list sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( elem_sort : sort ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - create_sort ctx r a b c d e f + sort_of_ptr ctx r a b c d e f (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = @@ -2618,23 +2261,26 @@ end (** Functions to manipulate Tuple expressions *) module Tuple = struct - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + type tuple_sort = TupleSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in TupleSort(s) + let sort_of_tuple_sort s = match s with TupleSort(x) -> x + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - + (** Create a new tuple sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( field_names : symbol array ) ( field_sorts : sort array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : sort array ) = let f x = Symbol.gno x in let f2 x = ptr_of_ast (ast_of_sort x) in let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in (* CMW: leaks a,b? *) - create_sort ctx r + sort_of_ptr ctx r (** The constructor function of the tuple. *) let get_mk_decl ( x : tuple_sort ) = @@ -2651,13 +2297,144 @@ struct end (** Functions to manipulate arithmetic expressions *) -module Arithmetic = -struct - - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - arith_expr_of_expr (expr_of_ptr ctx no) +module rec Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr + + val sort_of_arith_sort : arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> arith_sort + val expr_of_arith_expr : arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> arith_expr - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end + + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool + val mk_add : context -> arith_expr array -> arith_expr + val mk_mul : context -> arith_expr array -> arith_expr + val mk_sub : context -> arith_expr array -> arith_expr + val mk_unary_minus : context -> arith_expr -> arith_expr + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr +end = struct + type arith_sort = ArithSort of sort + type arith_expr = ArithExpr of expr + + let arith_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithExpr(e) + + let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + arith_expr_of_expr (expr_of_ptr ctx no) + + let sort_of_arith_sort s = match s with ArithSort(x) -> x + let expr_of_arith_expr e = match e with ArithExpr(x) -> x + + let arith_sort_of_sort s = match s with Sort(a) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithSort(s) + + let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = arith_sort_of_sort (sort_of_ptr ctx no) let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) @@ -2667,16 +2444,72 @@ struct let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (nc_of_expr e) let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (ptr_of_expr e) - module Integer = - struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - int_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - int_num_of_int_expr (create_expr ctx no) + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end = struct + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + let int_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntExpr(e) + + let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let int_num_of_int_expr e = + match e with IntExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + IntNum(e) + + let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_num_of_int_expr (int_expr_of_ptr ctx no) + + let arith_sort_of_int_sort s = match s with IntSort(x) -> x + let arith_expr_of_int_expr e = match e with IntExpr(x) -> x + let int_expr_of_int_num e = match e with IntNum(x) -> x + + let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntSort(s) + + let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) @@ -2687,11 +2520,11 @@ struct let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - + (** Create a new integer sort. *) let mk_sort ( ctx : context ) = - create_sort ctx (Z3native.mk_int_sort (context_gno ctx)) + int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) (** Retrieve the int value. *) let get_int ( x : int_num ) = @@ -2705,7 +2538,7 @@ struct (** Creates an integer constant. *) - let mk_int_const ( ctx : context ) ( name : symbol ) = + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) (** @@ -2719,21 +2552,21 @@ struct The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) (** Create an integer numeral. @param v A string representing the Term value in decimal notation. *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) (** Create an integer numeral. @@ -2741,7 +2574,7 @@ struct @return A Term with value and sort Integer *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) (** Coerce an integer to a real. @@ -2754,7 +2587,7 @@ struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) + Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) (** Create an bit bit-vector from the integer argument . @@ -2767,19 +2600,76 @@ struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - bitvec_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) + BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) end - module Real = - struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - rat_num_of_real_expr (create_expr ctx no) + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : real_sort -> arith_sort + val real_sort_of_arith_sort : arith_sort -> real_sort + val arith_expr_of_real_expr : real_expr -> arith_expr + val real_expr_of_rat_num : rat_num -> real_expr + val real_expr_of_arith_expr : arith_expr -> real_expr + val rat_num_of_real_expr : real_expr -> rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end = struct + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + let arith_sort_of_real_sort s = match s with RealSort(x) -> x + let arith_expr_of_real_expr e = match e with RealExpr(x) -> x + let real_expr_of_rat_num e = match e with RatNum(x) -> x + + let real_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealExpr(e) + + let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let rat_num_of_real_expr e = + match e with RealExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + RatNum(e) + + let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + rat_num_of_real_expr (real_expr_of_ptr ctx no) + + let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealSort(s) + + let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) @@ -2790,19 +2680,19 @@ struct let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - + (** Create a real sort. *) let mk_sort ( ctx : context ) = - create_sort ctx (Z3native.mk_real_sort (context_gno ctx)) + real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = - Integer.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = - Integer.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2813,7 +2703,7 @@ struct let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) (** Creates a real constant. *) - let mk_real_const ( ctx : context ) ( name : symbol ) = + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) (** Creates a real constant. *) @@ -2832,7 +2722,7 @@ struct if (den == 0) then raise (Z3native.Exception "Denominator is zero") else - create_num ctx (Z3native.mk_real (context_gno ctx) num den) + rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) (** Create a real numeral. @@ -2840,7 +2730,7 @@ struct @return A Term with value and sort Real *) let mk_numeral_s ( ctx : context ) ( v : string ) = - create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) (** Create a real numeral. @@ -2849,11 +2739,11 @@ struct @return A Term with value and sort Real *) let mk_numeral_i ( ctx : context ) ( v : int ) = - create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) (** Coerce a real to an integer. @@ -2863,18 +2753,39 @@ struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) + Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) end - module AlgebraicNumber = - struct - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end = struct + type algebraic_num = AlgebraicNum of arith_expr + + let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x + + let algebraic_num_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + AlgebraicNum(e) + + let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - + (** Return a upper bound for a given real algebraic number. @@ -2884,7 +2795,7 @@ struct @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = - Real.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) (** Return a lower bound for the given real algebraic number. @@ -2894,7 +2805,7 @@ struct @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = - Real.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -3056,38 +2967,186 @@ struct Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) end (** Functions to manipulate bit-vector expressions *) -module BitVector = -struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = +and BitVector : +sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + + val mk_sort : context -> int -> bitvec_sort + val is_bv : Expr.expr -> bool + val is_bv_numeral : Expr.expr -> bool + val is_bv_bit1 : Expr.expr -> bool + val is_bv_bit0 : Expr.expr -> bool + val is_bv_uminus : Expr.expr -> bool + val is_bv_add : Expr.expr -> bool + val is_bv_sub : Expr.expr -> bool + val is_bv_mul : Expr.expr -> bool + val is_bv_sdiv : Expr.expr -> bool + val is_bv_udiv : Expr.expr -> bool + val is_bv_SRem : Expr.expr -> bool + val is_bv_urem : Expr.expr -> bool + val is_bv_smod : Expr.expr -> bool + val is_bv_sdiv0 : Expr.expr -> bool + val is_bv_udiv0 : Expr.expr -> bool + val is_bv_srem0 : Expr.expr -> bool + val is_bv_urem0 : Expr.expr -> bool + val is_bv_smod0 : Expr.expr -> bool + val is_bv_ule : Expr.expr -> bool + val is_bv_sle : Expr.expr -> bool + val is_bv_uge : Expr.expr -> bool + val is_bv_sge : Expr.expr -> bool + val is_bv_ult : Expr.expr -> bool + val is_bv_slt : Expr.expr -> bool + val is_bv_ugt : Expr.expr -> bool + val is_bv_sgt : Expr.expr -> bool + val is_bv_and : Expr.expr -> bool + val is_bv_or : Expr.expr -> bool + val is_bv_not : Expr.expr -> bool + val is_bv_xor : Expr.expr -> bool + val is_bv_nand : Expr.expr -> bool + val is_bv_nor : Expr.expr -> bool + val is_bv_xnor : Expr.expr -> bool + val is_bv_concat : Expr.expr -> bool + val is_bv_signextension : Expr.expr -> bool + val is_bv_zeroextension : Expr.expr -> bool + val is_bv_extract : Expr.expr -> bool + val is_bv_repeat : Expr.expr -> bool + val is_bv_reduceor : Expr.expr -> bool + val is_bv_reduceand : Expr.expr -> bool + val is_bv_comp : Expr.expr -> bool + val is_bv_shiftleft : Expr.expr -> bool + val is_bv_shiftrightlogical : Expr.expr -> bool + val is_bv_shiftrightarithmetic : Expr.expr -> bool + val is_bv_rotateleft : Expr.expr -> bool + val is_bv_rotateright : Expr.expr -> bool + val is_bv_rotateleftextended : Expr.expr -> bool + val is_bv_rotaterightextended : Expr.expr -> bool + val is_int_to_bv : Expr.expr -> bool + val is_bv_to_int : Expr.expr -> bool + val is_bv_carry : Expr.expr -> bool + val is_bv_xor3 : Expr.expr -> bool + val get_size : bitvec_sort -> int + val get_int : bitvec_num -> int + val to_string : bitvec_num -> string + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + val mk_const_s : context -> string -> int -> bitvec_expr + val mk_not : context -> bitvec_expr -> Expr.expr + val mk_redand : context -> bitvec_expr -> Expr.expr + val mk_redor : context -> bitvec_expr -> Expr.expr + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_neg : context -> bitvec_expr -> bitvec_expr + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_numeral : context -> string -> int -> bitvec_num +end = struct + type bitvec_sort = BitVecSort of sort + type bitvec_expr = BitVecExpr of expr + type bitvec_num = BitVecNum of bitvec_expr + + let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x + + let bitvec_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecSort(s) + + let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = bitvec_sort_of_sort (sort_of_ptr ctx no) - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let bitvec_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecExpr(e) + + let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = bitvec_expr_of_expr (expr_of_ptr ctx no) - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_num_of_bitvec_expr (create_expr ctx no) + let bitvec_num_of_bitvec_expr e = + match e with BitVecExpr(Expr(a)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecNum(e) + + let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) + + let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x + let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x + let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) @@ -3098,13 +3157,13 @@ struct let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - + (** Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - create_sort ctx (Z3native.mk_bv_sort (context_gno ctx) size) + bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. @@ -3391,8 +3450,8 @@ struct (** Creates a bit-vector constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = - BitVecExpr(Expr.mk_const ctx name (match (mk_sort ctx size) with BitVecSort(s) -> s)) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) (** Creates a bit-vector constant. @@ -3426,70 +3485,70 @@ struct The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) (** Unsigned division. @@ -3501,7 +3560,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) (** Signed division. @@ -3516,7 +3575,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) (** Unsigned remainder. @@ -3526,7 +3585,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) (** Signed remainder. @@ -3538,7 +3597,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed remainder (sign follows divisor). @@ -3547,7 +3606,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than @@ -3555,7 +3614,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than @@ -3563,7 +3622,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) (** Unsigned less-than or equal to. @@ -3571,7 +3630,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than or equal to. @@ -3579,7 +3638,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater than or equal to. @@ -3587,7 +3646,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater than or equal to. @@ -3595,7 +3654,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater-than. @@ -3603,7 +3662,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater-than. @@ -3611,7 +3670,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) (** Bit-vector concatenation. @@ -3622,7 +3681,7 @@ struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector extraction. @@ -3633,7 +3692,7 @@ struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) (** Bit-vector sign extension. @@ -3643,7 +3702,7 @@ struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) (** Bit-vector zero extension. @@ -3654,7 +3713,7 @@ struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) (** Bit-vector repetition. @@ -3662,7 +3721,7 @@ struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) (** Shift left. @@ -3677,8 +3736,8 @@ struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - + bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + (** Logical shift right @@ -3692,7 +3751,7 @@ struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) (** Arithmetic shift right @@ -3708,7 +3767,7 @@ struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) (** Rotate Left. @@ -3717,7 +3776,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) (** Rotate Right. @@ -3726,7 +3785,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) (** Rotate Left. @@ -3735,7 +3794,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) (** Rotate Right. @@ -3745,7 +3804,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) (** Create an integer from the bit-vector argument . @@ -3763,7 +3822,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integer.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) + Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3771,7 +3830,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3779,7 +3838,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not overflow. @@ -3787,7 +3846,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3795,7 +3854,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3803,7 +3862,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3811,7 +3870,7 @@ struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3819,7 +3878,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3827,7 +3886,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a bit-vector numeral. @@ -3836,7 +3895,7 @@ struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx size))) + bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) end (** Functions to manipulate proof expressions *) @@ -4321,7 +4380,8 @@ end tactics and solvers. *) module Goal = struct - + type goal = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : goal = { m_ctx = ctx ; m_n_obj = null ; @@ -4330,7 +4390,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** The precision of the goal. @@ -4359,7 +4419,7 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) - let assert_ ( x : goal ) ( constraints : bool_expr array ) = + let assert_ ( x : goal ) ( constraints : Boolean.bool_expr array ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in ignore (Array.map f constraints) ; () @@ -4381,7 +4441,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in Array.init n f @@ -4401,7 +4461,7 @@ struct create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - let simplify ( x : goal ) ( p : params option ) = + let simplify ( x : goal ) ( p : Params.params option ) = let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in Z3native.tactic_inc_ref (z3obj_gnc x) tn ; let arn = match p with @@ -4441,7 +4501,8 @@ end A Model contains interpretations (assignments) of constants and functions. *) module Model = struct - + type model = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; m_n_obj = null ; @@ -4450,7 +4511,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Function interpretations @@ -4459,7 +4520,8 @@ struct *) module FuncInterp = struct - + type func_interp = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_interp = { m_ctx = ctx ; m_n_obj = null ; @@ -4468,7 +4530,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Function interpretations entries @@ -4476,7 +4538,8 @@ struct *) module FuncEntry = struct - + type func_entry = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; m_n_obj = null ; @@ -4485,7 +4548,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Return the (symbolic) value of this entry. @@ -4677,7 +4740,7 @@ struct An array of expressions, where each is an element of the universe of *) let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f @@ -4699,7 +4762,8 @@ end *) module Probe = struct - + type probe = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : probe = { m_ctx = ctx ; m_n_obj = null ; @@ -4708,14 +4772,14 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Execute the probe over the goal. A probe always produce a double value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let apply ( x : probe ) (g : goal) = + let apply ( x : probe ) ( g : Goal.goal ) = Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (** @@ -4820,7 +4884,8 @@ end *) module Tactic = struct - + type tactic = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : tactic = { m_ctx = ctx ; m_n_obj = null ; @@ -4829,7 +4894,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Tactic application results @@ -4837,7 +4902,8 @@ struct tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult = struct - + type apply_result = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : apply_result = { m_ctx = ctx ; m_n_obj = null ; @@ -4846,7 +4912,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** The number of Subgoals. *) let get_num_subgoals ( x : apply_result ) = @@ -4866,7 +4932,7 @@ struct goal g, that the ApplyResult was obtained from. #return A model for g *) - let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) (** A string representation of the ApplyResult. *) @@ -4878,10 +4944,10 @@ struct (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.create (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) - let apply ( x : tactic ) ( g : goal ) ( p : params option ) = + let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) @@ -4949,14 +5015,14 @@ struct If evaluates to false, then the new tactic behaves like the skip tactic. *) (* CMW: when is a keyword *) - let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = + let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) - let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = + let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** @@ -4981,7 +5047,7 @@ struct (** Create a tactic that fails if the probe evaluates to false. *) - let fail_if ( ctx : context ) ( p : probe ) = + let fail_if ( ctx : context ) ( p : Probe.probe ) = create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** @@ -4994,14 +5060,14 @@ struct (** Create a tactic that applies using the given set of parameters . *) - let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = + let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . Alias for UsingParams*) (* CMW: with is a keyword *) - let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = + let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p (** @@ -5029,7 +5095,9 @@ end (** Solvers *) module Solver = struct - + type solver = z3_native_object + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; @@ -5038,7 +5106,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + let string_of_status ( s : status) = match s with | UNSATISFIABLE -> "unsatisfiable" @@ -5048,7 +5116,8 @@ struct (** Objects that track statistical information about solvers. *) module Statistics = struct - + type statistics = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; @@ -5066,7 +5135,13 @@ struct *) module Entry = struct - + type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } + let create_si k v = let res : statistics_entry = { m_key = k ; @@ -5086,7 +5161,7 @@ struct m_float = v } in res - + (** The key of the entry. *) let get_key (x : statistics_entry) = x.m_key @@ -5142,11 +5217,9 @@ struct let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** - The value of a particular statistical counter. - *) + (** The value of a particular statistical counter. *) let get ( x : statistics ) ( key : string ) = - let f p c = (if (Entry.get_key c) = key then (Some c) else p) in + let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in Array.fold_left f None (get_entries x) end @@ -5158,14 +5231,14 @@ struct (** Sets the solver parameters. *) - let set_parameters ( x : solver ) ( p : params )= + let set_parameters ( x : solver ) ( p : Params.params )= Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - Params.ParamDescrs.create (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). @@ -5196,7 +5269,7 @@ struct (** Assert a constraint (or multiple) into the solver. *) - let assert_ ( x : solver ) ( constraints : bool_expr array ) = + let assert_ ( x : solver ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) @@ -5213,7 +5286,7 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = + let assert_and_track ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else @@ -5232,14 +5305,14 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = + let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) (** The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -5247,9 +5320,9 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in Array.init n f (** @@ -5259,12 +5332,12 @@ struct *) - let check ( x : solver ) ( assumptions : bool_expr array) = + let check ( x : solver ) ( assumptions : Boolean.bool_expr array) = let r = if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - let f x = (ptr_of_expr (expr_of_bool_expr x)) in + let f x = (ptr_of_expr (Boolean.expr_of_bool_expr x)) in lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Array.map f assumptions)) in match r with @@ -5306,7 +5379,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -5330,7 +5403,7 @@ struct check-sat command, and check-sat commands that take more than a given number of milliseconds to be solved. *) - let mk_solver ( ctx : context ) ( logic : symbol option ) = + let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) @@ -5354,7 +5427,7 @@ struct The solver supports the commands Push and Pop, but it will always solve each check from scratch. *) - let mk_solver_t ( ctx : context ) ( t : tactic ) = + let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** @@ -5366,7 +5439,9 @@ end (** Fixedpoint solving *) module Fixedpoint = -struct +struct + type fixedpoint = z3_native_object + let create ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; @@ -5375,7 +5450,7 @@ struct (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; (z3obj_create res) ; res - + (** A string that describes all available fixedpoint solver parameters. @@ -5386,19 +5461,19 @@ struct (** Sets the fixedpoint solver parameters. *) - let set_params ( x : fixedpoint ) ( p : params )= + let set_params ( x : fixedpoint ) ( p : Params.params )= Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.create (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. *) - let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = + let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) ; () @@ -5412,7 +5487,7 @@ struct (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = match name with | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) @@ -5429,11 +5504,11 @@ struct The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - let query ( x : fixedpoint ) ( query : bool_expr ) = + let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN (** Query the fixedpoint solver. @@ -5444,9 +5519,9 @@ struct let query_r ( x : fixedpoint ) ( relations : func_decl array ) = let f x = ptr_of_ast (ast_of_func_decl x) in match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN (** Creates a backtracking point. @@ -5467,7 +5542,7 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = + let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) (** @@ -5518,33 +5593,33 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = let f2 x = (Symbol.gno x) in Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) - let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - let f x = ptr_of_expr (expr_of_bool_expr x) in + let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr array ) = + let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** @@ -5628,9 +5703,9 @@ struct @param formula Formula to be checked for consistency in conjunction with assumptions. @return A string representation of the benchmark. *) - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr array ) ( formula : Boolean.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (let f x = ptr_of_expr (expr_of_bool_expr x) in (Array.map f assumptions)) + (Array.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.map f assumptions)) (Boolean.gno formula) (** @@ -5642,7 +5717,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5662,7 +5737,7 @@ struct Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5688,7 +5763,7 @@ struct *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in Array.init n f @@ -5702,7 +5777,7 @@ struct *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in Array.init n f (** @@ -5737,7 +5812,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5745,19 +5820,19 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) - cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) + cd + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5765,13 +5840,13 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) - cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name + cs + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) + cd + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) end @@ -5818,23 +5893,3 @@ let get_global_param ( id : string ) = *) let global_param_reset_all = Z3native.global_param_reset_all - - - -(* - -(** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. -*) - public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); - - internal Z3native.error_handler m_n_err_handler = null; - - internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) - - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - -*) From 9d15c958562df323be46cd0465036fde21d1765e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 19:49:09 +0000 Subject: [PATCH 282/507] ML API: proper use of datatype API for list/enum/constructor. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/Makefile | 2 +- src/api/ml/z3.ml | 47 ++++++++++++++++++++------------------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index abcefa4af..96fd0a55d 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -7,4 +7,4 @@ all: doc: *.ml mkdir -p doc - ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.mli -hide Z3 + ocamldoc -html -d doc -I _build -sort *.mli -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c261fce05..344e542f7 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -2159,15 +2159,10 @@ end module Enumeration = struct type enum_sort = EnumSort of sort - - let _constdecls = Hashtbl.create 0 - let _testerdecls = Hashtbl.create 0 let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = let s = (sort_of_ptr ctx no) in let res = EnumSort(s) in - Hashtbl.add _constdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f cdecls)) ; - Hashtbl.add _testerdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f tdecls)) ; res let sort_of_enum_sort s = match s with EnumSort(x) -> x @@ -2191,33 +2186,27 @@ struct mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) - let get_const_decls ( x : enum_sort ) = Hashtbl.find _constdecls x + let get_const_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in + Array.init n f (** The test predicates for the constants in the enumeration. *) - let get_tester_decls ( x : enum_sort ) = Hashtbl.find _testerdecls x + let get_tester_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in + Array.init n f + end (** Functions to manipulate List expressions *) module List_ = struct type list_sort = ListSort of sort - - let _nildecls = Hashtbl.create 0 - let _is_nildecls = Hashtbl.create 0 - let _consdecls = Hashtbl.create 0 - let _is_consdecls = Hashtbl.create 0 - let _headdecls = Hashtbl.create 0 - let _taildecls = Hashtbl.create 0 let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in let res = ListSort(s) in - Hashtbl.add _nildecls res (func_decl_of_ptr ctx nildecl) ; - Hashtbl.add _is_nildecls res (func_decl_of_ptr ctx is_nildecl) ; - Hashtbl.add _consdecls res (func_decl_of_ptr ctx consdecl) ; - Hashtbl.add _is_consdecls res (func_decl_of_ptr ctx is_consdecl) ; - Hashtbl.add _headdecls res (func_decl_of_ptr ctx headdecl) ; - Hashtbl.add _taildecls res (func_decl_of_ptr ctx taildecl) ; res let sort_of_list_sort s = match s with ListSort(x) -> x @@ -2237,22 +2226,28 @@ struct mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) - let get_nil_decl ( x : list_sort ) = (Hashtbl.find _nildecls x) + let get_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl ( x : list_sort ) = (Hashtbl.find _is_nildecls x) + let get_is_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) (** The declaration of the cons function of this list sort. *) - let get_cons_decl ( x : list_sort ) = (Hashtbl.find _consdecls x) + let get_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl ( x : list_sort ) = (Hashtbl.find _is_consdecls x) + let get_is_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) (** The declaration of the head function of this list sort. *) - let get_head_decl ( x : list_sort ) = (Hashtbl.find _headdecls x) + let get_head_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) (** The declaration of the tail function of this list sort. *) - let get_tail_decl ( x : list_sort ) = (Hashtbl.find _taildecls x) + let get_tail_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) (** The empty list. *) let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] From 576591086df79e48c7316a23ca2b30eeae69c8ca Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 22:07:18 +0000 Subject: [PATCH 283/507] ML API savepoint Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2595 +--------------------------------------------- 1 file changed, 50 insertions(+), 2545 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 344e542f7..b1e40fcac 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -338,7 +338,7 @@ struct else ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr + let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr let unwrap_ast ( x : ast ) = (z3obj_gno x) end @@ -744,6 +744,7 @@ sig val is_not : expr -> bool val is_implies : expr -> bool val is_label : expr -> bool + val is_label_lit : expr -> bool val is_oeq : expr -> bool val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val mk_const_s : context -> string -> Sort.sort -> expr @@ -794,257 +795,97 @@ end = struct let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (Array.length args) (expr_aton args) in expr_of_ptr ctx o - (** - Returns a simplified version of the expression. - @param p A set of parameters to configure the simplifier - - *) let simplify ( x : expr ) ( p : Params.params option ) = match p with | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) - (** - a string describing all available parameters to Expr.Simplify. - *) let get_simplify_help ( ctx : context ) = Z3native.simplify_get_help (context_gno ctx) - (** - Retrieves parameter descriptions for simplifier. - *) let get_simplify_parameter_descrs ( ctx : context ) = Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - - (** - The function declaration of the function that is applied in this expression. - *) let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) - (** - Indicates whether the expression is the true or false expression - or something else (L_UNDEF). - *) let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (nc_of_expr x) (ptr_of_expr x)) - (** - The number of arguments of the expression. - *) let get_num_args ( x : expr ) = Z3native.get_app_num_args (nc_of_expr x) (ptr_of_expr x) - (** - The arguments of the expression. - *) let get_args ( x : expr ) = let n = (get_num_args x) in let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in Array.init n f - (** - Update the arguments of the expression using the arguments - The number of new arguments should coincide with the current number of arguments. - *) let update ( x : expr ) args = if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (Array.length args) (expr_aton args)) - (** - Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. - - The result is the new expression. The arrays from and to must have size num_exprs. - For every i smaller than num_exprs, we must have that - sort of from[i] must be equal to sort of to[i]. - *) let substitute ( x : expr ) from to_ = if (Array.length from) <> (Array.length to_) then raise (Z3native.Exception "Argument sizes do not match") else expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (Array.length from) (expr_aton from) (expr_aton to_)) - (** - Substitute every occurrence of from in the expression with to. - - *) let substitute_one ( x : expr ) from to_ = substitute ( x : expr ) [| from |] [| to_ |] - (** - Substitute the free variables in the expression with the expressions in - - For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. - *) let substitute_vars ( x : expr ) to_ = expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (Array.length to_) (expr_aton to_)) - (** - Translates (copies) the term to the Context . - @param ctx A context - @return A copy of the term which is associated with - *) let translate ( x : expr ) to_ctx = if (c_of_expr x) == to_ctx then x else expr_of_ptr to_ctx (Z3native.translate (nc_of_expr x) (ptr_of_expr x) (context_gno to_ctx)) - (** - Returns a string representation of the expression. - *) let to_string ( x : expr ) = Z3native.ast_to_string (nc_of_expr x) (ptr_of_expr x) - (** - Indicates whether the term is a numeral - *) let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (ptr_of_expr x)) - (** - Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. - *) let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (nc_of_expr x) (ptr_of_expr x) - (** - The Sort of the term. - *) let get_sort ( x : expr ) = sort_of_ptr (c_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)) - (** - Indicates whether the term has Boolean sort. - *) let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (Z3native.is_eq_sort (nc_of_expr x) (Z3native.mk_bool_sort (nc_of_expr x)) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x))) - (** - Indicates whether the term represents a constant. - *) let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - - (** - Indicates whether the term is the constant true. - *) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - - (** - Indicates whether the term is the constant false. - *) let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - - (** - Indicates whether the term is an equality predicate. - *) let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - - (** - Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). - *) let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - - (** - Indicates whether the term is a ternary if-then-else term - *) let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - - (** - Indicates whether the term is an n-ary conjunction - *) let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - - (** - Indicates whether the term is an n-ary disjunction - *) let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - - (** - Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) - *) let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - - (** - Indicates whether the term is an exclusive or - *) let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - - (** - Indicates whether the term is a negation - *) let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - - (** - Indicates whether the term is an implication - *) let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - - (** - Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. - *) let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) - - (** - Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) - *) - - (** - Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. - *) + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) - (** - Creates a new Constant of sort and named . - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) - - (** - Creates a new Constant of sort and named . - *) let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) range - - (** - Creates a constant from the func_decl . - @param f An expression of a 0-arity function - *) let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [||] - (** - Creates a fresh constant of sort and a - name prefixed with . - *) let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - (** - Create a new function application. - *) let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = expr_of_func_app ctx f args - (** - Create a numeral of a given sort. - @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - @return A Term with value and sort - *) let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) - (** - Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - *) let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) end @@ -1052,7 +893,6 @@ end open FuncDecl open Expr -(** Boolean expressions *) module Boolean = struct type bool_sort = BoolSort of Sort.sort @@ -1091,97 +931,53 @@ struct let mk_sort ( ctx : context ) = BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) - (** - Create a Boolean constant. - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) = let s = (match (mk_sort ctx) with BoolSort(q) -> q) in BoolExpr(Expr.mk_const ctx name s) - (** - Create a Boolean constant. - *) let mk_const_s ( ctx : context ) ( name : string ) = mk_const ctx (Symbol.mk_string ctx name) - (** - The true Term. - *) let mk_true ( ctx : context ) = bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) - (** - The false Term. - *) let mk_false ( ctx : context ) = bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) - (** - Creates a Boolean value. - *) let mk_val ( ctx : context ) ( value : bool ) = if value then mk_true ctx else mk_false ctx - (** - Creates the equality = . - *) let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) - (** - Creates a distinct term. - *) let mk_distinct ( ctx : context ) ( args : expr array ) = bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (expr_aton args)) - (** - Mk an expression representing not(a). - *) let mk_not ( ctx : context ) ( a : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - (** - Create an expression representing an if-then-else: ite(t1, t2, t3). - @param t1 An expression with Boolean sort - @param t2 An expression - @param t3 An expression with the same sort as - *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - (** - Create an expression representing t1 iff t2. - *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - (** - Create an expression representing t1 -> t2. - *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - (** - Create an expression representing t1 xor t2. - *) + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - (** - Create an expression representing the AND of args - *) let mk_and ( ctx : context ) ( args : bool_expr array ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (Array.map f args)) - (** - Create an expression representing the OR of args - *) let mk_or ( ctx : context ) ( args : bool_expr array ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (Array.map f args)) end -(** Quantifier expressions *) + module Quantifier = struct type quantifier = Quantifier of expr @@ -1200,12 +996,6 @@ struct let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. - *) module Pattern = struct type pattern = Pattern of ast @@ -1220,155 +1010,68 @@ struct let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - (** - The number of terms in the pattern. - *) let get_num_terms ( x : pattern ) = Z3native.get_pattern_num_terms (gnc x) (gno x) - (** - The terms in the pattern. - *) let get_terms ( x : pattern ) = let n = (get_num_terms x) in let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in Array.init n f - (** - A string representation of the pattern. - *) let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) end - (** - The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. - *) let get_index ( x : expr ) = if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) - (** - Indicates whether the quantifier is universal. - *) let is_universal ( x : quantifier ) = Z3native.is_quantifier_forall (gnc x) (gno x) - (** - Indicates whether the quantifier is existential. - *) let is_existential ( x : quantifier ) = not (is_universal x) - (** - The weight of the quantifier. - *) let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) - (** - The number of patterns. - *) let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) - (** - The patterns. - *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f - (** - The number of no-patterns. - *) let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) - (** - The no-patterns. - *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f - (** - The number of bound variables. - *) let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) - (** - The symbols for the bound variables. - *) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in Array.init n f - (** - The sorts of the bound variables. - *) let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in Array.init n f - (** - The body of the quantifier. - *) let get_body ( x : quantifier ) = Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) - (** - Creates a new bound variable. - @param index The de-Bruijn index of the variable - @param ty The sort of the variable - *) let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - (** - Create a quantifier pattern. - *) let mk_pattern ( ctx : context ) ( terms : expr array ) = if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) - (** - Create a universal Quantifier. - - Creates a forall formula, where is the weight, - is an array of patterns, is an array - with the sorts of the bound variables, is an array with the - 'names' of the bound variables, and is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during instantiation. - - @param sorts the sorts of the bound variables. - @param names names of the bound variables - @param body the body of the quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param patterns array containing the patterns created using MkPattern. - @param noPatterns array containing the anti-patterns created using MkPattern. - @param quantifierID optional symbol to track quantifier. - @param skolemID optional symbol to track skolem constants. - *) let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") @@ -1390,9 +1093,6 @@ struct (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) - (** - Create a universal Quantifier. - *) let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true @@ -1410,10 +1110,6 @@ struct (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) - (** - Create an existential Quantifier. - - *) let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") @@ -1435,9 +1131,6 @@ struct (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) - (** - Create an existential Quantifier. - *) let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false @@ -1455,19 +1148,12 @@ struct (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) - (** - Create a Quantifier. - *) let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - - (** - Create a Quantifier. - *) let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id @@ -1475,7 +1161,7 @@ struct mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id end -(** Functions to manipulate Array expressions *) + module Array_ = struct type array_sort = ArraySort of sort @@ -1516,144 +1202,46 @@ struct let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - (** - Create a new array sort. - *) let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - (** - Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. - *) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - - (** - Indicates whether the term is an array select. - *) let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - - (** - Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. - *) let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - - (** - Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. - *) let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - - (** - Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. - *) let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - - (** - Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. - *) let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) - - (** - Indicates whether the term is of an array sort. - *) let is_array ( x : expr ) = (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) - (** The domain of the array sort. *) let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) - - (** The range of the array sort. *) let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) - (** - Create an array constant. - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) - (** - Create an array constant. - *) let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range - (** - Array read. - - The argument a is the array and i is the index - of the array that gets read. - - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. - - - *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) - - (** - Array update. - - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). - - - *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = + array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) + + let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) - (** - Create a constant array. - - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. - - - *) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) - (** - Maps f on the argument arrays. - - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. - - - - *) let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = let m x = (ptr_of_expr (expr_of_array_expr x)) in array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) - (** - Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. - *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end -(** Functions to manipulate Set expressions *) + module Set = struct type set_sort = SetSort of sort @@ -1664,100 +1252,49 @@ struct let sort_of_set_sort s = match s with SetSort(x) -> x - (** - Indicates whether the term is set union - *) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - - (** - Indicates whether the term is set intersection - *) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - - (** - Indicates whether the term is set difference - *) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - - (** - Indicates whether the term is set complement - *) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - - (** - Indicates whether the term is set subset - *) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) - - (** - Create a set type. - *) let mk_sort ( ctx : context ) ( ty : sort ) = set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - (** - Create an empty set. - *) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + + let mk_empty ( ctx : context ) ( domain : sort ) = (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) - (** - Create the full set. - *) let mk_full ( ctx : context ) ( domain : sort ) = expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) - (** - Add an element to the set. - *) let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) - (** - Remove an element from a set. - *) let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) - (** - Take the union of a list of sets. - *) let mk_union ( ctx : context ) ( args : expr array ) = expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (expr_aton args)) - (** - Take the intersection of a list of sets. - *) let mk_intersection ( ctx : context ) ( args : expr array ) = expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (expr_aton args)) - (** - Take the difference between two sets. - *) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) - (** - Take the complement of a set. - *) let mk_complement ( ctx : context ) ( arg : expr ) = expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (ptr_of_expr arg)) - (** - Check for set membership. - *) let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (ptr_of_expr elem) (ptr_of_expr set)) - (** - Check for subsetness of sets. - *) let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) end -(** Functions to manipulate Finite Domain expressions *) + module FiniteDomain = struct type finite_domain_sort = FiniteDomainSort of sort @@ -1774,41 +1311,28 @@ struct let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - (** - Create a new finite domain sort. - *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in FiniteDomainSort(s) - (** - Create a new finite domain sort. - *) let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = mk_sort ctx (Symbol.mk_string ctx name) size - (** - Indicates whether the term is of an array sort. - *) let is_finite_domain ( x : expr ) = let nc = (nc_of_expr x) in (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == FINITE_DOMAIN_SORT) - (** - Indicates whether the term is a less than predicate over a finite domain. - *) let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - (** The size of the finite domain sort. *) let get_size ( x : finite_domain_sort ) = let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in if r then v else raise (Z3native.Exception "Conversion failed.") end -(** Functions to manipulate Relation expressions *) + module Relation = struct type relation_sort = RelationSort of sort @@ -1830,119 +1354,27 @@ struct let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - (** - Indicates whether the term is of a relation sort. - *) let is_relation ( x : expr ) = let nc = (nc_of_expr x) in ((Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == RELATION_SORT)) - (** - Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. - *) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - - (** - Indicates whether the term is an empty relation - *) let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - - (** - Indicates whether the term is a test for the emptiness of a relation - *) let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - - (** - Indicates whether the term is a relational join - *) let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - - (** - Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. - *) let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - - (** - Indicates whether the term is the widening of two relations - The function takes two arguments. - *) let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - - (** - Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. - *) let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - - (** - Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. - *) let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - - (** - Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. - *) let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - - (** - Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. - *) let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - - (** - Indicates whether the term is the complement of a relation - *) let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - - (** - Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. - *) let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - - (** - Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind - to perform destructive updates to the first argument. - *) let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - (** The arity of the relation sort. *) let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) - (** The sorts of the columns of the relation sort. *) let get_column_sorts ( x : relation_sort ) = let n = get_arity x in let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in @@ -1950,7 +1382,7 @@ struct end -(** Functions to manipulate Datatype expressions *) + module Datatype = struct type datatype_sort = DatatypeSort of sort @@ -1983,14 +1415,10 @@ struct let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - - (** Constructors *) module Constructor = struct type constructor = z3_native_object - let _counts = Hashtbl.create 0 - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then @@ -2009,42 +1437,29 @@ struct m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in - Hashtbl.add _counts no n ; (z3obj_sno no ctx ptr) ; (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; no + + let get_num_fields ( x : constructor ) = Z3native.get_arity (z3obj_gnc x) (z3obj_gno x) - let get_n ( x : constructor ) = (Hashtbl.find _counts x) - - let rec constructor_decl ( x : constructor ) = - let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + let get_constructor_decl ( x : constructor ) = + let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in func_decl_of_ptr (z3obj_gc x) a - let rec tester_decl ( x : constructor ) = - let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + let get_tester_decl ( x : constructor ) = + let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in func_decl_of_ptr (z3obj_gc x) b - - let rec accessor_decls ( x : constructor ) = - let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + + let get_accessor_decls ( x : constructor ) = + let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in let f y = func_decl_of_ptr (z3obj_gc x) y in Array.map f c - (** The number of fields of the constructor. *) - let get_num_fields ( x : constructor ) = get_n x - - (** The function declaration of the constructor. *) - let get_constructor_decl ( x : constructor ) = constructor_decl x - - (** The function declaration of the tester. *) - let get_tester_decl ( x : constructor ) = tester_decl x - - (** The function declarations of the accessors *) - let get_accessor_decls ( x : constructor ) = accessor_decls x end - (** Constructor list objects *) module ConstructorList = struct type constructor_list = z3_native_object @@ -2062,54 +1477,21 @@ struct res end - (* DATATYPES *) - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = Constructor.create ctx name recognizer field_names sorts sort_refs - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - - (** - Create a new datatype sort. - *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array ) = let f x = (z3obj_gno x) in let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in sort_of_ptr ctx x - (** - Create a new datatype sort. - *) let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors - (** - Create mutually recursive datatypes. - @param names names of datatype sorts - @param c list of constructors, one list per sort. - *) let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = let n = (Array.length names) in let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in @@ -2119,7 +1501,6 @@ struct let g e = (sort_of_ptr ctx e) in (Array.map g r) - (** Create mutually recursive data-types. *) let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = mk_sorts ctx ( @@ -2128,22 +1509,18 @@ struct ) c - (** The number of constructors of the datatype sort. *) let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) - (** The range of the array sort. *) let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in Array.init n f - (** The recognizers. *) let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in Array.init n f - (** The constructor accessors. *) let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = ( @@ -2155,7 +1532,7 @@ struct Array.init n f end -(** Functions to manipulate Enumeration expressions *) + module Enumeration = struct type enum_sort = EnumSort of sort @@ -2171,27 +1548,19 @@ struct let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - (** - Create a new enumeration sort. - *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = let f x = Symbol.gno x in let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in sort_of_ptr ctx a b c - (** - Create a new enumeration sort. - *) let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string array ) = mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - (** The function declarations of the constants in the enumeration. *) let get_const_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in Array.init n f - (** The test predicates for the constants in the enumeration. *) let get_tester_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in @@ -2199,7 +1568,7 @@ struct end -(** Functions to manipulate List expressions *) + module List_ = struct type list_sort = ListSort of sort @@ -2214,46 +1583,36 @@ struct let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - - - (** Create a new list sort. *) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in sort_of_ptr ctx r a b c d e f - (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = mk_sort ctx (Symbol.mk_string ctx name) elem_sort - (** The declaration of the nil function of this list sort. *) let get_nil_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) - (** The declaration of the isNil function of this list sort. *) let get_is_nil_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) - (** The declaration of the cons function of this list sort. *) let get_cons_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) - (** The declaration of the isCons function of this list sort. *) let get_is_cons_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) - (** The declaration of the head function of this list sort. *) let get_head_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) - (** The declaration of the tail function of this list sort. *) let get_tail_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) - (** The empty list. *) let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] end -(** Functions to manipulate Tuple expressions *) + module Tuple = struct type tuple_sort = TupleSort of sort @@ -2268,30 +1627,24 @@ struct let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - - (** Create a new tuple sort. *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : sort array ) = let f x = Symbol.gno x in let f2 x = ptr_of_ast (ast_of_sort x) in - let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in - (* CMW: leaks a,b? *) + let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in sort_of_ptr ctx r - (** The constructor function of the tuple. *) let get_mk_decl ( x : tuple_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) - (** The number of fields in the tuple. *) let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) - (** The field declarations. *) let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in Array.init n f end -(** Functions to manipulate arithmetic expressions *) + module rec Arithmetic : sig type arith_sort = ArithSort of Sort.sort @@ -2516,84 +1869,37 @@ end = struct let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - - (** Create a new integer sort. *) let mk_sort ( ctx : context ) = int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - (** Retrieve the int value. *) let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - (** - Creates an integer constant. - *) let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) - (** - Creates an integer constant. - *) let mk_int_const_s ( ctx : context ) ( name : string ) = mk_int_const ctx (Symbol.mk_string ctx name) - (** - Create an expression representing t1 mod t2. - The arguments must have int type. - *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) - (** - Create an expression representing t1 rem t2. - The arguments must have int type. - *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) - (** - Create an integer numeral. - @param v A string representing the Term value in decimal notation. - *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - (** - Create an integer numeral. - @param v value of the numeral. - @return A Term with value and sort Integer - *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - (** - Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. - *) let mk_int2real ( ctx : context ) ( t : int_expr ) = Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) - (** - Create an bit bit-vector from the integer argument . - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. - *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) end @@ -2677,76 +1983,41 @@ end = struct let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - (** Create a real sort. *) let mk_sort ( ctx : context ) = real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) - (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) let to_decimal_string ( x : rat_num ) ( precision : int ) = Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - (** Returns a string representation of the numeral. *) let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - (** Creates a real constant. *) let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) - (** Creates a real constant. *) let mk_real_const_s ( ctx : context ) ( name : string ) = mk_real_const ctx (Symbol.mk_string ctx name) - (** - Create a real from a fraction. - - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - *) let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = if (den == 0) then raise (Z3native.Exception "Denominator is zero") else rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) - (** - Create a real numeral. - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - *) let mk_numeral_s ( ctx : context ) ( v : string ) = rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - (** - Create a real numeral. - - @param v value of the numeral. - @return A Term with value and sort Real - *) let mk_numeral_i ( ctx : context ) ( v : int ) = rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) - (** - Coerce a real to an integer. - - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. - *) let mk_real2int ( ctx : context ) ( t : real_expr ) = Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) end @@ -2782,208 +2053,97 @@ end = struct let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - (** - Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) let to_upper ( x : algebraic_num ) ( precision : int ) = Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) - (** - Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) let to_lower ( x : algebraic_num ) precision = Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) let to_decimal_string ( x : algebraic_num ) ( precision : int ) = Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) end - (** - Indicates whether the term is of integer sort. - *) let is_int ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (nc_of_expr x)) && ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == INT_SORT) - (** - Indicates whether the term is an arithmetic numeral. - *) let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - (** - Indicates whether the term is a less-than-or-equal - *) let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - (** - Indicates whether the term is a greater-than-or-equal - *) let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - (** - Indicates whether the term is a less-than - *) let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - (** - Indicates whether the term is a greater-than - *) let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - (** - Indicates whether the term is addition (binary) - *) let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - (** - Indicates whether the term is subtraction (binary) - *) let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - (** - Indicates whether the term is a unary minus - *) let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - (** - Indicates whether the term is multiplication (binary) - *) let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - (** - Indicates whether the term is division (binary) - *) let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - (** - Indicates whether the term is integer division (binary) - *) let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - (** - Indicates whether the term is remainder (binary) - *) let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - (** - Indicates whether the term is modulus (binary) - *) let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - (** - Indicates whether the term is a coercion of integer to real (unary) - *) let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - (** - Indicates whether the term is a coercion of real to integer (unary) - *) let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - (** - Indicates whether the term is a check that tests whether a real is integral (unary) - *) let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - (** - Indicates whether the term is of sort real. - *) let is_real ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == REAL_SORT) - - (** - Indicates whether the term is an integer numeral. - *) let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - (** - Indicates whether the term is a real numeral. - *) let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - (** - Indicates whether the term is an algebraic number - *) let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) - (** - Create an expression representing t[0] + t[1] + .... - *) let mk_add ( ctx : context ) ( t : arith_expr array ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Array.map f t))) - (** - Create an expression representing t[0] * t[1] * .... - *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Array.map f t))) - (** - Create an expression representing t[0] - t[1] - .... - *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Array.map f t))) - (** - Create an expression representing -t. - *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) - (** - Create an expression representing t1 / t2. - *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 ^ t2. - *) let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 < t2 - *) let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 <= t2 - *) let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 > t2 - *) let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 >= t2 - *) let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) end -(** Functions to manipulate bit-vector expressions *) + and BitVector : sig type bitvec_sort = BitVecSort of Sort.sort @@ -3089,8 +2249,10 @@ sig val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr @@ -3154,1225 +2316,213 @@ end = struct let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - (** - Create a new bit-vector sort. - *) let mk_sort ( ctx : context ) size = bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) - - (** - Indicates whether the terms is of bit-vector sort. - *) let is_bv ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == BV_SORT) - - (** - Indicates whether the term is a bit-vector numeral - *) let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - - (** - Indicates whether the term is a one-bit bit-vector with value one - *) let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - - (** - Indicates whether the term is a one-bit bit-vector with value zero - *) let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - - (** - Indicates whether the term is a bit-vector unary minus - *) let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - - (** - Indicates whether the term is a bit-vector addition (binary) - *) let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - - (** - Indicates whether the term is a bit-vector subtraction (binary) - *) let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - - (** - Indicates whether the term is a bit-vector multiplication (binary) - *) let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - - (** - Indicates whether the term is a bit-vector signed division (binary) - *) let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - - (** - Indicates whether the term is a bit-vector unsigned division (binary) - *) let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - - (** - Indicates whether the term is a bit-vector signed remainder (binary) - *) let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - - (** - Indicates whether the term is a bit-vector unsigned remainder (binary) - *) let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - - (** - Indicates whether the term is a bit-vector signed modulus - *) let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - - (** - Indicates whether the term is a bit-vector signed division by zero - *) let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - - (** - Indicates whether the term is a bit-vector unsigned division by zero - *) let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - - (** - Indicates whether the term is a bit-vector signed remainder by zero - *) let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - - (** - Indicates whether the term is a bit-vector unsigned remainder by zero - *) let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - - (** - Indicates whether the term is a bit-vector signed modulus by zero - *) let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - - (** - Indicates whether the term is an unsigned bit-vector less-than-or-equal - *) let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - - (** - Indicates whether the term is a signed bit-vector less-than-or-equal - *) let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - - (** - Indicates whether the term is an unsigned bit-vector greater-than-or-equal - *) let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - - (** - Indicates whether the term is a signed bit-vector greater-than-or-equal - *) let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - - (** - Indicates whether the term is an unsigned bit-vector less-than - *) let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - - (** - Indicates whether the term is a signed bit-vector less-than - *) let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - - (** - Indicates whether the term is an unsigned bit-vector greater-than - *) let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - - (** - Indicates whether the term is a signed bit-vector greater-than - *) let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - - (** - Indicates whether the term is a bit-wise AND - *) let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - - (** - Indicates whether the term is a bit-wise OR - *) let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - - (** - Indicates whether the term is a bit-wise NOT - *) let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - - (** - Indicates whether the term is a bit-wise XOR - *) let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - - (** - Indicates whether the term is a bit-wise NAND - *) let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - - (** - Indicates whether the term is a bit-wise NOR - *) let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - - (** - Indicates whether the term is a bit-wise XNOR - *) let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - - (** - Indicates whether the term is a bit-vector concatenation (binary) - *) let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - - (** - Indicates whether the term is a bit-vector sign extension - *) let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - - (** - Indicates whether the term is a bit-vector zero extension - *) let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - - (** - Indicates whether the term is a bit-vector extraction - *) let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - - (** - Indicates whether the term is a bit-vector repetition - *) let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - - (** - Indicates whether the term is a bit-vector reduce OR - *) let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - - (** - Indicates whether the term is a bit-vector reduce AND - *) let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - - (** - Indicates whether the term is a bit-vector comparison - *) let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - - (** - Indicates whether the term is a bit-vector shift left - *) let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - - (** - Indicates whether the term is a bit-vector logical shift right - *) let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - - (** - Indicates whether the term is a bit-vector arithmetic shift left - *) let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - - (** - Indicates whether the term is a bit-vector rotate left - *) let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - - (** - Indicates whether the term is a bit-vector rotate right - *) let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - - (** - Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. - *) let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - - (** - Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. - *) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - - (** - Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - *) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - - (** - Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - *) let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - - (** - Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) - *) let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - - (** - Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) - *) let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - - (** The size of a bit-vector sort. *) let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) - - (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - - (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - - (** - Creates a bit-vector constant. - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) - - (** - Creates a bit-vector constant. - *) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = mk_const ctx (Symbol.mk_string ctx name) size - - (** - Bitwise negation. - The argument must have a bit-vector sort. - *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) - - (** - Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. - *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) - - (** - Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. - *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) - - (** - Bitwise conjunction. - The arguments must have a bit-vector sort. - *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise disjunction. - The arguments must have a bit-vector sort. - *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise XOR. - The arguments must have a bit-vector sort. - *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise NAND. - The arguments must have a bit-vector sort. - *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise NOR. - The arguments must have a bit-vector sort. - *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise XNOR. - The arguments must have a bit-vector sort. - *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) - - (** - Standard two's complement unary minus. - The arguments must have a bit-vector sort. - *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) - - (** - Two's complement addition. - The arguments must have the same bit-vector sort. - *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) - - (** - Two's complement subtraction. - The arguments must have the same bit-vector sort. - *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) - - (** - Two's complement multiplication. - The arguments must have the same bit-vector sort. - *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) - - (** - Unsigned division. - - - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. - *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) - - (** - Signed division. - - It is defined in the following way: - - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) - - (** - Unsigned remainder. - - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) - - (** - Signed remainder. - - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) - - (** - Two's complement signed remainder (sign follows divisor). - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) - - (** - Unsigned less-than - - The arguments must have the same bit-vector sort. - *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed less-than - - The arguments must have the same bit-vector sort. - *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) - - (** - Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) - - (** - Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) - - (** - Unsigned greater-than. - - The arguments must have the same bit-vector sort. - *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. - *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) - - (** - Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). - *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) - - (** - Bit-vector extraction. - - Extract the bits down to from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. - The argument must have a bit-vector sort. - *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) - - (** - Bit-vector sign extension. - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. - The argument must have a bit-vector sort. - *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) - - (** - Bit-vector zero extension. - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the - given bit-vector. - The argument must have a bit-vector sort. - *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) - - (** - Bit-vector repetition. - - The argument must have a bit-vector sort. - *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) - - (** - Shift left. - - - It is equivalent to multiplication by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - - - (** - Logical shift right - - It is equivalent to unsigned division by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) - - (** - Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) - - (** - Rotate Left. - - Rotate bits of \c t to the left \c i times. - The argument must have a bit-vector sort. - *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) - - (** - Rotate Right. - - Rotate bits of \c t to the right \c i times. - The argument must have a bit-vector sort. - *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) - - (** - Rotate Left. - - Rotate bits of to the left times. - The arguments must have the same bit-vector sort. - *) - let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) - - (** - Rotate Right. - - - Rotate bits of to the right times. - The arguments must have the same bit-vector sort. - *) - let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) - - (** - Create an integer from the bit-vector argument . - - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where - N are the number of bits in . - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of bit-vector sort. - *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) - - (** - Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - - (** - Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. - *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. - *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) - - (** - Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) - - (** - Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - - (** - Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. - *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a bit-vector numeral. - - @param v A string representing the value in decimal notation. - @param size the size of the bit-vector - *) let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) end -(** Functions to manipulate proof expressions *) + module Proof = struct - (** - Indicates whether the term is a Proof for the expression 'true'. - *) let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - - (** - Indicates whether the term is a proof for a fact asserted by the user. - *) let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - - (** - Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. - *) let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - - (** - Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). - *) let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - - (** - Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. - *) let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - - (** - Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. - *) let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - - (** - Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) - *) let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - - (** - Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. - *) let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - - - (** - Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. - *) let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - - (** - Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - *) let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - - (** - Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. - *) let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - - (** - Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i - *) let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - - (** - Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) - *) let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - - (** - Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) - *) let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - - (** - Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - *) let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - - (** - Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - *) let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - - (** - Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents - *) let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - - (** - Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents - *) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - - (** - Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. - *) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - - (** - Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. - *) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - - (** - Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) - *) let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - - (** - Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. - *) let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - - (** - Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. - *) let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - - (** - Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - *) let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - - (** - Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) - *) let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - - (** - Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) - *) let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - - (** - Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. - *) let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - - (** - Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). - *) let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - - (** - Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) - *) let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - - (** - Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. - *) let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - - (** - Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) - *) let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - - (** - Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. - *) let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - - (** - Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) - *) let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - - (** - Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - - (** - Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - - (** - Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. - *) let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - - (** - Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q - *) let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - - (** - Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - *) let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end -(** Goals - - A goal (aka problem). A goal is essentially a - of formulas, that can be solved and/or transformed using - tactics and solvers. *) module Goal = struct type goal = z3_native_object @@ -4386,76 +2536,52 @@ struct (z3obj_create res) ; res - - (** The precision of the goal. - - Goals can be transformed using over and under approximations. - An under approximation is applied when the objective is to find a model for a given goal. - An over approximation is applied when the objective is to find a proof for a given goal. - *) let get_precision ( x : goal ) = goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) - (** Indicates whether the goal is precise. *) let is_precise ( x : goal ) = (get_precision x) == GOAL_PRECISE - (** Indicates whether the goal is an under-approximation. *) let is_underapproximation ( x : goal ) = (get_precision x) == GOAL_UNDER - (** Indicates whether the goal is an over-approximation. *) let is_overapproximation ( x : goal ) = (get_precision x) == GOAL_OVER - (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - (** Adds the constraints to the given goal. *) - (* CMW: assert seems to be a keyword. *) let assert_ ( x : goal ) ( constraints : Boolean.bool_expr array ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in ignore (Array.map f constraints) ; () - (** Indicates whether the goal contains `false'. *) let is_inconsistent ( x : goal ) = Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) - (** The depth of the goal. - This tracks how many transformations were applied to it. *) let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) - (** Erases all formulas from the given goal. *) let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) - (** The number of formulas in the goal. *) let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) - (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in Array.init n f - (** The number of formulas, subformulas and terms in the goal. *) let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) - (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) let is_decided_sat ( x : goal ) = Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) - (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) let is_decided_unsat ( x : goal ) = Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) - (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) let simplify ( x : goal ) ( p : Params.params option ) = let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in Z3native.tactic_inc_ref (z3obj_gnc x) tn ; @@ -4473,27 +2599,13 @@ struct Z3native.tactic_dec_ref (z3obj_gnc x) tn ; create (z3obj_gc x) res - - (** - Creates a new Goal. - - Note that the Context must have been created with proof generation support if - is set to true here. - @param models Indicates whether model generation should be enabled. - @param unsat_cores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) - (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) module Model = struct type model = z3_native_object @@ -4507,12 +2619,6 @@ struct (z3obj_create res) ; res - - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. - *) module FuncInterp = struct type func_interp = z3_native_object @@ -4526,11 +2632,6 @@ struct (z3obj_create res) ; res - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) module FuncEntry = struct type func_entry = z3_native_object @@ -4544,61 +2645,33 @@ struct (z3obj_create res) ; res - - (** - Return the (symbolic) value of this entry. - *) let get_value ( x : func_entry ) = expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) - (** - The number of arguments of the entry. - *) let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) - (** - The arguments of the function entry. - *) let get_args ( x : func_entry ) = let n = (get_num_args x) in let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f - (** - A string representation of the function entry. - *) let to_string ( x : func_entry ) = let a = (get_args x) in let f c p = (p ^ (Expr.to_string c) ^ ", ") in "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") end - (** - The number of entries in the function interpretation. - *) let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) - (** - The entries in the function interpretation - *) let get_entries ( x : func_interp ) = let n = (get_num_entries x) in let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f - (** - The (symbolic) `else' value of the function interpretation. - *) let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) - (** - The arity of the function interpretation - *) let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) - (** - A string representation of the function interpretation. - *) let to_string ( x : func_interp ) = let f c p = ( let n = (FuncEntry.get_num_args c) in @@ -4613,9 +2686,6 @@ struct Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") end - (** Retrieves the interpretation (the assignment) of in the model. - A function declaration of zero arity - An expression if the function has an interpretation in the model, null otherwise. *) let get_const_interp ( x : model ) ( f : func_decl ) = if (FuncDecl.get_arity f) != 0 || (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then @@ -4627,16 +2697,9 @@ struct else Some (expr_of_ptr (z3obj_gc x) np) - (** Retrieves the interpretation (the assignment) of in the model. - A Constant - An expression if the constant has an interpretation in the model, null otherwise. - *) let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - (** Retrieves the interpretation (the assignment) of a non-constant in the model. - A function declaration of non-zero arity - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) let rec get_func_interp ( x : model ) ( f : func_decl ) = let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in if (FuncDecl.get_arity f) == 0 then @@ -4659,23 +2722,18 @@ struct (** The number of constants that have an interpretation in the model. *) let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) - (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - - (** The number of function interpretations in the model. *) let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) - (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in @@ -4683,24 +2741,8 @@ struct let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) exception ModelEvaluationFailedException of string - (** - Evaluates the expression in the current model. - - - This function may fail if contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - - An expression - - When this flag is enabled, a model value will be assigned to any constant - or function that does not have an interpretation in the model. - - The evaluation of in the model. - *) let eval ( x : model ) ( t : expr ) ( completion : bool ) = let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (ptr_of_expr t) completion) in if not r then @@ -4708,53 +2750,26 @@ struct else expr_of_ptr (z3obj_gc x) v - (** Alias for eval. *) let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = eval x t completion - (** The number of uninterpreted sorts that the model has an interpretation for. *) let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - - - *) let get_sorts ( x : model ) = let n = (get_num_sorts x) in let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f - - (** The finite set of distinct values that represent the interpretation for sort . - - An uninterpreted sort - An array of expressions, where each is an element of the universe of - *) let sort_universe ( x : model ) ( s : sort ) = let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f - - (** Conversion of models to strings. - A string representation of the model. - *) + let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) module Probe = struct type probe = z3_native_object @@ -4769,114 +2784,52 @@ struct res - (** - Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - *) let apply ( x : probe ) ( g : Goal.goal ) = Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) - (** - The number of supported Probes. - *) let get_num_probes ( ctx : context ) = Z3native.get_num_probes (context_gno ctx) - (** - The names of all supported Probes. - *) let get_probe_names ( ctx : context ) = let n = (get_num_probes ctx) in let f i = (Z3native.get_probe_name (context_gno ctx) i) in Array.init n f - (** - Returns a string containing a description of the probe with the given name. - *) let get_probe_description ( ctx : context ) ( name : string ) = Z3native.probe_get_descr (context_gno ctx) name - (** - Creates a new Probe. - *) let mk_probe ( ctx : context ) ( name : string ) = (create ctx (Z3native.mk_probe (context_gno ctx) name)) - (** - Create a probe that always evaluates to . - *) let const ( ctx : context ) ( v : float ) = (create ctx (Z3native.probe_const (context_gno ctx) v)) - (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by - *) let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by - *) let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by - *) let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by - *) let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by - *) let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". - *) - (* CMW: and is a keyword *) let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". - *) - (* CMW: or is a keyword *) let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". - *) - (* CMW: is not a keyword? *) let not_ ( ctx : context ) ( p : probe ) = (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) end -(** Tactics - - Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using Context.get_num_tactics - and Context.get_tactic_names. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) module Tactic = struct type tactic = z3_native_object @@ -4890,11 +2843,6 @@ struct (z3obj_create res) ; res - - (** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult = struct type apply_result = z3_native_object @@ -4908,75 +2856,46 @@ struct (z3obj_create res) ; res - - (** The number of Subgoals. *) let get_num_subgoals ( x : apply_result ) = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) - (** Retrieves the subgoals from the apply_result. *) let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** Retrieves the subgoals from the apply_result. *) let get_subgoal ( x : apply_result ) ( i : int ) = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) - (** Convert a model for the subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g - *) let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) - (** A string representation of the ApplyResult. *) let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) end - (** A string containing a description of parameters accepted by the tactic. *) let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) - (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - (** Apply the tactic to the goal. *) let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) - (** - The number of supported tactics. - *) let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) - (** - The names of all supported tactics. - *) let get_tactic_names ( ctx : context ) = let n = (get_num_tactics ctx ) in let f i = (Z3native.get_tactic_name (context_gno ctx) i) in Array.init n f - - (** - Returns a string containing a description of the tactic with the given name. - *) let get_tactic_description ( ctx : context ) ( name : string ) = Z3native.tactic_get_descr (context_gno ctx) name - (** - Creates a new Tactic. - *) let mk_tactic ( ctx : context ) ( name : string ) = create ctx (Z3native.mk_tactic (context_gno ctx) name) - (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . - *) let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = let f p c = (match p with | None -> (Some (z3obj_gno c)) @@ -4988,106 +2907,50 @@ struct let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) - (** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. - *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - (** - Create a tactic that applies to a goal for milliseconds. - - If does not terminate within milliseconds, then it fails. - *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) - (** - Create a tactic that applies to a given goal if the probe - evaluates to true. - - If evaluates to false, then the new tactic behaves like the skip tactic. - *) - (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) - (** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. - *) let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) - (** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. - *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) - (** - Create a tactic that just returns the given goal. - *) let skip ( ctx : context ) = create ctx (Z3native.tactic_skip (context_gno ctx)) - (** - Create a tactic always fails. - *) let fail ( ctx : context ) = create ctx (Z3native.tactic_fail (context_gno ctx)) - (** - Create a tactic that fails if the probe evaluates to false. - *) let fail_if ( ctx : context ) ( p : Probe.probe ) = create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) - (** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). - *) let fail_if_not_decided ( ctx : context ) = create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) - (** - Create a tactic that applies using the given set of parameters . - *) let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) - (** - Create a tactic that applies using the given set of parameters . - Alias for UsingParams*) - (* CMW: with is a keyword *) let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p - (** - Create a tactic that applies the given tactics in parallel. - *) let par_or ( ctx : context ) ( t : tactic array ) = create ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) - (** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. - *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - (** - Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. - *) let interrupt ( ctx : context ) = Z3native.interrupt (context_gno ctx) end -(** Solvers *) module Solver = struct type solver = z3_native_object @@ -5102,13 +2965,11 @@ struct (z3obj_create res) ; res - let string_of_status ( s : status) = match s with | UNSATISFIABLE -> "unsatisfiable" | SATISFIABLE -> "satisfiable" | _ -> "unknown" - (** Objects that track statistical information about solvers. *) module Statistics = struct type statistics = z3_native_object @@ -5123,11 +2984,6 @@ struct res - (** - Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - - *) module Entry = struct type statistics_entry = { @@ -5158,22 +3014,11 @@ struct res - (** The key of the entry. *) let get_key (x : statistics_entry) = x.m_key - - (** The int-value of the entry. *) - let get_int (x : statistics_entry) = x.m_int - - (** The float-value of the entry. *) + let get_int (x : statistics_entry) = x.m_int let get_float (x : statistics_entry) = x.m_float - - (** True if the entry is uint-valued. *) let is_int (x : statistics_entry) = x.m_is_int - - (** True if the entry is double-valued. *) let is_float (x : statistics_entry) = x.m_is_float - - (** The string representation of the the entry's value. *) let to_string_value (x : statistics_entry) = if (is_int x) then string_of_int (get_int x) @@ -5181,18 +3026,13 @@ struct string_of_float (get_float x) else raise (Z3native.Exception "Unknown statistical entry type") - - (** The string representation of the entry (key and value) *) let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) end - (** A string representation of the statistical data. *) let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) - (** The number of statistical data. *) let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) - (** The data entries. *) let get_entries ( x : statistics ) = let n = (get_size x ) in let f i = ( @@ -5204,129 +3044,56 @@ struct ) in Array.init n f - (** - The statistical counters. - *) let get_keys ( x : statistics ) = let n = (get_size x) in let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** The value of a particular statistical counter. *) let get ( x : statistics ) ( key : string ) = let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in Array.fold_left f None (get_entries x) end - (** - A string that describes all available solver parameters. - *) let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) - (** - Sets the solver parameters. - *) let set_parameters ( x : solver ) ( p : Params.params )= Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - (** - Retrieves parameter descriptions for solver. - *) let get_param_descrs ( x : solver ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - (** - The current number of backtracking points (scopes). - - - *) let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) - (** - Creates a backtracking point. - - *) let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) - (** - Backtracks backtracking points. - Note that an exception is thrown if is not smaller than NumScopes - - *) let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n - (** - Resets the Solver. - This removes all assertions from the solver. - *) let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - (** - Assert a constraint (or multiple) into the solver. - *) let assert_ ( x : solver ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) - (** - * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using - * and the Boolean literals - * provided using with assumptions. - *) - let assert_and_track ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = + let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) (Boolean.gno (Array.get ps i))) in ignore (Array.iteri f cs) - (** - * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using - * and the Boolean literals - * provided using with assumptions. - *) let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) - (** - The number of assertions in the solver. - *) let get_num_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) - - (** - The set of asserted formulas. - *) let get_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in Array.init n f - (** - Checks whether the assertions in the solver are consistent or not. - - - - - *) let check ( x : solver ) ( assumptions : Boolean.bool_expr array) = let r = if ((Array.length assumptions) == 0) then @@ -5340,12 +3107,6 @@ struct | L_FALSE -> UNSATISFIABLE | _ -> UNKNOWN - (** - The model of the last Check. - - The result is None if Check was not invoked before, - if its results was not SATISFIABLE, or if model production is not enabled. - *) let get_model ( x : solver ) = let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then @@ -5353,12 +3114,6 @@ struct else Some (Model.create (z3obj_gc x) q) - (** - The proof of the last Check. - - The result is null if Check was not invoked before, - if its results was not UNSATISFIABLE, or if proof production is disabled. - *) let get_proof ( x : solver ) = let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then @@ -5366,73 +3121,35 @@ struct else Some (expr_of_ptr (z3obj_gc x) q) - (** - The unsat core of the last Check. - - The unsat core is a subset of Assertions - The result is empty if Check was not invoked before, - if its results was not UNSATISFIABLE, or if core production is disabled. - *) let get_unsat_core ( x : solver ) = let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f - (** - A brief justification of why the last call to Check returned UNKNOWN. - *) let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - (** - Solver statistics. - *) let get_statistics ( x : solver ) = (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) - (** - Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. - *) let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) - (** - Creates a new (incremental) solver. - - *) let mk_solver_s ( ctx : context ) ( logic : string ) = mk_solver ctx (Some (Symbol.mk_string ctx logic)) - (** - Creates a new (incremental) solver. - *) let mk_simple_solver ( ctx : context ) = (create ctx (Z3native.mk_simple_solver (context_gno ctx))) - (** - Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. - *) let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) - (** - A string representation of the solver. - *) let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Fixedpoint solving *) module Fixedpoint = struct type fixedpoint = z3_native_object @@ -5447,70 +3164,37 @@ struct res - (** - A string that describes all available fixedpoint solver parameters. - *) let get_help ( x : fixedpoint ) = Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) - (** - Sets the fixedpoint solver parameters. - *) let set_params ( x : fixedpoint ) ( p : Params.params )= Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - (** - Retrieves parameter descriptions for Fixedpoint solver. - *) let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - (** - Assert a constraints into the fixedpoint solver. - *) let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) ; () - (** - Register predicate as recursive relation. - *) let register_relation ( x : fixedpoint ) ( f : func_decl ) = Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - (** - Add rule into the fixedpoint solver. - *) let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = match name with | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) - (** - Add table fact to the fixedpoint solver. - *) let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args - (** - Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. - *) let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN - (** - Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. - *) let query_r ( x : fixedpoint ) ( relations : func_decl array ) = let f x = ptr_of_ast (ast_of_func_decl x) in match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with @@ -5518,32 +3202,15 @@ struct | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN - (** - Creates a backtracking point. - - *) let push ( x : fixedpoint ) = Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) - (** - Backtrack one backtracking point. - - Note that an exception is thrown if Pop is called without a corresponding Push - - *) let pop ( x : fixedpoint ) = Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - (** - Update named rule into in the fixedpoint solver. - *) let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) - (** - Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. - *) let get_answer ( x : fixedpoint ) = let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in if (Z3native.is_null q) then @@ -5551,21 +3218,12 @@ struct else Some (expr_of_ptr (z3obj_gc x) q) - (** - Retrieve explanation why fixedpoint engine returned status Unknown. - *) let get_reason_unknown ( x : fixedpoint ) = Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - (** - Retrieve the number of levels explored for a given predicate. - *) let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) - (** - Retrieve the cover of a predicate. - *) let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in if (Z3native.is_null q) then @@ -5573,82 +3231,40 @@ struct else Some (expr_of_ptr (z3obj_gc x) q) - (** - Add property about the predicate. - The property is added at level. - *) let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (ptr_of_expr property) - (** - Retrieve internal string representation of fixedpoint object. - *) let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - (** - Instrument the Datalog engine on which table representation to use for recursive predicate. - *) let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = let f2 x = (Symbol.gno x) in Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) - (** - Convert benchmark given as set of axioms, rules and queries to a string. - *) let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr array ) = let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) - (** - Retrieve set of rules added to fixedpoint context. - *) let get_rules ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f - (** - Retrieve set of assertions added to fixedpoint context. - *) let get_assertions ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f - (** - Create a Fixedpoint context. - *) let mk_fixedpoint ( ctx : context ) = create ctx end -(** Global and context options - - Note: This module contains functions that set parameters/options for context - objects as well as functions that set options that are used globally, across - contexts.*) module Options = struct - (** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - - *) let update_param_value ( ctx : context ) ( id : string) ( value : string )= Z3native.update_param_value (context_gno ctx) id value - (** - Get a configuration parameter. - - Returns None if the parameter value does not exist. - - *) let get_param_value ( ctx : context ) ( id : string ) = let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in if not r then @@ -5656,62 +3272,21 @@ struct else Some v - (** - Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - - - - - *) let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) - (** - Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. - *) let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled end -(** Functions for handling SMT and SMT2 expressions and files *) + module SMT = struct - (** - Convert a benchmark into an SMT-LIB formatted string. - - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - *) let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr array ) ( formula : Boolean.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes (Array.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.map f assumptions)) (Boolean.gno formula) - (** - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. - *) let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5728,10 +3303,6 @@ struct (let f x = Symbol.gno x in (Array.map f decl_names)) (let f x = FuncDecl.gno x in (Array.map f decls)) - (** - Parse the given file using the SMT-LIB parser. - - *) let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5748,65 +3319,34 @@ struct (let f x = Symbol.gno x in (Array.map f decl_names)) (let f x = FuncDecl.gno x in (Array.map f decls)) - (** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) - (** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in Array.init n f - - (** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) - (** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in Array.init n f - (** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) - (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f - (** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - - (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) + let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f - (** - Parse the given string using the SMT-LIB2 parser. - - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - *) let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5823,10 +3363,6 @@ struct (let f x = Symbol.gno x in (Array.map f decl_names)) (let f x = FuncDecl.gno x in (Array.map f decls)))) - (** - Parse the given file using the SMT-LIB2 parser. - - *) let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5845,34 +3381,9 @@ struct end -(* Global functions *) - -(** - * Set a global (or module) parameter, which is shared by all Z3 contexts. - * - * When a Z3 module is initialized it will use the value of these parameters - * when Z3_params objects are not provided. - * The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. - * The character '.' is a delimiter (more later). - * The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. - * Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". - * This function can be used to set parameters for a specific Z3 module. - * This can be done by using .. - * For example: - * (set_global_param "pp.decimal" "true") - * will set the parameter "decimal" in the module "pp" to true. -*) let set_global_param ( id : string ) ( value : string ) = (Z3native.global_param_set id value) -(** - * Get a global (or module) parameter. - * - * Returns None if the parameter does not exist. - * The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. - * This function cannot be invoked simultaneously from different threads without synchronization. - * The result string stored in param_value is stored in a shared location. -*) let get_global_param ( id : string ) = let (r, v) = (Z3native.global_param_get id) in if not r then @@ -5880,11 +3391,5 @@ let get_global_param ( id : string ) = else Some v -(** - * Restore the value of all global (and module) parameters. - * - * This command will not affect already created objects (such as tactics and solvers) - * -*) let global_param_reset_all = Z3native.global_param_reset_all From a0f6d1d3dfcab9f5c8b79a1aaa2fba8d9ee67f42 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 00:29:51 +0000 Subject: [PATCH 284/507] ML API: replaced arrays with lists. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 46 ++-- src/api/ml/z3.ml | 507 +++++++++++++++++++------------------- 2 files changed, 279 insertions(+), 274 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 6dfe11623..31f31d566 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -33,13 +33,13 @@ let model_converter_test ( ctx : context ) = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [| (mk_gt ctx xr + (Goal.assert_ g4 [ (mk_gt ctx xr (arith_expr_of_real_expr (real_expr_of_rat_num - (Real.mk_numeral_nd ctx 10 1)))) |]) ; - (Goal.assert_ g4 [| (mk_eq ctx + (Real.mk_numeral_nd ctx 10 1)))) ]) ; + (Goal.assert_ g4 [ (mk_eq ctx (expr_of_arith_expr yr) - (expr_of_arith_expr (Arithmetic.mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |]) ) ) |] ) ; - (Goal.assert_ g4 [| (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) |]) ; + (expr_of_arith_expr (Arithmetic.mk_add ctx [ xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) ]) ) ) ] ) ; + (Goal.assert_ g4 [ (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) ]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -50,7 +50,7 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ); ( - let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") [||]) g4 None) in + let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") []) g4 None) in if ((get_num_subgoals ar) == 1 && ((is_decided_sat (get_subgoal ar 0)) || (is_decided_unsat (get_subgoal ar 0)))) then @@ -59,9 +59,9 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ; let solver = (mk_solver ctx None) in - let f e = (Solver.assert_ solver [| e |]) in - ignore (Array.map f (get_formulas (get_subgoal ar 0))) ; - let q = (check solver [||]) in + let f e = (Solver.assert_ solver [ e ]) in + ignore (List.map f (get_formulas (get_subgoal ar 0))) ; + let q = (check solver []) in if q != SATISFIABLE then raise (TestFailedException "") else @@ -84,23 +84,23 @@ let basic_tests ( ctx : context ) = let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in let bs = (sort_of_bool_sort (Boolean.mk_sort ctx)) in - let domain = [| bs; bs |] in + let domain = [ bs; bs ] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in let fapp = (mk_app ctx f - [| (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) |]) in - let fargs2 = [| (mk_fresh_const ctx "cp" bs) |] in - let domain2 = [| bs |] in + [ (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) ]) in + let fargs2 = [ (mk_fresh_const ctx "cp" bs) ] in + let domain2 = [ bs ] in let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in let trivial_eq = (mk_eq ctx fapp fapp) in let nontrivial_eq = (mk_eq ctx fapp fapp2) in let g = (mk_goal ctx true false false) in - (Goal.assert_ g [| trivial_eq |]) ; - (Goal.assert_ g [| nontrivial_eq |]) ; + (Goal.assert_ g [ trivial_eq ]) ; + (Goal.assert_ g [ nontrivial_eq ]) ; Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; ( let solver = (mk_solver ctx None) in - (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; - if (check solver [||]) != SATISFIABLE then + (List.iter (fun a -> (Solver.assert_ solver [ a ])) (get_formulas g)) ; + if (check solver []) != SATISFIABLE then raise (TestFailedException "") else Printf.printf "Test passed.\n" @@ -122,11 +122,11 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ); - (Goal.assert_ g [| (mk_eq ctx + (Goal.assert_ g [ (mk_eq ctx (mk_numeral_int ctx 1 (sort_of_bitvec_sort (BitVector.mk_sort ctx 32))) (mk_numeral_int ctx 2 - (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) |] ) + (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) ] ) ; ( let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in @@ -147,7 +147,7 @@ let basic_tests ( ctx : context ) = ); ( let g2 = (mk_goal ctx true true false) in - (Goal.assert_ g2 [| (Boolean.mk_false ctx) |]) ; + (Goal.assert_ g2 [ (Boolean.mk_false ctx) ]) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then @@ -159,10 +159,10 @@ let basic_tests ( ctx : context ) = let g3 = (mk_goal ctx true true false) in let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in - (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; - (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; + (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; + (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; let constr = (mk_eq ctx xc yc) in - (Goal.assert_ g3 [| constr |] ) ; + (Goal.assert_ g3 [ constr ] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b1e40fcac..56d319c1a 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -79,10 +79,6 @@ struct let z3obj_nil_ref x y = () - let array_to_native a = - let f e = (z3obj_gno e) in - Array.map f a - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> let res : z3_native_object = { m_ctx = ctx ; m_n_obj = null ; @@ -127,6 +123,9 @@ let mk_list ( f : int -> 'a ) ( n : int ) = in mk_list' f 0 n [] +let list_of_array ( x : _ array ) = + let f i = (Array.get x i) in + mk_list f (Array.length x) let mk_context ( cfg : ( string * string ) list ) = create_context cfg @@ -180,6 +179,10 @@ struct match x with | S_Int(n) -> (z3obj_gno n) | S_Str(n) -> (z3obj_gno n) + + let symbol_lton ( a : symbol list ) = + let f ( e : symbol ) = (gno e) in + Array.of_list (List.map f a) let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL @@ -197,13 +200,13 @@ struct let mk_string ( ctx : context ) ( s : string ) = S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - let mk_ints ( ctx : context ) ( names : int array ) = + let mk_ints ( ctx : context ) ( names : int list ) = let f elem = mk_int ( ctx : context ) elem in - (Array.map f names) + (List.map f names) - let mk_strings ( ctx : context ) ( names : string array ) = + let mk_strings ( ctx : context ) ( names : string list ) = let f elem = mk_string ( ctx : context ) elem in - (Array.map f names) + (List.map f names) end @@ -292,7 +295,9 @@ struct Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) let get_keys ( x : ast_map ) = - ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in + let f i = (ASTVector.get av i) in + mk_list f (ASTVector.get_size av) let to_string ( x : ast_map ) = Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) @@ -376,10 +381,13 @@ struct else UninterpretedSort(s) - let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) + + let sort_lton ( a : sort list ) = + let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) let ( = ) : sort -> sort -> bool = fun a b -> (a == b) || @@ -438,9 +446,9 @@ sig val get_func_decl : parameter -> func_decl val get_rational : parameter -> string end - val mk_func_decl : context -> Symbol.symbol -> Sort.sort array -> Sort.sort -> func_decl - val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl - val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl val mk_const_decl_s : context -> string -> Sort.sort -> func_decl val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl @@ -449,13 +457,13 @@ sig val get_id : func_decl -> int val get_arity : func_decl -> int val get_domain_size : func_decl -> int - val get_domain : func_decl -> Sort.sort array + val get_domain : func_decl -> Sort.sort list val get_range : func_decl -> Sort.sort val get_decl_kind : func_decl -> Z3enums.decl_kind val get_name : func_decl -> Symbol.symbol val get_num_parameters : func_decl -> int val get_parameters : func_decl -> Parameter.parameter list - val apply : func_decl -> Expr.expr array -> Expr.expr + val apply : func_decl -> Expr.expr list -> Expr.expr end = struct type func_decl = FuncDecl of AST.ast @@ -467,23 +475,21 @@ end = struct let ast_of_func_decl f = match f with FuncDecl(x) -> x - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (AST.ptr_of_ast (ast_of_sort x)) in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Array.map f domain) (Sort.gno range))) ; + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (AST.ptr_of_ast (ast_of_sort x)) in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Array.map f domain) (Sort.gno range))) ; + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) @@ -548,23 +554,23 @@ end = struct | _ -> raise (Z3native.Exception "parameter is not a rational string") end - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = create_ndr ctx name domain range - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = create_pdr ctx prefix domain range let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_ndr ctx name [||] range + create_ndr ctx name [] range let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = - create_ndr ctx (Symbol.mk_string ctx name) [||] range + create_ndr ctx (Symbol.mk_string ctx name) [] range let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = - create_pdr ctx prefix [||] range + create_pdr ctx prefix [] range let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || @@ -584,7 +590,7 @@ end = struct let get_domain ( x : func_decl ) = let n = (get_domain_size x) in let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in - Array.init n f + mk_list f n let get_range ( x : func_decl ) = sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) @@ -608,7 +614,7 @@ end = struct ) in mk_list f n - let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.expr_of_func_app (gc x) x args + let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args end @@ -621,7 +627,7 @@ sig val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs val validate : param_descrs -> params -> unit val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - val get_names : param_descrs -> Symbol.symbol array + val get_names : param_descrs -> Symbol.symbol list val get_size : param_descrs -> int val to_string : param_descrs -> string end @@ -660,7 +666,7 @@ end = struct let get_names ( x : param_descrs ) = let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) @@ -710,21 +716,21 @@ sig val c_of_expr : expr -> context val nc_of_expr : expr -> Z3native.ptr val ptr_of_expr : expr -> Z3native.ptr - val expr_aton : expr array -> Z3native.ptr array + val expr_lton : expr list -> Z3native.ptr array val ast_of_expr : expr -> AST.ast val expr_of_ast : AST.ast -> expr - val expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr + val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr val simplify : expr -> Params.params option -> expr val get_simplify_help : context -> string val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs val get_func_decl : expr -> FuncDecl.func_decl val get_bool_value : expr -> Z3enums.lbool val get_num_args : expr -> int - val get_args : expr -> expr array - val update : expr -> expr array -> expr - val substitute : expr -> expr array -> expr array -> expr + val get_args : expr -> expr list + val update : expr -> expr list -> expr + val substitute : expr -> expr list -> expr list -> expr val substitute_one : expr -> expr -> expr -> expr - val substitute_vars : expr -> expr array -> expr + val substitute_vars : expr -> expr list -> expr val translate : expr -> context -> expr val to_string : expr -> string val is_numeral : expr -> bool @@ -750,7 +756,7 @@ sig val mk_const_s : context -> string -> Sort.sort -> expr val mk_const_f : context -> FuncDecl.func_decl -> expr val mk_fresh_const : context -> string -> Sort.sort -> expr - val mk_app : context -> FuncDecl.func_decl -> expr array -> expr + val mk_app : context -> FuncDecl.func_decl -> expr list -> expr val mk_numeral_string : context -> string -> Sort.sort -> expr val mk_numeral_int : context -> int -> Sort.sort -> expr end = struct @@ -786,13 +792,13 @@ end = struct let ast_of_expr e = match e with Expr(a) -> a - let expr_aton ( a : expr array ) = + let expr_lton ( a : expr list ) = let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in - Array.map f a + Array.of_list (List.map f a) - let expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr = fun ctx f args -> + let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> match f with FuncDecl.FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (Array.length args) (expr_aton args) in + let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in expr_of_ptr ctx o let simplify ( x : expr ) ( p : Params.params option ) = match p with @@ -812,25 +818,25 @@ end = struct let get_args ( x : expr ) = let n = (get_num_args x) in let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in - Array.init n f + mk_list f n - let update ( x : expr ) args = - if (Array.length args <> (get_num_args x)) then + let update ( x : expr ) ( args : expr list ) = + if (List.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (Array.length args) (expr_aton args)) + expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (List.length args) (expr_lton args)) let substitute ( x : expr ) from to_ = - if (Array.length from) <> (Array.length to_) then + if (List.length from) <> (List.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (Array.length from) (expr_aton from) (expr_aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (List.length from) (expr_lton from) (expr_lton to_)) let substitute_one ( x : expr ) from to_ = - substitute ( x : expr ) [| from |] [| to_ |] + substitute ( x : expr ) [ from ] [ to_ ] let substitute_vars ( x : expr ) to_ = - expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (Array.length to_) (expr_aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (List.length to_) (expr_lton to_)) let translate ( x : expr ) to_ctx = if (c_of_expr x) == to_ctx then @@ -876,12 +882,12 @@ end = struct let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) range - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [||] + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = expr_of_func_app ctx f args + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) @@ -950,8 +956,8 @@ struct let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) - let mk_distinct ( ctx : context ) ( args : expr array ) = - bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (expr_aton args)) + let mk_distinct ( ctx : context ) ( args : expr list ) = + bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) let mk_not ( ctx : context ) ( a : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) @@ -968,13 +974,13 @@ struct let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - let mk_and ( ctx : context ) ( args : bool_expr array ) = + let mk_and ( ctx : context ) ( args : bool_expr list ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (Array.map f args)) + bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - let mk_or ( ctx : context ) ( args : bool_expr array ) = + let mk_or ( ctx : context ) ( args : bool_expr list ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (Array.map f args)) + bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) end @@ -1016,7 +1022,7 @@ struct let get_terms ( x : pattern ) = let n = (get_num_terms x) in let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) end @@ -1039,26 +1045,26 @@ struct let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_body ( x : quantifier ) = Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) @@ -1066,95 +1072,95 @@ struct let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - let mk_pattern ( ctx : context ) ( terms : expr array ) = - if (Array.length terms) == 0 then + let mk_pattern ( ctx : context ) ( terms : expr list ) = + if (List.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) + Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (Array.length sorts) != (Array.length names) then + let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) (ptr_of_expr body))) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (Array.length sorts) != (Array.length names) then + let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) (ptr_of_expr body))) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -1233,9 +1239,9 @@ struct let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = let m x = (ptr_of_expr (expr_of_array_expr x)) in - array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) + array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) let mk_term_array ( ctx : context ) ( arg : array_expr ) = array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) @@ -1274,11 +1280,11 @@ struct let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) - let mk_union ( ctx : context ) ( args : expr array ) = - expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (expr_aton args)) + let mk_union ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) - let mk_intersection ( ctx : context ) ( args : expr array ) = - expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (expr_aton args)) + let mk_intersection ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) @@ -1378,7 +1384,7 @@ struct let get_column_sorts ( x : relation_sort ) = let n = get_arity x in let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in - Array.init n f + mk_list f n end @@ -1418,21 +1424,23 @@ struct module Constructor = struct type constructor = z3_native_object + + let _sizes = Hashtbl.create 0 - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = - let n = (Array.length field_names) in - if n != (Array.length sorts) then + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let n = (List.length field_names) in + if n != (List.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") else - if n != (Array.length sort_refs) then + if n != (List.length sort_refs) then raise (Z3native.Exception "Number of field names does not match number of sort refs") else let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) n - (let f x = (Symbol.gno x) in (Array.map f field_names)) - (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - sort_refs) in + (Symbol.symbol_lton field_names) + (sort_lton sorts) + (Array.of_list sort_refs)) in let no : constructor = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; @@ -1441,9 +1449,10 @@ struct (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; + Hashtbl.add _sizes no n ; no - let get_num_fields ( x : constructor ) = Z3native.get_arity (z3obj_gnc x) (z3obj_gno x) + let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x let get_constructor_decl ( x : constructor ) = let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in @@ -1455,8 +1464,8 @@ struct let get_accessor_decls ( x : constructor ) = let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - let f y = func_decl_of_ptr (z3obj_gc x) y in - Array.map f c + let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in + mk_list f (Array.length c) end @@ -1464,48 +1473,47 @@ struct struct type constructor_list = z3_native_object - let create ( ctx : context ) ( c : Constructor.constructor array ) = + let create ( ctx : context ) ( c : Constructor.constructor list ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in let f x =(z3obj_gno x) in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Array.map f c))) ; + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; (z3obj_create res) ; let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f res; res end - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = Constructor.create ctx name recognizer field_names sorts sort_refs - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = let f x = (z3obj_gno x) in - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in sort_of_ptr ctx x - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = mk_sort ctx (Symbol.mk_string ctx name) constructors - let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = - let n = (Array.length names) in + let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = + let n = (List.length names) in let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in - let cla = (Array.map f c) in - let f2 x = (Symbol.gno x) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Array.map f2 names) cla) in - let g e = (sort_of_ptr ctx e) in - (Array.map g r) + let cla = (Array.of_list (List.map f c)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in + let g i = (sort_of_ptr ctx (Array.get r i)) in + mk_list g (Array.length r) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in - Array.map f names + List.map f names ) c @@ -1514,12 +1522,12 @@ struct let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in - Array.init n f + mk_list f n let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in - Array.init n f + mk_list f n let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in @@ -1527,9 +1535,9 @@ struct let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in - Array.init ds g + mk_list g ds ) in - Array.init n f + mk_list f n end @@ -1537,7 +1545,7 @@ module Enumeration = struct type enum_sort = EnumSort of sort - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = let s = (sort_of_ptr ctx no) in let res = EnumSort(s) in res @@ -1548,23 +1556,22 @@ struct let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = - let f x = Symbol.gno x in - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in - sort_of_ptr ctx a b c + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in + sort_of_ptr ctx a (list_of_array b) (list_of_array c) - let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) let get_const_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in - Array.init n f + mk_list f n let get_tester_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in - Array.init n f + mk_list f n end @@ -1609,7 +1616,7 @@ struct let get_tail_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) - let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] + let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] end @@ -1627,10 +1634,8 @@ struct let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : sort array ) = - let f x = Symbol.gno x in - let f2 x = ptr_of_ast (ast_of_sort x) in - let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = + let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in sort_of_ptr ctx r let get_mk_decl ( x : tuple_sort ) = @@ -1641,7 +1646,7 @@ struct let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in - Array.init n f + mk_list f n end @@ -1746,9 +1751,9 @@ sig val is_int_numeral : Expr.expr -> bool val is_rat_num : Expr.expr -> bool val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr array -> arith_expr - val mk_mul : context -> arith_expr array -> arith_expr - val mk_sub : context -> arith_expr array -> arith_expr + val mk_add : context -> arith_expr list -> arith_expr + val mk_mul : context -> arith_expr list -> arith_expr + val mk_sub : context -> arith_expr list -> arith_expr val mk_unary_minus : context -> arith_expr -> arith_expr val mk_div : context -> arith_expr -> arith_expr -> arith_expr val mk_power : context -> arith_expr -> arith_expr -> arith_expr @@ -2109,17 +2114,17 @@ end = struct let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) - let mk_add ( ctx : context ) ( t : arith_expr array ) = + let mk_add ( ctx : context ) ( t : arith_expr list ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Array.map f t))) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_mul ( ctx : context ) ( t : arith_expr array ) = + let mk_mul ( ctx : context ) ( t : arith_expr list ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Array.map f t))) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_sub ( ctx : context ) ( t : arith_expr array ) = + let mk_sub ( ctx : context ) ( t : arith_expr list ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Array.map f t))) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) @@ -2551,9 +2556,9 @@ struct let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - let assert_ ( x : goal ) ( constraints : Boolean.bool_expr array ) = + let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in - ignore (Array.map f constraints) ; + ignore (List.map f constraints) ; () let is_inconsistent ( x : goal ) = @@ -2569,7 +2574,7 @@ struct let n = get_size x in let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in - Array.init n f + mk_list f n let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) @@ -2653,12 +2658,12 @@ struct let get_args ( x : func_entry ) = let n = (get_num_args x) in let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in - Array.init n f + mk_list f n let to_string ( x : func_entry ) = let a = (get_args x) in let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") end let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) @@ -2666,7 +2671,7 @@ struct let get_entries ( x : func_interp ) = let n = (get_num_entries x) in let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in - Array.init n f + mk_list f n let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) @@ -2678,12 +2683,12 @@ struct p ^ let g c p = (p ^ (Expr.to_string c) ^ ", ") in (if n > 1 then "[" else "") ^ - (Array.fold_right + (List.fold_right g (FuncEntry.get_args c) ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") end let get_const_interp ( x : model ) ( f : func_decl ) = @@ -2725,21 +2730,21 @@ struct let get_const_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) let get_func_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - Array.append (Array.init n_funcs f) (Array.init n_consts g) + (mk_list f n_funcs) @ (mk_list g n_consts) exception ModelEvaluationFailedException of string @@ -2758,13 +2763,13 @@ struct let get_sorts ( x : model ) = let n = (get_num_sorts x) in let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in - Array.init n f + mk_list f n let sort_universe ( x : model ) ( s : sort ) = let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in - Array.init n f + mk_list f n let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) end @@ -2793,7 +2798,7 @@ struct let get_probe_names ( ctx : context ) = let n = (get_num_probes ctx) in let f i = (Z3native.get_probe_name (context_gno ctx) i) in - Array.init n f + mk_list f n let get_probe_description ( ctx : context ) ( name : string ) = Z3native.probe_get_descr (context_gno ctx) name @@ -2862,7 +2867,7 @@ struct let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_subgoal ( x : apply_result ) ( i : int ) = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) @@ -2888,7 +2893,7 @@ struct let get_tactic_names ( ctx : context ) = let n = (get_num_tactics ctx ) in let f i = (Z3native.get_tactic_name (context_gno ctx) i) in - Array.init n f + mk_list f n let get_tactic_description ( ctx : context ) ( name : string ) = Z3native.tactic_get_descr (context_gno ctx) name @@ -2896,11 +2901,11 @@ struct let mk_tactic ( ctx : context ) ( name : string ) = create ctx (Z3native.mk_tactic (context_gno ctx) name) - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = let f p c = (match p with | None -> (Some (z3obj_gno c)) | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in - match (Array.fold_left f None ts) with + match (List.fold_left f None ts) with | None -> create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) | Some(x) -> @@ -2940,8 +2945,9 @@ struct let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p - let par_or ( ctx : context ) ( t : tactic array ) = - create ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) + let par_or ( ctx : context ) ( t : tactic list ) = + let f e = (z3obj_gno e) in + create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) @@ -3042,16 +3048,16 @@ struct else (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in - Array.init n f + mk_list f n let get_keys ( x : statistics ) = let n = (get_size x) in let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get ( x : statistics ) ( key : string ) = let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in - Array.fold_left f None (get_entries x) + List.fold_left f None (get_entries x) end let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) @@ -3070,16 +3076,16 @@ struct let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - let assert_ ( x : solver ) ( constraints : Boolean.bool_expr array ) = + let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (Array.map f constraints) + ignore (List.map f constraints) - let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = - if ((Array.length cs) != (Array.length ps)) then + let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = + if ((List.length cs) != (List.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) (Boolean.gno (Array.get ps i))) in - ignore (Array.iteri f cs) + let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in + ignore (List.iter2 f cs ps) let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) @@ -3092,15 +3098,15 @@ struct let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in - Array.init n f + mk_list f n - let check ( x : solver ) ( assumptions : Boolean.bool_expr array) = + let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = let r = - if ((Array.length assumptions) == 0) then + if ((List.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else let f x = (ptr_of_expr (Boolean.expr_of_bool_expr x)) in - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Array.map f assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) in match r with | L_TRUE -> SATISFIABLE @@ -3125,7 +3131,7 @@ struct let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in - Array.init n f + mk_list f n let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) @@ -3173,9 +3179,9 @@ struct let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr array ) = + let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (Array.map f constraints) ; + ignore (List.map f constraints) ; () let register_relation ( x : fixedpoint ) ( f : func_decl ) = @@ -3186,8 +3192,8 @@ struct | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with @@ -3195,9 +3201,9 @@ struct | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN - let query_r ( x : fixedpoint ) ( relations : func_decl array ) = + let query_r ( x : fixedpoint ) ( relations : func_decl list ) = let f x = ptr_of_ast (ast_of_func_decl x) in - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -3236,25 +3242,24 @@ struct let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = - let f2 x = (Symbol.gno x) in - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr array ) = + let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) let get_rules ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - Array.init n f + mk_list f n let get_assertions ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - Array.init n f + mk_list f n let mk_fixedpoint ( ctx : context ) = create ctx end @@ -3282,102 +3287,102 @@ end module SMT = struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr array ) ( formula : Boolean.bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.map f assumptions)) + (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) (Boolean.gno formula) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Z3native.parse_smtlib_string (context_gno ctx) str cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in - Array.init n f + mk_list f n let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in - Array.init n f + mk_list f n let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in - Array.init n f + mk_list f n let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in - Array.init n f + mk_list f n - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) end From 6417f9e64815f98a59693146f1bc8d6b5c57a2d8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 13:25:31 +0000 Subject: [PATCH 285/507] ML API: flat & rich layer in place. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 40 +- src/api/ml/z3.ml | 1458 ++++------------ src/api/ml/z3_rich.ml | 3400 +++++++++++++++++++++++++++++++++++++ src/api/ml/z3_rich.mli | 3072 +++++++++++++++++++++++++++++++++ 4 files changed, 6865 insertions(+), 1105 deletions(-) create mode 100644 src/api/ml/z3_rich.ml create mode 100644 src/api/ml/z3_rich.mli diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 31f31d566..823a08fe2 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -26,20 +26,14 @@ exception TestFailedException of string *) let model_converter_test ( ctx : context ) = Printf.printf "ModelConverterTest\n"; - let xr = (arith_expr_of_expr - (Expr.mk_const ctx (Symbol.mk_string ctx "x") - (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in - let yr = (arith_expr_of_expr - (Expr.mk_const ctx (Symbol.mk_string ctx "y") - (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in + let xr = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Real.mk_sort ctx)) in + let yr = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Real.mk_sort ctx)) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [ (mk_gt ctx xr - (arith_expr_of_real_expr (real_expr_of_rat_num - (Real.mk_numeral_nd ctx 10 1)))) ]) ; + (Goal.assert_ g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; (Goal.assert_ g4 [ (mk_eq ctx - (expr_of_arith_expr yr) - (expr_of_arith_expr (Arithmetic.mk_add ctx [ xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) ]) ) ) ] ) ; - (Goal.assert_ g4 [ (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) ]) ; + yr + (Arithmetic.mk_add ctx [ xr; (Real.mk_numeral_nd ctx 1 1) ])) ]) ; + (Goal.assert_ g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -83,7 +77,7 @@ let basic_tests ( ctx : context ) = let fname = (mk_string ctx "f") in let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in - let bs = (sort_of_bool_sort (Boolean.mk_sort ctx)) in + let bs = (Boolean.mk_sort ctx) in let domain = [ bs; bs ] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in let fapp = (mk_app ctx f @@ -123,10 +117,8 @@ let basic_tests ( ctx : context ) = Printf.printf "Test passed.\n" ); (Goal.assert_ g [ (mk_eq ctx - (mk_numeral_int ctx 1 - (sort_of_bitvec_sort (BitVector.mk_sort ctx 32))) - (mk_numeral_int ctx 2 - (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) ] ) + (mk_numeral_int ctx 1 (BitVector.mk_sort ctx 32)) + (mk_numeral_int ctx 2 (BitVector.mk_sort ctx 32))) ] ) ; ( let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in @@ -157,10 +149,10 @@ let basic_tests ( ctx : context ) = ); ( let g3 = (mk_goal ctx true true false) in - let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in - let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in - (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; - (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; + let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Integer.mk_sort ctx)) in + let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Integer.mk_sort ctx)) in + (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; + (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; let constr = (mk_eq ctx xc yc) in (Goal.assert_ g3 [ constr ] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in @@ -228,9 +220,9 @@ let _ = let rs = (Real.mk_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string is); Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string (sort_of_bool_sort bs)); - Printf.printf "int sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_int_sort ints))); - Printf.printf "real sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_real_sort rs))); + Printf.printf "bool sort: %s\n" (Sort.to_string bs); + Printf.printf "int sort: %s\n" (Sort.to_string ints); + Printf.printf "real sort: %s\n" (Sort.to_string rs); basic_tests ctx ; Printf.printf "Disposing...\n"; Gc.full_major () diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 56d319c1a..0676f1a39 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -133,52 +133,34 @@ let mk_context ( cfg : ( string * string ) list ) = module Symbol = struct - (* Symbol types *) - type int_symbol = z3_native_object - type string_symbol = z3_native_object - - type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - + type symbol = z3_native_object let create_i ( ctx : context ) ( no : Z3native.ptr ) = - let res : int_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in + let res : symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + let create_s ( ctx : context ) ( no : Z3native.ptr ) = - let res : string_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in + let res : symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; (z3obj_create res) ; res let create ( ctx : context ) ( no : Z3native.ptr ) = match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> S_Int (create_i ctx no) - | STRING_SYMBOL -> S_Str (create_s ctx no) + | INT_SYMBOL -> (create_i ctx no) + | STRING_SYMBOL -> (create_s ctx no) - let gc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gc n) - | S_Str(n) -> (z3obj_gc n) - - let gnc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gnc n) - | S_Str(n) -> (z3obj_gnc n) - - let gno ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gno n) - | S_Str(n) -> (z3obj_gno n) + let gc ( x : symbol ) = (z3obj_gc x) + let gnc ( x : symbol ) = (z3obj_gnc x) + let gno ( x : symbol ) = (z3obj_gno x) let symbol_lton ( a : symbol list ) = let f ( e : symbol ) = (gno e) in @@ -187,18 +169,18 @@ struct let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) + let get_int (o : symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) + let get_string (o : symbol ) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) let to_string ( o : symbol ) = match (kind o) with | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) let mk_int ( ctx : context ) ( i : int ) = - S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) let mk_string ( ctx : context ) ( s : string ) = - S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) let mk_ints ( ctx : context ) ( names : int list ) = let f elem = mk_int ( ctx : context ) elem in @@ -353,7 +335,6 @@ open AST module Sort = struct type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> let q = (z3_native_object_of_ast_ptr ctx no) in @@ -373,14 +354,7 @@ struct | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") let ast_of_sort s = match s with Sort(x) -> x - let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x - - let uninterpreted_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - UninterpretedSort(s) - + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) @@ -409,7 +383,7 @@ struct dec_ref = Z3native.dec_ref } in (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; (z3obj_create res) ; - UninterpretedSort(Sort(res)) + Sort(res) let mk_uninterpreted_s ( ctx : context ) ( s : string ) = mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) @@ -713,9 +687,9 @@ and Expr : sig type expr = Expr of AST.ast val expr_of_ptr : context -> Z3native.ptr -> expr - val c_of_expr : expr -> context - val nc_of_expr : expr -> Z3native.ptr - val ptr_of_expr : expr -> Z3native.ptr + val gc : expr -> context + val gnc : expr -> Z3native.ptr + val gno : expr -> Z3native.ptr val expr_lton : expr list -> Z3native.ptr array val ast_of_expr : expr -> AST.ast val expr_of_ast : AST.ast -> expr @@ -762,9 +736,9 @@ sig end = struct type expr = Expr of AST.ast - let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) - let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) - let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + let gc e = match e with Expr(a) -> (z3obj_gc a) + let gnc e = match e with Expr(a) -> (z3obj_gnc a) + let gno e = match e with Expr(a) -> (z3obj_gno a) let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then @@ -802,60 +776,60 @@ end = struct expr_of_ptr ctx o let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) - | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) + | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (gnc x) (gno x)) + | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) let get_simplify_help ( ctx : context ) = Z3native.simplify_get_help (context_gno ctx) let get_simplify_parameter_descrs ( ctx : context ) = Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (nc_of_expr x) (ptr_of_expr x)) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) - let get_num_args ( x : expr ) = Z3native.get_app_num_args (nc_of_expr x) (ptr_of_expr x) + let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in + let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in mk_list f n let update ( x : expr ) ( args : expr list ) = if (List.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (List.length args) (expr_lton args)) + expr_of_ptr (Expr.gc x) (Z3native.update_term (gnc x) (gno x) (List.length args) (expr_lton args)) let substitute ( x : expr ) from to_ = if (List.length from) <> (List.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (List.length from) (expr_lton from) (expr_lton to_)) + expr_of_ptr (Expr.gc x) (Z3native.substitute (gnc x) (gno x) (List.length from) (expr_lton from) (expr_lton to_)) let substitute_one ( x : expr ) from to_ = substitute ( x : expr ) [ from ] [ to_ ] let substitute_vars ( x : expr ) to_ = - expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (List.length to_) (expr_lton to_)) + expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (gnc x) (gno x) (List.length to_) (expr_lton to_)) let translate ( x : expr ) to_ctx = - if (c_of_expr x) == to_ctx then + if (Expr.gc x) == to_ctx then x else - expr_of_ptr to_ctx (Z3native.translate (nc_of_expr x) (ptr_of_expr x) (context_gno to_ctx)) + expr_of_ptr to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) - let to_string ( x : expr ) = Z3native.ast_to_string (nc_of_expr x) (ptr_of_expr x) + let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (ptr_of_expr x)) + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (nc_of_expr x) (ptr_of_expr x) + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) - let get_sort ( x : expr ) = sort_of_ptr (c_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)) + let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (nc_of_expr x) - (Z3native.mk_bool_sort (nc_of_expr x)) - (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x))) + (Z3native.is_eq_sort (gnc x) + (Z3native.mk_bool_sort (gnc x)) + (Z3native.get_sort (gnc x) (gno x))) let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (get_num_args x) == 0 && @@ -901,86 +875,52 @@ open Expr module Boolean = struct - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.ast_of_ptr ctx no) in - BoolExpr(Expr.Expr(a)) - - let bool_expr_of_expr e = - match e with Expr.Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolExpr(e) - - let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - BoolSort(sort_of_ptr ctx no) - - let sort_of_bool_sort s = match s with BoolSort(x) -> x - - let bool_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolSort(s) - - let expr_of_bool_expr e = match e with BoolExpr(x) -> x - - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) - let mk_sort ( ctx : context ) = - BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) + (sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - let s = (match (mk_sort ctx) with BoolSort(q) -> q) in - BoolExpr(Expr.mk_const ctx name s) + (Expr.mk_const ctx name (mk_sort ctx)) let mk_const_s ( ctx : context ) ( name : string ) = mk_const ctx (Symbol.mk_string ctx name) let mk_true ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) + expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) let mk_false ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) + expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) let mk_val ( ctx : context ) ( value : bool ) = if value then mk_true ctx else mk_false ctx let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) + expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) let mk_distinct ( ctx : context ) ( args : expr list ) = - bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) + expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) - let mk_not ( ctx : context ) ( a : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) + let mk_not ( ctx : context ) ( a : expr ) = + expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + let mk_ite ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( t3 : expr ) = + expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + let mk_iff ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + let mk_implies ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - let mk_and ( ctx : context ) ( args : bool_expr list ) = - let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) + let mk_and ( ctx : context ) ( args : expr list ) = + let f x = (Expr.gno (x)) in + expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - let mk_or ( ctx : context ) ( args : bool_expr list ) = - let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) + let mk_or ( ctx : context ) ( args : expr list ) = + let f x = (Expr.gno (x)) in + expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) end @@ -998,9 +938,9 @@ struct else Quantifier(e) - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (c_of_expr e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) module Pattern = struct @@ -1031,7 +971,7 @@ struct if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else - Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) + Z3native.get_index_value (Expr.gnc x) (Expr.gno x) let is_universal ( x : quantifier ) = Z3native.is_quantifier_forall (gnc x) (gno x) @@ -1067,7 +1007,7 @@ struct mk_list f n let get_body ( x : quantifier ) = - Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) @@ -1087,7 +1027,7 @@ struct (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) @@ -1097,7 +1037,7 @@ struct (List.length nopatterns) (expr_lton nopatterns) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -1105,7 +1045,7 @@ struct (match weight with | None -> 1 | Some(x) -> x) (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) @@ -1114,7 +1054,7 @@ struct (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length nopatterns) (expr_lton nopatterns) - (ptr_of_expr body))) + (Expr.gno body))) let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (List.length sorts) != (List.length names) then @@ -1125,7 +1065,7 @@ struct (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) @@ -1135,7 +1075,7 @@ struct (List.length nopatterns) (expr_lton nopatterns) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -1143,7 +1083,7 @@ struct (match weight with | None -> 1 | Some(x) -> x) (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) @@ -1152,7 +1092,7 @@ struct (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length nopatterns) (expr_lton nopatterns) - (ptr_of_expr body))) + (Expr.gno body))) let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then @@ -1170,46 +1110,8 @@ end module Array_ = struct - type array_sort = ArraySort of sort - type array_expr = ArrayExpr of expr - - let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (expr_of_ptr ctx no) in - ArrayExpr(e) - - let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - ArraySort(s) - - let sort_of_array_sort s = match s with ArraySort(x) -> x - - let array_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArraySort(s) - - let array_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArrayExpr(e) - - let expr_of_array_expr e = match e with ArrayExpr(x) -> x - - let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) - - let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) - let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) - let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) + sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) @@ -1218,48 +1120,40 @@ struct let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) let is_array ( x : expr ) = - (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) - let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) - let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) + let get_domain ( x : sort ) = Sort.sort_of_ptr (Sort.gc x) (Z3native.get_array_sort_domain (Sort.gnc x) (Sort.gno x)) + let get_range ( x : sort ) = Sort.sort_of_ptr (Sort.gc x) (Z3native.get_array_sort_range (Sort.gnc x) (Sort.gno x)) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) + (Expr.mk_const ctx name (mk_sort ctx domain range)) let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) + let mk_select ( ctx : context ) ( a : expr ) ( i : expr ) = + expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (Expr.gno a) (Expr.gno i)) - let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) + let mk_store ( ctx : context ) ( a : expr ) ( i : expr ) ( v : expr ) = + expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (Expr.gno a) (Expr.gno i) (Expr.gno v)) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) + expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = - let m x = (ptr_of_expr (expr_of_array_expr x)) in - array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) + let mk_map ( ctx : context ) ( f : func_decl ) ( args : expr list ) = + let m x = (Expr.gno x) in + expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) - let mk_term_array ( ctx : context ) ( arg : array_expr ) = - array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) + let mk_term_array ( ctx : context ) ( arg : expr ) = + expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (Expr.gno arg)) end module Set = struct - type set_sort = SetSort of sort - - let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - SetSort(s) - - let sort_of_set_sort s = match s with SetSort(x) -> x - let mk_sort ( ctx : context ) ( ty : sort ) = - set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) + sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) @@ -1275,10 +1169,10 @@ struct expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) + expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) + expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) let mk_union ( ctx : context ) ( args : expr list ) = expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) @@ -1287,53 +1181,37 @@ struct expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) + expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) let mk_complement ( ctx : context ) ( arg : expr ) = - expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (ptr_of_expr arg)) + expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (ptr_of_expr elem) (ptr_of_expr set)) + expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) + expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) end module FiniteDomain = struct - type finite_domain_sort = FiniteDomainSort of sort - - let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x - - let finite_domain_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - FiniteDomainSort(s) - - let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in - FiniteDomainSort(s) + (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = mk_sort ctx (Symbol.mk_string ctx name) size - let is_finite_domain ( x : expr ) = - let nc = (nc_of_expr x) in - (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == FINITE_DOMAIN_SORT) + let nc = (Expr.gnc x) in + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - let get_size ( x : finite_domain_sort ) = - let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in + let get_size ( x : sort ) = + let (r, v) = (Z3native.get_finite_domain_sort_size (Sort.gnc x) (Sort.gno x)) in if r then v else raise (Z3native.Exception "Conversion failed.") end @@ -1341,29 +1219,10 @@ end module Relation = struct - type relation_sort = RelationSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - RelationSort(s) - - let sort_of_relation_sort s = match s with RelationSort(x) -> x - - let relation_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RelationSort(s) - - let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - - let is_relation ( x : expr ) = - let nc = (nc_of_expr x) in - ((Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == RELATION_SORT)) + let nc = (Expr.gnc x) in + ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) @@ -1379,48 +1238,17 @@ struct let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) + let get_arity ( x : sort ) = Z3native.get_relation_arity (Sort.gnc x) (Sort.gno x) - let get_column_sorts ( x : relation_sort ) = + let get_column_sorts ( x : sort ) = let n = get_arity x in - let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in + let f i = (sort_of_ptr (Sort.gc x) (Z3native.get_relation_column (Sort.gnc x) (Sort.gno x) i)) in mk_list f n - end module Datatype = struct - type datatype_sort = DatatypeSort of sort - type datatype_expr = DatatypeExpr of expr - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - DatatypeSort(s) - - let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x - - let datatype_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeSort(s) - - let datatype_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeExpr(e) - - let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x - - let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - module Constructor = struct type constructor = z3_native_object @@ -1517,24 +1345,24 @@ struct ) c - let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) + let get_num_constructors ( x : sort ) = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) - let get_constructors ( x : datatype_sort ) = + let get_constructors ( x : sort ) = let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i) in mk_list f n - let get_recognizers ( x : datatype_sort ) = + let get_recognizers ( x : sort ) = let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) i) in mk_list f n - let get_accessors ( x : datatype_sort ) = + let get_accessors ( x : sort ) = let n = (get_num_constructors x) in let f i = ( - let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let fd = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i) in let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in + let g j = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) i j) in mk_list g ds ) in mk_list f n @@ -1543,467 +1371,133 @@ end module Enumeration = struct - type enum_sort = EnumSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = - let s = (sort_of_ptr ctx no) in - let res = EnumSort(s) in - res - - let sort_of_enum_sort s = match s with EnumSort(x) -> x - - let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in - sort_of_ptr ctx a (list_of_array b) (list_of_array c) + let (a, _, _) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in + sort_of_ptr ctx a let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - let get_const_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in + let get_const_decls ( x : sort ) = + let n = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) in + let f i = (func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i)) in mk_list f n - let get_tester_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in + let get_tester_decls ( x : sort ) = + let n = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) in + let f i = (func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) i)) in mk_list f n end module List_ = -struct - type list_sort = ListSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - let res = ListSort(s) in - res - - let sort_of_list_sort s = match s with ListSort(x) -> x - - let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - +struct let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - sort_of_ptr ctx r a b c d e f + let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in + sort_of_ptr ctx r let mk_list_s ( ctx : context ) (name : string) elem_sort = mk_sort ctx (Symbol.mk_string ctx name) elem_sort - let get_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) + let get_nil_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) 0) - let get_is_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) + let get_is_nil_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) 0) - let get_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) + let get_cons_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) 1) - let get_is_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) + let get_is_cons_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) 1) - let get_head_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) + let get_head_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) 1 0) - let get_tail_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) + let get_tail_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) 1 1) - let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] + let nil ( x : sort ) = expr_of_func_app (Sort.gc x) (get_nil_decl x) [] end module Tuple = struct - type tuple_sort = TupleSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - TupleSort(s) - - let sort_of_tuple_sort s = match s with TupleSort(x) -> x - - let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in sort_of_ptr ctx r - let get_mk_decl ( x : tuple_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) + let get_mk_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_tuple_sort_mk_decl (Sort.gnc x) (Sort.gno x)) - let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) + let get_num_fields ( x : sort ) = Z3native.get_tuple_sort_num_fields (Sort.gnc x) (Sort.gno x) - let get_field_decls ( x : tuple_sort ) = + let get_field_decls ( x : sort ) = let n = get_num_fields x in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_tuple_sort_field_decl (Sort.gnc x) (Sort.gno x) i) in mk_list f n end -module rec Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> arith_sort - val expr_of_arith_expr : arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> arith_expr +module Arithmetic = +struct - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end - - val is_int : Expr.expr -> bool - val is_arithmetic_numeral : Expr.expr -> bool - val is_le : Expr.expr -> bool - val is_ge : Expr.expr -> bool - val is_lt : Expr.expr -> bool - val is_gt : Expr.expr -> bool - val is_add : Expr.expr -> bool - val is_sub : Expr.expr -> bool - val is_uminus : Expr.expr -> bool - val is_mul : Expr.expr -> bool - val is_div : Expr.expr -> bool - val is_idiv : Expr.expr -> bool - val is_remainder : Expr.expr -> bool - val is_modulus : Expr.expr -> bool - val is_inttoreal : Expr.expr -> bool - val is_real_to_int : Expr.expr -> bool - val is_real_is_int : Expr.expr -> bool - val is_real : Expr.expr -> bool - val is_int_numeral : Expr.expr -> bool - val is_rat_num : Expr.expr -> bool - val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr list -> arith_expr - val mk_mul : context -> arith_expr list -> arith_expr - val mk_sub : context -> arith_expr list -> arith_expr - val mk_unary_minus : context -> arith_expr -> arith_expr - val mk_div : context -> arith_expr -> arith_expr -> arith_expr - val mk_power : context -> arith_expr -> arith_expr -> arith_expr - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr -end = struct - type arith_sort = ArithSort of sort - type arith_expr = ArithExpr of expr - - let arith_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithExpr(e) - - let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_expr_of_expr (expr_of_ptr ctx no) - - let sort_of_arith_sort s = match s with ArithSort(x) -> x - let expr_of_arith_expr e = match e with ArithExpr(x) -> x - - let arith_sort_of_sort s = match s with Sort(a) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithSort(s) - - let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_sort_of_sort (sort_of_ptr ctx no) - - let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) - let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (c_of_expr e) - let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (nc_of_expr e) - let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (ptr_of_expr e) - - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end = struct - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntExpr(e) - - let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - IntNum(e) - - let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_num_of_int_expr (int_expr_of_ptr ctx no) - - let arith_sort_of_int_sort s = match s with IntSort(x) -> x - let arith_expr_of_int_expr e = match e with IntExpr(x) -> x - let int_expr_of_int_num e = match e with IntNum(x) -> x - - let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntSort(s) - - let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) - - let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) - let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) - let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) - let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) - let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) - let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) - let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) - let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) - let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - + module Integer = + struct let mk_sort ( ctx : context ) = - int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) + sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - let get_int ( x : int_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + let get_int ( x : expr ) = + let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = - IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) + Expr.mk_const ctx name (mk_sort ctx) let mk_int_const_s ( ctx : context ) ( name : string ) = mk_int_const ctx (Symbol.mk_string ctx name) - let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + let mk_mod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + let mk_rem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) - let mk_int2real ( ctx : context ) ( t : int_expr ) = - Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) + let mk_int2real ( ctx : context ) ( t : expr ) = + (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (Expr.gno t))) - let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) + let mk_int2bv ( ctx : context ) ( n : int ) ( t : expr ) = + (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (Expr.gno t))) end - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : real_sort -> arith_sort - val real_sort_of_arith_sort : arith_sort -> real_sort - val arith_expr_of_real_expr : real_expr -> arith_expr - val real_expr_of_rat_num : rat_num -> real_expr - val real_expr_of_arith_expr : arith_expr -> real_expr - val rat_num_of_real_expr : real_expr -> rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end = struct - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - let arith_sort_of_real_sort s = match s with RealSort(x) -> x - let arith_expr_of_real_expr e = match e with RealExpr(x) -> x - let real_expr_of_rat_num e = match e with RatNum(x) -> x - - let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealExpr(e) - - let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - RatNum(e) - - let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - rat_num_of_real_expr (real_expr_of_ptr ctx no) - - let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealSort(s) - - let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) - let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) - let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) - let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) - let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) - let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) - let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) - let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) - let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - - + module Real = + struct let mk_sort ( ctx : context ) = - real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) + sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - let get_numerator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + let get_numerator ( x : expr ) = + expr_of_ptr (Expr.gc x) (Z3native.get_numerator (Expr.gnc x) (Expr.gno x)) - let get_denominator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + let get_denominator ( x : expr ) = + expr_of_ptr (Expr.gc x) (Z3native.get_denominator (Expr.gnc x) (Expr.gno x)) - let to_decimal_string ( x : rat_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + let to_decimal_string ( x : expr ) ( precision : int ) = + Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = - RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) + Expr.mk_const ctx name (mk_sort ctx) let mk_real_const_s ( ctx : context ) ( name : string ) = mk_real_const ctx (Symbol.mk_string ctx name) @@ -2012,67 +1506,38 @@ end = struct if (den == 0) then raise (Z3native.Exception "Denominator is zero") else - rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) + expr_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) let mk_numeral_s ( ctx : context ) ( v : string ) = - rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) let mk_numeral_i ( ctx : context ) ( v : int ) = - rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) - let mk_is_integer ( ctx : context ) ( t : real_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) + let mk_is_integer ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (Expr.gno t))) - let mk_real2int ( ctx : context ) ( t : real_expr ) = - Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) + let mk_real2int ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (Expr.gno t))) end - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end = struct - type algebraic_num = AlgebraicNum of arith_expr - - let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x - - let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - AlgebraicNum(e) - - let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) - - let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) - let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) - let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - - - let to_upper ( x : algebraic_num ) ( precision : int ) = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + module AlgebraicNumber = + struct + let to_upper ( x : expr ) ( precision : int ) = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) - let to_lower ( x : algebraic_num ) precision = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + let to_lower ( x : expr ) precision = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + let to_decimal_string ( x : expr ) ( precision : int ) = + Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) end let is_int ( x : expr ) = - (Z3native.is_numeral_ast (nc_of_expr x) (nc_of_expr x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == INT_SORT) + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) @@ -2107,224 +1572,55 @@ end = struct let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == REAL_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - let mk_add ( ctx : context ) ( t : arith_expr list ) = - let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + let mk_add ( ctx : context ) ( t : expr list ) = + let f x = (Expr.gno x) in + (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_mul ( ctx : context ) ( t : arith_expr list ) = - let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + let mk_mul ( ctx : context ) ( t : expr list ) = + let f x = (Expr.gno x) in + (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_sub ( ctx : context ) ( t : arith_expr list ) = - let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + let mk_sub ( ctx : context ) ( t : expr list ) = + let f x = (Expr.gno x) in + (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) + let mk_unary_minus ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) - let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) + let mk_div ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) + let mk_power ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) + let mk_lt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) + let mk_le ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) + let mk_gt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) + let mk_ge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) end -and BitVector : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - - val mk_sort : context -> int -> bitvec_sort - val is_bv : Expr.expr -> bool - val is_bv_numeral : Expr.expr -> bool - val is_bv_bit1 : Expr.expr -> bool - val is_bv_bit0 : Expr.expr -> bool - val is_bv_uminus : Expr.expr -> bool - val is_bv_add : Expr.expr -> bool - val is_bv_sub : Expr.expr -> bool - val is_bv_mul : Expr.expr -> bool - val is_bv_sdiv : Expr.expr -> bool - val is_bv_udiv : Expr.expr -> bool - val is_bv_SRem : Expr.expr -> bool - val is_bv_urem : Expr.expr -> bool - val is_bv_smod : Expr.expr -> bool - val is_bv_sdiv0 : Expr.expr -> bool - val is_bv_udiv0 : Expr.expr -> bool - val is_bv_srem0 : Expr.expr -> bool - val is_bv_urem0 : Expr.expr -> bool - val is_bv_smod0 : Expr.expr -> bool - val is_bv_ule : Expr.expr -> bool - val is_bv_sle : Expr.expr -> bool - val is_bv_uge : Expr.expr -> bool - val is_bv_sge : Expr.expr -> bool - val is_bv_ult : Expr.expr -> bool - val is_bv_slt : Expr.expr -> bool - val is_bv_ugt : Expr.expr -> bool - val is_bv_sgt : Expr.expr -> bool - val is_bv_and : Expr.expr -> bool - val is_bv_or : Expr.expr -> bool - val is_bv_not : Expr.expr -> bool - val is_bv_xor : Expr.expr -> bool - val is_bv_nand : Expr.expr -> bool - val is_bv_nor : Expr.expr -> bool - val is_bv_xnor : Expr.expr -> bool - val is_bv_concat : Expr.expr -> bool - val is_bv_signextension : Expr.expr -> bool - val is_bv_zeroextension : Expr.expr -> bool - val is_bv_extract : Expr.expr -> bool - val is_bv_repeat : Expr.expr -> bool - val is_bv_reduceor : Expr.expr -> bool - val is_bv_reduceand : Expr.expr -> bool - val is_bv_comp : Expr.expr -> bool - val is_bv_shiftleft : Expr.expr -> bool - val is_bv_shiftrightlogical : Expr.expr -> bool - val is_bv_shiftrightarithmetic : Expr.expr -> bool - val is_bv_rotateleft : Expr.expr -> bool - val is_bv_rotateright : Expr.expr -> bool - val is_bv_rotateleftextended : Expr.expr -> bool - val is_bv_rotaterightextended : Expr.expr -> bool - val is_int_to_bv : Expr.expr -> bool - val is_bv_to_int : Expr.expr -> bool - val is_bv_carry : Expr.expr -> bool - val is_bv_xor3 : Expr.expr -> bool - val get_size : bitvec_sort -> int - val get_int : bitvec_num -> int - val to_string : bitvec_num -> string - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr - val mk_const_s : context -> string -> int -> bitvec_expr - val mk_not : context -> bitvec_expr -> Expr.expr - val mk_redand : context -> bitvec_expr -> Expr.expr - val mk_redor : context -> bitvec_expr -> Expr.expr - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_neg : context -> bitvec_expr -> bitvec_expr - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_numeral : context -> string -> int -> bitvec_num -end = struct - type bitvec_sort = BitVecSort of sort - type bitvec_expr = BitVecExpr of expr - type bitvec_num = BitVecNum of bitvec_expr - - let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x - - let bitvec_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecSort(s) - - let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_sort_of_sort (sort_of_ptr ctx no) - - let bitvec_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecExpr(e) - - let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_expr_of_expr (expr_of_ptr ctx no) - - let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(a)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecNum(e) - - let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) - - let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x - let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x - - - let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) - let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) - let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) - let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (c_of_expr e) - let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (nc_of_expr e) - let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (ptr_of_expr e) - let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) - let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) - let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - - +module BitVector = +struct let mk_sort ( ctx : context ) size = - bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) + sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == BV_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) @@ -2376,112 +1672,112 @@ end = struct let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) - let get_int ( x : bitvec_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + let get_size (x : sort ) = Z3native.get_bv_sort_size (Sort.gnc x) (Sort.gno x) + let get_int ( x : expr ) = + let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) + Expr.mk_const ctx name (mk_sort ctx size) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = mk_const ctx (Symbol.mk_string ctx name) size - let mk_not ( ctx : context ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) - let mk_redand ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) - let mk_redor ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) - let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) - let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) - let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) - let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) - let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) - let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) - let mk_neg ( ctx : context ) ( t : bitvec_expr) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) - let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) - let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) - let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) - let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) - let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) - let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) - let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) - let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) - let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) - let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) - let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) - let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) - let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) - let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) - let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) - let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) - let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) - let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) - let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) - let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) - let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) - let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) - let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) - let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) - let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) - let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) - let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) - let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) - let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) - let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) + let mk_not ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (Expr.gno t)) + let mk_redand ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (Expr.gno t)) + let mk_redor ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (Expr.gno t)) + let mk_and ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_or ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_nand ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_nor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_xnor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_neg ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (Expr.gno t)) + let mk_add ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_sub ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_mul ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_udiv ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_sdiv ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_urem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_srem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_smod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_ult ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_slt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_ule ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sle ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_uge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_ugt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sgt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_concat ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (Expr.gno t)) + let mk_sign_ext ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (Expr.gno t)) + let mk_zero_ext ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (Expr.gno t)) + let mk_repeat ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (Expr.gno t)) + let mk_shl ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_lshr ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_ashr ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_rotate_left ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (Expr.gno t)) + let mk_rotate_right ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (Expr.gno t)) + let mk_ext_rotate_left ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_ext_rotate_right ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_bv2int ( ctx : context ) ( t : expr ) ( signed : bool ) = + expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (Expr.gno t) signed) + let mk_add_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = + (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) + let mk_add_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sub_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sub_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = + (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) + let mk_sdiv_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_neg_no_overflow ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (Expr.gno t))) + let mk_mul_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = + (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) + let mk_mul_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx size))) end @@ -2556,8 +1852,8 @@ struct let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in + let assert_ ( x : goal ) ( constraints : expr list ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e) in ignore (List.map f constraints) ; () @@ -2572,7 +1868,7 @@ struct let get_formulas ( x : goal ) = let n = get_size x in - let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + let f i = ((expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in mk_list f n @@ -2749,7 +2045,7 @@ struct exception ModelEvaluationFailedException of string let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (ptr_of_expr t) completion) in + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then raise (ModelEvaluationFailedException "evaluation failed") else @@ -3076,19 +2372,19 @@ struct let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + let assert_ ( x : solver ) ( constraints : expr list ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) - let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = + let assert_and_track_a ( x : solver ) ( cs : expr list ) ( ps : expr list ) = if ((List.length cs) != (List.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in + let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno a) (Expr.gno b)) in ignore (List.iter2 f cs ps) - let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) + let assert_and_track ( x : solver ) ( c : expr ) ( p : expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno c) (Expr.gno p) let get_num_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in @@ -3097,15 +2393,15 @@ struct let get_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in + let f i = (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in mk_list f n - let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = + let check ( x : solver ) ( assumptions : expr list ) = let r = if ((List.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - let f x = (ptr_of_expr (Boolean.expr_of_bool_expr x)) in + let f x = (Expr.gno x) in lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) in match r with @@ -3179,24 +2475,24 @@ struct let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + let assert_ ( x : fixedpoint ) ( constraints : expr list ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) ; () let register_relation ( x : fixedpoint ) ( f : func_decl ) = Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : expr ) ( name : Symbol.symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) (Symbol.gno y) let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) - let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with + let query ( x : fixedpoint ) ( query : expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Expr.gno query))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -3214,8 +2510,8 @@ struct let pop ( x : fixedpoint ) = Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) + let update_rule ( x : fixedpoint ) ( rule : expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) (Symbol.gno name) let get_answer ( x : fixedpoint ) = let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in @@ -3238,27 +2534,27 @@ struct Some (expr_of_ptr (z3obj_gc x) q) let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (ptr_of_expr property) + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = - let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in + let to_string_q ( x : fixedpoint ) ( queries : expr list ) = + let f x = Expr.gno x in Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) let get_rules ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n let get_assertions ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n let mk_fixedpoint ( ctx : context ) = create ctx @@ -3287,10 +2583,10 @@ end module SMT = struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : expr list ) ( formula : expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) - (Boolean.gno formula) + (List.length assumptions) (let f x = Expr.gno (x) in (Array.of_list (List.map f assumptions))) + (Expr.gno formula) let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = let csn = (List.length sort_names) in @@ -3328,14 +2624,14 @@ struct let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in + let f i =(expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in mk_list f n let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in + let f i = (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in mk_list f n let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) @@ -3360,14 +2656,14 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - + (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = let csn = (List.length sort_names) in let cs = (List.length sorts) in @@ -3376,13 +2672,13 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) + (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) end diff --git a/src/api/ml/z3_rich.ml b/src/api/ml/z3_rich.ml new file mode 100644 index 000000000..052ca5e22 --- /dev/null +++ b/src/api/ml/z3_rich.ml @@ -0,0 +1,3400 @@ +(** + The Z3 ML/Ocaml Interface. + + Copyright (C) 2012 Microsoft Corporation + @author CM Wintersteiger (cwinter) 2012-12-17 +*) + +open Z3enums + +(* Some helpers. *) +let null = Z3native.mk_null() +let is_null o = (Z3native.is_null o) + + +(* Internal types *) +type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +type context = z3_native_context + +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } + + +(** Internal stuff *) +module Internal = +struct + let dispose_context ctx = + if ctx.m_n_obj_cnt == 0 then ( + (Z3native.del_context ctx.m_n_ctx) + ) else ( + Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; + ) + + let create_context settings = + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + Z3native.set_internal_error_handler v ; + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> dispose_context o in + Gc.finalise f res; + res + + let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) + let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) + let context_gno ctx = ctx.m_n_ctx + + + let z3obj_gc o = o.m_ctx + let z3obj_gnc o = (context_gno o.m_ctx) + + let z3obj_gno o = o.m_n_obj + let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + + let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + + let z3obj_create o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o + + let z3obj_nil_ref x y = () + + let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> + let res : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res +end + +open Internal + +module Log = +struct + let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) + let close = Z3native.close_log + let append s = Z3native.append_log s +end + + +module Version = +struct + let major = let (x, _, _, _) = Z3native.get_version in x + let minor = let (_, x, _, _) = Z3native.get_version in x + let build = let (_, _, x, _) = Z3native.get_version in x + let revision = let (_, _, _, x) = Z3native.get_version in x + let to_string = + let (mj, mn, bld, rev) = Z3native.get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + + +let mk_list ( f : int -> 'a ) ( n : int ) = + let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = + if (i >= n) then + tail + else + (mk_list' f (i+1) n ((f i) :: tail)) + in + mk_list' f 0 n [] + +let list_of_array ( x : _ array ) = + let f i = (Array.get x i) in + mk_list f (Array.length x) + +let mk_context ( cfg : ( string * string ) list ) = + create_context cfg + + +module Symbol = +struct + (* Symbol types *) + type int_symbol = z3_native_object + type string_symbol = z3_native_object + + type symbol = + | S_Int of int_symbol + | S_Str of string_symbol + + + let create_i ( ctx : context ) ( no : Z3native.ptr ) = + let res : int_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let create_s ( ctx : context ) ( no : Z3native.ptr ) = + let res : string_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with + | INT_SYMBOL -> S_Int (create_i ctx no) + | STRING_SYMBOL -> S_Str (create_s ctx no) + + let gc ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gc n) + | S_Str(n) -> (z3obj_gc n) + + let gnc ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gnc n) + | S_Str(n) -> (z3obj_gnc n) + + let gno ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gno n) + | S_Str(n) -> (z3obj_gno n) + + let symbol_lton ( a : symbol list ) = + let f ( e : symbol ) = (gno e) in + Array.of_list (List.map f a) + + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) + let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL + let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL + let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) + let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) + let to_string ( o : symbol ) = + match (kind o) with + | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) + | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) + + let mk_int ( ctx : context ) ( i : int ) = + S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + + let mk_string ( ctx : context ) ( s : string ) = + S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + + let mk_ints ( ctx : context ) ( names : int list ) = + let f elem = mk_int ( ctx : context ) elem in + (List.map f names) + + let mk_strings ( ctx : context ) ( names : string list ) = + let f elem = mk_string ( ctx : context ) elem in + (List.map f names) +end + + +module AST = +struct + type ast = z3_native_object + + let context_of_ast ( x : ast ) = (z3obj_gc x) + let nc_of_ast ( x : ast ) = (z3obj_gnc x) + let ptr_of_ast ( x : ast ) = (z3obj_gno x) + + let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST + | SORT_AST + | QUANTIFIER_AST + | APP_AST + | NUMERAL_AST + | VAR_AST -> z3_native_object_of_ast_ptr ctx no + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") + + module ASTVector = + struct + type ast_vector = z3_native_object + + let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_vector = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_vector_inc_ref ; + dec_ref = Z3native.ast_vector_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_size ( x : ast_vector ) = + Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) + + let get ( x : ast_vector ) ( i : int ) = + ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) + + let set ( x : ast_vector ) ( i : int ) ( value : ast ) = + Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) + + let resize ( x : ast_vector ) ( new_size : int ) = + Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size + + let push ( x : ast_vector ) ( a : ast ) = + Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) + + let translate ( x : ast_vector ) ( to_ctx : context ) = + ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + + let to_string ( x : ast_vector ) = + Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) + end + + module ASTMap = + struct + type ast_map = z3_native_object + + let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_map = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_map_inc_ref ; + dec_ref = Z3native.ast_map_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let contains ( x : ast_map ) ( key : ast ) = + Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) + + let find ( x : ast_map ) ( key : ast ) = + ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) + + let insert ( x : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) + + let erase ( x : ast_map ) ( key : ast ) = + Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) + + let reset ( x : ast_map ) = + Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) + + let get_size ( x : ast_map ) = + Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) + + let get_keys ( x : ast_map ) = + let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in + let f i = (ASTVector.get av i) in + mk_list f (ASTVector.get_size av) + + let to_string ( x : ast_map ) = + Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) + end + + let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) + let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) + let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) + + let is_expr ( x : ast ) = + match get_ast_kind ( x : ast ) with + | APP_AST + | NUMERAL_AST + | QUANTIFIER_AST + | VAR_AST -> true + | _ -> false + + let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST + let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST + let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST + let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST + + let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) + let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) + + + let ( = ) ( a : ast ) ( b : ast ) = (a == b) || + if (z3obj_gnc a) != (z3obj_gnc b) then + false + else + Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) + + let compare a b = + if (get_id a) < (get_id b) then -1 else + if (get_id a) > (get_id b) then 1 else + 0 + + let ( < ) (a : ast) (b : ast) = (compare a b) + + let translate ( x : ast ) ( to_ctx : context ) = + if (z3obj_gnc x) == (context_gno to_ctx) then + x + else + ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + + let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr + let unwrap_ast ( x : ast ) = (z3obj_gno x) +end + +open AST + + +module Sort = +struct + type sort = Sort of AST.ast + type uninterpreted_sort = UninterpretedSort of sort + + let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> + let q = (z3_native_object_of_ast_ptr ctx no) in + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then + raise (Z3native.Exception "Invalid coercion") + else + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + let ast_of_sort s = match s with Sort(x) -> x + let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x + + let uninterpreted_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + UninterpretedSort(s) + + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) + let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) + let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) + + let sort_lton ( a : sort list ) = + let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) + + let ( = ) : sort -> sort -> bool = fun a b -> + (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) + + + let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) + let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) + let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) + let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) + + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; + (z3obj_create res) ; + UninterpretedSort(Sort(res)) + + let mk_uninterpreted_s ( ctx : context ) ( s : string ) = + mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) +end + +open Sort + + +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + val func_decl_of_ptr : context -> Z3native.ptr -> func_decl + val gc : func_decl -> context + val gnc : func_decl -> Z3native.ptr + val gno : func_decl -> Z3native.ptr + module Parameter : + sig + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + val get_kind : parameter -> Z3enums.parameter_kind + val get_int : parameter -> int + val get_float : parameter -> float + val get_symbol : parameter -> Symbol.symbol + val get_sort : parameter -> Sort.sort + val get_ast : parameter -> AST.ast + val get_func_decl : parameter -> func_decl + val get_rational : parameter -> string + end + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + val ( = ) : func_decl -> func_decl -> bool + val to_string : func_decl -> string + val get_id : func_decl -> int + val get_arity : func_decl -> int + val get_domain_size : func_decl -> int + val get_domain : func_decl -> Sort.sort list + val get_range : func_decl -> Sort.sort + val get_decl_kind : func_decl -> Z3enums.decl_kind + val get_name : func_decl -> Symbol.symbol + val get_num_parameters : func_decl -> int + val get_parameters : func_decl -> Parameter.parameter list + val apply : func_decl -> Expr.expr list -> Expr.expr +end = struct + type func_decl = FuncDecl of AST.ast + + let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + FuncDecl(z3_native_object_of_ast_ptr ctx no) + + let ast_of_func_decl f = match f with FuncDecl(x) -> x + + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) + let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) + let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) + + module Parameter = + struct + type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + let get_kind ( x : parameter ) = + (match x with + | P_Int(_) -> PARAMETER_INT + | P_Dbl(_) -> PARAMETER_DOUBLE + | P_Sym(_) -> PARAMETER_SYMBOL + | P_Srt(_) -> PARAMETER_SORT + | P_Ast(_) -> PARAMETER_AST + | P_Fdl(_) -> PARAMETER_FUNC_DECL + | P_Rat(_) -> PARAMETER_RATIONAL) + + let get_int ( x : parameter ) = + match x with + | P_Int(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an int") + + let get_float ( x : parameter ) = + match x with + | P_Dbl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a double") + + let get_symbol ( x : parameter ) = + match x with + | P_Sym(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a symbol") + + let get_sort ( x : parameter ) = + match x with + | P_Srt(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a sort") + + let get_ast ( x : parameter ) = + match x with + | P_Ast(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an ast") + + let get_func_decl ( x : parameter ) = + match x with + | P_Fdl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a func_decl") + + let get_rational ( x : parameter ) = + match x with + | P_Rat(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a rational string") + end + + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = + create_ndr ctx name domain range + + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = + mk_func_decl ctx (Symbol.mk_string ctx name) domain range + + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = + create_pdr ctx prefix domain range + + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + create_ndr ctx name [] range + + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = + create_ndr ctx (Symbol.mk_string ctx name) [] range + + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = + create_pdr ctx prefix [] range + + + let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) + + let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) + + let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) + + let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) + + let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) + + let get_domain ( x : func_decl ) = + let n = (get_domain_size x) in + let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in + mk_list f n + + let get_range ( x : func_decl ) = + sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) + + let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) + + let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) + + let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) + + let get_parameters ( x : func_decl ) = + let n = (get_num_parameters x) in + let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with + | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + ) in + mk_list f n + + let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args +end + + +and Params : +sig + type params = z3_native_object + module ParamDescrs : + sig + type param_descrs + val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + val get_names : param_descrs -> Symbol.symbol list + val get_size : param_descrs -> int + val to_string : param_descrs -> string + end + val add_bool : params -> Symbol.symbol -> bool -> unit + val add_int : params -> Symbol.symbol -> int -> unit + val add_double : params -> Symbol.symbol -> float -> unit + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + val add_s_bool : params -> string -> bool -> unit + val add_s_int : params -> string -> int -> unit + val add_s_double : params -> string -> float -> unit + val add_s_symbol : params -> string -> Symbol.symbol -> unit + val mk_params : context -> params + val to_string : params -> string +end = struct + type params = z3_native_object + + module ParamDescrs = + struct + type param_descrs = z3_native_object + + let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let res : param_descrs = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.param_descrs_inc_ref ; + dec_ref = Z3native.param_descrs_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let validate ( x : param_descrs ) ( p : params ) = + Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) + + let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) + + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in + let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) + end + + let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = + Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value + + let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = + Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value + + let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value + + let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = + Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) + + let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = + add_bool x (Symbol.mk_string (z3obj_gc x) name) value + + let add_s_int ( x : params) ( name : string ) ( value : int ) = + add_int x (Symbol.mk_string (z3obj_gc x) name) value + + let add_s_double ( x : params ) ( name : string ) ( value : float ) = + add_double x (Symbol.mk_string (z3obj_gc x) name) value + + let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = + add_symbol x (Symbol.mk_string (z3obj_gc x) name) value + + let mk_params ( ctx : context ) = + let res : params = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.params_inc_ref ; + dec_ref = Z3native.params_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; + (z3obj_create res) ; + res + + let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) +end + +(** General expressions (terms) *) +and Expr : +sig + type expr = Expr of AST.ast + val expr_of_ptr : context -> Z3native.ptr -> expr + val gc : expr -> context + val gnc : expr -> Z3native.ptr + val gno : expr -> Z3native.ptr + val expr_lton : expr list -> Z3native.ptr array + val ast_of_expr : expr -> AST.ast + val expr_of_ast : AST.ast -> expr + val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr + val simplify : expr -> Params.params option -> expr + val get_simplify_help : context -> string + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + val get_func_decl : expr -> FuncDecl.func_decl + val get_bool_value : expr -> Z3enums.lbool + val get_num_args : expr -> int + val get_args : expr -> expr list + val update : expr -> expr list -> expr + val substitute : expr -> expr list -> expr list -> expr + val substitute_one : expr -> expr -> expr -> expr + val substitute_vars : expr -> expr list -> expr + val translate : expr -> context -> expr + val to_string : expr -> string + val is_numeral : expr -> bool + val is_well_sorted : expr -> bool + val get_sort : expr -> Sort.sort + val is_bool : expr -> bool + val is_const : expr -> bool + val is_true : expr -> bool + val is_false : expr -> bool + val is_eq : expr -> bool + val is_distinct : expr -> bool + val is_ite : expr -> bool + val is_and : expr -> bool + val is_or : expr -> bool + val is_iff : expr -> bool + val is_xor : expr -> bool + val is_not : expr -> bool + val is_implies : expr -> bool + val is_label : expr -> bool + val is_label_lit : expr -> bool + val is_oeq : expr -> bool + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val mk_const_s : context -> string -> Sort.sort -> expr + val mk_const_f : context -> FuncDecl.func_decl -> expr + val mk_fresh_const : context -> string -> Sort.sort -> expr + val mk_app : context -> FuncDecl.func_decl -> expr list -> expr + val mk_numeral_string : context -> string -> Sort.sort -> expr + val mk_numeral_int : context -> int -> Sort.sort -> expr +end = struct + type expr = Expr of AST.ast + + let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) + let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) + let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + + let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then + Expr(z3_native_object_of_ast_ptr ctx no) + else + let s = Z3native.get_sort (context_gno ctx) no in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) no) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + if (Z3native.is_numeral_ast (context_gno ctx) no) then + if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + raise (Z3native.Exception "Unsupported numeral object") + else + Expr(z3_native_object_of_ast_ptr ctx no) + + let expr_of_ast a = + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Expr(a) + + let ast_of_expr e = match e with Expr(a) -> a + + let expr_lton ( a : expr list ) = + let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) + + let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> + match f with FuncDecl.FuncDecl(fa) -> + let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in + expr_of_ptr ctx o + + let simplify ( x : expr ) ( p : Params.params option ) = match p with + | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (Expr.gnc x) (Expr.gno x)) + | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (Expr.gnc x) (Expr.gno x) (z3obj_gno pp)) + + let get_simplify_help ( ctx : context ) = + Z3native.simplify_get_help (context_gno ctx) + + let get_simplify_parameter_descrs ( ctx : context ) = + Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (Expr.gnc x) (Expr.gno x)) + + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (Expr.gnc x) (Expr.gno x)) + + let get_num_args ( x : expr ) = Z3native.get_app_num_args (Expr.gnc x) (Expr.gno x) + + let get_args ( x : expr ) = let n = (get_num_args x) in + let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (Expr.gnc x) (Expr.gno x) i) in + mk_list f n + + let update ( x : expr ) ( args : expr list ) = + if (List.length args <> (get_num_args x)) then + raise (Z3native.Exception "Number of arguments does not match") + else + expr_of_ptr (Expr.gc x) (Z3native.update_term (Expr.gnc x) (Expr.gno x) (List.length args) (expr_lton args)) + + let substitute ( x : expr ) from to_ = + if (List.length from) <> (List.length to_) then + raise (Z3native.Exception "Argument sizes do not match") + else + expr_of_ptr (Expr.gc x) (Z3native.substitute (Expr.gnc x) (Expr.gno x) (List.length from) (expr_lton from) (expr_lton to_)) + + let substitute_one ( x : expr ) from to_ = + substitute ( x : expr ) [ from ] [ to_ ] + + let substitute_vars ( x : expr ) to_ = + expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (Expr.gnc x) (Expr.gno x) (List.length to_) (expr_lton to_)) + + let translate ( x : expr ) to_ctx = + if (Expr.gc x) == to_ctx then + x + else + expr_of_ptr to_ctx (Z3native.translate (Expr.gnc x) (Expr.gno x) (context_gno to_ctx)) + + let to_string ( x : expr ) = Z3native.ast_to_string (Expr.gnc x) (Expr.gno x) + + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) + + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (Expr.gnc x) (Expr.gno x) + + let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)) + + let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (Z3native.is_eq_sort (Expr.gnc x) + (Z3native.mk_bool_sort (Expr.gnc x)) + (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) + + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (get_num_args x) == 0 && + (FuncDecl.get_domain_size (get_func_decl x)) == 0 + + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) + let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) + let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) + + let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = + mk_const ctx (Symbol.mk_string ctx name) range + + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] + + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) + + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args + + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) + + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) +end + +open FuncDecl +open Expr + +module Boolean = +struct + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + + let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let a = (AST.ast_of_ptr ctx no) in + BoolExpr(Expr.Expr(a)) + + let bool_expr_of_expr e = + match e with Expr.Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolExpr(e) + + let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + BoolSort(sort_of_ptr ctx no) + + let sort_of_bool_sort s = match s with BoolSort(x) -> x + + let bool_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolSort(s) + + let expr_of_bool_expr e = match e with BoolExpr(x) -> x + + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) + + let mk_sort ( ctx : context ) = + BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) + + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = + let s = (match (mk_sort ctx) with BoolSort(q) -> q) in + BoolExpr(Expr.mk_const ctx name s) + + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) + + let mk_true ( ctx : context ) = + bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) + + let mk_false ( ctx : context ) = + bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) + + let mk_val ( ctx : context ) ( value : bool ) = + if value then mk_true ctx else mk_false ctx + + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + + let mk_distinct ( ctx : context ) ( args : expr list ) = + bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) + + let mk_not ( ctx : context ) ( a : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) + + let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + + let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + + let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + + let mk_and ( ctx : context ) ( args : bool_expr list ) = + let f x = (Expr.gno (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) + + let mk_or ( ctx : context ) ( args : bool_expr list ) = + let f x = (Expr.gno (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) +end + + +module Quantifier = +struct + type quantifier = Quantifier of expr + + let expr_of_quantifier e = match e with Quantifier(x) -> x + + let quantifier_of_expr e = + match e with Expr.Expr(a) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.QUANTIFIER_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Quantifier(e) + + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) + + module Pattern = + struct + type pattern = Pattern of ast + + let ast_of_pattern e = match e with Pattern(x) -> x + + let pattern_of_ast a = + (* CMW: Unchecked ok? *) + Pattern(a) + + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) + let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) + let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) + + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms (gnc x) (gno x) + + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in + mk_list f n + + let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) + end + + let get_index ( x : expr ) = + if not (AST.is_var (match x with Expr.Expr(a) -> a)) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value (Expr.gnc x) (Expr.gno x) + + let is_universal ( x : quantifier ) = + Z3native.is_quantifier_forall (gnc x) (gno x) + + let is_existential ( x : quantifier ) = not (is_universal x) + + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) + + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) + + let get_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in + mk_list f n + + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) + + let get_no_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in + mk_list f n + + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) + + let get_bound_variable_names ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in + mk_list f n + + let get_bound_variable_sorts ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in + mk_list f n + + let get_body ( x : quantifier ) = + Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) + + let mk_pattern ( ctx : context ) ( terms : expr list ) = + if (List.length terms) == 0 then + raise (Z3native.Exception "Cannot create a pattern from zero terms") + else + Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) + + let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + + let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (Expr.gno body))) + + let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + + let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (Expr.gno body))) + + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (universal) then + (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + else + (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (universal) then + mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id + else + mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id +end + + +module Array_ = +struct + type array_sort = ArraySort of sort + type array_expr = ArrayExpr of expr + + let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (expr_of_ptr ctx no) in + ArrayExpr(e) + + let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + ArraySort(s) + + let sort_of_array_sort s = match s with ArraySort(x) -> x + + let array_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArraySort(s) + + let array_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArrayExpr(e) + + let expr_of_array_expr e = match e with ArrayExpr(x) -> x + + let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) + + let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) + let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) + let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) + + let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = + array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) + + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_array ( x : expr ) = + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) + + let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) + let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) + + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = + ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) + + let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = + mk_const ctx (Symbol.mk_string ctx name) domain range + + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = + array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) + + let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = + array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) + + let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = + array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) + + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = + let m x = (Expr.gno (expr_of_array_expr x)) in + array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) + + let mk_term_array ( ctx : context ) ( arg : array_expr ) = + array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) +end + + +module Set = +struct + type set_sort = SetSort of sort + + let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + SetSort(s) + + let sort_of_set_sort s = match s with SetSort(x) -> x + + let mk_sort ( ctx : context ) ( ty : sort ) = + set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) + + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + + + let mk_empty ( ctx : context ) ( domain : sort ) = + (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) + + let mk_full ( ctx : context ) ( domain : sort ) = + expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) + + let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) + + let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) + + let mk_union ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) + + let mk_intersection ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) + + let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + + let mk_complement ( ctx : context ) ( arg : expr ) = + expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) + + let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) + + let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + +end + + +module FiniteDomain = +struct + type finite_domain_sort = FiniteDomainSort of sort + + let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x + + let finite_domain_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + FiniteDomainSort(s) + + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in + FiniteDomainSort(s) + + let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_sort ctx (Symbol.mk_string ctx name) size + + + let is_finite_domain ( x : expr ) = + let nc = (Expr.gnc x) in + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) + + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + + let get_size ( x : finite_domain_sort ) = + let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in + if r then v + else raise (Z3native.Exception "Conversion failed.") +end + + +module Relation = +struct + type relation_sort = RelationSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + RelationSort(s) + + let sort_of_relation_sort s = match s with RelationSort(x) -> x + + let relation_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RelationSort(s) + + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) + + + let is_relation ( x : expr ) = + let nc = (Expr.gnc x) in + ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) + + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + + let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) + + let get_column_sorts ( x : relation_sort ) = + let n = get_arity x in + let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in + mk_list f n + +end + + +module Datatype = +struct + type datatype_sort = DatatypeSort of sort + type datatype_expr = DatatypeExpr of expr + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + DatatypeSort(s) + + let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x + + let datatype_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeSort(s) + + let datatype_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeExpr(e) + + let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x + + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) + + module Constructor = + struct + type constructor = z3_native_object + + let _sizes = Hashtbl.create 0 + + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let n = (List.length field_names) in + if n != (List.length sorts) then + raise (Z3native.Exception "Number of field names does not match number of sorts") + else + if n != (List.length sort_refs) then + raise (Z3native.Exception "Number of field names does not match number of sort refs") + else + let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) + (Symbol.gno recognizer) + n + (Symbol.symbol_lton field_names) + (sort_lton sorts) + (Array.of_list sort_refs)) in + let no : constructor = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + (z3obj_sno no ctx ptr) ; + (z3obj_create no) ; + let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f no ; + Hashtbl.add _sizes no n ; + no + + let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x + + let get_constructor_decl ( x : constructor ) = + let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in + func_decl_of_ptr (z3obj_gc x) a + + let get_tester_decl ( x : constructor ) = + let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in + func_decl_of_ptr (z3obj_gc x) b + + let get_accessor_decls ( x : constructor ) = + let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in + let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in + mk_list f (Array.length c) + + end + + module ConstructorList = + struct + type constructor_list = z3_native_object + + let create ( ctx : context ) ( c : Constructor.constructor list ) = + let res : constructor_list = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + let f x =(z3obj_gno x) in + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; + (z3obj_create res) ; + let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f res; + res + end + + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + Constructor.create ctx name recognizer field_names sorts sort_refs + + + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = + let f x = (z3obj_gno x) in + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in + sort_of_ptr ctx x + + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = + mk_sort ctx (Symbol.mk_string ctx name) constructors + + let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = + let n = (List.length names) in + let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in + let cla = (Array.of_list (List.map f c)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in + let g i = (sort_of_ptr ctx (Array.get r i)) in + mk_list g (Array.length r) + + let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = + mk_sorts ctx + ( + let f e = (Symbol.mk_string ctx e) in + List.map f names + ) + c + + let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) + + let get_constructors ( x : datatype_sort ) = + let n = (get_num_constructors x) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + mk_list f n + + let get_recognizers ( x : datatype_sort ) = + let n = (get_num_constructors x) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in + mk_list f n + + let get_accessors ( x : datatype_sort ) = + let n = (get_num_constructors x) in + let f i = ( + let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in + let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in + mk_list g ds + ) in + mk_list f n +end + + +module Enumeration = +struct + type enum_sort = EnumSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = + let s = (sort_of_ptr ctx no) in + let res = EnumSort(s) in + res + + let sort_of_enum_sort s = match s with EnumSort(x) -> x + + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in + sort_of_ptr ctx a (list_of_array b) (list_of_array c) + + let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = + mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) + + let get_const_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in + mk_list f n + + let get_tester_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in + mk_list f n + +end + + +module List_ = +struct + type list_sort = ListSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + let res = ListSort(s) in + res + + let sort_of_list_sort s = match s with ListSort(x) -> x + + let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in + sort_of_ptr ctx r a b c d e f + + let mk_list_s ( ctx : context ) (name : string) elem_sort = + mk_sort ctx (Symbol.mk_string ctx name) elem_sort + + let get_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) + + let get_is_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) + + let get_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) + + let get_is_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) + + let get_head_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) + + let get_tail_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) + + let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] +end + + +module Tuple = +struct + type tuple_sort = TupleSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + TupleSort(s) + + let sort_of_tuple_sort s = match s with TupleSort(x) -> x + + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = + let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in + sort_of_ptr ctx r + + let get_mk_decl ( x : tuple_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) + + let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) + + let get_field_decls ( x : tuple_sort ) = + let n = get_num_fields x in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in + mk_list f n +end + + +module rec Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr + + val sort_of_arith_sort : arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> arith_sort + val expr_of_arith_expr : arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> arith_expr + + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end + + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool + val mk_add : context -> arith_expr list -> arith_expr + val mk_mul : context -> arith_expr list -> arith_expr + val mk_sub : context -> arith_expr list -> arith_expr + val mk_unary_minus : context -> arith_expr -> arith_expr + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr +end = struct + type arith_sort = ArithSort of sort + type arith_expr = ArithExpr of expr + + let arith_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithExpr(e) + + let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + arith_expr_of_expr (expr_of_ptr ctx no) + + let sort_of_arith_sort s = match s with ArithSort(x) -> x + let expr_of_arith_expr e = match e with ArithExpr(x) -> x + + let arith_sort_of_sort s = match s with Sort(a) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithSort(s) + + let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + arith_sort_of_sort (sort_of_ptr ctx no) + + let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) + let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) + let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) + let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) + + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end = struct + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + let int_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntExpr(e) + + let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let int_num_of_int_expr e = + match e with IntExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + IntNum(e) + + let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_num_of_int_expr (int_expr_of_ptr ctx no) + + let arith_sort_of_int_sort s = match s with IntSort(x) -> x + let arith_expr_of_int_expr e = match e with IntExpr(x) -> x + let int_expr_of_int_num e = match e with IntNum(x) -> x + + let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntSort(s) + + let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) + + let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) + let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) + let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) + let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) + let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) + let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) + let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) + let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) + let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) + + let mk_sort ( ctx : context ) = + int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) + + let get_int ( x : int_num ) = + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + if r then v + else raise (Z3native.Exception "Conversion failed.") + + let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) + + let mk_int_const_s ( ctx : context ) ( name : string ) = + mk_int_const ctx (Symbol.mk_string ctx name) + + let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + + let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + + let mk_int_numeral_s ( ctx : context ) ( v : string ) = + int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_int_numeral_i ( ctx : context ) ( v : int ) = + int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_int2real ( ctx : context ) ( t : int_expr ) = + Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) + + let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = + BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) + end + + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : real_sort -> arith_sort + val real_sort_of_arith_sort : arith_sort -> real_sort + val arith_expr_of_real_expr : real_expr -> arith_expr + val real_expr_of_rat_num : rat_num -> real_expr + val real_expr_of_arith_expr : arith_expr -> real_expr + val rat_num_of_real_expr : real_expr -> rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end = struct + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + let arith_sort_of_real_sort s = match s with RealSort(x) -> x + let arith_expr_of_real_expr e = match e with RealExpr(x) -> x + let real_expr_of_rat_num e = match e with RatNum(x) -> x + + let real_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealExpr(e) + + let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let rat_num_of_real_expr e = + match e with RealExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + RatNum(e) + + let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + rat_num_of_real_expr (real_expr_of_ptr ctx no) + + let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealSort(s) + + let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) + + let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) + let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) + let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) + let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) + let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) + let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) + let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) + let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) + let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) + + + let mk_sort ( ctx : context ) = + real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) + + let get_numerator ( x : rat_num ) = + Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + + let get_denominator ( x : rat_num ) = + Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + + let to_decimal_string ( x : rat_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) + + let mk_real_const_s ( ctx : context ) ( name : string ) = + mk_real_const ctx (Symbol.mk_string ctx name) + + let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + if (den == 0) then + raise (Z3native.Exception "Denominator is zero") + else + rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) + + let mk_numeral_s ( ctx : context ) ( v : string ) = + rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_numeral_i ( ctx : context ) ( v : int ) = + rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_is_integer ( ctx : context ) ( t : real_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) + + let mk_real2int ( ctx : context ) ( t : real_expr ) = + Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) + end + + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end = struct + type algebraic_num = AlgebraicNum of arith_expr + + let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x + + let algebraic_num_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + AlgebraicNum(e) + + let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + + let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) + let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) + let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) + + + let to_upper ( x : algebraic_num ) ( precision : int ) = + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + + let to_lower ( x : algebraic_num ) precision = + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + end + + let is_int ( x : expr ) = + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) + + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + + let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) + + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) + + let mk_add ( ctx : context ) ( t : arith_expr list ) = + let f x = (Expr.gno (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + + let mk_mul ( ctx : context ) ( t : arith_expr list ) = + let f x = (Expr.gno (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + + let mk_sub ( ctx : context ) ( t : arith_expr list ) = + let f x = (Expr.gno (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + + let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) + + let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) + + let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) + + let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) + + let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) + + let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) + + let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) +end + + +and BitVector : +sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + + val mk_sort : context -> int -> bitvec_sort + val is_bv : Expr.expr -> bool + val is_bv_numeral : Expr.expr -> bool + val is_bv_bit1 : Expr.expr -> bool + val is_bv_bit0 : Expr.expr -> bool + val is_bv_uminus : Expr.expr -> bool + val is_bv_add : Expr.expr -> bool + val is_bv_sub : Expr.expr -> bool + val is_bv_mul : Expr.expr -> bool + val is_bv_sdiv : Expr.expr -> bool + val is_bv_udiv : Expr.expr -> bool + val is_bv_SRem : Expr.expr -> bool + val is_bv_urem : Expr.expr -> bool + val is_bv_smod : Expr.expr -> bool + val is_bv_sdiv0 : Expr.expr -> bool + val is_bv_udiv0 : Expr.expr -> bool + val is_bv_srem0 : Expr.expr -> bool + val is_bv_urem0 : Expr.expr -> bool + val is_bv_smod0 : Expr.expr -> bool + val is_bv_ule : Expr.expr -> bool + val is_bv_sle : Expr.expr -> bool + val is_bv_uge : Expr.expr -> bool + val is_bv_sge : Expr.expr -> bool + val is_bv_ult : Expr.expr -> bool + val is_bv_slt : Expr.expr -> bool + val is_bv_ugt : Expr.expr -> bool + val is_bv_sgt : Expr.expr -> bool + val is_bv_and : Expr.expr -> bool + val is_bv_or : Expr.expr -> bool + val is_bv_not : Expr.expr -> bool + val is_bv_xor : Expr.expr -> bool + val is_bv_nand : Expr.expr -> bool + val is_bv_nor : Expr.expr -> bool + val is_bv_xnor : Expr.expr -> bool + val is_bv_concat : Expr.expr -> bool + val is_bv_signextension : Expr.expr -> bool + val is_bv_zeroextension : Expr.expr -> bool + val is_bv_extract : Expr.expr -> bool + val is_bv_repeat : Expr.expr -> bool + val is_bv_reduceor : Expr.expr -> bool + val is_bv_reduceand : Expr.expr -> bool + val is_bv_comp : Expr.expr -> bool + val is_bv_shiftleft : Expr.expr -> bool + val is_bv_shiftrightlogical : Expr.expr -> bool + val is_bv_shiftrightarithmetic : Expr.expr -> bool + val is_bv_rotateleft : Expr.expr -> bool + val is_bv_rotateright : Expr.expr -> bool + val is_bv_rotateleftextended : Expr.expr -> bool + val is_bv_rotaterightextended : Expr.expr -> bool + val is_int_to_bv : Expr.expr -> bool + val is_bv_to_int : Expr.expr -> bool + val is_bv_carry : Expr.expr -> bool + val is_bv_xor3 : Expr.expr -> bool + val get_size : bitvec_sort -> int + val get_int : bitvec_num -> int + val to_string : bitvec_num -> string + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + val mk_const_s : context -> string -> int -> bitvec_expr + val mk_not : context -> bitvec_expr -> Expr.expr + val mk_redand : context -> bitvec_expr -> Expr.expr + val mk_redor : context -> bitvec_expr -> Expr.expr + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_neg : context -> bitvec_expr -> bitvec_expr + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_numeral : context -> string -> int -> bitvec_num +end = struct + type bitvec_sort = BitVecSort of sort + type bitvec_expr = BitVecExpr of expr + type bitvec_num = BitVecNum of bitvec_expr + + let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x + + let bitvec_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecSort(s) + + let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_sort_of_sort (sort_of_ptr ctx no) + + let bitvec_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecExpr(e) + + let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_expr_of_expr (expr_of_ptr ctx no) + + let bitvec_num_of_bitvec_expr e = + match e with BitVecExpr(Expr(a)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecNum(e) + + let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) + + let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x + let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x + + + let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) + let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) + let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) + let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) + let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) + let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) + let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) + let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) + let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) + + + let mk_sort ( ctx : context ) size = + bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) + let is_bv ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) + let get_int ( x : bitvec_num ) = + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + if r then v + else raise (Z3native.Exception "Conversion failed.") + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) + let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_const ctx (Symbol.mk_string ctx name) size + let mk_not ( ctx : context ) ( t : bitvec_expr ) = + expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) + let mk_redand ( ctx : context ) ( t : bitvec_expr) = + expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) + let mk_redor ( ctx : context ) ( t : bitvec_expr) = + expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) + let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) + let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) + let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) + let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) + let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) + let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) + let mk_neg ( ctx : context ) ( t : bitvec_expr) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) + let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) + let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) + let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) + let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) + let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) + let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) + let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) + let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) + let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) + let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) + let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) + let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) + let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) + let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) + let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) + let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) + let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) + let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) + let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) + let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) + let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) + let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) + let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) + let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) + let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) + let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) + let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) + let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = + Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) + let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) + let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) + let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) + let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) + let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) + let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) + let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = + bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) +end + + +module Proof = +struct + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) +end + + +module Goal = +struct + type goal = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : goal = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.goal_inc_ref ; + dec_ref = Z3native.goal_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_precision ( x : goal ) = + goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) + + let is_precise ( x : goal ) = + (get_precision x) == GOAL_PRECISE + + let is_underapproximation ( x : goal ) = + (get_precision x) == GOAL_UNDER + + let is_overapproximation ( x : goal ) = + (get_precision x) == GOAL_OVER + + let is_garbage ( x : goal ) = + (get_precision x) == GOAL_UNDER_OVER + + let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in + ignore (List.map f constraints) ; + () + + let is_inconsistent ( x : goal ) = + Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) + + let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) + + let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) + + let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) + + let get_formulas ( x : goal ) = + let n = get_size x in + let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in + mk_list f n + + let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) + + let is_decided_sat ( x : goal ) = + Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) + + let is_decided_unsat ( x : goal ) = + Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) + + let translate ( x : goal ) ( to_ctx : context ) = + create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + + let simplify ( x : goal ) ( p : Params.params option ) = + let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in + Z3native.tactic_inc_ref (z3obj_gnc x) tn ; + let arn = match p with + | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) + | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) + in + Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; + let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in + let res = if sg == 0 then + raise (Z3native.Exception "No subgoals") + else + Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in + Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; + Z3native.tactic_dec_ref (z3obj_gnc x) tn ; + create (z3obj_gc x) res + + let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = + create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) + + let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) +end + + +module Model = +struct + type model = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : model = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.model_inc_ref ; + dec_ref = Z3native.model_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + module FuncInterp = + struct + type func_interp = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_interp = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_interp_inc_ref ; + dec_ref = Z3native.func_interp_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + module FuncEntry = + struct + type func_entry = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_entry = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_entry_inc_ref ; + dec_ref = Z3native.func_entry_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_value ( x : func_entry ) = + expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) + + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) + + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in + mk_list f n + + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + end + + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) + + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in + mk_list f n + + let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) + + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) + + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (List.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in + if (Z3native.is_null np) then + None + else + Some (expr_of_ptr (z3obj_gc x) np) + + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if not (Z3native.is_as_array (z3obj_gnc x) n) then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in + get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in + if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) + + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) + + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + (mk_list f n_funcs) @ (mk_list g n_consts) + + exception ModelEvaluationFailedException of string + + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in + if not r then + raise (ModelEvaluationFailedException "evaluation failed") + else + expr_of_ptr (z3obj_gc x) v + + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) + + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + mk_list f n + + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in + mk_list f n + + let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) +end + + +module Probe = +struct + type probe = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : probe = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.probe_inc_ref ; + dec_ref = Z3native.probe_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + + let apply ( x : probe ) ( g : Goal.goal ) = + Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) + + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes (context_gno ctx) + + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name (context_gno ctx) i) in + mk_list f n + + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr (context_gno ctx) name + + let mk_probe ( ctx : context ) ( name : string ) = + (create ctx (Z3native.mk_probe (context_gno ctx) name)) + + let const ( ctx : context ) ( v : float ) = + (create ctx (Z3native.probe_const (context_gno ctx) v)) + + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let not_ ( ctx : context ) ( p : probe ) = + (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) +end + + +module Tactic = +struct + type tactic = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : tactic = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.tactic_inc_ref ; + dec_ref = Z3native.tactic_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + module ApplyResult = + struct + type apply_result = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : apply_result = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.apply_result_inc_ref ; + dec_ref = Z3native.apply_result_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) + + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_subgoal ( x : apply_result ) ( i : int ) = + Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) + + let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) + end + + let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) + + let get_param_descrs ( x : tactic ) = + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + + let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = + match p with + | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) + | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) + + let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) + + let get_tactic_names ( ctx : context ) = + let n = (get_num_tactics ctx ) in + let f i = (Z3native.get_tactic_name (context_gno ctx) i) in + mk_list f n + + let get_tactic_description ( ctx : context ) ( name : string ) = + Z3native.tactic_get_descr (context_gno ctx) name + + let mk_tactic ( ctx : context ) ( name : string ) = + create ctx (Z3native.mk_tactic (context_gno ctx) name) + + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = + let f p c = (match p with + | None -> (Some (z3obj_gno c)) + | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in + match (List.fold_left f None ts) with + | None -> + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + | Some(x) -> + let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) + + let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + + let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = + create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) + + let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = + create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) + + let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = + create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) + + let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = + create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) + + let skip ( ctx : context ) = + create ctx (Z3native.tactic_skip (context_gno ctx)) + + let fail ( ctx : context ) = + create ctx (Z3native.tactic_fail (context_gno ctx)) + + let fail_if ( ctx : context ) ( p : Probe.probe ) = + create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) + + let fail_if_not_decided ( ctx : context ) = + create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) + + let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) + + let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + using_params ctx t p + + let par_or ( ctx : context ) ( t : tactic list ) = + let f e = (z3obj_gno e) in + create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) + + let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + + let interrupt ( ctx : context ) = + Z3native.interrupt (context_gno ctx) +end + + +module Solver = +struct + type solver = z3_native_object + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : solver = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.solver_inc_ref ; + dec_ref = Z3native.solver_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let string_of_status ( s : status) = match s with + | UNSATISFIABLE -> "unsatisfiable" + | SATISFIABLE -> "satisfiable" + | _ -> "unknown" + + module Statistics = + struct + type statistics = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : statistics = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.stats_inc_ref ; + dec_ref = Z3native.stats_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + + module Entry = + struct + type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } + + let create_si k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = true ; + m_is_float = false ; + m_int = v ; + m_float = 0.0 + } in + res + + let create_sd k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = false ; + m_is_float = true ; + m_int = 0 ; + m_float = v + } in + res + + + let get_key (x : statistics_entry) = x.m_key + let get_int (x : statistics_entry) = x.m_int + let get_float (x : statistics_entry) = x.m_float + let is_int (x : statistics_entry) = x.m_is_int + let is_float (x : statistics_entry) = x.m_is_float + let to_string_value (x : statistics_entry) = + if (is_int x) then + string_of_int (get_int x) + else if (is_float x) then + string_of_float (get_float x) + else + raise (Z3native.Exception "Unknown statistical entry type") + let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) + end + + let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) + + let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) + + let get_entries ( x : statistics ) = + let n = (get_size x ) in + let f i = ( + let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in + if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then + (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) + else + (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + ) in + mk_list f n + + let get_keys ( x : statistics ) = + let n = (get_size x) in + let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get ( x : statistics ) ( key : string ) = + let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in + List.fold_left f None (get_entries x) + end + + let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) + + let set_parameters ( x : solver ) ( p : Params.params )= + Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) + + let get_param_descrs ( x : solver ) = + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + + let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) + + let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) + + let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n + + let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) + + let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + ignore (List.map f constraints) + + let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = + if ((List.length cs) != (List.length ps)) then + raise (Z3native.Exception "Argument size mismatch") + else + let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in + ignore (List.iter2 f cs ps) + + let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) + + let get_num_assertions ( x : solver ) = + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + (AST.ASTVector.get_size a) + + let get_assertions ( x : solver ) = + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size a) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in + mk_list f n + + let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = + let r = + if ((List.length assumptions) == 0) then + lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) + else + let f x = (Expr.gno (Boolean.expr_of_bool_expr x)) in + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) + in + match r with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN + + let get_model ( x : solver ) = + let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in + if (Z3native.is_null q) then + None + else + Some (Model.create (z3obj_gc x) q) + + let get_proof ( x : solver ) = + let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in + if (Z3native.is_null q) then + None + else + Some (expr_of_ptr (z3obj_gc x) q) + + let get_unsat_core ( x : solver ) = + let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size cn) in + let f i = (AST.ASTVector.get cn i) in + mk_list f n + + let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) + + let get_statistics ( x : solver ) = + (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) + + let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = + match logic with + | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) + + let mk_solver_s ( ctx : context ) ( logic : string ) = + mk_solver ctx (Some (Symbol.mk_string ctx logic)) + + let mk_simple_solver ( ctx : context ) = + (create ctx (Z3native.mk_simple_solver (context_gno ctx))) + + let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = + (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) + + let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) +end + + +module Fixedpoint = +struct + type fixedpoint = z3_native_object + + let create ( ctx : context ) = + let res : fixedpoint = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.fixedpoint_inc_ref ; + dec_ref = Z3native.fixedpoint_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; + (z3obj_create res) ; + res + + + let get_help ( x : fixedpoint ) = + Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) + + let set_params ( x : fixedpoint ) ( p : Params.params )= + Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) + + let get_param_descrs ( x : fixedpoint ) = + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + + let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + ignore (List.map f constraints) ; + () + + let register_relation ( x : fixedpoint ) ( f : func_decl ) = + Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) + + let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = + match name with + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) + + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) + + let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + let query_r ( x : fixedpoint ) ( relations : func_decl list ) = + let f x = ptr_of_ast (ast_of_func_decl x) in + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + let push ( x : fixedpoint ) = + Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) + + let pop ( x : fixedpoint ) = + Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) + + let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) + + let get_answer ( x : fixedpoint ) = + let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in + if (Z3native.is_null q) then + None + else + Some (expr_of_ptr (z3obj_gc x) q) + + let get_reason_unknown ( x : fixedpoint ) = + Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) + + let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = + Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) + + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = + let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in + if (Z3native.is_null q) then + None + else + Some (expr_of_ptr (z3obj_gc x) q) + + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) + + let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] + + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) + + let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = + let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) + + let get_rules ( x : fixedpoint ) = + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + mk_list f n + + let get_assertions ( x : fixedpoint ) = + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + mk_list f n + + let mk_fixedpoint ( ctx : context ) = create ctx +end + +module Options = +struct + + let update_param_value ( ctx : context ) ( id : string) ( value : string )= + Z3native.update_param_value (context_gno ctx) id value + + let get_param_value ( ctx : context ) ( id : string ) = + let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in + if not r then + None + else + Some v + + let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = + Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) + + let toggle_warning_messages ( enabled: bool ) = + Z3native.toggle_warning_messages enabled +end + + +module SMT = +struct + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = + Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes + (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) + (Boolean.gno formula) + + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Z3native.parse_smtlib_string (context_gno ctx) str + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) + + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Z3native.parse_smtlib_file (context_gno ctx) file_name + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) + + let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) + + let get_smtlib_formulas ( ctx : context ) = + let n = (get_num_smtlib_formulas ctx ) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in + mk_list f n + + let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) + + let get_smtlib_assumptions ( ctx : context ) = + let n = (get_num_smtlib_assumptions ctx ) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in + mk_list f n + + let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) + + let get_smtlib_decls ( ctx : context ) = + let n = (get_num_smtlib_decls ctx) in + let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in + mk_list f n + + let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) + + let get_smtlib_sorts ( ctx : context ) = + let n = (get_num_smtlib_sorts ctx) in + let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in + mk_list f n + + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) + + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) +end + + +let set_global_param ( id : string ) ( value : string ) = + (Z3native.global_param_set id value) + +let get_global_param ( id : string ) = + let (r, v) = (Z3native.global_param_get id) in + if not r then + None + else + Some v + +let global_param_reset_all = + Z3native.global_param_reset_all diff --git a/src/api/ml/z3_rich.mli b/src/api/ml/z3_rich.mli new file mode 100644 index 000000000..8b6681e11 --- /dev/null +++ b/src/api/ml/z3_rich.mli @@ -0,0 +1,3072 @@ +(** + The Z3 ML/Ocaml Interface. + + Copyright (C) 2012 Microsoft Corporation + @author CM Wintersteiger (cwinter) 2012-12-17 + + NOTE: This is the *rich* version of the interface, using more + type information directly in the type system. Coercion functions + are provided to tran coerce on type into another where applicable. +*) + +(** Context objects. + + Most interactions with Z3 are interpreted in some context; many users will only + require one such object, but power users may require more than one. To start using + Z3, do + + + let ctx = (mk_context []) in + (...) + + + where a list of pairs of strings may be passed to set options on + the context, e.g., like so: + + + let cfg = [("model", "true"); ("...", "...")] in + let ctx = (mk_context cfg) in + (...) + +*) +type context + +(** Create a context object *) +val mk_context : (string * string) list -> context + + +(** Interaction logging for Z3 + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log : +sig + (** Open an interaction log file. + @return True if opening the log file succeeds, false otherwise. *) + (* CMW: "open" seems to be a reserved keyword? *) + val open_ : string -> bool + + (** Closes the interaction log. *) + val close : unit + + (** Appends a user-provided string to the interaction log. *) + val append : string -> unit +end + +(** Version information *) +module Version : +sig + (** The major version. *) + val major : int + + (** The minor version. *) + val minor : int + + (** The build version. *) + val build : int + + (** The revision. *) + val revision : int + + (** A string representation of the version information. *) + val to_string : string +end + +(** Symbols are used to name several term and type constructors *) +module Symbol : +sig + (** Numbered Symbols *) + type int_symbol + + (** Named Symbols *) + type string_symbol + + (** Symbols *) + type symbol = S_Int of int_symbol | S_Str of string_symbol + + (** The kind of the symbol (int or string) *) + val kind : symbol -> Z3enums.symbol_kind + + (** Indicates whether the symbol is of Int kind *) + val is_int_symbol : symbol -> bool + + (** Indicates whether the symbol is of string kind. *) + val is_string_symbol : symbol -> bool + + (** The int value of the symbol. *) + val get_int : int_symbol -> int + + (** The string value of the symbol. *) + val get_string : string_symbol -> string + + (** A string representation of the symbol. *) + val to_string : symbol -> string + + (** Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. *) + val mk_int : context -> int -> symbol + + (** Creates a new symbol using a string. *) + val mk_string : context -> string -> symbol + + (** Create a list of symbols. *) + val mk_ints : context -> int list -> symbol list + + (** Create a list of symbols. *) + val mk_strings : context -> string list -> symbol list +end + +(** The abstract syntax tree (AST) module *) +module AST : +sig + type ast + + (** Vectors of ASTs *) + module ASTVector : + sig + type ast_vector + + (** The size of the vector *) + val get_size : ast_vector -> int + + (** + Retrieves the i-th object in the vector. + @return An AST *) + val get : ast_vector -> int -> ast + + (** Sets the i-th object in the vector. *) + val set : ast_vector -> int -> ast -> unit + + (** Resize the vector to a new size. *) + val resize : ast_vector -> int -> unit + + (** Add an ast to the back of the vector. The size + is increased by 1. *) + val push : ast_vector -> ast -> unit + + (** Translates all ASTs in the vector to another context. + @return A new ASTVector *) + val translate : ast_vector -> context -> ast_vector + + (** Retrieves a string representation of the vector. *) + val to_string : ast_vector -> string + end + + (** Map from AST to AST *) + module ASTMap : + sig + type ast_map + + (** Checks whether the map contains a key. + @return True if the key in the map, false otherwise. *) + val contains : ast_map -> ast -> bool + + (** Finds the value associated with the key. + This function signs an error when the key is not a key in the map. *) + val find : ast_map -> ast -> ast + + (** Stores or replaces a new key/value pair in the map. *) + val insert : ast_map -> ast -> ast -> unit + + (** Erases the key from the map.*) + val erase : ast_map -> ast -> unit + + (** Removes all keys from the map. *) + val reset : ast_map -> unit + + (** The size of the map *) + val get_size : ast_map -> int + + (** The keys stored in the map. *) + val get_keys : ast_map -> ast list + + (** Retrieves a string representation of the map.*) + val to_string : ast_map -> string + end + + (** The AST's hash code. + @return A hash code *) + val get_hash_code : ast -> int + + (** A unique identifier for the AST (unique among all ASTs). *) + val get_id : ast -> int + + (** The kind of the AST. *) + val get_ast_kind : ast -> Z3enums.ast_kind + + (** Indicates whether the AST is an Expr *) + val is_expr : ast -> bool + + (** Indicates whether the AST is a bound variable*) + val is_var : ast -> bool + + (** Indicates whether the AST is a Quantifier *) + val is_quantifier : ast -> bool + + (** Indicates whether the AST is a Sort *) + val is_sort : ast -> bool + + (** Indicates whether the AST is a func_decl *) + val is_func_decl : ast -> bool + + (** A string representation of the AST. *) + val to_string : ast -> string + + (** A string representation of the AST in s-expression notation. *) + val to_sexpr : ast -> string + + (** Comparison operator. + @return True if the two ast's are from the same context + and represent the same sort; false otherwise. *) + val ( = ) : ast -> ast -> bool + + (** Object Comparison. + @return Negative if the first ast should be sorted before the second, positive if after else zero. *) + val compare : ast -> ast -> int + + (** Operator < *) + val ( < ) : ast -> ast -> int + + (** Translates (copies) the AST to another context. + @return A copy of the AST which is associated with the other context. *) + val translate : ast -> context -> ast + + (** Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) + and that it must have a correct reference count (see e.g., + Z3native.inc_ref). *) + val wrap_ast : context -> Z3native.z3_ast -> ast + + (** Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + Z3native.inc_ref). + {!wrap_ast} *) + val unwrap_ast : ast -> Z3native.ptr +end + +(** The Sort module implements type information for ASTs *) +module Sort : +sig + (** Sorts *) + type sort = Sort of AST.ast + + (** Uninterpreted Sorts *) + type uninterpreted_sort = UninterpretedSort of sort + + val ast_of_sort : sort -> AST.ast + val sort_of_uninterpreted_sort : uninterpreted_sort -> sort + val uninterpreted_sort_of_sort : sort -> uninterpreted_sort + + (** Comparison operator. + @return True if the two sorts are from the same context + and represent the same sort; false otherwise. *) + val ( = ) : sort -> sort -> bool + + (** Returns a unique identifier for the sort. *) + val get_id : sort -> int + + (** The kind of the sort. *) + val get_sort_kind : sort -> Z3enums.sort_kind + + (** The name of the sort *) + val get_name : sort -> Symbol.symbol + + (** A string representation of the sort. *) + val to_string : sort -> string + + (** Create a new uninterpreted sort. *) + val mk_uninterpreted : context -> Symbol.symbol -> uninterpreted_sort + + (** Create a new uninterpreted sort. *) + val mk_uninterpreted_s : context -> string -> uninterpreted_sort +end + +(** Function declarations *) +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + + (** Parameters of Func_Decls *) + module Parameter : + sig + (** Parameters of func_decls *) + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + (** The kind of the parameter. *) + val get_kind : parameter -> Z3enums.parameter_kind + + (** The int value of the parameter.*) + val get_int : parameter -> int + + (** The double value of the parameter.*) + val get_float : parameter -> float + + (** The Symbol.Symbol value of the parameter.*) + val get_symbol : parameter -> Symbol.symbol + + (** The Sort value of the parameter.*) + val get_sort : parameter -> Sort.sort + + (** The AST value of the parameter.*) + val get_ast : parameter -> AST.ast + + (** The FunctionDeclaration value of the parameter.*) + val get_func_decl : parameter -> func_decl + + (** The rational string value of the parameter.*) + val get_rational : parameter -> string + end + + (** Creates a new function declaration. *) + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl + + (** Creates a new function declaration. *) + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + (** Creates a fresh function declaration with a name prefixed with a prefix string. *) + + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl + + (** Creates a new constant function declaration. *) + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + + (** Creates a new constant function declaration. *) + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + + (** Creates a fresh constant function declaration with a name prefixed with a prefix string. + {!mk_func_decl} + {!mk_func_decl} *) + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + + (** Comparison operator. + @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) + val ( = ) : func_decl -> func_decl -> bool + + (** A string representations of the function declaration. *) + val to_string : func_decl -> string + + (** Returns a unique identifier for the function declaration. *) + val get_id : func_decl -> int + + (** The arity of the function declaration *) + val get_arity : func_decl -> int + + (** The size of the domain of the function declaration + {!get_arity} *) + val get_domain_size : func_decl -> int + + (** The domain of the function declaration *) + val get_domain : func_decl -> Sort.sort list + + (** The range of the function declaration *) + val get_range : func_decl -> Sort.sort + + (** The kind of the function declaration. *) + val get_decl_kind : func_decl -> Z3enums.decl_kind + + (** The name of the function declaration*) + val get_name : func_decl -> Symbol.symbol + + (** The number of parameters of the function declaration *) + val get_num_parameters : func_decl -> int + + (** The parameters of the function declaration *) + val get_parameters : func_decl -> Parameter.parameter list + + (** Create expression that applies function to arguments. *) + val apply : func_decl -> Expr.expr list -> Expr.expr +end + +(** Parameter sets (of Solvers, Tactics, ...) + + A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) +and Params : +sig + type params + + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs : + sig + type param_descrs + + (** Validate a set of parameters. *) + val validate : param_descrs -> params -> unit + + (** Retrieve kind of parameter. *) + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + + (** Retrieve all names of parameters. *) + val get_names : param_descrs -> Symbol.symbol list + + (** The size of the ParamDescrs. *) + val get_size : param_descrs -> int + + (** Retrieves a string representation of the ParamDescrs. *) + val to_string : param_descrs -> string + end + + (** Adds a parameter setting. *) + val add_bool : params -> Symbol.symbol -> bool -> unit + + (** Adds a parameter setting. *) + val add_int : params -> Symbol.symbol -> int -> unit + + (** Adds a parameter setting. *) + val add_double : params -> Symbol.symbol -> float -> unit + + (** Adds a parameter setting. *) + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + + (** Adds a parameter setting. *) + val add_s_bool : params -> string -> bool -> unit + + (** Adds a parameter setting. *) + val add_s_int : params -> string -> int -> unit + + (** Adds a parameter setting. *) + val add_s_double : params -> string -> float -> unit + + (** Adds a parameter setting. *) + val add_s_symbol : params -> string -> Symbol.symbol -> unit + + (** Creates a new parameter set *) + val mk_params : context -> params + + (** A string representation of the parameter set. *) + val to_string : params -> string +end + +(** General Expressions (terms) *) +and Expr : +sig + type expr = Expr of AST.ast + + val ast_of_expr : Expr.expr -> AST.ast + val expr_of_ast : AST.ast -> Expr.expr + + (** Returns a simplified version of the expression. + {!get_simplify_help} *) + val simplify : Expr.expr -> Params.params option -> expr + + (** A string describing all available parameters to Expr.Simplify. *) + val get_simplify_help : context -> string + + (** Retrieves parameter descriptions for simplifier. *) + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + + (** The function declaration of the function that is applied in this expression. *) + val get_func_decl : Expr.expr -> FuncDecl.func_decl + + (** Indicates whether the expression is the true or false expression + or something else (L_UNDEF). *) + val get_bool_value : Expr.expr -> Z3enums.lbool + + (** The number of arguments of the expression. *) + val get_num_args : Expr.expr -> int + + (** The arguments of the expression. *) + val get_args : Expr.expr -> Expr.expr list + + (** Update the arguments of the expression using an array of expressions. + The number of new arguments should coincide with the current number of arguments. *) + val update : Expr.expr -> Expr.expr list -> expr + + (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + + The result is the new expression. The arrays from and to must have size num_exprs. + For every i smaller than num_exprs, we must have that + sort of from[i] must be equal to sort of to[i]. *) + val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr + + (** Substitute every occurrence of from in the expression with to. + {!substitute} *) + val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr + + (** Substitute the free variables in the expression with the expressions in the expr array + + For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) + val substitute_vars : Expr.expr -> Expr.expr list -> expr + + (** Translates (copies) the term to another context. + @return A copy of the term which is associated with the other context *) + val translate : Expr.expr -> context -> expr + + (** Returns a string representation of the expression. *) + val to_string : Expr.expr -> string + + (** Indicates whether the term is a numeral *) + val is_numeral : Expr.expr -> bool + + (** Indicates whether the term is well-sorted. + @return True if the term is well-sorted, false otherwise. *) + val is_well_sorted : Expr.expr -> bool + + (** The Sort of the term. *) + val get_sort : Expr.expr -> Sort.sort + + (** Indicates whether the term has Boolean sort. *) + val is_bool : Expr.expr -> bool + + (** Indicates whether the term represents a constant. *) + val is_const : Expr.expr -> bool + + (** Indicates whether the term is the constant true. *) + val is_true : Expr.expr -> bool + + (** Indicates whether the term is the constant false. *) + val is_false : Expr.expr -> bool + + (** Indicates whether the term is an equality predicate. *) + val is_eq : Expr.expr -> bool + + (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) + val is_distinct : Expr.expr -> bool + + (** Indicates whether the term is a ternary if-then-else term *) + val is_ite : Expr.expr -> bool + + (** Indicates whether the term is an n-ary conjunction *) + val is_and : Expr.expr -> bool + + (** Indicates whether the term is an n-ary disjunction *) + val is_or : Expr.expr -> bool + + (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) + val is_iff : Expr.expr -> bool + + (** Indicates whether the term is an exclusive or *) + val is_xor : Expr.expr -> bool + + (** Indicates whether the term is a negation *) + val is_not : Expr.expr -> bool + + (** Indicates whether the term is an implication *) + val is_implies : Expr.expr -> bool + + (** Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) + val is_label : Expr.expr -> bool + + (** Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) + val is_label_lit : Expr.expr -> bool + + (** Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) + val is_oeq : Expr.expr -> bool + + (** Creates a new constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + + (** Creates a new constant. *) + val mk_const_s : context -> string -> Sort.sort -> expr + + (** Creates a constant from the func_decl. *) + val mk_const_f : context -> FuncDecl.func_decl -> expr + + (** Creates a fresh constant with a name prefixed with a string. *) + val mk_fresh_const : context -> string -> Sort.sort -> expr + + (** Create a new function application. *) + val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr + + (** Create a numeral of a given sort. + @return A Term with the goven value and sort *) + val mk_numeral_string : context -> string -> Sort.sort -> expr + + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @return A Term with the given value and sort *) + val mk_numeral_int : context -> int -> Sort.sort -> expr +end + +(** Boolean expressions *) +module Boolean : +sig + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + + val expr_of_bool_expr : bool_expr -> Expr.expr + val sort_of_bool_sort : bool_sort -> Sort.sort + val bool_sort_of_sort : Sort.sort -> bool_sort + val bool_expr_of_expr : Expr.expr -> bool_expr + + (** Create a Boolean sort *) + val mk_sort : context -> bool_sort + + (** Create a Boolean constant. *) + val mk_const : context -> Symbol.symbol -> bool_expr + + (** Create a Boolean constant. *) + val mk_const_s : context -> string -> bool_expr + + (** The true Term. *) + val mk_true : context -> bool_expr + + (** The false Term. *) + val mk_false : context -> bool_expr + + (** Creates a Boolean value. *) + val mk_val : context -> bool -> bool_expr + + (** Creates the equality between two expr's. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr + + (** Creates a distinct term. *) + val mk_distinct : context -> Expr.expr list -> bool_expr + + (** Mk an expression representing not(a). *) + val mk_not : context -> bool_expr -> bool_expr + + (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 iff t2. *) + val mk_iff : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 -> t2. *) + val mk_implies : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 xor t2. *) + val mk_xor : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing the AND of args *) + val mk_and : context -> bool_expr list -> bool_expr + + (** Create an expression representing the OR of args *) + val mk_or : context -> bool_expr list -> bool_expr +end + +(** Quantifier expressions *) +module Quantifier : +sig + type quantifier = Quantifier of Expr.expr + + val expr_of_quantifier : quantifier -> Expr.expr + val quantifier_of_expr : Expr.expr -> quantifier + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. *) + module Pattern : + sig + type pattern = Pattern of AST.ast + + val ast_of_pattern : pattern -> AST.ast + val pattern_of_ast : AST.ast -> pattern + + (** The number of terms in the pattern. *) + val get_num_terms : pattern -> int + + (** The terms in the pattern. *) + val get_terms : pattern -> Expr.expr list + + (** A string representation of the pattern. *) + val to_string : pattern -> string + end + + + (** The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. *) + val get_index : Expr.expr -> int + + (** Indicates whether the quantifier is universal. *) + val is_universal : quantifier -> bool + + (** Indicates whether the quantifier is existential. *) + val is_existential : quantifier -> bool + + (** The weight of the quantifier. *) + val get_weight : quantifier -> int + + (** The number of patterns. *) + val get_num_patterns : quantifier -> int + + (** The patterns. *) + val get_patterns : quantifier -> Pattern.pattern list + + (** The number of no-patterns. *) + val get_num_no_patterns : quantifier -> int + + (** The no-patterns. *) + val get_no_patterns : quantifier -> Pattern.pattern list + + (** The number of bound variables. *) + val get_num_bound : quantifier -> int + + (** The symbols for the bound variables. *) + val get_bound_variable_names : quantifier -> Symbol.symbol list + + (** The sorts of the bound variables. *) + val get_bound_variable_sorts : quantifier -> Sort.sort list + + (** The body of the quantifier. *) + val get_body : quantifier -> Boolean.bool_expr + + (** Creates a new bound variable. *) + val mk_bound : context -> int -> Sort.sort -> Expr.expr + + (** Create a quantifier pattern. *) + val mk_pattern : context -> Expr.expr list -> Pattern.pattern + + (** Create a universal Quantifier. *) + val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a universal Quantifier. *) + val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier +end + +(** Functions to manipulate Array expressions *) +module Array_ : +sig + type array_sort = ArraySort of Sort.sort + type array_expr = ArrayExpr of Expr.expr + + val sort_of_array_sort : array_sort -> Sort.sort + val array_sort_of_sort : Sort.sort -> array_sort + val expr_of_array_expr : array_expr -> Expr.expr + + val array_expr_of_expr : Expr.expr -> array_expr + + (** Create a new array sort. *) + val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort + + (** Indicates whether the term is an array store. + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. *) + val is_store : Expr.expr -> bool + + (** Indicates whether the term is an array select. *) + val is_select : Expr.expr -> bool + + (** Indicates whether the term is a constant array. + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) + val is_constant_array : Expr.expr -> bool + + (** Indicates whether the term is a default array. + For example default(const(v)) = v. The function is unary. *) + val is_default_array : Expr.expr -> bool + + (** Indicates whether the term is an array map. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) + val is_array_map : Expr.expr -> bool + + (** Indicates whether the term is an as-array term. + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. *) + val is_as_array : Expr.expr -> bool + + (** Indicates whether the term is of an array sort. *) + val is_array : Expr.expr -> bool + + (** The domain of the array sort. *) + val get_domain : array_sort -> Sort.sort + + (** The range of the array sort. *) + val get_range : array_sort -> Sort.sort + + (** Create an array constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr + + (** Create an array constant. *) + val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr + + (** Array read. + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + {!Array_.mk_sort} + {!mk_store} *) + val mk_select : context -> array_expr -> Expr.expr -> array_expr + + (** Array update. + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + {!Array_.mk_sort} + {!mk_select} *) + val mk_store : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr + + (** Create a constant array. + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + {!Array_.mk_sort} + {!mk_select} *) + val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr + + (** Maps f on the argument arrays. + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + {!Array_.mk_sort} + {!mk_select} + {!mk_store} *) + val mk_map : context -> FuncDecl.func_decl -> array_expr list -> array_expr + + (** Access the array default value. + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. *) + val mk_term_array : context -> array_expr -> array_expr +end + +(** Functions to manipulate Set expressions *) +module Set : +sig + type set_sort = SetSort of Sort.sort + + val sort_of_set_sort : set_sort -> Sort.sort + + (** Create a set type. *) + val mk_sort : context -> Sort.sort -> set_sort + + (** Indicates whether the term is set union *) + val is_union : Expr.expr -> bool + + (** Indicates whether the term is set intersection *) + val is_intersect : Expr.expr -> bool + + (** Indicates whether the term is set difference *) + val is_difference : Expr.expr -> bool + + (** Indicates whether the term is set complement *) + val is_complement : Expr.expr -> bool + + (** Indicates whether the term is set subset *) + val is_subset : Expr.expr -> bool + + (** Create an empty set. *) + val mk_empty : context -> Sort.sort -> Expr.expr + + (** Create the full set. *) + val mk_full : context -> Sort.sort -> Expr.expr + + (** Add an element to the set. *) + val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Remove an element from a set. *) + val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Take the union of a list of sets. *) + val mk_union : context -> Expr.expr list -> Expr.expr + + (** Take the intersection of a list of sets. *) + val mk_intersection : context -> Expr.expr list -> Expr.expr + + (** Take the difference between two sets. *) + val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Take the complement of a set. *) + val mk_complement : context -> Expr.expr -> Expr.expr + + (** Check for set membership. *) + val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Check for subsetness of sets. *) + val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr +end + +(** Functions to manipulate Finite Domain expressions *) +module FiniteDomain : +sig + type finite_domain_sort = FiniteDomainSort of Sort.sort + + val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort + val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort + + (** Create a new finite domain sort. *) + val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort + + (** Create a new finite domain sort. *) + val mk_sort_s : context -> string -> int -> finite_domain_sort + + (** Indicates whether the term is of an array sort. *) + val is_finite_domain : Expr.expr -> bool + + (** Indicates whether the term is a less than predicate over a finite domain. *) + val is_lt : Expr.expr -> bool + + (** The size of the finite domain sort. *) + val get_size : finite_domain_sort -> int +end + + +(** Functions to manipulate Relation expressions *) +module Relation : +sig + type relation_sort = RelationSort of Sort.sort + + val sort_of_relation_sort : relation_sort -> Sort.sort + val relation_sort_of_sort : Sort.sort -> relation_sort + + (** Indicates whether the term is of a relation sort. *) + val is_relation : Expr.expr -> bool + + (** Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. *) + val is_store : Expr.expr -> bool + + (** Indicates whether the term is an empty relation *) + val is_empty : Expr.expr -> bool + + (** Indicates whether the term is a test for the emptiness of a relation *) + val is_is_empty : Expr.expr -> bool + + (** Indicates whether the term is a relational join *) + val is_join : Expr.expr -> bool + + (** Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. *) + val is_union : Expr.expr -> bool + + (** Indicates whether the term is the widening of two relations + The function takes two arguments. *) + val is_widen : Expr.expr -> bool + + (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. *) + val is_project : Expr.expr -> bool + + (** Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. *) + val is_filter : Expr.expr -> bool + + (** Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. *) + val is_negation_filter : Expr.expr -> bool + + (** Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. *) + val is_rename : Expr.expr -> bool + + (** Indicates whether the term is the complement of a relation *) + val is_complement : Expr.expr -> bool + + (** Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. *) + val is_select : Expr.expr -> bool + + (** Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind {!is_union} + to perform destructive updates to the first argument. *) + val is_clone : Expr.expr -> bool + + (** The arity of the relation sort. *) + val get_arity : relation_sort -> int + + (** The sorts of the columns of the relation sort. *) + val get_column_sorts : relation_sort -> relation_sort list +end + +(** Functions to manipulate Datatype expressions *) +module Datatype : +sig + type datatype_sort = DatatypeSort of Sort.sort + type datatype_expr = DatatypeExpr of Expr.expr + + val sort_of_datatype_sort : datatype_sort -> Sort.sort + val datatype_sort_of_sort : Sort.sort -> datatype_sort + val expr_of_datatype_expr : datatype_expr -> Expr.expr + val datatype_expr_of_expr : Expr.expr -> datatype_expr + + (** Datatype Constructors *) + module Constructor : + sig + type constructor + + (** The number of fields of the constructor. *) + val get_num_fields : constructor -> int + + (** The function declaration of the constructor. *) + val get_constructor_decl : constructor -> FuncDecl.func_decl + + (** The function declaration of the tester. *) + val get_tester_decl : constructor -> FuncDecl.func_decl + + (** The function declarations of the accessors *) + val get_accessor_decls : constructor -> FuncDecl.func_decl list + end + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + + (** Create a new datatype sort. *) + val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> datatype_sort + + (** Create a new datatype sort. *) + val mk_sort_s : context -> string -> Constructor.constructor list -> datatype_sort + + (** Create mutually recursive datatypes. *) + val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> datatype_sort list + + (** Create mutually recursive data-types. *) + val mk_sorts_s : context -> string list -> Constructor.constructor list list -> datatype_sort list + + + (** The number of constructors of the datatype sort. *) + val get_num_constructors : datatype_sort -> int + + (** The constructors. *) + val get_constructors : datatype_sort -> FuncDecl.func_decl list + + (** The recognizers. *) + val get_recognizers : datatype_sort -> FuncDecl.func_decl list + + (** The constructor accessors. *) + val get_accessors : datatype_sort -> FuncDecl.func_decl list list +end + +(** Functions to manipulate Enumeration expressions *) +module Enumeration : +sig + type enum_sort = EnumSort of Sort.sort + + val sort_of_enum_sort : enum_sort -> Sort.sort + + (** Create a new enumeration sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> enum_sort + + (** Create a new enumeration sort. *) + val mk_sort_s : context -> string -> string list -> enum_sort + + (** The function declarations of the constants in the enumeration. *) + val get_const_decls : enum_sort -> FuncDecl.func_decl list + + (** The test predicates for the constants in the enumeration. *) + val get_tester_decls : enum_sort -> FuncDecl.func_decl list +end + +(** Functions to manipulate List expressions *) +module List_ : +sig + type list_sort = ListSort of Sort.sort + + val sort_of_list_sort : list_sort -> Sort.sort + + (** Create a new list sort. *) + val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort + + (** Create a new list sort. *) + val mk_list_s : context -> string -> Sort.sort -> list_sort + + (** The declaration of the nil function of this list sort. *) + val get_nil_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the isNil function of this list sort. *) + val get_is_nil_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the cons function of this list sort. *) + val get_cons_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the isCons function of this list sort. *) + val get_is_cons_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the head function of this list sort. *) + val get_head_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the tail function of this list sort. *) + val get_tail_decl : list_sort -> FuncDecl.func_decl + + (** The empty list. *) + val nil : list_sort -> Expr.expr +end + +(** Functions to manipulate Tuple expressions *) +module Tuple : +sig + type tuple_sort = TupleSort of Sort.sort + + val sort_of_tuple_sort : tuple_sort -> Sort.sort + + (** Create a new tuple sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> tuple_sort + + (** The constructor function of the tuple. *) + val get_mk_decl : tuple_sort -> FuncDecl.func_decl + + (** The number of fields in the tuple. *) + val get_num_fields : tuple_sort -> int + + (** The field declarations. *) + val get_field_decls : tuple_sort -> FuncDecl.func_decl list +end + +(** Functions to manipulate arithmetic expressions *) +module rec Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr + + val sort_of_arith_sort : Arithmetic.arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> Arithmetic.arith_sort + val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr + + (** Integer Arithmetic *) + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val arith_sort_of_int_sort : Arithmetic.Integer.int_sort -> Arithmetic.arith_sort + val int_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Integer.int_sort + val arith_expr_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.arith_expr + val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr + val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr + val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num + + (** Create a new integer sort. *) + val mk_sort : context -> int_sort + + (** Retrieve the int value. *) + val get_int : int_num -> int + + (** Returns a string representation of the numeral. *) + val to_string : int_num -> string + + (** Creates an integer constant. *) + val mk_int_const : context -> Symbol.symbol -> int_expr + + (** Creates an integer constant. *) + val mk_int_const_s : context -> string -> int_expr + + (** Create an expression representing t1 mod t2. + The arguments must have int type. *) + val mk_mod : context -> int_expr -> int_expr -> int_expr + + (** Create an expression representing t1 rem t2. + The arguments must have int type. *) + val mk_rem : context -> int_expr -> int_expr -> int_expr + + (** Create an integer numeral. *) + val mk_int_numeral_s : context -> string -> int_num + + (** Create an integer numeral. + @return A Term with the given value and sort Integer *) + val mk_int_numeral_i : context -> int -> int_num + + (** Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. *) + val mk_int2real : context -> int_expr -> Real.real_expr + + (** Create an n-bit bit-vector from an integer argument. + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. *) + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end + + (** Real Arithmetic *) + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + + (** Create a real sort. *) + val mk_sort : context -> real_sort + + (** The numerator of a rational numeral. *) + val get_numerator : rat_num -> Integer.int_num + + (** The denominator of a rational numeral. *) + val get_denominator : rat_num -> Integer.int_num + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as indicated by the int argument.*) + val to_decimal_string : rat_num -> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : rat_num -> string + + (** Creates a real constant. *) + val mk_real_const : context -> Symbol.symbol -> real_expr + + (** Creates a real constant. *) + val mk_real_const_s : context -> string -> real_expr + + (** Create a real numeral from a fraction. + @return A Term with rational value and sort Real + {!mk_numeral_s} *) + val mk_numeral_nd : context -> int -> int -> rat_num + + (** Create a real numeral. + @return A Term with the given value and sort Real *) + val mk_numeral_s : context -> string -> rat_num + + (** Create a real numeral. + @return A Term with the given value and sort Real *) + val mk_numeral_i : context -> int -> rat_num + + (** Creates an expression that checks whether a real number is an integer. *) + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + + (** Coerce a real to an integer. + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) + val mk_real2int : context -> real_expr -> Integer.int_expr + end + + (** Algebraic Numbers *) + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr + val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num + + (** Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_upper : algebraic_num -> int -> Real.rat_num + + (** Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_lower : algebraic_num -> int -> Real.rat_num + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as the int argument provided.*) + val to_decimal_string : algebraic_num -> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : algebraic_num -> string + end + + (** Indicates whether the term is of integer sort. *) + val is_int : Expr.expr -> bool + + (** Indicates whether the term is an arithmetic numeral. *) + val is_arithmetic_numeral : Expr.expr -> bool + + (** Indicates whether the term is a less-than-or-equal *) + val is_le : Expr.expr -> bool + + (** Indicates whether the term is a greater-than-or-equal *) + val is_ge : Expr.expr -> bool + + (** Indicates whether the term is a less-than *) + val is_lt : Expr.expr -> bool + + (** Indicates whether the term is a greater-than *) + val is_gt : Expr.expr -> bool + + (** Indicates whether the term is addition (binary) *) + val is_add : Expr.expr -> bool + + (** Indicates whether the term is subtraction (binary) *) + val is_sub : Expr.expr -> bool + + (** Indicates whether the term is a unary minus *) + val is_uminus : Expr.expr -> bool + + (** Indicates whether the term is multiplication (binary) *) + val is_mul : Expr.expr -> bool + + (** Indicates whether the term is division (binary) *) + val is_div : Expr.expr -> bool + + (** Indicates whether the term is integer division (binary) *) + val is_idiv : Expr.expr -> bool + + (** Indicates whether the term is remainder (binary) *) + val is_remainder : Expr.expr -> bool + + (** Indicates whether the term is modulus (binary) *) + val is_modulus : Expr.expr -> bool + + (** Indicates whether the term is a coercion of integer to real (unary) *) + val is_inttoreal : Expr.expr -> bool + + (** Indicates whether the term is a coercion of real to integer (unary) *) + val is_real_to_int : Expr.expr -> bool + + (** Indicates whether the term is a check that tests whether a real is integral (unary) *) + val is_real_is_int : Expr.expr -> bool + + (** Indicates whether the term is of sort real. *) + val is_real : Expr.expr -> bool + + (** Indicates whether the term is an integer numeral. *) + val is_int_numeral : Expr.expr -> bool + + (** Indicates whether the term is a real numeral. *) + val is_rat_num : Expr.expr -> bool + + (** Indicates whether the term is an algebraic number *) + val is_algebraic_number : Expr.expr -> bool + + (** Create an expression representing t[0] + t[1] + .... *) + val mk_add : context -> arith_expr list -> arith_expr + + (** Create an expression representing t[0] * t[1] * .... *) + val mk_mul : context -> arith_expr list -> arith_expr + + (** Create an expression representing t[0] - t[1] - .... *) + val mk_sub : context -> arith_expr list -> arith_expr + + (** Create an expression representing -t. *) + val mk_unary_minus : context -> arith_expr -> arith_expr + + (** Create an expression representing t1 / t2. *) + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + + (** Create an expression representing t1 ^ t2. *) + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + + (** Create an expression representing t1 < t2 *) + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 <= t2 *) + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 > t2 *) + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 >= t2 *) + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr +end + +(** Functions to manipulate bit-vector expressions *) +and BitVector : +sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + + (** Create a new bit-vector sort. *) + val mk_sort : context -> int -> bitvec_sort + + (** Indicates whether the terms is of bit-vector sort. *) + val is_bv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector numeral *) + val is_bv_numeral : Expr.expr -> bool + + (** Indicates whether the term is a one-bit bit-vector with value one *) + val is_bv_bit1 : Expr.expr -> bool + + (** Indicates whether the term is a one-bit bit-vector with value zero *) + val is_bv_bit0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unary minus *) + val is_bv_uminus : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector addition (binary) *) + val is_bv_add : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector subtraction (binary) *) + val is_bv_sub : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector multiplication (binary) *) + val is_bv_mul : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed division (binary) *) + val is_bv_sdiv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned division (binary) *) + val is_bv_udiv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed remainder (binary) *) + val is_bv_SRem : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) + val is_bv_urem : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed modulus *) + val is_bv_smod : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed division by zero *) + val is_bv_sdiv0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned division by zero *) + val is_bv_udiv0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed remainder by zero *) + val is_bv_srem0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned remainder by zero *) + val is_bv_urem0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed modulus by zero *) + val is_bv_smod0 : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) + val is_bv_ule : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector less-than-or-equal *) + val is_bv_sle : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) + val is_bv_uge : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) + val is_bv_sge : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector less-than *) + val is_bv_ult : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector less-than *) + val is_bv_slt : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector greater-than *) + val is_bv_ugt : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector greater-than *) + val is_bv_sgt : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise AND *) + val is_bv_and : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise OR *) + val is_bv_or : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NOT *) + val is_bv_not : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise XOR *) + val is_bv_xor : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NAND *) + val is_bv_nand : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NOR *) + val is_bv_nor : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise XNOR *) + val is_bv_xnor : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector concatenation (binary) *) + val is_bv_concat : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector sign extension *) + val is_bv_signextension : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector zero extension *) + val is_bv_zeroextension : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector extraction *) + val is_bv_extract : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector repetition *) + val is_bv_repeat : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector reduce OR *) + val is_bv_reduceor : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector reduce AND *) + val is_bv_reduceand : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector comparison *) + val is_bv_comp : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector shift left *) + val is_bv_shiftleft : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector logical shift right *) + val is_bv_shiftrightlogical : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector arithmetic shift left *) + val is_bv_shiftrightarithmetic : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate left *) + val is_bv_rotateleft : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate right *) + val is_bv_rotateright : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate left (extended) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) + val is_bv_rotateleftextended : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate right (extended) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) + val is_bv_rotaterightextended : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + + (** Indicates whether the term is a coercion from bit-vector to integer + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + val is_int_to_bv : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + val is_bv_to_int : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector carry + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) + val is_bv_carry : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector ternary XOR + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) + val is_bv_xor3 : Expr.expr -> bool + + (** The size of a bit-vector sort. *) + val get_size : bitvec_sort -> int + + (** Retrieve the int value. *) + val get_int : bitvec_num -> int + + (** Returns a string representation of the numeral. *) + val to_string : bitvec_num -> string + + (** Creates a bit-vector constant. *) + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + + (** Creates a bit-vector constant. *) + val mk_const_s : context -> string -> int -> bitvec_expr + + (** Bitwise negation. + The argument must have a bit-vector sort. *) + val mk_not : context -> bitvec_expr -> Expr.expr + + (** Take conjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) + val mk_redand : context -> bitvec_expr -> Expr.expr + + (** Take disjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) + val mk_redor : context -> bitvec_expr -> Expr.expr + + (** Bitwise conjunction. + The arguments must have a bit-vector sort. *) + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise disjunction. + The arguments must have a bit-vector sort. *) + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise XOR. + The arguments must have a bit-vector sort. *) + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise NAND. + The arguments must have a bit-vector sort. *) + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise NOR. + The arguments must have a bit-vector sort. *) + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise XNOR. + The arguments must have a bit-vector sort. *) + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Standard two's complement unary minus. + The arguments must have a bit-vector sort. *) + val mk_neg : context -> bitvec_expr -> bitvec_expr + + (** Two's complement addition. + The arguments must have the same bit-vector sort. *) + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement subtraction. + The arguments must have the same bit-vector sort. *) + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement multiplication. + The arguments must have the same bit-vector sort. *) + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned division. + + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. *) + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Signed remainder. + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned less-than + + The arguments must have the same bit-vector sort. *) + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed less-than + + The arguments must have the same bit-vector sort. *) + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned less-than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed less-than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned greater than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed greater than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned greater-than. + + The arguments must have the same bit-vector sort. *) + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed greater-than. + + The arguments must have the same bit-vector sort. *) + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Bit-vector concatenation. + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). *) + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bit-vector extraction. + + Extract the bits between two limits from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. *) + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector sign extension. + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. *) + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector zero extension. + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. *) + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector repetition. *) + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + + (** Shift left. + + It is equivalent to multiplication by 2^x where \c x is the value of third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling.*) + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Logical shift right + + It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Arithmetic shift right + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Rotate Left. + Rotate bits of \c t to the left \c i times. *) + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + + (** Rotate Right. + Rotate bits of \c t to the right \c i times.*) + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + + (** Rotate Left. + Rotate bits of the second argument to the left.*) + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Rotate Right. + Rotate bits of the second argument to the right. *) + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Create an integer from the bit-vector argument + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in the argument. + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function.*) + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + + (** Create a predicate that checks that the bit-wise addition does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise addition does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise subtraction does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise subtraction does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise signed division does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise negation does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise multiplication does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise multiplication does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a bit-vector numeral. *) + val mk_numeral : context -> string -> int -> bitvec_num +end + +(** Functions to manipulate proof expressions *) +module Proof : +sig + (** Indicates whether the term is a Proof for the expression 'true'. *) + val is_true : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact asserted by the user. *) + val is_asserted : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) + val is_goal : Expr.expr -> bool + + (** Indicates whether the term is proof via modus ponens + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). *) + val is_modus_ponens : Expr.expr -> bool + + (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. *) + val is_reflexivity : Expr.expr -> bool + + (** Indicates whether the term is proof by symmetricity of a relation + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. *) + val is_symmetry : Expr.expr -> bool + + (** Indicates whether the term is a proof by transitivity of a relation + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) *) + val is_transitivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by condensed transitivity of a relation + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. *) + val is_Transitivity_star : Expr.expr -> bool + + (** Indicates whether the term is a monotonicity proof object. + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. *) + val is_monotonicity : Expr.expr -> bool + + (** Indicates whether the term is a quant-intro proof + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) + val is_quant_intro : Expr.expr -> bool + + (** Indicates whether the term is a distributivity proof object. + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. *) + val is_distributivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by elimination of AND + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i *) + val is_and_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by eliminiation of not-or + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) *) + val is_or_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) + val is_rewrite : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) + val is_rewrite_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) + val is_pull_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents *) + val is_pull_quant_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pushing quantifiers in. + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents *) + val is_push_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for elimination of unused variables. + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. *) + val is_elim_unused_vars : Expr.expr -> bool + + (** Indicates whether the term is a proof for destructive equality resolution + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. *) + val is_der : Expr.expr -> bool + + (** Indicates whether the term is a proof for quantifier instantiation + + A proof of (or (not (forall (x) (P x))) (P a)) *) + val is_quant_inst : Expr.expr -> bool + + (** Indicates whether the term is a hypthesis marker. + Mark a hypothesis in a natural deduction style proof. *) + val is_hypothesis : Expr.expr -> bool + + (** Indicates whether the term is a proof by lemma + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. *) + val is_lemma : Expr.expr -> bool + + (** Indicates whether the term is a proof by unit resolution + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) + val is_unit_resolution : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-true + + T1: p + [iff-true T1]: (iff p true) *) + val is_iff_true : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-false + + T1: (not p) + [iff-false T1]: (iff p false) *) + val is_iff_false : Expr.expr -> bool + + (** Indicates whether the term is a proof by commutativity + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. *) + val is_commutativity : Expr.expr -> bool + + (** Indicates whether the term is a proof for Tseitin-like axioms + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). *) + val is_def_axiom : Expr.expr -> bool + + (** Indicates whether the term is a proof for introduction of a name + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) *) + val is_def_intro : Expr.expr -> bool + + (** Indicates whether the term is a proof for application of a definition + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. *) + val is_apply_def : Expr.expr -> bool + + (** Indicates whether the term is a proof iff-oeq + + T1: (iff p q) + [iff~ T1]: (~ p q) *) + val is_iff_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for a positive NNF step + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. *) + val is_nnf_pos : Expr.expr -> bool + + (** Indicates whether the term is a proof for a negative NNF step + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) *) + val is_nnf_neg : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + val is_nnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + val is_cnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for a Skolemization step + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. *) + val is_skolemize : Expr.expr -> bool + + (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q *) + val is_modus_ponens_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for theory lemma + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) + val is_theory_lemma : Expr.expr -> bool +end + +(** Goals + + A goal (aka problem). A goal is essentially a + of formulas, that can be solved and/or transformed using + tactics and solvers. *) +module Goal : +sig + type goal + + (** The precision of the goal. + + Goals can be transformed using over and under approximations. + An under approximation is applied when the objective is to find a model for a given goal. + An over approximation is applied when the objective is to find a proof for a given goal. *) + val get_precision : goal -> Z3enums.goal_prec + + (** Indicates whether the goal is precise. *) + val is_precise : goal -> bool + + (** Indicates whether the goal is an under-approximation. *) + val is_underapproximation : goal -> bool + + (** Indicates whether the goal is an over-approximation. *) + val is_overapproximation : goal -> bool + + (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) + val is_garbage : goal -> bool + + (** Adds the constraints to the given goal. *) + val assert_ : goal -> Boolean.bool_expr list -> unit + + (** Indicates whether the goal contains `false'. *) + val is_inconsistent : goal -> bool + + (** The depth of the goal. + This tracks how many transformations were applied to it. *) + val get_depth : goal -> int + + (** Erases all formulas from the given goal. *) + val reset : goal -> unit + + (** The number of formulas in the goal. *) + val get_size : goal -> int + + (** The formulas in the goal. *) + val get_formulas : goal -> Boolean.bool_expr list + + (** The number of formulas, subformulas and terms in the goal. *) + val get_num_exprs : goal -> int + + (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) + val is_decided_sat : goal -> bool + + (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) + val is_decided_unsat : goal -> bool + + (** Translates (copies) the Goal to another context.. *) + val translate : goal -> context -> goal + + (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) + val simplify : goal -> Params.params option -> goal + + (** Creates a new Goal. + + Note that the Context must have been created with proof generation support if + the fourth argument is set to true here. *) + val mk_goal : context -> bool -> bool -> bool -> goal + + (** A string representation of the Goal. *) + val to_string : goal -> string +end + +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model : +sig + type model + + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. *) + module FuncInterp : + sig + type func_interp + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. *) + module FuncEntry : + sig + type func_entry + + (** Return the (symbolic) value of this entry. + *) + val get_value : func_entry -> Expr.expr + + (** The number of arguments of the entry. + *) + val get_num_args : func_entry -> int + + (** The arguments of the function entry. + *) + val get_args : func_entry -> Expr.expr list + + (** A string representation of the function entry. + *) + val to_string : func_entry -> string + end + + (** The number of entries in the function interpretation. *) + val get_num_entries : func_interp -> int + + (** The entries in the function interpretation *) + val get_entries : func_interp -> FuncEntry.func_entry list + + (** The (symbolic) `else' value of the function interpretation. *) + val get_else : func_interp -> Expr.expr + + (** The arity of the function interpretation *) + val get_arity : func_interp -> int + + (** A string representation of the function interpretation. *) + val to_string : func_interp -> string + end + + (** Retrieves the interpretation (the assignment) of a func_decl in the model. + An expression if the function has an interpretation in the model, null otherwise. *) + val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option + + (** Retrieves the interpretation (the assignment) of an expression in the model. + An expression if the constant has an interpretation in the model, null otherwise. *) + val get_const_interp_e : model -> Expr.expr -> Expr.expr option + + (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option + + (** The number of constant interpretations in the model. *) + val get_num_consts : model -> int + + (** The function declarations of the constants in the model. *) + val get_const_decls : model -> FuncDecl.func_decl list + + (** The number of function interpretations in the model. *) + val get_num_funcs : model -> int + + (** The function declarations of the function interpretations in the model. *) + val get_func_decls : model -> FuncDecl.func_decl list + + (** All symbols that have an interpretation in the model. *) + val get_decls : model -> FuncDecl.func_decl list + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** Evaluates an expression in the current model. + + This function may fail if the argument contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + *) + val eval : model -> Expr.expr -> bool -> Expr.expr + + (** Alias for eval. *) + val evaluate : model -> Expr.expr -> bool -> Expr.expr + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + val get_num_sorts : model -> int + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + {!get_num_sorts} + {!sort_universe} *) + val get_sorts : model -> Sort.sort list + + (** The finite set of distinct values that represent the interpretation of a sort. + {!get_sorts} + @returns A list of expressions, where each is an element of the universe of the sort *) + val sort_universe : model -> Sort.sort -> AST.ast list + + (** Conversion of models to strings. + A string representation of the model. *) + val to_string : model -> string +end + +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe : +sig + type probe + + (** Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + val apply : probe -> Goal.goal -> float + + (** The number of supported Probes. *) + val get_num_probes : context -> int + + (** The names of all supported Probes. *) + val get_probe_names : context -> string list + + (** Returns a string containing a description of the probe with the given name. *) + val get_probe_description : context -> string -> string + + (** Creates a new Probe. *) + val mk_probe : context -> string -> probe + + (** Create a probe that always evaluates to a float value. *) + val const : context -> float -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than the value returned by second argument *) + val lt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than the value returned by second argument *) + val gt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than or equal the value returned by second argument *) + val le : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than or equal the value returned by second argument *) + val ge : context -> probe -> probe -> probe + + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is equal the value returned by second argument *) + val eq : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) + val and_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) + val or_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) + val not_ : context -> probe -> probe +end + +(** Tactics + + Tactics are the basic building block for creating custom solvers for specific problem domains. + The complete list of tactics may be obtained using Context.get_num_tactics + and Context.get_tactic_names. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Tactic : +sig + type tactic + + (** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) + module ApplyResult : + sig + type apply_result + + (** The number of Subgoals. *) + val get_num_subgoals : apply_result -> int + + (** Retrieves the subgoals from the apply_result. *) + val get_subgoals : apply_result -> Goal.goal list + + (** Retrieves a subgoal from the apply_result. *) + val get_subgoal : apply_result -> int -> Goal.goal + + (** Convert a model for a subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g *) + val convert_model : apply_result -> int -> Model.model -> Model.model + + (** A string representation of the ApplyResult. *) + val to_string : apply_result -> string + end + + (** A string containing a description of parameters accepted by the tactic. *) + val get_help : tactic -> string + + (** Retrieves parameter descriptions for Tactics. *) + val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs + + (** Apply the tactic to the goal. *) + val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result + + (** The number of supported tactics. *) + val get_num_tactics : context -> int + + (** The names of all supported tactics. *) + val get_tactic_names : context -> string list + + (** Returns a string containing a description of the tactic with the given name. *) + val get_tactic_description : context -> string -> string + + (** Creates a new Tactic. *) + val mk_tactic : context -> string -> tactic + + (** Create a tactic that applies one tactic to a Goal and + then another one to every subgoal produced by the first one. *) + val and_then : context -> tactic -> tactic -> tactic list -> tactic + + (** Create a tactic that first applies one tactic to a Goal and + if it fails then returns the result of another tactic applied to the Goal. *) + val or_else : context -> tactic -> tactic -> tactic + + (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). + + If the tactic does not terminate within the timeout, then it fails. *) + val try_for : context -> tactic -> int -> tactic + + (** Create a tactic that applies one tactic to a given goal if the probe + evaluates to true. + + If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) + val when_ : context -> Probe.probe -> tactic -> tactic + + (** Create a tactic that applies a tactic to a given goal if the probe + evaluates to true and another tactic otherwise. *) + val cond : context -> Probe.probe -> tactic -> tactic -> tactic + + (** Create a tactic that keeps applying one tactic until the goal is not + modified anymore or the maximum number of iterations is reached. *) + val repeat : context -> tactic -> int -> tactic + + (** Create a tactic that just returns the given goal. *) + val skip : context -> tactic + + (** Create a tactic always fails. *) + val fail : context -> tactic + + (** Create a tactic that fails if the probe evaluates to false. *) + val fail_if : context -> Probe.probe -> tactic + + (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) + val fail_if_not_decided : context -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. *) + val using_params : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. + Alias for UsingParams*) + val with_ : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies the given tactics in parallel. *) + val par_or : context -> tactic list -> tactic + + (** Create a tactic that applies a tactic to a given goal and then another tactic + to every subgoal produced by the first one. The subgoals are processed in parallel. *) + val par_and_then : context -> tactic -> tactic -> tactic + + (** Interrupt the execution of a Z3 procedure. + This procedure can be used to interrupt: solvers, simplifiers and tactics. *) + val interrupt : context -> unit +end + +(** Solvers *) +module Solver : +sig + type solver + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + val string_of_status : status -> string + + (** Objects that track statistical information about solvers. *) + module Statistics : + sig + type statistics + + (** Statistical data is organized into pairs of \[Key, Entry\], where every + Entry is either a floating point or integer value. + *) + module Entry : + sig + type statistics_entry + + (** The key of the entry. *) + val get_key : statistics_entry -> string + + (** The int-value of the entry. *) + val get_int : statistics_entry -> int + + (** The float-value of the entry. *) + val get_float : statistics_entry -> float + + (** True if the entry is uint-valued. *) + val is_int : statistics_entry -> bool + + (** True if the entry is double-valued. *) + val is_float : statistics_entry -> bool + + (** The string representation of the the entry's value. *) + val to_string_value : statistics_entry -> string + + (** The string representation of the entry (key and value) *) + val to_string : statistics_entry -> string + end + + (** A string representation of the statistical data. *) + val to_string : statistics -> string + + (** The number of statistical data. *) + val get_size : statistics -> int + + (** The data entries. *) + val get_entries : statistics -> Entry.statistics_entry list + + (** The statistical counters. *) + val get_keys : statistics -> string list + + (** The value of a particular statistical counter. *) + val get : statistics -> string -> Entry.statistics_entry option + end + + (** A string that describes all available solver parameters. *) + val get_help : solver -> string + + (** Sets the solver parameters. *) + val set_parameters : solver -> Params.params -> unit + + (** Retrieves parameter descriptions for solver. *) + val get_param_descrs : solver -> Params.ParamDescrs.param_descrs + + (** The current number of backtracking points (scopes). + {!pop} + {!push} *) + val get_num_scopes : solver -> int + + (** Creates a backtracking point. + {!pop} *) + val push : solver -> unit + + (** Backtracks a number of backtracking points. + Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} + {!push} *) + val pop : solver -> int -> unit + + (** Resets the Solver. + This removes all assertions from the solver. *) + val reset : solver -> unit + + (** Assert a constraint (or multiple) into the solver. *) + val assert_ : solver -> Boolean.bool_expr list -> unit + + (** * Assert multiple constraints (cs) into the solver, and track them (in the + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track_a : solver -> Boolean.bool_expr list -> Boolean.bool_expr list -> unit + + (** * Assert a constraint (c) into the solver, and track it (in the unsat) core + * using the Boolean constant p. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit + + (** The number of assertions in the solver. *) + val get_num_assertions : solver -> int + + (** The set of asserted formulas. *) + val get_assertions : solver -> Boolean.bool_expr list + + (** Checks whether the assertions in the solver are consistent or not. + + {!Model} + {!get_unsat_core} + {!Proof} *) + val check : solver -> Boolean.bool_expr list -> status + + (** The model of the last Check. + + The result is None if Check was not invoked before, + if its results was not SATISFIABLE, or if model production is not enabled. *) + val get_model : solver -> Model.model option + + (** The proof of the last Check. + + The result is null if Check was not invoked before, + if its results was not UNSATISFIABLE, or if proof production is disabled. *) + val get_proof : solver -> Expr.expr option + + (** The unsat core of the last Check. + + The unsat core is a subset of Assertions + The result is empty if Check was not invoked before, + if its results was not UNSATISFIABLE, or if core production is disabled. *) + val get_unsat_core : solver -> AST.ast list + + (** A brief justification of why the last call to Check returned UNKNOWN. *) + val get_reason_unknown : solver -> string + + (** Solver statistics. *) + val get_statistics : solver -> Statistics.statistics + + (** Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) + val mk_solver : context -> Symbol.symbol option -> solver + + (** Creates a new (incremental) solver. + {!mk_solver} *) + val mk_solver_s : context -> string -> solver + + (** Creates a new (incremental) solver. *) + val mk_simple_solver : context -> solver + + (** Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) + val mk_solver_t : context -> Tactic.tactic -> solver + + (** A string representation of the solver. *) + val to_string : solver -> string +end + +(** Fixedpoint solving *) +module Fixedpoint : +sig + type fixedpoint + + (** A string that describes all available fixedpoint solver parameters. *) + val get_help : fixedpoint -> string + + (** Sets the fixedpoint solver parameters. *) + val set_params : fixedpoint -> Params.params -> unit + + (** Retrieves parameter descriptions for Fixedpoint solver. *) + val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs + + (** Assert a constraints into the fixedpoint solver. *) + val assert_ : fixedpoint -> Boolean.bool_expr list -> unit + + (** Register predicate as recursive relation. *) + val register_relation : fixedpoint -> FuncDecl.func_decl -> unit + + (** Add rule into the fixedpoint solver. *) + val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit + + (** Add table fact to the fixedpoint solver. *) + val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit + + (** Query the fixedpoint solver. + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. *) + val query : fixedpoint -> Boolean.bool_expr -> Solver.status + + (** Query the fixedpoint solver. + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. *) + val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status + + (** Creates a backtracking point. + {!pop} *) + val push : fixedpoint -> unit + + (** Backtrack one backtracking point. + + Note that an exception is thrown if Pop is called without a corresponding Push + {!push} *) + val pop : fixedpoint -> unit + + (** Update named rule into in the fixedpoint solver. *) + val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit + + (** Retrieve satisfying instance or instances of solver, + or definitions for the recursive predicates that show unsatisfiability. *) + val get_answer : fixedpoint -> Expr.expr option + + (** Retrieve explanation why fixedpoint engine returned status Unknown. *) + val get_reason_unknown : fixedpoint -> string + + (** Retrieve the number of levels explored for a given predicate. *) + val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int + + (** Retrieve the cover of a predicate. *) + val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option + + (** Add property about the predicate. + The property is added at level. *) + val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit + + (** Retrieve internal string representation of fixedpoint object. *) + val to_string : fixedpoint -> string + + (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) + val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit + + (** Convert benchmark given as set of axioms, rules and queries to a string. *) + val to_string_q : fixedpoint -> Boolean.bool_expr list -> string + + (** Retrieve set of rules added to fixedpoint context. *) + val get_rules : fixedpoint -> Boolean.bool_expr list + + (** Retrieve set of assertions added to fixedpoint context. *) + val get_assertions : fixedpoint -> Boolean.bool_expr list + + (** Create a Fixedpoint context. *) + val mk_fixedpoint : context -> fixedpoint +end + +(** Global and context options + + Note: This module contains functions that set parameters/options for context + objects as well as functions that set options that are used globally, across + contexts.*) +module Options : +sig + (** Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + {!get_param_value} *) + val update_param_value : context -> string -> string -> unit + + (** Get a configuration parameter. + + Returns None if the parameter value does not exist. + {!update_param_value} *) + val get_param_value : context -> string -> string option + + (** Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) + val set_print_mode : context -> Z3enums.ast_print_mode -> unit + + (** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) + val toggle_warning_messages : bool -> unit +end + +(** Functions for handling SMT and SMT2 expressions and files *) +module SMT : +sig + (** Convert a benchmark into an SMT-LIB formatted string. + + @return A string representation of the benchmark. *) + val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr list -> Boolean.bool_expr -> string + + (** Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays in the third and fifth argument + don't need to match the names of the sorts and declarations in the arrays in the fourth + and sixth argument. This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) + val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit + + (** Parse the given file using the SMT-LIB parser. + {!parse_smtlib_string} *) + val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit + + (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_formulas : context -> int + + (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_formulas : context -> Boolean.bool_expr list + + (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_assumptions : context -> int + + (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_assumptions : context -> Boolean.bool_expr list + + (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_decls : context -> int + + (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_decls : context -> FuncDecl.func_decl list + + (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_sorts : context -> int + + (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_sorts : context -> Sort.sort list + + (** Parse the given string using the SMT-LIB2 parser. + + {!parse_smtlib_string} + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) + val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr + + (** Parse the given file using the SMT-LIB2 parser. + {!parse_smtlib2_string} *) + val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr +end + +(** Set a global (or module) parameter, which is shared by all Z3 contexts. + + When a Z3 module is initialized it will use the value of these parameters + when Z3_params objects are not provided. + The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + The character '.' is a delimiter (more later). + The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + This function can be used to set parameters for a specific Z3 module. + This can be done by using .. + For example: + (set_global_param "pp.decimal" "true") + will set the parameter "decimal" in the module "pp" to true. +*) +val set_global_param : string -> string -> unit + +(** Get a global (or module) parameter. + + Returns None if the parameter does not exist. + The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + This function cannot be invoked simultaneously from different threads without synchronization. + The result string stored in param_value is stored in a shared location. +*) +val get_global_param : string -> string option + +(** Restore the value of all global (and module) parameters. + + This command will not affect already created objects (such as tactics and solvers) + {!set_global_param} +*) +val global_param_reset_all : unit From 13416de27e3e6f824f54f0cc1f09ee57da5da58a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 14:17:35 +0000 Subject: [PATCH 286/507] ML API savegame Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 124 +++++++++++++++++++------------------- src/api/ml/z3.ml | 18 +++--- src/api/ml/z3_rich.ml | 43 +++++++------ src/api/ml/z3_rich.mli | 13 ++-- 4 files changed, 96 insertions(+), 102 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 823a08fe2..f7a4cbc00 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -162,70 +162,68 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ) ; - model_converter_test ctx -(* - // Real num/den test. - RatNum rn = ctx.MkReal(42, 43); - Expr inum = rn.Numerator; - Expr iden = rn.Denominator; - Console.WriteLine("Numerator: " + inum + " Denominator: " + iden); - if (inum.ToString() != "42" || iden.ToString() != "43") - throw new TestFailedException(); - - if (rn.ToDecimalString(3) != "0.976?") - throw new TestFailedException(); - - BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); - BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); - BigIntCheck(ctx, ctx.MkReal("-234234333")); - BigIntCheck(ctx, ctx.MkReal("234234333/2")); - - - string bn = "1234567890987654321"; - - if (ctx.MkInt(bn).BigInteger.ToString() != bn) - throw new TestFailedException(); - - if (ctx.MkBV(bn, 128).BigInteger.ToString() != bn) - throw new TestFailedException(); - - if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn) - throw new TestFailedException(); - - // Error handling test. - try - { - IntExpr i = ctx.MkInt("1/2"); - throw new TestFailedException(); // unreachable - } - catch (Z3Exception) - { - } - } -*) + model_converter_test ctx ; + (* Real num/den test. *) + let rn = Real.mk_numeral_nd ctx 42 43 in + let inum = (get_numerator rn) in + let iden = get_denominator rn in + Printf.printf "Numerator: %s Denominator: %s\n" (Real.to_string inum) (Real.to_string iden) ; + if ((Real.to_string inum) <> "42" or (Real.to_string iden) <> "43") then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ; + if ((to_decimal_string rn 3) <> "0.976?") then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ; + if (to_decimal_string (Real.mk_numeral_s ctx "-1231231232/234234333") 5 <> "-5.25640?") then + raise (TestFailedException "") + else if (to_decimal_string (Real.mk_numeral_s ctx "-123123234234234234231232/234234333") 5 <> "-525641278361333.28170?") then + raise (TestFailedException "") + else if (to_decimal_string (Real.mk_numeral_s ctx "-234234333") 5 <> "-234234333") then + raise (TestFailedException "") + else if (to_decimal_string (Real.mk_numeral_s ctx "234234333/2") 5 <> "117117166.5") then + raise (TestFailedException "") + ; + (* Error handling test. *) + try ( + let i = Integer.mk_numeral_s ctx "1/2" in + raise (TestFailedException "") (* unreachable *) + ) + with Z3native.Exception(_) -> ( + Printf.printf "Exception caught, OK.\n" + ) let _ = - if not (Log.open_ "z3.log") then - raise (TestFailedException "Log couldn't be opened.") - else - ( - Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = [("model", "true"); ("proof", "false")] in - let ctx = (mk_context cfg) in - let is = (Symbol.mk_int ctx 42) in - let ss = (Symbol.mk_string ctx "mySymbol") in - let bs = (Boolean.mk_sort ctx) in - let ints = (Integer.mk_sort ctx) in - let rs = (Real.mk_sort ctx) in - Printf.printf "int symbol: %s\n" (Symbol.to_string is); - Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string bs); - Printf.printf "int sort: %s\n" (Sort.to_string ints); - Printf.printf "real sort: %s\n" (Sort.to_string rs); - basic_tests ctx ; - Printf.printf "Disposing...\n"; - Gc.full_major () - ); - Printf.printf "Exiting.\n"; + try ( + if not (Log.open_ "z3.log") then + raise (TestFailedException "Log couldn't be opened.") + else + ( + Printf.printf "Running Z3 version %s\n" Version.to_string ; + let cfg = [("model", "true"); ("proof", "false")] in + let ctx = (mk_context cfg) in + let is = (Symbol.mk_int ctx 42) in + let ss = (Symbol.mk_string ctx "mySymbol") in + let bs = (Boolean.mk_sort ctx) in + let ints = (Integer.mk_sort ctx) in + let rs = (Real.mk_sort ctx) in + Printf.printf "int symbol: %s\n" (Symbol.to_string is); + Printf.printf "string symbol: %s\n" (Symbol.to_string ss); + Printf.printf "bool sort: %s\n" (Sort.to_string bs); + Printf.printf "int sort: %s\n" (Sort.to_string ints); + Printf.printf "real sort: %s\n" (Sort.to_string rs); + basic_tests ctx ; + Printf.printf "Disposing...\n"; + Gc.full_major () + ); + Printf.printf "Exiting.\n" ; + exit 0 + ) with Z3native.Exception(msg) -> ( + Printf.printf "Z3 EXCEPTION: %s\n" msg ; + exit 1 + ) ;; diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0676f1a39..e62732924 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -11,7 +11,6 @@ open Z3enums let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) - (* Internal types *) type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } type context = z3_native_context @@ -21,7 +20,6 @@ type z3_native_object = { mutable m_n_obj : Z3native.ptr ; inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - (** Internal stuff *) module Internal = @@ -1455,11 +1453,11 @@ struct let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = Expr.mk_const ctx name (mk_sort ctx) - let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_mod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) @@ -1467,10 +1465,10 @@ struct let mk_rem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_int_numeral_s ( ctx : context ) ( v : string ) = + let mk_numeral_s ( ctx : context ) ( v : string ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) - let mk_int_numeral_i ( ctx : context ) ( v : int ) = + let mk_numeral_i ( ctx : context ) ( v : int ) = expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) let mk_int2real ( ctx : context ) ( t : expr ) = @@ -1496,11 +1494,11 @@ struct let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = Expr.mk_const ctx name (mk_sort ctx) - let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = if (den == 0) then diff --git a/src/api/ml/z3_rich.ml b/src/api/ml/z3_rich.ml index 052ca5e22..0c2f95b6b 100644 --- a/src/api/ml/z3_rich.ml +++ b/src/api/ml/z3_rich.ml @@ -1,4 +1,4 @@ -(** +\(** The Z3 ML/Ocaml Interface. Copyright (C) 2012 Microsoft Corporation @@ -11,7 +11,6 @@ open Z3enums let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) - (* Internal types *) type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } type context = z3_native_context @@ -1679,12 +1678,12 @@ sig val mk_sort : context -> int_sort val get_int : int_num -> int val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr + val mk_const : context -> Symbol.symbol -> int_expr + val mk_const_s : context -> string -> int_expr val mk_mod : context -> int_expr -> int_expr -> int_expr val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num + val mk_numeral_s : context -> string -> int_num + val mk_numeral_i : context -> int -> int_num val mk_int2real : context -> int_expr -> Real.real_expr val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr end @@ -1709,8 +1708,8 @@ sig val get_denominator : rat_num -> Integer.int_num val to_decimal_string : rat_num -> int -> string val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr + val mk_const : context -> Symbol.symbol -> real_expr + val mk_const_s : context -> string -> real_expr val mk_numeral_nd : context -> int -> int -> rat_num val mk_numeral_s : context -> string -> rat_num val mk_numeral_i : context -> int -> rat_num @@ -1816,12 +1815,12 @@ end = struct val mk_sort : context -> int_sort val get_int : int_num -> int val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr + val mk_const : context -> Symbol.symbol -> int_expr + val mk_const_s : context -> string -> int_expr val mk_mod : context -> int_expr -> int_expr -> int_expr val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num + val mk_numeral_s : context -> string -> int_num + val mk_numeral_i : context -> int -> int_num val mk_int2real : context -> int_expr -> Real.real_expr val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr end = struct @@ -1884,11 +1883,11 @@ end = struct let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) - let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) @@ -1896,10 +1895,10 @@ end = struct let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) - let mk_int_numeral_s ( ctx : context ) ( v : string ) = + let mk_numeral_s ( ctx : context ) ( v : string ) = int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - let mk_int_numeral_i ( ctx : context ) ( v : int ) = + let mk_numeral_i ( ctx : context ) ( v : int ) = int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) let mk_int2real ( ctx : context ) ( t : int_expr ) = @@ -1930,8 +1929,8 @@ end = struct val get_denominator : rat_num -> Integer.int_num val to_decimal_string : rat_num -> int -> string val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr + val mk_const : context -> Symbol.symbol -> real_expr + val mk_const_s : context -> string -> real_expr val mk_numeral_nd : context -> int -> int -> rat_num val mk_numeral_s : context -> string -> rat_num val mk_numeral_i : context -> int -> rat_num @@ -2002,11 +2001,11 @@ end = struct let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) - let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = if (den == 0) then diff --git a/src/api/ml/z3_rich.mli b/src/api/ml/z3_rich.mli index 8b6681e11..f2ecd326d 100644 --- a/src/api/ml/z3_rich.mli +++ b/src/api/ml/z3_rich.mli @@ -34,7 +34,6 @@ type context (** Create a context object *) val mk_context : (string * string) list -> context - (** Interaction logging for Z3 Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) @@ -1219,10 +1218,10 @@ sig val to_string : int_num -> string (** Creates an integer constant. *) - val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_const : context -> Symbol.symbol -> int_expr (** Creates an integer constant. *) - val mk_int_const_s : context -> string -> int_expr + val mk_const_s : context -> string -> int_expr (** Create an expression representing t1 mod t2. The arguments must have int type. *) @@ -1233,11 +1232,11 @@ sig val mk_rem : context -> int_expr -> int_expr -> int_expr (** Create an integer numeral. *) - val mk_int_numeral_s : context -> string -> int_num + val mk_numeral_s : context -> string -> int_num (** Create an integer numeral. @return A Term with the given value and sort Integer *) - val mk_int_numeral_i : context -> int -> int_num + val mk_numeral_i : context -> int -> int_num (** Coerce an integer to a real. @@ -1291,10 +1290,10 @@ sig val to_string : rat_num -> string (** Creates a real constant. *) - val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_const : context -> Symbol.symbol -> real_expr (** Creates a real constant. *) - val mk_real_const_s : context -> string -> real_expr + val mk_const_s : context -> string -> real_expr (** Create a real numeral from a fraction. @return A Term with rational value and sort Real From 74ab6dbd2262509881d7d72e5dcbe6fc0b02d949 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 18:53:29 +0000 Subject: [PATCH 287/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index a0b7e6250..44d871348 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1339,9 +1339,10 @@ def mk_ml(): ml_wrapper.write(' // upon errors, but the actual error handling is done by throwing exceptions in the\n') ml_wrapper.write(' // wrappers below.\n') ml_wrapper.write('}\n\n') - ml_wrapper.write('void n_set_internal_error_handler(Z3_context c)\n') + ml_wrapper.write('void n_set_internal_error_handler(value a0)\n') ml_wrapper.write('{\n') - ml_wrapper.write(' Z3_set_error_handler(c, MLErrorHandler);\n') + ml_wrapper.write(' Z3_context _a0 = * (Z3_context*) Data_custom_val(a0);\n') + ml_wrapper.write(' Z3_set_error_handler(_a0, MLErrorHandler);\n') ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) From c37eb794c2d14b710cf8f281c0008781251eac13 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 26 Feb 2013 19:45:45 +0000 Subject: [PATCH 288/507] ML API: renamed assert_ to add Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 24 ++++++++++++------------ src/api/ml/z3.ml | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index f7a4cbc00..c9ed1d948 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -29,11 +29,11 @@ let model_converter_test ( ctx : context ) = let xr = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Real.mk_sort ctx)) in let yr = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Real.mk_sort ctx)) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; - (Goal.assert_ g4 [ (mk_eq ctx + (Goal.add g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; + (Goal.add g4 [ (mk_eq ctx yr (Arithmetic.mk_add ctx [ xr; (Real.mk_numeral_nd ctx 1 1) ])) ]) ; - (Goal.assert_ g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; + (Goal.add g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -53,7 +53,7 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ; let solver = (mk_solver ctx None) in - let f e = (Solver.assert_ solver [ e ]) in + let f e = (Solver.add solver [ e ]) in ignore (List.map f (get_formulas (get_subgoal ar 0))) ; let q = (check solver []) in if q != SATISFIABLE then @@ -88,12 +88,12 @@ let basic_tests ( ctx : context ) = let trivial_eq = (mk_eq ctx fapp fapp) in let nontrivial_eq = (mk_eq ctx fapp fapp2) in let g = (mk_goal ctx true false false) in - (Goal.assert_ g [ trivial_eq ]) ; - (Goal.assert_ g [ nontrivial_eq ]) ; + (Goal.add g [ trivial_eq ]) ; + (Goal.add g [ nontrivial_eq ]) ; Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; ( let solver = (mk_solver ctx None) in - (List.iter (fun a -> (Solver.assert_ solver [ a ])) (get_formulas g)) ; + (List.iter (fun a -> (Solver.add solver [ a ])) (get_formulas g)) ; if (check solver []) != SATISFIABLE then raise (TestFailedException "") else @@ -116,7 +116,7 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ); - (Goal.assert_ g [ (mk_eq ctx + (Goal.add g [ (mk_eq ctx (mk_numeral_int ctx 1 (BitVector.mk_sort ctx 32)) (mk_numeral_int ctx 2 (BitVector.mk_sort ctx 32))) ] ) ; @@ -139,7 +139,7 @@ let basic_tests ( ctx : context ) = ); ( let g2 = (mk_goal ctx true true false) in - (Goal.assert_ g2 [ (Boolean.mk_false ctx) ]) ; + (Goal.add g2 [ (Boolean.mk_false ctx) ]) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then @@ -151,10 +151,10 @@ let basic_tests ( ctx : context ) = let g3 = (mk_goal ctx true true false) in let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Integer.mk_sort ctx)) in let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Integer.mk_sort ctx)) in - (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; - (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; + (Goal.add g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; + (Goal.add g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; let constr = (mk_eq ctx xc yc) in - (Goal.assert_ g3 [ constr ] ) ; + (Goal.add g3 [ constr ] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index e62732924..8eb5427bb 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1850,7 +1850,7 @@ struct let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - let assert_ ( x : goal ) ( constraints : expr list ) = + let add ( x : goal ) ( constraints : expr list ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e) in ignore (List.map f constraints) ; () @@ -2370,11 +2370,11 @@ struct let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - let assert_ ( x : solver ) ( constraints : expr list ) = + let add ( x : solver ) ( constraints : expr list ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) - let assert_and_track_a ( x : solver ) ( cs : expr list ) ( ps : expr list ) = + let assert_and_track_l ( x : solver ) ( cs : expr list ) ( ps : expr list ) = if ((List.length cs) != (List.length ps)) then raise (Z3native.Exception "Argument size mismatch") else @@ -2473,7 +2473,7 @@ struct let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - let assert_ ( x : fixedpoint ) ( constraints : expr list ) = + let add ( x : fixedpoint ) ( constraints : expr list ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) ; () From 17005a413b346ec04d9baaa68ceee87858721346 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 3 Jun 2013 18:26:07 +0100 Subject: [PATCH 289/507] Removed unnecessary file Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/README-win | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/api/ml/README-win diff --git a/src/api/ml/README-win b/src/api/ml/README-win deleted file mode 100644 index 82ddc2652..000000000 --- a/src/api/ml/README-win +++ /dev/null @@ -1,23 +0,0 @@ -The OCaml API for Z3 was tested using OCaml 3.12.1. -You also need CamlIDL to be able to generate the OCaml API. - -- To download OCaml: - http://caml.inria.fr/ocaml/ - -- To download CamlIDL: - http://forge.ocamlcore.org/projects/camlidl/ - -- To build the OCaml API for Z3: - .\build-lib.cmd - -Remark: The OCaml and C compiler tool chains must be configured in your environment. -Running from the Visual Studio Command Prompt configures the Microsoft C compiler. - -Remark: Building the OCaml API copies some pathnames into files, -so the OCaml API must be recompiled if the Z3 library files are moved. - -See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3. - -Acknowledgements: -The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg. -Many thanks to them! From c0df7640396a16c4ea12619997d7917f9cf53ef6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 3 Jun 2013 18:51:40 +0100 Subject: [PATCH 290/507] Updates to ML API. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 43 ++++----- src/api/ml/z3.mli | 233 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+), 23 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8eb5427bb..4a8fbaa0a 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -323,8 +323,8 @@ struct else ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + let unwrap_ast ( x : ast ) = (z3obj_gno x) let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr - let unwrap_ast ( x : ast ) = (z3obj_gno x) end open AST @@ -678,6 +678,19 @@ end = struct res let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) + + let update_param_value ( ctx : context ) ( id : string) ( value : string )= + Z3native.update_param_value (context_gno ctx) id value + + let get_param_value ( ctx : context ) ( id : string ) = + let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in + if not r then + None + else + Some v + + let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = + Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) end (** General expressions (terms) *) @@ -1106,7 +1119,7 @@ struct end -module Array_ = +module Array = struct let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) @@ -1389,7 +1402,7 @@ struct end -module List_ = +module List = struct let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in @@ -2558,26 +2571,6 @@ struct let mk_fixedpoint ( ctx : context ) = create ctx end -module Options = -struct - - let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value (context_gno ctx) id value - - let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in - if not r then - None - else - Some v - - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) - - let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages enabled -end - module SMT = struct @@ -2692,3 +2685,7 @@ let get_global_param ( id : string ) = let global_param_reset_all = Z3native.global_param_reset_all + +let toggle_warning_messages ( enabled: bool ) = + Z3native.toggle_warning_messages enabled + diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 2eb9eecb7..1eae4f013 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -756,9 +756,27 @@ and goal_prec = the first conjunct in the body of an implication is position 1 the second conjunct in the body of an implication is position 2 +<<<<<<< HEAD For general implications where the head is a disjunction, the first n positions correspond to the n disjuncts in the head. The next m positions correspond to the m conjuncts in the body. +======= +(** Create a context object + The following parameters can be set: + + - proof (Boolean) Enable proof generation + - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting + - trace (Boolean) Tracing support for VCC + - trace_file_name (String) Trace out file for VCC traces + - timeout (unsigned) default timeout (in milliseconds) used for solvers + - well_sorted_check type checker + - auto_config use heuristics to automatically select solver and configure it + - model model generation for solvers, this parameter can be overwritten when creating a solver + - model_validate validate models produced by solvers + - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver +*) +val mk_context : (string * string) list -> context +>>>>>>> Updates to ML API. The premises can be universally quantified so that the most general non-ground form is: @@ -1084,6 +1102,7 @@ val mk_symbol: context -> symbol_refined -> symbol external mk_int_symbol : context -> int -> symbol = "camlidl_z3_Z3_mk_int_symbol" +<<<<<<< HEAD (** Summary: Create a Z3 symbol using a C string. Symbols are used to name several term and type constructors. @@ -1137,6 +1156,27 @@ type sort_refined = | Sort_datatype of datatype_constructor array | Sort_relation of sort array | Sort_unknown +======= + (** Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + Z3native.inc_ref). + {!wrap_ast} *) + val unwrap_ast : ast -> Z3native.ptr + + (** Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) + and that it must have a correct reference count (see e.g., + Z3native.inc_ref). *) + val wrap_ast : context -> Z3native.z3_ast -> ast +end +>>>>>>> Updates to ML API. (** @@ -1693,6 +1733,7 @@ external mk_bvnot : context -> ast -> ast external mk_bvredand : context -> ast -> ast = "camlidl_z3_Z3_mk_bvredand" +<<<<<<< HEAD (** Summary: \[ [ mk_bvredor c t1 ] \] Take disjunction of bits in vector, return vector of length 1. @@ -1701,6 +1742,41 @@ external mk_bvredand : context -> ast -> ast *) external mk_bvredor : context -> ast -> ast = "camlidl_z3_Z3_mk_bvredor" +======= + (** A string representation of the parameter set. *) + val to_string : params -> string + + (** Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -p + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + {!get_param_value} *) + val update_param_value : context -> string -> string -> unit + + (** Get a configuration parameter. + + Returns None if the parameter value does not exist. + {!update_param_value} *) + val get_param_value : context -> string -> string option + + (** Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) + val set_print_mode : context -> Z3enums.ast_print_mode -> unit +end +>>>>>>> Updates to ML API. (** Summary: \[ [ mk_bvand c t1 t2 ] \] @@ -1931,6 +2007,7 @@ external mk_bvugt : context -> ast -> ast -> ast external mk_bvsgt : context -> ast -> ast -> ast = "camlidl_z3_Z3_mk_bvsgt" +<<<<<<< HEAD (** Summary: \[ [ mk_concat c t1 t2 ] \] Concatenate the given bit-vectors. @@ -1941,6 +2018,106 @@ external mk_bvsgt : context -> ast -> ast -> ast *) external mk_concat : context -> ast -> ast -> ast = "camlidl_z3_Z3_mk_concat" +======= +(** Functions to manipulate Array expressions *) +module Array : +sig + (** Create a new array sort. *) + val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort + + (** Indicates whether the term is an array store. + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. *) + val is_store : Expr.expr -> bool + + (** Indicates whether the term is an array select. *) + val is_select : Expr.expr -> bool + + (** Indicates whether the term is a constant array. + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) + val is_constant_array : Expr.expr -> bool + + (** Indicates whether the term is a default array. + For example default(const(v)) = v. The function is unary. *) + val is_default_array : Expr.expr -> bool + + (** Indicates whether the term is an array map. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) + val is_array_map : Expr.expr -> bool + + (** Indicates whether the term is an as-array term. + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. *) + val is_as_array : Expr.expr -> bool + + (** Indicates whether the term is of an array sort. *) + val is_array : Expr.expr -> bool + + (** The domain of the array sort. *) + val get_domain : Sort.sort -> Sort.sort + + (** The range of the array sort. *) + val get_range : Sort.sort -> Sort.sort + + (** Create an array constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> Expr.expr + + (** Create an array constant. *) + val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> Expr.expr + + (** Array read. + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + {!Array.mk_sort} + {!mk_store} *) + val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Array update. + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + {!Array.mk_sort} + {!mk_select} *) + val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a constant array. + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + {!Array.mk_sort} + {!mk_select} *) + val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr + + (** Maps f on the argument arrays. + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + {!Array.mk_sort} + {!mk_select} + {!mk_store} *) + val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr + + (** Access the array default value. + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. *) + val mk_term_array : context -> Expr.expr -> Expr.expr +end +>>>>>>> Updates to ML API. (** Summary: \[ [ mk_extract c high low t1 ] \] @@ -2259,12 +2436,20 @@ external mk_set_sort : context -> sort -> sort external mk_empty_set : context -> sort -> ast = "camlidl_z3_Z3_mk_empty_set" +<<<<<<< HEAD (** Summary: Create the full set. def_API('mk_full_set', AST, (_in(CONTEXT), _in(SORT))) *) external mk_full_set : context -> sort -> ast = "camlidl_z3_Z3_mk_full_set" +======= +(** Functions to manipulate List expressions *) +module List : +sig + (** Create a new list sort. *) + val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort +>>>>>>> Updates to ML API. (** Summary: Add an element to a set. @@ -8806,6 +8991,7 @@ external theory_get_num_apps : theory -> int external theory_get_app : theory -> int -> ast = "camlidl_z3V3_Z3_theory_get_app" +<<<<<<< HEAD (** {2 {L Deprecated Injective functions API}} *) @@ -9135,6 +9321,12 @@ external get_model_func_decl : context -> model -> int -> func_decl *) external eval_func_decl : context -> model -> func_decl -> bool * ast = "camlidl_z3V3_Z3_eval_func_decl" +======= +(** Functions for handling SMT and SMT2 expressions and files *) +module SMT : +sig + (** Convert a benchmark into an SMT-LIB formatted string. +>>>>>>> Updates to ML API. (** Summary: \[ [ is_array_value c v ] \] @@ -9586,3 +9778,44 @@ val set_new_relevant_callback : theory -> (ast -> unit) -> unit end +<<<<<<< HEAD +======= +(** Set a global (or module) parameter, which is shared by all Z3 contexts. + + When a Z3 module is initialized it will use the value of these parameters + when Z3_params objects are not provided. + The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + The character '.' is a delimiter (more later). + The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + This function can be used to set parameters for a specific Z3 module. + This can be done by using .. + For example: + (set_global_param "pp.decimal" "true") + will set the parameter "decimal" in the module "pp" to true. +*) +val set_global_param : string -> string -> unit + +(** Get a global (or module) parameter. + + Returns None if the parameter does not exist. + The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + This function cannot be invoked simultaneously from different threads without synchronization. + The result string stored in param_value is stored in a shared location. +*) +val get_global_param : string -> string option + +(** Restore the value of all global (and module) parameters. + + This command will not affect already created objects (such as tactics and solvers) + {!set_global_param} +*) + +val global_param_reset_all : unit + + (** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) + val toggle_warning_messages : bool -> unit +>>>>>>> Updates to ML API. From 9726ee4c5faa875c991dca1a4c9d75aa80923355 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 3 Jun 2013 19:12:00 +0100 Subject: [PATCH 291/507] ML API: refactoring Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 74 +- src/api/ml/z3.mli | 11735 +++++++++----------------------------------- 2 files changed, 2454 insertions(+), 9355 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 4a8fbaa0a..081433f1f 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,6 +7,8 @@ open Z3enums +exception Error = Z3native.Exception + (* Some helpers. *) let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) @@ -283,7 +285,7 @@ struct Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) end - let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) + let hash ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) @@ -304,7 +306,7 @@ struct let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - let ( = ) ( a : ast ) ( b : ast ) = (a == b) || + let equal ( a : ast ) ( b : ast ) = (a == b) || if (z3obj_gnc a) != (z3obj_gnc b) then false else @@ -314,8 +316,6 @@ struct if (get_id a) < (get_id b) then -1 else if (get_id a) > (get_id b) then 1 else 0 - - let ( < ) (a : ast) (b : ast) = (compare a b) let translate ( x : ast ) ( to_ctx : context ) = if (z3obj_gnc x) == (context_gno to_ctx) then @@ -361,7 +361,7 @@ struct let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in Array.of_list (List.map f a) - let ( = ) : sort -> sort -> bool = fun a b -> + let equal : sort -> sort -> bool = fun a b -> (a == b) || if (gnc a) != (gnc b) then false @@ -424,7 +424,7 @@ sig val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl val mk_const_decl_s : context -> string -> Sort.sort -> func_decl val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - val ( = ) : func_decl -> func_decl -> bool + val equal : func_decl -> func_decl -> bool val to_string : func_decl -> string val get_id : func_decl -> int val get_arity : func_decl -> int @@ -498,7 +498,7 @@ end = struct let get_float ( x : parameter ) = match x with | P_Dbl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a double") + | _ -> raise (Z3native.Exception "parameter is not a float") let get_symbol ( x : parameter ) = match x with @@ -545,7 +545,7 @@ end = struct create_pdr ctx prefix [] range - let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || + let equal ( a : func_decl ) ( b : func_decl ) = (a == b) || if (gnc a) != (gnc b) then false else @@ -605,12 +605,8 @@ sig end val add_bool : params -> Symbol.symbol -> bool -> unit val add_int : params -> Symbol.symbol -> int -> unit - val add_double : params -> Symbol.symbol -> float -> unit + val add_float : params -> Symbol.symbol -> float -> unit val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - val add_s_bool : params -> string -> bool -> unit - val add_s_int : params -> string -> int -> unit - val add_s_double : params -> string -> float -> unit - val add_s_symbol : params -> string -> Symbol.symbol -> unit val mk_params : context -> params val to_string : params -> string end = struct @@ -650,24 +646,12 @@ end = struct let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + let add_float ( x : params ) ( name : Symbol.symbol ) ( value : float ) = Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = - add_bool x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_int ( x : params) ( name : string ) ( value : int ) = - add_int x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_double ( x : params ) ( name : string ) ( value : float ) = - add_double x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = - add_symbol x (Symbol.mk_string (z3obj_gc x) name) value - let mk_params ( ctx : context ) = let res : params = { m_ctx = ctx ; m_n_obj = null ; @@ -734,8 +718,6 @@ sig val is_xor : expr -> bool val is_not : expr -> bool val is_implies : expr -> bool - val is_label : expr -> bool - val is_label_lit : expr -> bool val is_oeq : expr -> bool val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val mk_const_s : context -> string -> Sort.sort -> expr @@ -857,8 +839,6 @@ end = struct let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = @@ -1530,20 +1510,20 @@ struct let mk_real2int ( ctx : context ) ( t : expr ) = (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (Expr.gno t))) - end - module AlgebraicNumber = - struct - let to_upper ( x : expr ) ( precision : int ) = - expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) - - let to_lower ( x : expr ) precision = - expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) - - let to_decimal_string ( x : expr ) ( precision : int ) = - Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + module AlgebraicNumber = + struct + let to_upper ( x : expr ) ( precision : int ) = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) + + let to_lower ( x : expr ) precision = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) + + let to_decimal_string ( x : expr ) ( precision : int ) = + Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision + + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + end end let is_int ( x : expr ) = @@ -2052,13 +2032,11 @@ struct let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in (mk_list f n_funcs) @ (mk_list g n_consts) - - exception ModelEvaluationFailedException of string - + let eval ( x : model ) ( t : expr ) ( completion : bool ) = let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then - raise (ModelEvaluationFailedException "evaluation failed") + None else expr_of_ptr (z3obj_gc x) v @@ -2353,7 +2331,7 @@ struct if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_sd k (Z3native.stats_get_float_value (z3obj_gnc x) (z3obj_gno x) i)) ) in mk_list f n diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 1eae4f013..570ff8717 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1,766 +1,37 @@ -(* File generated from z3.idl *) +(** + The Z3 ML/Ocaml Interface. + Copyright (C) 2012 Microsoft Corporation + @author CM Wintersteiger (cwinter) 2012-12-17 +*) + +(** General Z3 exceptions + + Many functions in this API may throw an exception; if they do, it is this one.*) +exception Error + +(** Context objects. + + Most interactions with Z3 are interpreted in some context; many users will only + require one such object, but power users may require more than one. To start using + Z3, do + + + let ctx = (mk_context []) in + (...) + + + where a list of pairs of strings may be passed to set options on + the context, e.g., like so: + + + let cfg = [("model", "true"); ("...", "...")] in + let ctx = (mk_context cfg) in + (...) + +*) type context -and symbol -and ast -and sort = private ast -and func_decl = private ast -and app = private ast -and pattern = private ast -and params -and param_descrs -and model -and func_interp -and func_entry -and fixedpoint -and ast_vector -and ast_map -and goal -and tactic -and probe -and apply_result -and solver -and stats - - -and constructor -and constructor_list - -and lbool = - | L_FALSE - | L_UNDEF - | L_TRUE - -and symbol_kind = - | INT_SYMBOL - | STRING_SYMBOL - -and parameter_kind = - | PARAMETER_INT - | PARAMETER_DOUBLE - | PARAMETER_RATIONAL - | PARAMETER_SYMBOL - | PARAMETER_SORT - | PARAMETER_AST - | PARAMETER_FUNC_DECL - -and sort_kind = - | UNINTERPRETED_SORT - | BOOL_SORT - | INT_SORT - | REAL_SORT - | BV_SORT - | ARRAY_SORT - | DATATYPE_SORT - | RELATION_SORT - | FINITE_DOMAIN_SORT - | UNKNOWN_SORT - -and ast_kind = - | NUMERAL_AST - | APP_AST - | VAR_AST - | QUANTIFIER_AST - | SORT_AST - | FUNC_DECL_AST - | UNKNOWN_AST - -and decl_kind = - | OP_TRUE - | OP_FALSE - | OP_EQ - | OP_DISTINCT - | OP_ITE - | OP_AND - | OP_OR - | OP_IFF - | OP_XOR - | OP_NOT - | OP_IMPLIES - | OP_OEQ - | OP_ANUM - | OP_AGNUM - | OP_LE - | OP_GE - | OP_LT - | OP_GT - | OP_ADD - | OP_SUB - | OP_UMINUS - | OP_MUL - | OP_DIV - | OP_IDIV - | OP_REM - | OP_MOD - | OP_TO_REAL - | OP_TO_INT - | OP_IS_INT - | OP_POWER - | OP_STORE - | OP_SELECT - | OP_CONST_ARRAY - | OP_ARRAY_MAP - | OP_ARRAY_DEFAULT - | OP_SET_UNION - | OP_SET_INTERSECT - | OP_SET_DIFFERENCE - | OP_SET_COMPLEMENT - | OP_SET_SUBSET - | OP_AS_ARRAY - | OP_BNUM - | OP_BIT1 - | OP_BIT0 - | OP_BNEG - | OP_BADD - | OP_BSUB - | OP_BMUL - | OP_BSDIV - | OP_BUDIV - | OP_BSREM - | OP_BUREM - | OP_BSMOD - | OP_BSDIV0 - | OP_BUDIV0 - | OP_BSREM0 - | OP_BUREM0 - | OP_BSMOD0 - | OP_ULEQ - | OP_SLEQ - | OP_UGEQ - | OP_SGEQ - | OP_ULT - | OP_SLT - | OP_UGT - | OP_SGT - | OP_BAND - | OP_BOR - | OP_BNOT - | OP_BXOR - | OP_BNAND - | OP_BNOR - | OP_BXNOR - | OP_CONCAT - | OP_SIGN_EXT - | OP_ZERO_EXT - | OP_EXTRACT - | OP_REPEAT - | OP_BREDOR - | OP_BREDAND - | OP_BCOMP - | OP_BSHL - | OP_BLSHR - | OP_BASHR - | OP_ROTATE_LEFT - | OP_ROTATE_RIGHT - | OP_EXT_ROTATE_LEFT - | OP_EXT_ROTATE_RIGHT - | OP_INT2BV - | OP_BV2INT - | OP_CARRY - | OP_XOR3 - | OP_PR_UNDEF - | OP_PR_TRUE - | OP_PR_ASSERTED - | OP_PR_GOAL - | OP_PR_MODUS_PONENS - | OP_PR_REFLEXIVITY - | OP_PR_SYMMETRY - | OP_PR_TRANSITIVITY - | OP_PR_TRANSITIVITY_STAR - | OP_PR_MONOTONICITY - | OP_PR_QUANT_INTRO - | OP_PR_DISTRIBUTIVITY - | OP_PR_AND_ELIM - | OP_PR_NOT_OR_ELIM - | OP_PR_REWRITE - | OP_PR_REWRITE_STAR - | OP_PR_PULL_QUANT - | OP_PR_PULL_QUANT_STAR - | OP_PR_PUSH_QUANT - | OP_PR_ELIM_UNUSED_VARS - | OP_PR_DER - | OP_PR_QUANT_INST - | OP_PR_HYPOTHESIS - | OP_PR_LEMMA - | OP_PR_UNIT_RESOLUTION - | OP_PR_IFF_TRUE - | OP_PR_IFF_FALSE - | OP_PR_COMMUTATIVITY - | OP_PR_DEF_AXIOM - | OP_PR_DEF_INTRO - | OP_PR_APPLY_DEF - | OP_PR_IFF_OEQ - | OP_PR_NNF_POS - | OP_PR_NNF_NEG - | OP_PR_NNF_STAR - | OP_PR_CNF_STAR - | OP_PR_SKOLEMIZE - | OP_PR_MODUS_PONENS_OEQ - | OP_PR_TH_LEMMA - | OP_PR_HYPER_RESOLVE - | OP_RA_STORE - | OP_RA_EMPTY - | OP_RA_IS_EMPTY - | OP_RA_JOIN - | OP_RA_UNION - | OP_RA_WIDEN - | OP_RA_PROJECT - | OP_RA_FILTER - | OP_RA_NEGATION_FILTER - | OP_RA_RENAME - | OP_RA_COMPLEMENT - | OP_RA_SELECT - | OP_RA_CLONE - | OP_FD_LT - | OP_LABEL - | OP_LABEL_LIT - | OP_DT_CONSTRUCTOR - | OP_DT_RECOGNISER - | OP_DT_ACCESSOR - | OP_UNINTERPRETED - -and param_kind = - | PK_UINT - | PK_BOOL - | PK_DOUBLE - | PK_SYMBOL - | PK_STRING - | PK_OTHER - | PK_INVALID - -and ast_print_mode = - | PRINT_SMTLIB_FULL - | PRINT_LOW_LEVEL - | PRINT_SMTLIB_COMPLIANT - | PRINT_SMTLIB2_COMPLIANT - -and error_code = - | OK - | SORT_ERROR - | IOB - | INVALID_ARG - | PARSER_ERROR - | NO_PARSER - | INVALID_PATTERN - | MEMOUT_FAIL - | FILE_ACCESS_ERROR - | INTERNAL_FATAL - | INVALID_USAGE - | DEC_REF_ERROR - | EXCEPTION - -and goal_prec = - | GOAL_PRECISE - | GOAL_UNDER - | GOAL_OVER - | GOAL_UNDER_OVER - - -(** -*) -(** - {2 {L Types}} - Most of the types in the API are abstract. - - [context]: manager of all other Z3 objects, global configuration options, etc. - - [symbol]: Lisp-like symbol used to name types, constants, and functions. A symbol can be created using string or integers. - - [ast]: abstract syntax tree node. That is, the data-structure used in Z3 to represent terms, formulas and types. - - [sort]: kind of AST used to represent types. - - [func_decl]: kind of AST used to represent function symbols. - - [app]: kind of AST used to represent function applications. - - [pattern]: kind of AST used to represent pattern and multi-patterns used to guide quantifier instantiation. - - [params]: parameter set used to configure many components such as: simplifiers, tactics, solvers, etc. - - [model]: model for the constraints asserted into the logical context. - - [func_interp]: interpretation of a function in a model. - - [func_entry]: representation of the value of a [func_interp] at a particular point. - - [fixedpoint]: context for the recursive predicate solver. - - [ast_vector]: vector of [ast] objects. - - [ast_map]: mapping from [ast] to [ast] objects. - - [goal]: set of formulas that can be solved and/or transformed using tactics and solvers. - - [tactic]: basic building block for creating custom solvers for specific problem domains. - - [probe]: function/predicate used to inspect a goal and collect information that may be used to decide which solver and/or preprocessing step will be used. - - [apply_result]: collection of subgoals resulting from applying of a tactic to a goal. - - [solver]: (incremental) solver, possibly specialized by a particular tactic or logic. - - [stats]: statistical data for a solver. -*) -(** - {!lbool} - Lifted Boolean type: [false], [undefined], [true]. -*) -(** - {!symbol_kind} - The different kinds of symbol. - In Z3, a symbol can be represented using integers and strings (See {!get_symbol_kind}). - - {b See also}: {!mk_int_symbol} - - {b See also}: {!mk_string_symbol} -*) -(** - {!parameter_kind} - The different kinds of parameters that can be associated with function symbols. - - {b See also}: {!get_decl_num_parameters} - - {b See also}: {!get_decl_parameter_kind} - - PARAMETER_INT is used for integer parameters. - - PARAMETER_DOUBLE is used for double parameters. - - PARAMETER_RATIONAL is used for parameters that are rational numbers. - - PARAMETER_SYMBOL is used for parameters that are symbols. - - PARAMETER_SORT is used for sort parameters. - - PARAMETER_AST is used for expression parameters. - - PARAMETER_FUNC_DECL is used for function declaration parameters. -*) -(** - {!sort_kind} - The different kinds of Z3 types (See {!get_sort_kind}). -*) -(** - {!ast_kind} - The different kinds of Z3 AST (abstract syntax trees). That is, terms, formulas and types. - - APP_AST: constant and applications - - NUMERAL_AST: numeral constants - - VAR_AST: bound variables - - QUANTIFIER_AST: quantifiers - - SORT_AST: sort - - FUNC_DECL_AST: function declaration - - UNKNOWN_AST: internal -*) -(** - {!decl_kind} - The different kinds of interpreted function kinds. - - OP_TRUE The constant true. - - OP_FALSE The constant false. - - OP_EQ The equality predicate. - - OP_DISTINCT The n-ary distinct predicate (every argument is mutually distinct). - - OP_ITE The ternary if-then-else term. - - OP_AND n-ary conjunction. - - OP_OR n-ary disjunction. - - OP_IFF equivalence (binary). - - OP_XOR Exclusive or. - - OP_NOT Negation. - - OP_IMPLIES Implication. - - OP_OEQ Binary equivalence modulo namings. This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. - - OP_ANUM Arithmetic numeral. - - OP_AGNUM Arithmetic algebraic numeral. Algebraic numbers are used to represent irrational numbers in Z3. - - OP_LE <=. - - OP_GE >=. - - OP_LT <. - - OP_GT >. - - OP_ADD Addition - Binary. - - OP_SUB Binary subtraction. - - OP_UMINUS Unary minus. - - OP_MUL Multiplication - Binary. - - OP_DIV Division - Binary. - - OP_IDIV Integer division - Binary. - - OP_REM Remainder - Binary. - - OP_MOD Modulus - Binary. - - OP_TO_REAL Coercion of integer to real - Unary. - - OP_TO_INT Coercion of real to integer - Unary. - - OP_IS_INT Check if real is also an integer - Unary. - - OP_POWER Power operator x^y. - - OP_STORE Array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. - - OP_SELECT Array select. - - OP_CONST_ARRAY The constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary. - - OP_ARRAY_DEFAULT Default value of arrays. For example default(const(v)) = v. The function is unary. - - OP_ARRAY_MAP Array map operator. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. - - OP_SET_UNION Set union between two Booelan arrays (two arrays whose range type is Boolean). The function is binary. - - OP_SET_INTERSECT Set intersection between two Boolean arrays. The function is binary. - - OP_SET_DIFFERENCE Set difference between two Boolean arrays. The function is binary. - - OP_SET_COMPLEMENT Set complement of a Boolean array. The function is unary. - - OP_SET_SUBSET Subset predicate between two Boolean arrays. The relation is binary. - - OP_AS_ARRAY An array value that behaves as the function graph of the - function passed as parameter. - - OP_BNUM Bit-vector numeral. - - OP_BIT1 One bit bit-vector. - - OP_BIT0 Zero bit bit-vector. - - OP_BNEG Unary minus. - - OP_BADD Binary addition. - - OP_BSUB Binary subtraction. - - OP_BMUL Binary multiplication. - - OP_BSDIV Binary signed division. - - OP_BUDIV Binary unsigned int division. - - OP_BSREM Binary signed remainder. - - OP_BUREM Binary unsigned int remainder. - - OP_BSMOD Binary signed modulus. - - OP_BSDIV0 Unary function. bsdiv(x,0) is congruent to bsdiv0(x). - - OP_BUDIV0 Unary function. budiv(x,0) is congruent to budiv0(x). - - OP_BSREM0 Unary function. bsrem(x,0) is congruent to bsrem0(x). - - OP_BUREM0 Unary function. burem(x,0) is congruent to burem0(x). - - OP_BSMOD0 Unary function. bsmod(x,0) is congruent to bsmod0(x). - - OP_ULEQ Unsigned bit-vector <= - Binary relation. - - OP_SLEQ Signed bit-vector <= - Binary relation. - - OP_UGEQ Unsigned bit-vector >= - Binary relation. - - OP_SGEQ Signed bit-vector >= - Binary relation. - - OP_ULT Unsigned bit-vector < - Binary relation. - - OP_SLT Signed bit-vector < - Binary relation. - - OP_UGT Unsigned bit-vector > - Binary relation. - - OP_SGT Signed bit-vector > - Binary relation. - - OP_BAND Bit-wise and - Binary. - - OP_BOR Bit-wise or - Binary. - - OP_BNOT Bit-wise not - Unary. - - OP_BXOR Bit-wise xor - Binary. - - OP_BNAND Bit-wise nand - Binary. - - OP_BNOR Bit-wise nor - Binary. - - OP_BXNOR Bit-wise xnor - Binary. - - OP_CONCAT Bit-vector concatenation - Binary. - - OP_SIGN_EXT Bit-vector sign extension. - - OP_ZERO_EXT Bit-vector zero extension. - - OP_EXTRACT Bit-vector extraction. - - OP_REPEAT Repeat bit-vector n times. - - OP_BREDOR Bit-vector reduce or - Unary. - - OP_BREDAND Bit-vector reduce and - Unary. - - OP_BCOMP . - - OP_BSHL Shift left. - - OP_BLSHR Logical shift right. - - OP_BASHR Arithmetical shift right. - - OP_ROTATE_LEFT Left rotation. - - OP_ROTATE_RIGHT Right rotation. - - OP_EXT_ROTATE_LEFT (extended) Left rotation. Similar to OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. - - OP_EXT_ROTATE_RIGHT (extended) Right rotation. Similar to OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. - - OP_INT2BV Coerce integer to bit-vector. NB. This function - is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - - OP_BV2INT Coerce bit-vector to integer. NB. This function - is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - - OP_CARRY Compute the carry bit in a full-adder. - The meaning is given by the equivalence - (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) - - OP_XOR3 Compute ternary XOR. - The meaning is given by the equivalence - (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) - - OP_PR_UNDEF: Undef/Null proof object. - - OP_PR_TRUE: Proof for the expression 'true'. - - OP_PR_ASSERTED: Proof for a fact asserted by the user. - - OP_PR_GOAL: Proof for a fact (tagged as goal) asserted by the user. - - OP_PR_MODUS_PONENS: Given a proof for p and a proof for (implies p q), produces a proof for q. - {e - T1: p - T2: (implies p q) - [mp T1 T2]: q - } - The second antecedents may also be a proof for (iff p q). - - OP_PR_REFLEXIVITY: A proof for (R t t), where R is a reflexive relation. This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. - - OP_PR_SYMMETRY: Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - {e - T1: (R t s) - [symmetry T1]: (R s t) - } - T1 is the antecedent of this proof object. - - OP_PR_TRANSITIVITY: Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - {e - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) - } - - OP_PR_TRANSITIVITY_STAR: Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - {e - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - } - R must be a symmetric and transitive relation. - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. - - OP_PR_MONOTONICITY: Monotonicity proof object. - {e - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - } - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. - - OP_PR_QUANT_INTRO: Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - - OP_PR_DISTRIBUTIVITY: Distributivity proof object. - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. - - OP_PR_AND_ELIM: Given a proof for (and l_1 ... l_n), produces a proof for l_i - {e - T1: (and l_1 ... l_n) - [and-elim T1]: l_i - } - - OP_PR_NOT_OR_ELIM: Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - {e - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) - } - - OP_PR_REWRITE: A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - Examples: - {e - (= (+ x 0) x) - (= (+ x 1 2) (+ 3 x)) - (iff (or x false) x) - } - - OP_PR_REWRITE_STAR: A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - - OP_PR_PULL_QUANT: A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - - OP_PR_PULL_QUANT_STAR: A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents. - - OP_PR_PUSH_QUANT: A proof for: - {e - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - } - This proof object has no antecedents. - - OP_PR_ELIM_UNUSED_VARS: - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - It is used to justify the elimination of unused variables. - This proof object has no antecedents. - - OP_PR_DER: A proof for destructive equality resolution: - (iff (forall (x) (or (not (= x t)) P[x])) P[t]) - if x does not occur in t. - This proof object has no antecedents. - Several variables can be eliminated simultaneously. - - OP_PR_QUANT_INST: A proof of (or (not (forall (x) (P x))) (P a)) - - OP_PR_HYPOTHESIS: Mark a hypothesis in a natural deduction style proof. - - OP_PR_LEMMA: - {e - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - } - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. - - OP_PR_UNIT_RESOLUTION: - {e - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - } - - OP_PR_IFF_TRUE: - {e - T1: p - [iff-true T1]: (iff p true) - } - - OP_PR_IFF_FALSE: - {e - T1: (not p) - [iff-false T1]: (iff p false) - } - - - OP_PR_COMMUTATIVITY: - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. - - - OP_PR_DEF_AXIOM: Proof object used to justify Tseitin's like axioms: - - {e - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - } - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). - - - OP_PR_DEF_INTRO: Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) - - - OP_PR_APPLY_DEF: - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. - - - OP_PR_IFF_OEQ: - T1: (iff p q) - [iff~ T1]: (~ p q) - - - OP_PR_NNF_POS: Proof for a (positive) NNF step. Example: - {e - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - } - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - {e - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - } - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. - - - - OP_PR_NFF_NEG: Proof for a (negative) NNF step. Examples: - {e - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) - } - - OP_PR_NNF_STAR: A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - - - OP_PR_CNF_STAR: A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - - - OP_PR_SKOLEMIZE: Proof for: - - {e - [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y))) - [sk]: (~ (exists x (p x y)) (p (sk y) y)) - } - - This proof object has no antecedents. - - - OP_PR_MODUS_PONENS_OEQ: Modus ponens style rule for equi-satisfiability. - {e - T1: p - T2: (~ p q) - [mp~ T1 T2]: q - } - - - OP_PR_TH_LEMMA: Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - - triangle-eq - Indicates a lemma related to the equivalence: - {e - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - } - - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - - - - OP_PR_HYPER_RESOLVE: Hyper-resolution rule. - - The premises of the rules is a sequence of clauses. - The first clause argument is the main clause of the rule. - One literal from the second, third, .. clause is resolved - with a literal from the first (main) clause. - - Premises of the rules are of the form - {e - (or l0 l1 l2 .. ln) - } - or - {e - (=> (and ln+1 ln+2 .. ln+m) l0) - } - or in the most general (ground) form: - {e - (=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln-1)) - } - In other words we use the following (Prolog style) convention for Horn - implications: - The head of a Horn implication is position 0, - the first conjunct in the body of an implication is position 1 - the second conjunct in the body of an implication is position 2 - -<<<<<<< HEAD - For general implications where the head is a disjunction, the - first n positions correspond to the n disjuncts in the head. - The next m positions correspond to the m conjuncts in the body. -======= (** Create a context object The following parameters can be set: @@ -776,387 +47,194 @@ and goal_prec = - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver *) val mk_context : (string * string) list -> context ->>>>>>> Updates to ML API. - The premises can be universally quantified so that the most - general non-ground form is: +(** Interaction logging for Z3 + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log : +sig + (** Open an interaction log file. + @return True if opening the log file succeeds, false otherwise. *) + (* CMW: "open" seems to be a reserved keyword? *) + val open_ : string -> bool - {e - (forall (vars) (=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln-1))) - } + (** Closes the interaction log. *) + val close : unit - The hyper-resolution rule takes a sequence of parameters. - The parameters are substitutions of bound variables separated by pairs - of literal positions from the main clause and side clause. + (** Appends a user-provided string to the interaction log. *) + val append : string -> unit +end +(** Version information *) +module Version : +sig + (** The major version. *) + val major : int - - OP_RA_STORE: Insert a record into a relation. - The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements - correspond to the [n] columns of the relation. + (** The minor version. *) + val minor : int - - OP_RA_EMPTY: Creates the empty relation. + (** The build version. *) + val build : int - - OP_RA_IS_EMPTY: Tests if the relation is empty. + (** The revision. *) + val revision : int - - OP_RA_JOIN: Create the relational join. + (** A string representation of the version information. *) + val to_string : string +end - - OP_RA_UNION: Create the union or convex hull of two relations. - The function takes two arguments. +(** Symbols are used to name several term and type constructors *) +module Symbol : +sig + type symbol - - OP_RA_WIDEN: Widen two relations. - The function takes two arguments. + (** The kind of the symbol (int or string) *) + val kind : symbol -> Z3enums.symbol_kind - - OP_RA_PROJECT: Project the columns (provided as numbers in the parameters). - The function takes one argument. + (** Indicates whether the symbol is of Int kind *) + val is_int_symbol : symbol -> bool - - OP_RA_FILTER: Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. + (** Indicates whether the symbol is of string kind. *) + val is_string_symbol : symbol -> bool - - OP_RA_NEGATION_FILTER: Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function + (** The int value of the symbol. *) + val get_int : symbol -> int - target = filter_by_negation(pos, neg, columns) + (** The string value of the symbol. *) + val get_string : symbol -> string - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in x in pos, such that there is no y in neg that agrees with - x on the columns c1, d1, .., cN, dN. + (** A string representation of the symbol. *) + val to_string : symbol -> string + (** Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. *) + val mk_int : context -> int -> symbol - - OP_RA_RENAME: rename columns in the relation. - The function takes one argument. - The parameters contain the renaming as a cycle. + (** Creates a new symbol using a string. *) + val mk_string : context -> string -> symbol - - OP_RA_COMPLEMENT: Complement the relation. + (** Create a list of symbols. *) + val mk_ints : context -> int list -> symbol list - - OP_RA_SELECT: Check if a record is an element of the relation. - The function takes [n+1] arguments, where the first argument is a relation, - and the remaining [n] arguments correspond to a record. + (** Create a list of symbols. *) + val mk_strings : context -> string list -> symbol list +end - - OP_RA_CLONE: Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for [OP_RA_UNION] - to perform destructive updates to the first argument. +(** The abstract syntax tree (AST) module *) +module AST : +sig + type ast + (** Vectors of ASTs *) + module ASTVector : + sig + type ast_vector + + (** The size of the vector *) + val get_size : ast_vector -> int - - OP_FD_LT: A less than predicate over the finite domain FINITE_DOMAIN_SORT. + (** + Retrieves the i-th object in the vector. + @return An AST *) + val get : ast_vector -> int -> ast - - OP_LABEL: A label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. - It takes one argument, a formula. + (** Sets the i-th object in the vector. *) + val set : ast_vector -> int -> ast -> unit - - OP_LABEL_LIT: A label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. + (** Resize the vector to a new size. *) + val resize : ast_vector -> int -> unit - - OP_DT_CONSTRUCTOR: datatype constructor. + (** Add an ast to the back of the vector. The size + is increased by 1. *) + val push : ast_vector -> ast -> unit - - OP_DT_RECOGNISER: datatype recognizer. + (** Translates all ASTs in the vector to another context. + @return A new ASTVector *) + val translate : ast_vector -> context -> ast_vector - - OP_DT_ACCESSOR: datatype accessor. + (** Retrieves a string representation of the vector. *) + val to_string : ast_vector -> string + end - - OP_UNINTERPRETED: kind used for uninterpreted symbols. -*) -(** - {!param_kind} + (** Map from AST to AST *) + module ASTMap : + sig + type ast_map + + (** Checks whether the map contains a key. + @return True if the key in the map, false otherwise. *) + val contains : ast_map -> ast -> bool - The different kinds of parameters that can be associated with parameter sets. - (see {!mk_params}). + (** Finds the value associated with the key. + This function signs an error when the key is not a key in the map. *) + val find : ast_map -> ast -> ast - - PK_UINT integer parameters. - - PK_BOOL boolean parameters. - - PK_DOUBLE double parameters. - - PK_SYMBOL symbol parameters. - - PK_STRING string parameters. - - PK_OTHER all internal parameter kinds which are not exposed in the API. - - PK_INVALID invalid parameter. -*) -(** - {!ast_print_mode} - Z3 pretty printing modes (See {!set_ast_print_mode}). - - PRINT_SMTLIB_FULL: Print AST nodes in SMTLIB verbose format. - - PRINT_LOW_LEVEL: Print AST nodes using a low-level format. - - PRINT_SMTLIB_COMPLIANT: Print AST nodes in SMTLIB 1.x compliant format. - - PRINT_SMTLIB2_COMPLIANT: Print AST nodes in SMTLIB 2.x compliant format. -*) -(** - {!error_code} - Z3 error codes - - OK: No error. - - SORT_ERROR: User tried to build an invalid (type incorrect) AST. - - IOB: Index out of bounds. - - INVALID_ARG: Invalid argument was provided. - - PARSER_ERROR: An error occurred when parsing a string or file. - - NO_PARSER: Parser output is not available, that is, user didn't invoke {!parse_smtlib_string} or {!parse_smtlib_file}. - - INVALID_PATTERN: Invalid pattern was used to build a quantifier. - - MEMOUT_FAIL: A memory allocation failure was encountered. - - FILE_ACCESS_ERRROR: A file could not be accessed. - - INVALID_USAGE: API call is invalid in the current state. - - INTERNAL_FATAL: An error internal to Z3 occurred. - - DEC_REF_ERROR: Trying to decrement the reference counter of an AST that was deleted or the reference counter was not initialized. - - EXCEPTION: Internal Z3 exception. Additional details can be retrieved using {!get_error_msg}. -*) -(** - Definitions for update_api.py - def_Type('CONFIG', 'config', 'Config') - def_Type('CONTEXT', 'context', 'ContextObj') - def_Type('AST', 'ast', 'Ast') - def_Type('APP', 'app', 'Ast') - def_Type('SORT', 'sort', 'Sort') - def_Type('FUNC_DECL', 'func_decl', 'FuncDecl') - def_Type('PATTERN', 'pattern', 'Pattern') - def_Type('MODEL', 'model', 'Model') - def_Type('LITERALS', 'literals', 'Literals') - def_Type('CONSTRUCTOR', 'constructor', 'Constructor') - def_Type('CONSTRUCTOR_LIST', 'constructor_list', 'ConstructorList') - def_Type('THEORY', 'theory', 'ctypes.c_void_p') - def_Type('THEORY_DATA', 'theory_data', 'ctypes.c_void_p') - def_Type('SOLVER', 'solver', 'SolverObj') - def_Type('GOAL', 'goal', 'GoalObj') - def_Type('TACTIC', 'tactic', 'TacticObj') - def_Type('PARAMS', 'params', 'Params') - def_Type('PROBE', 'probe', 'ProbeObj') - def_Type('STATS', 'stats', 'StatsObj') - def_Type('AST_VECTOR', 'ast_vector', 'AstVectorObj') - def_Type('AST_MAP', 'ast_map', 'AstMapObj') - def_Type('APPLY_RESULT', 'apply_result', 'ApplyResultObj') - def_Type('FUNC_INTERP', 'func_interp', 'FuncInterpObj') - def_Type('FUNC_ENTRY', 'func_entry', 'FuncEntryObj') - def_Type('FIXEDPOINT', 'fixedpoint', 'FixedpointObj') - def_Type('PARAM_DESCRS', 'param_descrs', 'ParamDescrs') -*) + (** Stores or replaces a new key/value pair in the map. *) + val insert : ast_map -> ast -> ast -> unit -(** Exceptions raised by Z3. It is safe to continue interacting with Z3 after - catching [Error] exceptions. - - {b See also}: {!get_error_msg} -*) -exception Error of context * error_code + (** Erases the key from the map.*) + val erase : ast_map -> ast -> unit -(** - {!goal_prec} - A Goal is essentially a set of formulas. Z3 provide APIs for building strategies/tactics for solving and transforming Goals. Some of these transformations apply under/over approximations. - - GOAL_PRECISE: Approximations/Relaxations were not applied on the goal (sat and unsat answers were preserved). - - GOAL_UNDER: Goal is the product of a under-approximation (sat answers are preserved). - - GOAL_OVER: Goal is the product of an over-approximation (unsat answers are preserved). - - GOAL_UNDER_OVER: Goal is garbage (it is the product of over- and under-approximations, sat and unsat answers are not preserved). -*) -(** - {2 {L Create context}} -*) -(** - Summary: Create a context using the given configuration. - After a context is created, the configuration cannot be changed, - although some parameters can be changed using {!update_param_value}. - All main interaction with Z3 happens in the context of a [context]. - def_API('mk_context', CONTEXT, (_in(CONFIG),)) -*) -external mk_context: (string * string) list -> context = "caml_z3_mk_context" + (** Removes all keys from the map. *) + val reset : ast_map -> unit -(** - Summary: Set a value of a context parameter. - - {b See also}: {!global_param_set} - def_API('update_param_value', VOID, (_in(CONTEXT), _in(STRING), _in(STRING))) -*) -external update_param_value : context -> string -> string -> unit - = "camlidl_z3_Z3_update_param_value" + (** The size of the map *) + val get_size : ast_map -> int -(** - Summary: Return the value of a context parameter. - - {b See also}: {!global_param_get} - def_API('get_param_value', BOOL, (_in(CONTEXT), _in(STRING), _out(STRING))) -*) -external get_param_value : context -> string -> string option - = "camlidl_z3_Z3_get_param_value" + (** The keys stored in the map. *) + val get_keys : ast_map -> ast list -(** - Summary: Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. - def_API('interrupt', VOID, (_in(CONTEXT),)) -*) -external interrupt : context -> unit - = "camlidl_z3_Z3_interrupt" + (** Retrieves a string representation of the map.*) + val to_string : ast_map -> string + end -(** - {2 {L Parameters}} -*) -(** - Summary: Create a Z3 (empty) parameter set. - Starting at Z3 4.0, parameter sets are used to configure many components such as: - simplifiers, tactics, solvers, etc. - def_API('mk_params', PARAMS, (_in(CONTEXT),)) -*) -external mk_params : context -> params - = "camlidl_z3_Z3_mk_params" + (** The AST's hash code. + @return A hash code *) + val hash : ast -> int -(** - Summary: Add a Boolean parameter [k] with value [v] to the parameter set [p]. - def_API('params_set_bool', VOID, (_in(CONTEXT), _in(PARAMS), _in(SYMBOL), _in(BOOL))) -*) -external params_set_bool : context -> params -> symbol -> bool -> unit - = "camlidl_z3_Z3_params_set_bool" + (** A unique identifier for the AST (unique among all ASTs). *) + val get_id : ast -> int -(** - Summary: Add a unsigned int parameter [k] with value [v] to the parameter set [p]. - def_API('params_set_uint', VOID, (_in(CONTEXT), _in(PARAMS), _in(SYMBOL), _in(UINT))) -*) -external params_set_uint : context -> params -> symbol -> int -> unit - = "camlidl_z3_Z3_params_set_uint" + (** The kind of the AST. *) + val get_ast_kind : ast -> Z3enums.ast_kind -(** - Summary: Add a double parameter [k] with value [v] to the parameter set [p]. - def_API('params_set_double', VOID, (_in(CONTEXT), _in(PARAMS), _in(SYMBOL), _in(DOUBLE))) -*) -external params_set_double : context -> params -> symbol -> float -> unit - = "camlidl_z3_Z3_params_set_double" + (** Indicates whether the AST is an Expr *) + val is_expr : ast -> bool -(** - Summary: Add a symbol parameter [k] with value [v] to the parameter set [p]. - def_API('params_set_symbol', VOID, (_in(CONTEXT), _in(PARAMS), _in(SYMBOL), _in(SYMBOL))) -*) -external params_set_symbol : context -> params -> symbol -> symbol -> unit - = "camlidl_z3_Z3_params_set_symbol" + (** Indicates whether the AST is a bound variable*) + val is_var : ast -> bool -(** - Summary: Convert a parameter set into a string. This function is mainly used for printing the - contents of a parameter set. - def_API('params_to_string', STRING, (_in(CONTEXT), _in(PARAMS))) -*) -external params_to_string : context -> params -> string - = "camlidl_z3_Z3_params_to_string" + (** Indicates whether the AST is a Quantifier *) + val is_quantifier : ast -> bool -(** - Summary: Validate the parameter set [p] against the parameter description set [d]. - The procedure invokes the error handler if [p] is invalid. - def_API('params_validate', VOID, (_in(CONTEXT), _in(PARAMS), _in(PARAM_DESCRS))) -*) -external params_validate : context -> params -> param_descrs -> unit - = "camlidl_z3_Z3_params_validate" + (** Indicates whether the AST is a Sort *) + val is_sort : ast -> bool -(** - {2 {L Parameter Descriptions}} -*) -(** - Summary: Return the kind associated with the given parameter name [n]. - def_API('param_descrs_get_kind', UINT, (_in(CONTEXT), _in(PARAM_DESCRS), _in(SYMBOL))) -*) -external param_descrs_get_kind : context -> param_descrs -> symbol -> param_kind - = "camlidl_z3_Z3_param_descrs_get_kind" + (** Indicates whether the AST is a func_decl *) + val is_func_decl : ast -> bool -(** - Summary: Return the number of parameters in the given parameter description set. - def_API('param_descrs_size', UINT, (_in(CONTEXT), _in(PARAM_DESCRS))) -*) -external param_descrs_size : context -> param_descrs -> int - = "camlidl_z3_Z3_param_descrs_size" + (** A string representation of the AST. *) + val to_string : ast -> string -(** - Summary: Return the number of parameters in the given parameter description set. - - {b Precondition}: i < param_descrs_size c p - def_API('param_descrs_get_name', SYMBOL, (_in(CONTEXT), _in(PARAM_DESCRS), _in(UINT))) -*) -external param_descrs_get_name : context -> param_descrs -> int -> symbol - = "camlidl_z3_Z3_param_descrs_get_name" + (** A string representation of the AST in s-expression notation. *) + val to_sexpr : ast -> string -(** - Summary: Convert a parameter description set into a string. This function is mainly used for printing the - contents of a parameter description set. - def_API('param_descrs_to_string', STRING, (_in(CONTEXT), _in(PARAM_DESCRS))) -*) -external param_descrs_to_string : context -> param_descrs -> string - = "camlidl_z3_Z3_param_descrs_to_string" + (** Comparison operator. + @return True if the two ast's are from the same context + and represent the same sort; false otherwise. *) + val equal : ast -> ast -> bool -(** - {2 {L Symbols}} -*) + (** Object Comparison. + @return Negative if the first ast should be sorted before the second, positive if after else zero. *) + val compare : ast -> ast -> int -(** - Refined view of a {!symbol}. - - {b See also}: {!mk_symbol} - - {b See also}: {!symbol_refine} -*) -type symbol_refined = - | Symbol_int of int - | Symbol_string of string + (** Translates (copies) the AST to another context. + @return A copy of the AST which is associated with the other context. *) + val translate : ast -> context -> ast - -(** - Summary: \[ [ mk_symbol c sr ] \] constructs the symbol described by [sr]. - - {b See also}: {!symbol_refine} -*) -val mk_symbol: context -> symbol_refined -> symbol - -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Create a Z3 symbol using an integer. - Symbols are used to name several term and type constructors. - NB. Not all integers can be passed to this function. - The legal range of unsigned int integers is 0 to 2^30-1. - - {b See also}: {!mk_string_symbol} - def_API('mk_int_symbol', SYMBOL, (_in(CONTEXT), _in(INT))) -*) -external mk_int_symbol : context -> int -> symbol - = "camlidl_z3_Z3_mk_int_symbol" - -<<<<<<< HEAD -(** - Summary: Create a Z3 symbol using a C string. - Symbols are used to name several term and type constructors. - - {b See also}: {!mk_int_symbol} - def_API('mk_string_symbol', SYMBOL, (_in(CONTEXT), _in(STRING))) -*) -external mk_string_symbol : context -> string -> symbol - = "camlidl_z3_Z3_mk_string_symbol" - -(** - {2 {L Sorts}} -*) - -(** - A datatype constructor descriptor. -*) -type datatype_constructor_desc = { - constructor_desc : symbol; (** name of the constructor function *) - recognizer_desc : symbol; (** name of the recognizer function *) - accessor_descs : (symbol * sort) array; (** names and sorts of the fields *) -} -(** - A datatype is described by a name and constructor descriptors. -*) -type datatype_desc = symbol * datatype_constructor_desc array -(** - A datatype constructor representation. -*) -type datatype_constructor = { - constructor : func_decl; (** constructor function *) - recognizer : func_decl; (** recognizer function *) - accessors : func_decl array; (** field accessor functions *) -} -(** - A datatype is represented by a sort and constructors. -*) -type datatype = sort * datatype_constructor array -(** - Refined view of a {!sort}. - - {b See also}: {!mk_sort} - - {b See also}: {!sort_refine} -*) -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_bv of int - | Sort_finite_domain of symbol * int64 - | Sort_real - | Sort_array of sort * sort - | Sort_datatype of datatype_constructor array - | Sort_relation of sort array - | Sort_unknown -======= (** Unwraps an AST. This function is used for transitions between native and managed objects. It returns the native pointer to the AST. Note that @@ -1176,573 +254,185 @@ type sort_refined = Z3native.inc_ref). *) val wrap_ast : context -> Z3native.z3_ast -> ast end ->>>>>>> Updates to ML API. +(** The Sort module implements type information for ASTs *) +module Sort : +sig + type sort = Sort of AST.ast -(** - Summary: \[ [ mk_sort c sr ] \] constructs the sort described by [sr]. - - {b Precondition}: [sr] is not of form [Sort_relation] or [Sort_unknown], which cannot be directly constructed - - {b See also}: {!mk_datatypes} - - {b See also}: {!sort_refine} -*) -val mk_sort: context -> sort_refined -> sort -(** - \[ [mk_datatypes ctx sorts_to_descriptors] \] creates mutually recursive datatypes described by - [sorts_to_descriptors], which is a function from the sorts of the datatypes to be created to - descriptors of the datatypes' constructors. - - {b See also}: {!Test_mlapi.forest_example} -*) -val mk_datatypes: context -> (sort array -> (datatype_desc array) option) -> datatype array + val ast_of_sort : sort -> AST.ast -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Create a free (uninterpreted) type using the given name (symbol). - Two free types are considered the same iff the have the same name. - def_API('mk_uninterpreted_sort', SORT, (_in(CONTEXT), _in(SYMBOL))) -*) -external mk_uninterpreted_sort : context -> symbol -> sort - = "camlidl_z3_Z3_mk_uninterpreted_sort" + (** Comparison operator. + @return True if the two sorts are from the same context + and represent the same sort; false otherwise. *) + val equal : sort -> sort -> bool -(** - Summary: Create the Boolean type. - This type is used to create propositional variables and predicates. - def_API('mk_bool_sort', SORT, (_in(CONTEXT), )) -*) -external mk_bool_sort : context -> sort - = "camlidl_z3_Z3_mk_bool_sort" + (** Returns a unique identifier for the sort. *) + val get_id : sort -> int -(** - Summary: Create the integer type. - This type is not the int type found in programming languages. - A machine integer can be represented using bit-vectors. The function - {!mk_bv_sort} creates a bit-vector type. - - {b See also}: {!mk_bv_sort} - def_API('mk_int_sort', SORT, (_in(CONTEXT), )) -*) -external mk_int_sort : context -> sort - = "camlidl_z3_Z3_mk_int_sort" + (** The kind of the sort. *) + val get_sort_kind : sort -> Z3enums.sort_kind -(** - Summary: Create the real type. - This type is not a floating point number. - Z3 does not have support for floating point numbers yet. - def_API('mk_real_sort', SORT, (_in(CONTEXT), )) -*) -external mk_real_sort : context -> sort - = "camlidl_z3_Z3_mk_real_sort" + (** The name of the sort *) + val get_name : sort -> Symbol.symbol -(** - Summary: Create a bit-vector type of the given size. - This type can also be seen as a machine integer. - - {b Remarks}: The size of the bitvector type must be greater than zero. - def_API('mk_bv_sort', SORT, (_in(CONTEXT), _in(UINT))) -*) -external mk_bv_sort : context -> int -> sort - = "camlidl_z3_Z3_mk_bv_sort" + (** A string representation of the sort. *) + val to_string : sort -> string -(** - Summary: Create a named finite domain sort. - To create constants that belong to the finite domain, - use the APIs for creating numerals and pass a numeric - constant together with the sort returned by this call. - - {b See also}: {!get_finite_domain_sort_size} - def_API('mk_finite_domain_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT64))) -*) -external mk_finite_domain_sort : context -> symbol -> int64 -> sort - = "camlidl_z3_Z3_mk_finite_domain_sort" + (** Create a new uninterpreted sort. *) + val mk_uninterpreted : context -> Symbol.symbol -> sort -(** - Summary: Create an array type. - We usually represent the array type as: {e [domain -> range] }. - Arrays are usually used to model the heap/memory in software verification. - - {b See also}: {!mk_select} - - {b See also}: {!mk_store} - def_API('mk_array_sort', SORT, (_in(CONTEXT), _in(SORT), _in(SORT))) -*) -external mk_array_sort : context -> sort -> sort -> sort - = "camlidl_z3_Z3_mk_array_sort" + (** Create a new uninterpreted sort. *) + val mk_uninterpreted_s : context -> string -> sort +end -(** - Summary: Create a tuple type. - [mk_tuple_sort c name field_names field_sorts] creates a tuple with a constructor named [name], - a [n] fields, where [n] is the size of the arrays [field_names] and [field_sorts]. - @param c logical context - @param mk_tuple_name name of the constructor function associated with the tuple type. - @param num_fields number of fields in the tuple type. - @param field_names name of the projection functions. - @param field_sorts type of the tuple fields. - @param mk_tuple_decl output parameter that will contain the constructor declaration. - @param proj_decl output parameter that will contain the projection function declarations. This field must be a buffer of size [num_fields] allocated by the user. - def_API('mk_tuple_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _out(FUNC_DECL), _out_array(2, FUNC_DECL))) -*) -external mk_tuple_sort : context -> symbol -> symbol array -> sort array -> sort * func_decl * func_decl array - = "camlidl_z3_Z3_mk_tuple_sort" +(** Function declarations *) +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast -(** - Summary: Create a enumeration sort. - [mk_enumeration_sort c enums] creates an enumeration sort with enumeration names [enums], - it also returns [n] predicates, where [n] is the number of [enums] corresponding - to testing whether an element is one of the enumerants. - @param c logical context - @param name name of the enumeration sort. - @param n number of elemenets in enumeration sort. - @param enum_names names of the enumerated elements. - @param enum_consts constants corresponding to the enumerated elements. - @param enum_testers predicates testing if terms of the enumeration sort correspond to an enumeration. - For example, if this function is called with three symbols A, B, C and the name S, then - [s] is a sort whose name is S, and the function returns three terms corresponding to A, B, C in - [enum_consts]. The array [enum_testers] has three predicates of type {e (s -> Bool) }. - The first predicate (corresponding to A) is true when applied to A, and false otherwise. - Similarly for the other predicates. - def_API('mk_enumeration_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SYMBOL), _out_array(2, FUNC_DECL), _out_array(2, FUNC_DECL))) -*) -external mk_enumeration_sort : context -> symbol -> symbol array -> sort * func_decl array * func_decl array - = "camlidl_z3_Z3_mk_enumeration_sort" + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast -(** - Summary: Create a list sort - [mk_list_sort c name elem_sort] creates a list sort of [name], over elements of sort [elem_sort]. - @param c logical context - @param name name of the list sort. - @param elem_sort sort of list elements. - @param nil_decl declaration for the empty list. - @param is_nil_decl test for the empty list. - @param cons_decl declaration for a cons cell. - @param is_cons_decl cons cell test. - @param head_decl list head. - @param tail_decl list tail. - def_API('mk_list_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(SORT), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL))) -*) -external mk_list_sort : context -> symbol -> sort -> sort * func_decl * func_decl * func_decl * func_decl * func_decl * func_decl - = "camlidl_z3_Z3_mk_list_sort" + (** Parameters of Func_Decls *) + module Parameter : + sig + (** Parameters of func_decls *) + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + (** The kind of the parameter. *) + val get_kind : parameter -> Z3enums.parameter_kind -(* -(** - Summary: Create a constructor. - @param c logical context. - @param name constructor name. - @param recognizer name of recognizer function. - @param num_fields number of fields in constructor. - @param field_names names of the constructor fields. - @param sorts field sorts, [None] - if the field sort refers to a recursive sort. - @param sort_refs reference to datatype sort that is an argument to the constructor; if the corresponding - sort reference is [None], - then the value in sort_refs should be an index referring to - one of the recursive datatypes that is declared. - def_API('mk_constructor', CONSTRUCTOR, (_in(CONTEXT), _in(SYMBOL), _in(SYMBOL), _in(UINT), _in_array(3, SYMBOL), _in_array(3, SORT), _in_array(3, UINT))) -*) -external mk_constructor : context -> symbol -> symbol -> symbol array -> sort option array -> int array -> constructor - = "camlidl_z3_Z3_mk_constructor_bytecode" "camlidl_z3_Z3_mk_constructor" + (** The int value of the parameter.*) + val get_int : parameter -> int -(** - Summary: Reclaim memory allocated to constructor. - @param c logical context. - @param constr constructor. - def_API('del_constructor', VOID, (_in(CONTEXT), _in(CONSTRUCTOR))) -*) -external del_constructor : context -> constructor -> unit - = "camlidl_z3_Z3_del_constructor" + (** The float value of the parameter.*) + val get_float : parameter -> float -(** - Summary: Create datatype, such as lists, trees, records, enumerations or unions of records. - The datatype may be recursive. Return the datatype sort. - @param c logical context. - @param name name of datatype. - @param num_constructors number of constructors passed in. - @param constructors array of constructor containers. - def_API('mk_datatype', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _inout_array(2, CONSTRUCTOR))) -*) -external mk_datatype : context -> symbol -> constructor array -> sort * constructor array - = "camlidl_z3_Z3_mk_datatype" + (** The Symbol.Symbol value of the parameter.*) + val get_symbol : parameter -> Symbol.symbol -(** - Summary: Create list of constructors. - @param c logical context. - @param num_constructors number of constructors in list. - @param constructors list of constructors. - def_API('mk_constructor_list', CONSTRUCTOR_LIST, (_in(CONTEXT), _in(UINT), _in_array(1, CONSTRUCTOR))) -*) -external mk_constructor_list : context -> constructor array -> constructor_list - = "camlidl_z3_Z3_mk_constructor_list" + (** The Sort value of the parameter.*) + val get_sort : parameter -> Sort.sort -(** - Summary: Reclaim memory allocated for constructor list. - Each constructor inside the constructor list must be independently reclaimed using {!del_constructor}. - @param c logical context. - @param clist constructor list container. - def_API('del_constructor_list', VOID, (_in(CONTEXT), _in(CONSTRUCTOR_LIST))) -*) -external del_constructor_list : context -> constructor_list -> unit - = "camlidl_z3_Z3_del_constructor_list" + (** The AST value of the parameter.*) + val get_ast : parameter -> AST.ast -(** - Summary: Create mutually recursive datatypes. - @param c logical context. - @param num_sorts number of datatype sorts. - @param sort_names names of datatype sorts. - @param sorts array of datatype sorts. - @param constructor_lists list of constructors, one list per sort. - def_API('mk_datatypes', VOID, (_in(CONTEXT), _in(UINT), _in_array(1, SYMBOL), _out_array(1, SORT), _inout_array(1, CONSTRUCTOR_LIST))) -*) -external mk_datatypes : context -> symbol array -> constructor_list array -> sort array * constructor_list array - = "camlidl_z3_Z3_mk_datatypes" + (** The FunctionDeclaration value of the parameter.*) + val get_func_decl : parameter -> func_decl -(** - Summary: Query constructor for declared functions. - @param c logical context. - @param constr constructor container. The container must have been passed in to a {!mk_datatype} call. - @param num_fields number of accessor fields in the constructor. - @param constructor constructor function declaration. - @param tester constructor test function declaration. - @param accessors array of accessor function declarations. - def_API('query_constructor', VOID, (_in(CONTEXT), _in(CONSTRUCTOR), _in(UINT), _out(FUNC_DECL), _out(FUNC_DECL), _out_array(2, FUNC_DECL))) -*) -external query_constructor : context -> constructor -> int -> func_decl * func_decl * func_decl array - = "camlidl_z3_Z3_query_constructor" + (** The rational string value of the parameter.*) + val get_rational : parameter -> string + end -*) -(** - {2 {L Constants and Applications}} -*) -(** - Summary: Declare a constant or function. - [mk_func_decl c n d r] creates a function with name [n], domain [d], and range [r]. - The arity of the function is the size of the array [d]. - @param c logical context. - @param s name of the constant or function. - @param domain_size number of arguments. It is 0 when declaring a constant. - @param domain array containing the sort of each argument. The array must contain domain_size elements. It is 0 when declaring a constant. - @param range sort of the constant or the return sort of the function. - After declaring a constant or function, the function - {!mk_app} can be used to create a constant or function - application. - - {b See also}: {!mk_app} - def_API('mk_func_decl', FUNC_DECL, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SORT), _in(SORT))) -*) -external mk_func_decl : context -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3_Z3_mk_func_decl" + (** Creates a new function declaration. *) + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl -(** - Summary: Create a constant or function application. - - {b See also}: {!mk_func_decl} - def_API('mk_app', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT), _in_array(2, AST))) -*) -external mk_app : context -> func_decl -> ast array -> ast - = "camlidl_z3_Z3_mk_app" + (** Creates a new function declaration. *) + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + (** Creates a fresh function declaration with a name prefixed with a prefix string. *) -(** - Summary: Declare and create a constant. - [mk_const c s t] is a shorthand for [mk_app c (mk_func_decl c s [||] t) [||]] - - {b See also}: {!mk_func_decl} - - {b See also}: {!mk_app} - def_API('mk_const', AST, (_in(CONTEXT), _in(SYMBOL), _in(SORT))) -*) -external mk_const : context -> symbol -> sort -> ast - = "camlidl_z3_Z3_mk_const" + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl -(** - Summary: Declare a fresh constant or function. - Z3 will generate an unique name for this function declaration. - - {b See also}: {!mk_func_decl} - def_API('mk_fresh_func_decl', FUNC_DECL, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SORT), _in(SORT))) -*) -external mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl - = "camlidl_z3_Z3_mk_fresh_func_decl" + (** Creates a new constant function declaration. *) + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl -(** - Summary: Declare and create a fresh constant. - [mk_fresh_const c p t] is a shorthand for [mk_app c (mk_fresh_func_decl c p [||] t) [||]]. - - {b See also}: {!mk_func_decl} - - {b See also}: {!mk_app} - def_API('mk_fresh_const', AST, (_in(CONTEXT), _in(STRING), _in(SORT))) -*) -external mk_fresh_const : context -> string -> sort -> ast - = "camlidl_z3_Z3_mk_fresh_const" + (** Creates a new constant function declaration. *) + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl -(** - {2 {L Propositional Logic and Equality}} -*) -(** - Summary: Create an AST node representing [true]. - def_API('mk_true', AST, (_in(CONTEXT), )) -*) -external mk_true : context -> ast - = "camlidl_z3_Z3_mk_true" + (** Creates a fresh constant function declaration with a name prefixed with a prefix string. + {!mk_func_decl} + {!mk_func_decl} *) + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl -(** - Summary: Create an AST node representing [false]. - def_API('mk_false', AST, (_in(CONTEXT), )) -*) -external mk_false : context -> ast - = "camlidl_z3_Z3_mk_false" + (** Comparison operator. + @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) + val equal : func_decl -> func_decl -> bool -(** - Summary: \[ [ mk_eq c l r ] \] - Create an AST node representing {e l = r }. - The nodes [l] and [r] must have the same type. - def_API('mk_eq', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_eq : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_eq" + (** A string representations of the function declaration. *) + val to_string : func_decl -> string -(** - Summary: \[ [mk_distinct c [| t_1; ...; t_n |]] \] Create an AST - node represeting a distinct construct. It is used for declaring - the arguments t_i pairwise distinct. - The [distinct] construct is used for declaring the arguments pairwise distinct. - That is, {e Forall 0 <= i < j < num_args. not args[i] = args[j] }. - All arguments must have the same sort. - - {b Remarks}: The number of arguments of a distinct construct must be greater than one. - def_API('mk_distinct', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_distinct : context -> ast array -> ast - = "camlidl_z3_Z3_mk_distinct" + (** Returns a unique identifier for the function declaration. *) + val get_id : func_decl -> int -(** - Summary: \[ [ mk_not c a ] \] - Create an AST node representing {e not(a) }. - The node [a] must have Boolean sort. - def_API('mk_not', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_not : context -> ast -> ast - = "camlidl_z3_Z3_mk_not" + (** The arity of the function declaration *) + val get_arity : func_decl -> int -(** - Summary: \[ [ mk_ite c t1 t2 t2 ] \] - Create an AST node representing an if-then-else: {e ite(t1, t2, - t3) }. - The node [t1] must have Boolean sort, [t2] and [t3] must have the same sort. - The sort of the new node is equal to the sort of [t2] and [t3]. - def_API('mk_ite', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(AST))) -*) -external mk_ite : context -> ast -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ite" + (** The size of the domain of the function declaration + {!get_arity} *) + val get_domain_size : func_decl -> int + + (** The domain of the function declaration *) + val get_domain : func_decl -> Sort.sort list + + (** The range of the function declaration *) + val get_range : func_decl -> Sort.sort -(** - Summary: \[ [ mk_iff c t1 t2 ] \] - Create an AST node representing {e t1 iff t2 }. - The nodes [t1] and [t2] must have Boolean sort. - def_API('mk_iff', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_iff : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_iff" + (** The kind of the function declaration. *) + val get_decl_kind : func_decl -> Z3enums.decl_kind -(** - Summary: \[ [ mk_implies c t1 t2 ] \] - Create an AST node representing {e t1 implies t2 }. - The nodes [t1] and [t2] must have Boolean sort. - def_API('mk_implies', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_implies : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_implies" + (** The name of the function declaration*) + val get_name : func_decl -> Symbol.symbol -(** - Summary: \[ [ mk_xor c t1 t2 ] \] - Create an AST node representing {e t1 xor t2 }. - The nodes [t1] and [t2] must have Boolean sort. - def_API('mk_xor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_xor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_xor" + (** The number of parameters of the function declaration *) + val get_num_parameters : func_decl -> int -(** - Summary: \[ [mk_and c [| t_1; ...; t_n |]] \] Create the conjunction: {e t_1 and ... and t_n}. - All arguments must have Boolean sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_and', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_and : context -> ast array -> ast - = "camlidl_z3_Z3_mk_and" + (** The parameters of the function declaration *) + val get_parameters : func_decl -> Parameter.parameter list -(** - Summary: \[ [mk_or c [| t_1; ...; t_n |]] \] Create the disjunction: {e t_1 or ... or t_n}. - All arguments must have Boolean sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_or', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_or : context -> ast array -> ast - = "camlidl_z3_Z3_mk_or" + (** Create expression that applies function to arguments. *) + val apply : func_decl -> Expr.expr list -> Expr.expr +end -(** - {2 {L Arithmetic: Integers and Reals}} -*) -(** - Summary: \[ [mk_add c [| t_1; ...; t_n |]] \] Create the term: {e t_1 + ... + t_n}. - All arguments must have int or real sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_add', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_add : context -> ast array -> ast - = "camlidl_z3_Z3_mk_add" +(** Parameter sets (of Solvers, Tactics, ...) -(** - Summary: \[ [mk_mul c [| t_1; ...; t_n |]] \] Create the term: {e t_1 * ... * t_n}. - All arguments must have int or real sort. - - {b Remarks}: Z3 has limited support for non-linear arithmetic. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_mul', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_mul : context -> ast array -> ast - = "camlidl_z3_Z3_mk_mul" + A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) +and Params : +sig + type params -(** - Summary: \[ [mk_sub c [| t_1; ...; t_n |]] \] Create the term: {e t_1 - ... - t_n}. - All arguments must have int or real sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_sub', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_sub : context -> ast array -> ast - = "camlidl_z3_Z3_mk_sub" + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs : + sig + type param_descrs -(** - Summary: \[ [mk_unary_minus c arg] \] Create the term: {e - arg}. - The arguments must have int or real type. - def_API('mk_unary_minus', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_unary_minus : context -> ast -> ast - = "camlidl_z3_Z3_mk_unary_minus" + (** Validate a set of parameters. *) + val validate : param_descrs -> params -> unit -(** - Summary: \[ [mk_div c t_1 t_2] \] Create the term: {e t_1 div t_2}. - The arguments must either both have int type or both have real type. - If the arguments have int type, then the result type is an int type, otherwise the - the result type is real. - def_API('mk_div', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_div : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_div" + (** Retrieve kind of parameter. *) + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind -(** - Summary: \[ [mk_mod c t_1 t_2] \] Create the term: {e t_1 mod t_2}. - The arguments must have int type. - def_API('mk_mod', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_mod : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_mod" + (** Retrieve all names of parameters. *) + val get_names : param_descrs -> Symbol.symbol list -(** - Summary: \[ [mk_rem c t_1 t_2] \] Create the term: {e t_1 rem t_2}. - The arguments must have int type. - def_API('mk_rem', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_rem : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_rem" + (** The size of the ParamDescrs. *) + val get_size : param_descrs -> int -(** - The arguments must have int or real type. - def_API('mk_power', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_power : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_power" + (** Retrieves a string representation of the ParamDescrs. *) + val to_string : param_descrs -> string + end -(** - Summary: \[ [ mk_lt c t1 t2 ] \] - Create less than. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_lt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_lt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_lt" + (** Adds a parameter setting. *) + val add_bool : params -> Symbol.symbol -> bool -> unit -(** - Summary: \[ [ mk_le c t1 t2 ] \] - Create less than or equal to. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_le', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_le : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_le" + (** Adds a parameter setting. *) + val add_int : params -> Symbol.symbol -> int -> unit -(** - Summary: \[ [ mk_gt c t1 t2 ] \] - Create greater than. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_gt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_gt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_gt" + (** Adds a parameter setting. *) + val add_float : params -> Symbol.symbol -> float -> unit -(** - Summary: \[ [ mk_ge c t1 t2 ] \] - Create greater than or equal to. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_ge', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_ge : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ge" + (** Adds a parameter setting. *) + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit -(** - Summary: \[ [ mk_int2real c t1 ] \] - Coerce an integer to a real. - There is also a converse operation exposed. - It follows the semantics prescribed by the SMT-LIB standard. - You can take the floor of a real by - creating an auxiliary integer constant [k] and - and asserting {e mk_int2real(k) <= t1 < mk_int2real(k)+1 }. - The node [t1] must have sort integer. - - {b See also}: {!mk_real2int} - - {b See also}: {!mk_is_int} - def_API('mk_int2real', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_int2real : context -> ast -> ast - = "camlidl_z3_Z3_mk_int2real" + (** Creates a new parameter set *) + val mk_params : context -> params -(** - Summary: \[ [ mk_real2int c t1 ] \] - Coerce a real to an integer. - The semantics of this function follows the SMT-LIB standard - for the function to_int - - {b See also}: {!mk_int2real} - - {b See also}: {!mk_is_int} - def_API('mk_real2int', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_real2int : context -> ast -> ast - = "camlidl_z3_Z3_mk_real2int" - -(** - Summary: \[ [ mk_is_int c t1 ] \] - Check if a real number is an integer. - - {b See also}: {!mk_int2real} - - {b See also}: {!mk_real2int} - def_API('mk_is_int', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_is_int : context -> ast -> ast - = "camlidl_z3_Z3_mk_is_int" - -(** - {2 {L Bit-vectors}} -*) -(** - Summary: \[ [ mk_bvnot c t1 ] \] - Bitwise negation. - The node [t1] must have a bit-vector sort. - def_API('mk_bvnot', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvnot : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvnot" - -(** - Summary: \[ [ mk_bvredand c t1 ] \] - Take conjunction of bits in vector, return vector of length 1. - The node [t1] must have a bit-vector sort. - def_API('mk_bvredand', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvredand : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvredand" - -<<<<<<< HEAD -(** - Summary: \[ [ mk_bvredor c t1 ] \] - Take disjunction of bits in vector, return vector of length 1. - The node [t1] must have a bit-vector sort. - def_API('mk_bvredor', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvredor : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvredor" -======= (** A string representation of the parameter set. *) val to_string : params -> string @@ -1776,249 +466,300 @@ external mk_bvredor : context -> ast -> ast {!Sort.to_string} *) val set_print_mode : context -> Z3enums.ast_print_mode -> unit end ->>>>>>> Updates to ML API. -(** - Summary: \[ [ mk_bvand c t1 t2 ] \] - Bitwise and. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvand', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvand : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvand" +(** General Expressions (terms) *) +and Expr : +sig + type expr = Expr of AST.ast -(** - Summary: \[ [ mk_bvor c t1 t2 ] \] - Bitwise or. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvor" + val ast_of_expr : Expr.expr -> AST.ast + val expr_of_ast : AST.ast -> Expr.expr -(** - Summary: \[ [ mk_bvxor c t1 t2 ] \] - Bitwise exclusive-or. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvxor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvxor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvxor" + (** Returns a simplified version of the expression. + {!get_simplify_help} *) + val simplify : Expr.expr -> Params.params option -> expr -(** - Summary: \[ [ mk_bvnand c t1 t2 ] \] - Bitwise nand. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvnand', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvnand : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvnand" + (** A string describing all available parameters to Expr.Simplify. *) + val get_simplify_help : context -> string -(** - Summary: \[ [ mk_bvnor c t1 t2 ] \] - Bitwise nor. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvnor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvnor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvnor" + (** Retrieves parameter descriptions for simplifier. *) + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs -(** - Summary: \[ [ mk_bvxnor c t1 t2 ] \] - Bitwise xnor. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvxnor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvxnor : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvxnor" + (** The function declaration of the function that is applied in this expression. *) + val get_func_decl : Expr.expr -> FuncDecl.func_decl -(** - Summary: \[ [ mk_bvneg c t1 ] \] - Standard two's complement unary minus. - The node [t1] must have bit-vector sort. - def_API('mk_bvneg', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvneg : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvneg" + (** Indicates whether the expression is the true or false expression + or something else (L_UNDEF). *) + val get_bool_value : Expr.expr -> Z3enums.lbool -(** - Summary: \[ [ mk_bvadd c t1 t2 ] \] - Standard two's complement addition. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvadd', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvadd : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvadd" + (** The number of arguments of the expression. *) + val get_num_args : Expr.expr -> int -(** - Summary: \[ [ mk_bvsub c t1 t2 ] \] - Standard two's complement subtraction. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsub', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsub : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsub" + (** The arguments of the expression. *) + val get_args : Expr.expr -> Expr.expr list -(** - Summary: \[ [ mk_bvmul c t1 t2 ] \] - Standard two's complement multiplication. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvmul', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvmul : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvmul" + (** Update the arguments of the expression using an array of expressions. + The number of new arguments should coincide with the current number of arguments. *) + val update : Expr.expr -> Expr.expr list -> expr -(** - Summary: \[ [ mk_bvudiv c t1 t2 ] \] - Unsigned division. - It is defined as the [floor] of {e t1/t2 } if [t2] is - different from zero. If {e t2 } is zero, then the result - is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvudiv', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvudiv : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvudiv" + (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + + The result is the new expression. The arrays from and to must have size num_exprs. + For every i smaller than num_exprs, we must have that + sort of from[i] must be equal to sort of to[i]. *) + val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr -(** - Summary: \[ [ mk_bvsdiv c t1 t2 ] \] - Two's complement signed division. - It is defined in the following way: - - The [floor] of {e t1/t2 } if [t2] is different from zero, and {e t1*t2 >= 0 }. - - The [ceiling] of {e t1/t2 } if [t2] is different from zero, and {e t1*t2 < 0 }. - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsdiv', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsdiv : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsdiv" + (** Substitute every occurrence of from in the expression with to. + {!substitute} *) + val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr -(** - Summary: \[ [ mk_bvurem c t1 t2 ] \] - Unsigned remainder. - It is defined as {e t1 - (t1 /u t2) * t2 }, where {e /u } represents unsigned int division. - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvurem', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvurem : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvurem" + (** Substitute the free variables in the expression with the expressions in the expr array -(** - Summary: \[ [ mk_bvsrem c t1 t2 ] \] - Two's complement signed remainder (sign follows dividend). - It is defined as {e t1 - (t1 /s t2) * t2 }, where {e /s } represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of [t1]. - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - - {b See also}: {!mk_bvsmod} - def_API('mk_bvsrem', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsrem : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsrem" + For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) + val substitute_vars : Expr.expr -> Expr.expr list -> expr -(** - Summary: \[ [ mk_bvsmod c t1 t2 ] \] - Two's complement signed remainder (sign follows divisor). - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - - {b See also}: {!mk_bvsrem} - def_API('mk_bvsmod', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsmod : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsmod" + (** Translates (copies) the term to another context. + @return A copy of the term which is associated with the other context *) + val translate : Expr.expr -> context -> expr -(** - Summary: \[ [ mk_bvult c t1 t2 ] \] - Unsigned less than. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvult', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvult : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvult" + (** Returns a string representation of the expression. *) + val to_string : Expr.expr -> string -(** - Summary: \[ [ mk_bvslt c t1 t2 ] \] - Two's complement signed less than. - It abbreviates: - {v - (or (and (= (extract[|m-1|:|m-1|] t1) bit1) - (= (extract[|m-1|:|m-1|] t2) bit0)) - (and (= (extract[|m-1|:|m-1|] t1) (extract[|m-1|:|m-1|] t2)) - (bvult t1 t2))) - v} - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvslt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvslt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvslt" + (** Indicates whether the term is a numeral *) + val is_numeral : Expr.expr -> bool -(** - Summary: \[ [ mk_bvule c t1 t2 ] \] - Unsigned less than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvule', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvule : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvule" + (** Indicates whether the term is well-sorted. + @return True if the term is well-sorted, false otherwise. *) + val is_well_sorted : Expr.expr -> bool -(** - Summary: \[ [ mk_bvsle c t1 t2 ] \] - Two's complement signed less than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsle', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsle : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsle" + (** The Sort of the term. *) + val get_sort : Expr.expr -> Sort.sort -(** - Summary: \[ [ mk_bvuge c t1 t2 ] \] - Unsigned greater than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvuge', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvuge : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvuge" + (** Indicates whether the term has Boolean sort. *) + val is_bool : Expr.expr -> bool -(** - Summary: \[ [ mk_bvsge c t1 t2 ] \] - Two's complement signed greater than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsge', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsge : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsge" + (** Indicates whether the term represents a constant. *) + val is_const : Expr.expr -> bool -(** - Summary: \[ [ mk_bvugt c t1 t2 ] \] - Unsigned greater than. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvugt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvugt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvugt" + (** Indicates whether the term is the constant true. *) + val is_true : Expr.expr -> bool -(** - Summary: \[ [ mk_bvsgt c t1 t2 ] \] - Two's complement signed greater than. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsgt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsgt : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsgt" + (** Indicates whether the term is the constant false. *) + val is_false : Expr.expr -> bool + + (** Indicates whether the term is an equality predicate. *) + val is_eq : Expr.expr -> bool + + (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) + val is_distinct : Expr.expr -> bool + + (** Indicates whether the term is a ternary if-then-else term *) + val is_ite : Expr.expr -> bool + + (** Indicates whether the term is an n-ary conjunction *) + val is_and : Expr.expr -> bool + + (** Indicates whether the term is an n-ary disjunction *) + val is_or : Expr.expr -> bool + + (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) + val is_iff : Expr.expr -> bool + + (** Indicates whether the term is an exclusive or *) + val is_xor : Expr.expr -> bool + + (** Indicates whether the term is a negation *) + val is_not : Expr.expr -> bool + + (** Indicates whether the term is an implication *) + val is_implies : Expr.expr -> bool + + (** Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) + val is_oeq : Expr.expr -> bool + + (** Creates a new constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + + (** Creates a new constant. *) + val mk_const_s : context -> string -> Sort.sort -> expr + + (** Creates a constant from the func_decl. *) + val mk_const_f : context -> FuncDecl.func_decl -> expr + + (** Creates a fresh constant with a name prefixed with a string. *) + val mk_fresh_const : context -> string -> Sort.sort -> expr + + (** Create a new function application. *) + val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr + + (** Create a numeral of a given sort. + @return A Term with the goven value and sort *) + val mk_numeral_string : context -> string -> Sort.sort -> expr + + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @return A Term with the given value and sort *) + val mk_numeral_int : context -> int -> Sort.sort -> expr +end + +(** Boolean expressions *) +module Boolean : +sig + (** Create a Boolean sort *) + val mk_sort : context -> Sort.sort + + (** Create a Boolean constant. *) + val mk_const : context -> Symbol.symbol -> Expr.expr + + (** Create a Boolean constant. *) + val mk_const_s : context -> string -> Expr.expr + + (** The true Term. *) + val mk_true : context -> Expr.expr + + (** The false Term. *) + val mk_false : context -> Expr.expr + + (** Creates a Boolean value. *) + val mk_val : context -> bool -> Expr.expr + + (** Creates the equality between two expr's. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Creates a distinct term. *) + val mk_distinct : context -> Expr.expr list -> Expr.expr + + (** Mk an expression representing not(a). *) + val mk_not : context -> Expr.expr -> Expr.expr + + (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 iff t2. *) + val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 -> t2. *) + val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 xor t2. *) + val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing the AND of args *) + val mk_and : context -> Expr.expr list -> Expr.expr + + (** Create an expression representing the OR of args *) + val mk_or : context -> Expr.expr list -> Expr.expr +end + +(** Quantifier expressions *) +module Quantifier : +sig + type quantifier = Quantifier of Expr.expr + + val expr_of_quantifier : quantifier -> Expr.expr + val quantifier_of_expr : Expr.expr -> quantifier + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. *) + module Pattern : + sig + type pattern = Pattern of AST.ast + + val ast_of_pattern : pattern -> AST.ast + val pattern_of_ast : AST.ast -> pattern + + (** The number of terms in the pattern. *) + val get_num_terms : pattern -> int + + (** The terms in the pattern. *) + val get_terms : pattern -> Expr.expr list + + (** A string representation of the pattern. *) + val to_string : pattern -> string + end + + + (** The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. *) + val get_index : Expr.expr -> int + + (** Indicates whether the quantifier is universal. *) + val is_universal : quantifier -> bool + + (** Indicates whether the quantifier is existential. *) + val is_existential : quantifier -> bool + + (** The weight of the quantifier. *) + val get_weight : quantifier -> int + + (** The number of patterns. *) + val get_num_patterns : quantifier -> int + + (** The patterns. *) + val get_patterns : quantifier -> Pattern.pattern list + + (** The number of no-patterns. *) + val get_num_no_patterns : quantifier -> int + + (** The no-patterns. *) + val get_no_patterns : quantifier -> Pattern.pattern list + + (** The number of bound variables. *) + val get_num_bound : quantifier -> int + + (** The symbols for the bound variables. *) + val get_bound_variable_names : quantifier -> Symbol.symbol list + + (** The sorts of the bound variables. *) + val get_bound_variable_sorts : quantifier -> Sort.sort list + + (** The body of the quantifier. *) + val get_body : quantifier -> Expr.expr + + (** Creates a new bound variable. *) + val mk_bound : context -> int -> Sort.sort -> Expr.expr + + (** Create a quantifier pattern. *) + val mk_pattern : context -> Expr.expr list -> Pattern.pattern + + (** Create a universal Quantifier. *) + val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a universal Quantifier. *) + val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier +end -<<<<<<< HEAD -(** - Summary: \[ [ mk_concat c t1 t2 ] \] - Concatenate the given bit-vectors. - The nodes [t1] and [t2] must have (possibly different) bit-vector sorts - The result is a bit-vector of size {e n1+n2 }, where [n1] ([n2)] is the size - of [t1] ([t2)]. - def_API('mk_concat', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_concat : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_concat" -======= (** Functions to manipulate Array expressions *) module Array : sig @@ -2117,7669 +858,2049 @@ sig finite maps with a default range value. *) val mk_term_array : context -> Expr.expr -> Expr.expr end ->>>>>>> Updates to ML API. -(** - Summary: \[ [ mk_extract c high low t1 ] \] - Extract the bits [high] down to [low] from a bitvector of - size [m] to yield a new bitvector of size [n], where {e n = - high - low + 1 }. - The node [t1] must have a bit-vector sort. - def_API('mk_extract', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in(AST))) -*) -external mk_extract : context -> int -> int -> ast -> ast - = "camlidl_z3_Z3_mk_extract" +(** Functions to manipulate Set expressions *) +module Set : +sig + (** Create a set type. *) + val mk_sort : context -> Sort.sort -> Sort.sort -(** - Summary: \[ [ mk_sign_ext c i t1 ] \] - Sign-extend of the given bit-vector to the (signed) equivalent bitvector of - size {e m+i }, where [m] is the size of the given - bit-vector. - The node [t1] must have a bit-vector sort. - def_API('mk_sign_ext', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_sign_ext : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_sign_ext" + (** Indicates whether the term is set union *) + val is_union : Expr.expr -> bool -(** - Summary: \[ [ mk_zero_ext c i t1 ] \] - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size {e m+i }, where [m] is the size of the - given bit-vector. - The node [t1] must have a bit-vector sort. - def_API('mk_zero_ext', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_zero_ext : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_zero_ext" + (** Indicates whether the term is set intersection *) + val is_intersect : Expr.expr -> bool -(** - Summary: \[ [ mk_repeat c i t1 ] \] - Repeat the given bit-vector up length {e i }. - The node [t1] must have a bit-vector sort. - def_API('mk_repeat', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_repeat : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_repeat" + (** Indicates whether the term is set difference *) + val is_difference : Expr.expr -> bool -(** - Summary: \[ [ mk_bvshl c t1 t2 ] \] - Shift left. - It is equivalent to multiplication by {e 2^x } where [x] is the value of the - third argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvshl', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvshl : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvshl" + (** Indicates whether the term is set complement *) + val is_complement : Expr.expr -> bool -(** - Summary: \[ [ mk_bvlshr c t1 t2 ] \] - Logical shift right. - It is equivalent to unsigned int division by {e 2^x } where [x] is the - value of the third argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvlshr', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvlshr : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvlshr" + (** Indicates whether the term is set subset *) + val is_subset : Expr.expr -> bool -(** - Summary: \[ [ mk_bvashr c t1 t2 ] \] - Arithmetic shift right. - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvashr', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvashr : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvashr" + (** Create an empty set. *) + val mk_empty : context -> Sort.sort -> Expr.expr -(** - Summary: \[ [ mk_rotate_left c i t1 ] \] - Rotate bits of [t1] to the left [i] times. - The node [t1] must have a bit-vector sort. - def_API('mk_rotate_left', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_rotate_left : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_rotate_left" + (** Create the full set. *) + val mk_full : context -> Sort.sort -> Expr.expr -(** - Summary: \[ [ mk_rotate_right c i t1 ] \] - Rotate bits of [t1] to the right [i] times. - The node [t1] must have a bit-vector sort. - def_API('mk_rotate_right', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_rotate_right : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_rotate_right" + (** Add an element to the set. *) + val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: \[ [ mk_ext_rotate_left c t1 t2 ] \] - Rotate bits of [t1] to the left [t2] times. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_ext_rotate_left', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_ext_rotate_left : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ext_rotate_left" + (** Remove an element from a set. *) + val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: \[ [ mk_ext_rotate_right c t1 t2 ] \] - Rotate bits of [t1] to the right [t2] times. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_ext_rotate_right', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_ext_rotate_right : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_ext_rotate_right" + (** Take the union of a list of sets. *) + val mk_union : context -> Expr.expr list -> Expr.expr -(** - Summary: \[ [ mk_int2bv c n t1 ] \] - Create an [n] bit bit-vector from the integer argument [t1]. - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - The node [t1] must have integer sort. - def_API('mk_int2bv', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_int2bv : context -> int -> ast -> ast - = "camlidl_z3_Z3_mk_int2bv" + (** Take the intersection of a list of sets. *) + val mk_intersection : context -> Expr.expr list -> Expr.expr -(** - Summary: \[ [ mk_bv2int c t1 is_signed ] \] - Create an integer from the bit-vector argument [t1]. - If [is_signed] is false, then the bit-vector [t1] is treated as unsigned int. - So the result is non-negative - and in the range {e [0..2^N-1] }, where N are the number of bits in [t1]. - If [is_signed] is true, [t1] is treated as a signed bit-vector. - This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - The node [t1] must have a bit-vector sort. - def_API('mk_bv2int', AST, (_in(CONTEXT), _in(AST), _in(BOOL))) -*) -external mk_bv2int : context -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bv2int" + (** Take the difference between two sets. *) + val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: \[ [ mk_bvadd_no_overflow c t1 t2 is_signed ] \] - Create a predicate that checks that the bit-wise addition - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvadd_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) -*) -external mk_bvadd_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bvadd_no_overflow" + (** Take the complement of a set. *) + val mk_complement : context -> Expr.expr -> Expr.expr -(** - Summary: \[ [ mk_bvadd_no_underflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed addition - of [t1] and [t2] does not underflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvadd_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvadd_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvadd_no_underflow" + (** Check for set membership. *) + val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: \[ [ mk_bvsub_no_overflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed subtraction - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsub_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsub_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsub_no_overflow" + (** Check for subsetness of sets. *) + val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr +end -(** - Summary: \[ [ mk_bvsub_no_underflow c t1 t2 is_signed ] \] - Create a predicate that checks that the bit-wise subtraction - of [t1] and [t2] does not underflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsub_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) -*) -external mk_bvsub_no_underflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bvsub_no_underflow" +(** Functions to manipulate Finite Domain expressions *) +module FiniteDomain : +sig + (** Create a new finite domain sort. *) + val mk_sort : context -> Symbol.symbol -> int -> Sort.sort -(** - Summary: \[ [ mk_bvsdiv_no_overflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed division - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsdiv_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsdiv_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvsdiv_no_overflow" + (** Create a new finite domain sort. *) + val mk_sort_s : context -> string -> int -> Sort.sort -(** - Summary: \[ [ mk_bvneg_no_overflow c t1 ] \] - Check that bit-wise negation does not overflow when - [t1] is interpreted as a signed bit-vector. - The node [t1] must have bit-vector sort. - def_API('mk_bvneg_no_overflow', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvneg_no_overflow : context -> ast -> ast - = "camlidl_z3_Z3_mk_bvneg_no_overflow" + (** Indicates whether the term is of an array sort. *) + val is_finite_domain : Expr.expr -> bool -(** - Summary: \[ [ mk_bvmul_no_overflow c t1 t2 is_signed ] \] - Create a predicate that checks that the bit-wise multiplication - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvmul_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) -*) -external mk_bvmul_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3_Z3_mk_bvmul_no_overflow" + (** Indicates whether the term is a less than predicate over a finite domain. *) + val is_lt : Expr.expr -> bool -(** - Summary: \[ [ mk_bvmul_no_underflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed multiplication - of [t1] and [t2] does not underflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvmul_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvmul_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_bvmul_no_underflow" + (** The size of the finite domain sort. *) + val get_size : Sort.sort -> int +end -(** - {2 {L Arrays}} -*) -(** - Summary: \[ [ mk_select c a i ] \] - Array read. - The argument [a] is the array and [i] is the index of the array that gets read. - The node [a] must have an array sort {e [domain -> range] }, - and [i] must have the sort [domain]. - The sort of the result is [range]. - - {b See also}: {!mk_array_sort} - - {b See also}: {!mk_store} - def_API('mk_select', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_select : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_select" -(** - Summary: \[ [ mk_store c a i v ] \] - Array update. - The node [a] must have an array sort {e [domain -> range] }, [i] must have sort [domain], - [v] must have sort range. The sort of the result is {e [domain -> range] }. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to [a] (with respect to [select)] - on all indices except for [i], where it maps to [v] (and the [select] of [a] with - respect to [i] may be a different value). - - {b See also}: {!mk_array_sort} - - {b See also}: {!mk_select} - def_API('mk_store', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(AST))) -*) -external mk_store : context -> ast -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_store" +(** Functions to manipulate Relation expressions *) +module Relation : +sig + (** Indicates whether the term is of a relation sort. *) + val is_relation : Expr.expr -> bool -(** - Summary: Create the constant array. - The resulting term is an array, such that a [select] on an arbitrary index - produces the value [v]. - @param c logical context. - @param domain domain sort for the array. - @param v value that the array maps to. - def_API('mk_const_array', AST, (_in(CONTEXT), _in(SORT), _in(AST))) -*) -external mk_const_array : context -> sort -> ast -> ast - = "camlidl_z3_Z3_mk_const_array" + (** Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. *) + val is_store : Expr.expr -> bool -(** - Summary: \[ [ mk_map f n args ] \] - map f on the the argument arrays. - The [n] nodes [args] must be of array sorts {e [domain_i -> range_i] }. - The function declaration [f] must have type {e range_1 .. range_n -> range }. - [v] must have sort range. The sort of the result is {e [domain_i -> range] }. - - {b See also}: {!mk_array_sort} - - {b See also}: {!mk_store} - - {b See also}: {!mk_select} - def_API('mk_map', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT), _in_array(2, AST))) -*) -external mk_map : context -> func_decl -> int -> ast -> ast - = "camlidl_z3_Z3_mk_map" + (** Indicates whether the term is an empty relation *) + val is_empty : Expr.expr -> bool -(** - Summary: Access the array default value. - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. - @param c logical context. - @param array array value whose default range value is accessed. - def_API('mk_array_default', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_array_default : context -> ast -> ast - = "camlidl_z3_Z3_mk_array_default" + (** Indicates whether the term is a test for the emptiness of a relation *) + val is_is_empty : Expr.expr -> bool -(** - {2 {L Sets}} -*) -(** - Summary: Create Set type. - def_API('mk_set_sort', SORT, (_in(CONTEXT), _in(SORT))) -*) -external mk_set_sort : context -> sort -> sort - = "camlidl_z3_Z3_mk_set_sort" + (** Indicates whether the term is a relational join *) + val is_join : Expr.expr -> bool -(** - Summary: Create the empty set. - def_API('mk_empty_set', AST, (_in(CONTEXT), _in(SORT))) -*) -external mk_empty_set : context -> sort -> ast - = "camlidl_z3_Z3_mk_empty_set" + (** Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. *) + val is_union : Expr.expr -> bool + + (** Indicates whether the term is the widening of two relations + The function takes two arguments. *) + val is_widen : Expr.expr -> bool + + (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. *) + val is_project : Expr.expr -> bool + + (** Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. *) + val is_filter : Expr.expr -> bool + + (** Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. *) + val is_negation_filter : Expr.expr -> bool + + (** Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. *) + val is_rename : Expr.expr -> bool + + (** Indicates whether the term is the complement of a relation *) + val is_complement : Expr.expr -> bool + + (** Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. *) + val is_select : Expr.expr -> bool + + (** Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind {!is_union} + to perform destructive updates to the first argument. *) + val is_clone : Expr.expr -> bool + + (** The arity of the relation sort. *) + val get_arity : Sort.sort -> int + + (** The sorts of the columns of the relation sort. *) + val get_column_sorts : Sort.sort -> Sort.sort list +end + +(** Functions to manipulate Datatype expressions *) +module Datatype : +sig + (** Datatype Constructors *) + module Constructor : + sig + type constructor + + (** The number of fields of the constructor. *) + val get_num_fields : constructor -> int + + (** The function declaration of the constructor. *) + val get_constructor_decl : constructor -> FuncDecl.func_decl + + (** The function declaration of the tester. *) + val get_tester_decl : constructor -> FuncDecl.func_decl + + (** The function declarations of the accessors *) + val get_accessor_decls : constructor -> FuncDecl.func_decl list + end + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + + (** Create a new datatype sort. *) + val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> Sort.sort + + (** Create a new datatype sort. *) + val mk_sort_s : context -> string -> Constructor.constructor list -> Sort.sort + + (** Create mutually recursive datatypes. *) + val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> Sort.sort list + + (** Create mutually recursive data-types. *) + val mk_sorts_s : context -> string list -> Constructor.constructor list list -> Sort.sort list + + + (** The number of constructors of the datatype sort. *) + val get_num_constructors : Sort.sort -> int + + (** The constructors. *) + val get_constructors : Sort.sort -> FuncDecl.func_decl list + + (** The recognizers. *) + val get_recognizers : Sort.sort -> FuncDecl.func_decl list + + (** The constructor accessors. *) + val get_accessors : Sort.sort -> FuncDecl.func_decl list list +end + +(** Functions to manipulate Enumeration expressions *) +module Enumeration : +sig + (** Create a new enumeration sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort + + (** Create a new enumeration sort. *) + val mk_sort_s : context -> string -> string list -> Sort.sort + + (** The function declarations of the constants in the enumeration. *) + val get_const_decls : Sort.sort -> FuncDecl.func_decl list + + (** The test predicates for the constants in the enumeration. *) + val get_tester_decls : Sort.sort -> FuncDecl.func_decl list +end -<<<<<<< HEAD -(** - Summary: Create the full set. - def_API('mk_full_set', AST, (_in(CONTEXT), _in(SORT))) -*) -external mk_full_set : context -> sort -> ast - = "camlidl_z3_Z3_mk_full_set" -======= (** Functions to manipulate List expressions *) module List : sig (** Create a new list sort. *) val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort ->>>>>>> Updates to ML API. -(** - Summary: Add an element to a set. - The first argument must be a set, the second an element. - def_API('mk_set_add', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_add : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_add" + (** Create a new list sort. *) + val mk_list_s : context -> string -> Sort.sort -> Sort.sort -(** - Summary: Remove an element to a set. - The first argument must be a set, the second an element. - def_API('mk_set_del', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_del : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_del" + (** The declaration of the nil function of this list sort. *) + val get_nil_decl : Sort.sort -> FuncDecl.func_decl -(** - Summary: Take the union of a list of sets. - def_API('mk_set_union', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_set_union : context -> ast array -> ast - = "camlidl_z3_Z3_mk_set_union" + (** The declaration of the isNil function of this list sort. *) + val get_is_nil_decl : Sort.sort -> FuncDecl.func_decl -(** - Summary: Take the intersection of a list of sets. - def_API('mk_set_intersect', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_set_intersect : context -> ast array -> ast - = "camlidl_z3_Z3_mk_set_intersect" + (** The declaration of the cons function of this list sort. *) + val get_cons_decl : Sort.sort -> FuncDecl.func_decl -(** - Summary: Take the set difference between two sets. - def_API('mk_set_difference', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_difference : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_difference" + (** The declaration of the isCons function of this list sort. *) + val get_is_cons_decl : Sort.sort -> FuncDecl.func_decl -(** - Summary: Take the complement of a set. - def_API('mk_set_complement', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_set_complement : context -> ast -> ast - = "camlidl_z3_Z3_mk_set_complement" + (** The declaration of the head function of this list sort. *) + val get_head_decl : Sort.sort -> FuncDecl.func_decl -(** - Summary: Check for set membership. - The first argument should be an element type of the set. - def_API('mk_set_member', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_member : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_member" + (** The declaration of the tail function of this list sort. *) + val get_tail_decl : Sort.sort -> FuncDecl.func_decl -(** - Summary: Check for subsetness of sets. - def_API('mk_set_subset', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_subset : context -> ast -> ast -> ast - = "camlidl_z3_Z3_mk_set_subset" + (** The empty list. *) + val nil : Sort.sort -> Expr.expr +end -(** - {2 {L Numerals}} -*) +(** Functions to manipulate Tuple expressions *) +module Tuple : +sig + (** Create a new tuple sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> Sort.sort -(** - Summary: \[ [ numeral_refined ] \] is the refined view of a numeral . -*) -type numeral_refined = - | Numeral_int of int * sort - | Numeral_int64 of int64 * sort - | Numeral_large of string * sort - | Numeral_rational of numeral_refined * numeral_refined + (** The constructor function of the tuple. *) + val get_mk_decl : Sort.sort -> FuncDecl.func_decl + (** The number of fields in the tuple. *) + val get_num_fields : Sort.sort -> int -(** - Summary: \[ [ embed_numeral c nr ] \] constructs the numeral described by [nr]. - - {b See also}: {!numeral_refine} -*) -val embed_numeral: context -> numeral_refined -> ast + (** The field declarations. *) + val get_field_decls : Sort.sort -> FuncDecl.func_decl list +end -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Create a numeral of a given sort. - @param c logical context. - @param numeral A string representing the numeral value in decimal notation. If the given sort is a real, then the numeral can be a rational, that is, a string of the form {e [num]* / [num]* }. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, finite-domain, or bit-vectors of arbitrary size. - - {b See also}: {!mk_int} - def_API('mk_numeral', AST, (_in(CONTEXT), _in(STRING), _in(SORT))) -*) -external mk_numeral : context -> string -> sort -> ast - = "camlidl_z3_Z3_mk_numeral" +(** Functions to manipulate arithmetic expressions *) +module Arithmetic : +sig + (** Integer Arithmetic *) + module Integer : + sig + (** Create a new integer sort. *) + val mk_sort : context -> Sort.sort -(** - Summary: Create a real from a fraction. - @param c logical context. - @param num numerator of rational. - @param den denomerator of rational. - - {b Precondition}: den != 0 - - {b See also}: {!mk_numeral} - - {b See also}: {!mk_int} - def_API('mk_real', AST, (_in(CONTEXT), _in(INT), _in(INT))) -*) -external mk_real : context -> int -> int -> ast - = "camlidl_z3_Z3_mk_real" + (** Retrieve the int value. *) + val get_int : Expr.expr -> int -(** - Summary: Create a numeral of an int, bit-vector, or finite-domain sort. - This function can be use to create numerals that fit in a machine integer. - It is slightly faster than {!mk_numeral} since it is not necessary to parse a string. - - {b See also}: {!mk_numeral} - def_API('mk_int', AST, (_in(CONTEXT), _in(INT), _in(SORT))) -*) -external mk_int : context -> int -> sort -> ast - = "camlidl_z3_Z3_mk_int" + (** Returns a string representation of the numeral. *) + val to_string : Expr.expr -> string -(** - Summary: Create a numeral of a int, bit-vector, or finite-domain sort. - This function can be use to create numerals that fit in a machine long long integer. - It is slightly faster than {!mk_numeral} since it is not necessary to parse a string. - - {b See also}: {!mk_numeral} - def_API('mk_int64', AST, (_in(CONTEXT), _in(INT64), _in(SORT))) -*) -external mk_int64 : context -> int64 -> sort -> ast - = "camlidl_z3_Z3_mk_int64" + (** Creates an integer constant. *) + val mk_const : context -> Symbol.symbol -> Expr.expr -(** - {2 {L Quantifiers}} -*) -(** - Summary: Create a pattern for quantifier instantiation. - Z3 uses pattern matching to instantiate quantifiers. If a - pattern is not provided for a quantifier, then Z3 will - automatically compute a set of patterns for it. However, for - optimal performance, the user should provide the patterns. - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - a called a multi-pattern. - In general, one can pass in a list of (multi-)patterns in the - quantifier constructor. - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_pattern', PATTERN, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_pattern : context -> ast array -> pattern - = "camlidl_z3_Z3_mk_pattern" + (** Creates an integer constant. *) + val mk_const_s : context -> string -> Expr.expr -(** - Summary: Create a bound variable. - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - {v - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - v} - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper x appears, the higher is its - index. - @param c logical context - @param index de-Bruijn index - @param ty sort of the bound variable - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_bound', AST, (_in(CONTEXT), _in(UINT), _in(SORT))) -*) -external mk_bound : context -> int -> sort -> ast - = "camlidl_z3_Z3_mk_bound" + (** Create an expression representing t1 mod t2. + The arguments must have int type. *) + val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: Create a forall formula. It takes an expression [body] that contains bound variables - of the same sorts as the sorts listed in the array [sorts]. The bound variables are de-Bruijn indices created - using {!mk_bound}. The array [decl_names] contains the names that the quantified formula uses for the - bound variables. Z3 applies the convention that the last element in the [decl_names] and [sorts] array - refers to the variable with index 0, the second to last element of [decl_names] and [sorts] refers - to the variable with index 1, etc. - [mk_forall c w p t n b] creates a forall formula, where - [w] is the weight, [p] is an array of patterns, [t] is an array - with the sorts of the bound variables, [n] is an array with the - 'names' of the bound variables, and [b] is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during - instantiation. - @param c logical context. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @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 quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_exists} - def_API('mk_forall', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, PATTERN), _in(UINT), _in_array(4, SORT), _in_array(4, SYMBOL), _in(AST))) -*) -external mk_forall : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_forall_bytecode" "camlidl_z3_Z3_mk_forall" + (** Create an expression representing t1 rem t2. + The arguments must have int type. *) + val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: Create an exists formula. Similar to {!mk_forall}. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_forall} - - {b See also}: {!mk_quantifier} - def_API('mk_exists', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, PATTERN), _in(UINT), _in_array(4, SORT), _in_array(4, SYMBOL), _in(AST))) -*) -external mk_exists : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_exists_bytecode" "camlidl_z3_Z3_mk_exists" + (** Create an integer numeral. *) + val mk_numeral_s : context -> string -> Expr.expr -(** - Summary: Create a quantifier - universal or existential, with pattern hints. - See the documentation for {!mk_forall} for an explanation of the parameters. - @param c logical context. - @param is_forall flag to indicate if this is a universal or existential quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param num_decls number of variables to be bound. - @param sorts array of sorts of the bound variables. - @param decl_names names of the bound variables. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_quantifier', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(UINT), _in_array(3, PATTERN), _in(UINT), _in_array(5, SORT), _in_array(5, SYMBOL), _in(AST))) -*) -external mk_quantifier : context -> bool -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_bytecode" "camlidl_z3_Z3_mk_quantifier" + (** Create an integer numeral. + @return A Term with the given value and sort Integer *) + val mk_numeral_i : context -> int -> Expr.expr -(** - Summary: Create a quantifier - universal or existential, with pattern hints, no patterns, and attributes - @param c logical context. - @param is_forall flag to indicate if this is a universal or existential quantifier. - @param quantifier_id identifier to identify quantifier - @param skolem_id identifier to identify skolem constants introduced by quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param num_no_patterns number of no_patterns. - @param no_patterns array containing subexpressions to be excluded from inferred patterns. - @param num_decls number of variables to be bound. - @param sorts array of sorts of the bound variables. - @param decl_names names of the bound variables. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_quantifier_ex', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(SYMBOL), _in(SYMBOL), _in(UINT), _in_array(5, PATTERN), _in(UINT), _in_array(7, AST), _in(UINT), _in_array(9, SORT), _in_array(9, SYMBOL), _in(AST))) -*) -external mk_quantifier_ex : context -> bool -> int -> symbol -> symbol -> pattern array -> ast array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_ex_bytecode" "camlidl_z3_Z3_mk_quantifier_ex" + (** Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. *) + val mk_int2real : context -> Expr.expr -> Expr.expr -(** - Summary: Create a universal quantifier using a list of constants that - will form the set of bound variables. - @param c logical context. - @param weight quantifiers are associated with weights indicating the importance of using - the quantifier during instantiation. By default, pass the weight 0. - @param num_bound number of constants to be abstracted into bound variables. - @param bound array of constants to be abstracted into bound variables. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_exists_const} - def_API('mk_forall_const', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, APP), _in(UINT), _in_array(4, PATTERN), _in(AST))) -*) -external mk_forall_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3_Z3_mk_forall_const" - -(** - Summary: Similar to {!mk_forall_const}. - Summary: Create an existential quantifier using a list of constants that - will form the set of bound variables. - @param c logical context. - @param weight quantifiers are associated with weights indicating the importance of using - the quantifier during instantiation. By default, pass the weight 0. - @param num_bound number of constants to be abstracted into bound variables. - @param bound array of constants to be abstracted into bound variables. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_forall_const} - def_API('mk_exists_const', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, APP), _in(UINT), _in_array(4, PATTERN), _in(AST))) -*) -external mk_exists_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3_Z3_mk_exists_const" - -(** - Summary: Create a universal or existential - quantifier using a list of constants that - will form the set of bound variables. - def_API('mk_quantifier_const', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(UINT), _in_array(3, APP), _in(UINT), _in_array(5, PATTERN), _in(AST))) -*) -external mk_quantifier_const : context -> bool -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_const_bytecode" "camlidl_z3_Z3_mk_quantifier_const" - -(** - Summary: Create a universal or existential - quantifier using a list of constants that - will form the set of bound variables. - def_API('mk_quantifier_const_ex', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(SYMBOL), _in(SYMBOL), _in(UINT), _in_array(5, APP), _in(UINT), _in_array(7, PATTERN), _in(UINT), _in_array(9, AST), _in(AST))) -*) -external mk_quantifier_const_ex : context -> bool -> int -> symbol -> symbol -> app array -> pattern array -> ast array -> ast -> ast - = "camlidl_z3_Z3_mk_quantifier_const_ex_bytecode" "camlidl_z3_Z3_mk_quantifier_const_ex" - -(** - {2 {L Accessors}} -*) -(** - {3 {L Symbols}} -*) - -(** - Summary: \[ [ symbol_refine c s ] \] is the refined view of [s]. -*) -val symbol_refine: context -> symbol -> symbol_refined - -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Return [INT_SYMBOL] if the symbol was constructed - using {!mk_int_symbol}, and [STRING_SYMBOL] if the symbol - was constructed using {!mk_string_symbol}. - def_API('get_symbol_kind', UINT, (_in(CONTEXT), _in(SYMBOL))) -*) -external get_symbol_kind : context -> symbol -> symbol_kind - = "camlidl_z3_Z3_get_symbol_kind" - -(** - Summary: \[ [ get_symbol_int c s ] \] - Return the symbol int value. - - {b Precondition}: get_symbol_kind s == INT_SYMBOL - - {b See also}: {!mk_int_symbol} - def_API('get_symbol_int', INT, (_in(CONTEXT), _in(SYMBOL))) -*) -external get_symbol_int : context -> symbol -> int - = "camlidl_z3_Z3_get_symbol_int" - -(** - Summary: \[ [ get_symbol_string c s ] \] - Return the symbol name. - - {b Precondition}: get_symbol_string s == STRING_SYMBOL - - {b See also}: {!mk_string_symbol} - def_API('get_symbol_string', STRING, (_in(CONTEXT), _in(SYMBOL))) -*) -external get_symbol_string : context -> symbol -> string - = "camlidl_z3_Z3_get_symbol_string" - -(** - {3 {L Sorts}} -*) - -(** - Summary: \[ [ sort_refine c s ] \] is the refined view of [s]. -*) -val sort_refine: context -> sort -> sort_refined - -(** - Summary: Return the sort name as a symbol. - def_API('get_sort_name', SYMBOL, (_in(CONTEXT), _in(SORT))) -*) -external get_sort_name : context -> sort -> symbol - = "camlidl_z3_Z3_get_sort_name" - -(** - Summary: Return a unique identifier for [s]. - - {b Remarks}: Implicitly used by [Pervasives.( = )] and [Pervasives.compare]. - def_API('get_sort_id', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_sort_id : context -> sort -> int - = "camlidl_z3_Z3_get_sort_id" - -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Convert a [sort] into [ast]. - - {b Remarks}: [sort_to_ast c s] can be replaced by [(s :> ast)]. - def_API('sort_to_ast', AST, (_in(CONTEXT), _in(SORT))) -*) -external sort_to_ast : context -> sort -> ast - = "camlidl_z3_Z3_sort_to_ast" - -(** - Summary: compare sorts. - - {b Remarks}: [Pervasives.( = )] or [Pervasives.compare] can also be used. - def_API('is_eq_sort', BOOL, (_in(CONTEXT), _in(SORT), _in(SORT))) -*) -external is_eq_sort : context -> sort -> sort -> bool - = "camlidl_z3_Z3_is_eq_sort" - -(** - Summary: Return the sort kind (e.g., array, tuple, int, bool, etc). - - {b See also}: {!sort_kind} - def_API('get_sort_kind', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_sort_kind : context -> sort -> sort_kind - = "camlidl_z3_Z3_get_sort_kind" - -(** - Summary: \[ [ get_bv_sort_size c t ] \] - Return the size of the given bit-vector sort. - - {b Precondition}: get_sort_kind c t == BV_SORT - - {b See also}: {!mk_bv_sort} - - {b See also}: {!get_sort_kind} - def_API('get_bv_sort_size', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_bv_sort_size : context -> sort -> int - = "camlidl_z3_Z3_get_bv_sort_size" - -(** - Summary: Return the size of the sort in [r]. Return [None] if the call failed. - That is, get_sort_kind(s) == FINITE_DOMAIN_SORT - def_API('get_finite_domain_sort_size', BOOL, (_in(CONTEXT), _in(SORT), _out(UINT64))) -*) -external get_finite_domain_sort_size : context -> sort -> int64 option - = "camlidl_z3_Z3_get_finite_domain_sort_size" - -(** - Summary: \[ [ get_array_sort_domain c t ] \] - Return the domain of the given array sort. - - {b Precondition}: get_sort_kind c t == ARRAY_SORT - - {b See also}: {!mk_array_sort} - - {b See also}: {!get_sort_kind} - def_API('get_array_sort_domain', SORT, (_in(CONTEXT), _in(SORT))) -*) -external get_array_sort_domain : context -> sort -> sort - = "camlidl_z3_Z3_get_array_sort_domain" - -(** - Summary: \[ [ get_array_sort_range c t ] \] - Return the range of the given array sort. - - {b Precondition}: get_sort_kind c t == ARRAY_SORT - - {b See also}: {!mk_array_sort} - - {b See also}: {!get_sort_kind} - def_API('get_array_sort_range', SORT, (_in(CONTEXT), _in(SORT))) -*) -external get_array_sort_range : context -> sort -> sort - = "camlidl_z3_Z3_get_array_sort_range" - -(** - Summary: \[ [ get_tuple_sort_mk_decl c t ] \] - Return the constructor declaration of the given tuple - sort. - - {b Precondition}: get_sort_kind c t == DATATYPE_SORT - - {b See also}: {!mk_tuple_sort} - - {b See also}: {!get_sort_kind} - def_API('get_tuple_sort_mk_decl', FUNC_DECL, (_in(CONTEXT), _in(SORT))) -*) -external get_tuple_sort_mk_decl : context -> sort -> func_decl - = "camlidl_z3_Z3_get_tuple_sort_mk_decl" - -(** - Summary: \[ [ get_tuple_sort_num_fields c t ] \] - Return the number of fields of the given tuple sort. - - {b Precondition}: get_sort_kind c t == DATATYPE_SORT - - {b See also}: {!mk_tuple_sort} - - {b See also}: {!get_sort_kind} - def_API('get_tuple_sort_num_fields', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_tuple_sort_num_fields : context -> sort -> int - = "camlidl_z3_Z3_get_tuple_sort_num_fields" - -(** - Summary: \[ [ get_tuple_sort_field_decl c t i ] \] - Return the i-th field declaration (i.e., projection function declaration) - of the given tuple sort. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: i < get_tuple_sort_num_fields c t - - {b See also}: {!mk_tuple_sort} - - {b See also}: {!get_sort_kind} - def_API('get_tuple_sort_field_decl', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_tuple_sort_field_decl : context -> sort -> int -> func_decl - = "camlidl_z3_Z3_get_tuple_sort_field_decl" - -(** - Summary: Return number of constructors for datatype. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_recognizer} - - {b See also}: {!get_datatype_sort_constructor_accessor} - def_API('get_datatype_sort_num_constructors', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_datatype_sort_num_constructors : context -> sort -> int - = "camlidl_z3_Z3_get_datatype_sort_num_constructors" - -(** - Summary: Return idx'th constructor. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: idx < get_datatype_sort_num_constructors c t - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_recognizer} - - {b See also}: {!get_datatype_sort_constructor_accessor} - def_API('get_datatype_sort_constructor', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_datatype_sort_constructor : context -> sort -> int -> func_decl - = "camlidl_z3_Z3_get_datatype_sort_constructor" - -(** - Summary: Return idx'th recognizer. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: idx < get_datatype_sort_num_constructors c t - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_constructor_accessor} - def_API('get_datatype_sort_recognizer', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_datatype_sort_recognizer : context -> sort -> int -> func_decl - = "camlidl_z3_Z3_get_datatype_sort_recognizer" - -(** - Summary: Return idx_a'th accessor for the idx_c'th constructor. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: idx_c < get_datatype_sort_num_constructors c t - - {b Precondition}: idx_a < get_domain_size c get_datatype_sort_constructor c idx_c - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_recognizer} - def_API('get_datatype_sort_constructor_accessor', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT), _in(UINT))) -*) -external get_datatype_sort_constructor_accessor : context -> sort -> int -> int -> func_decl - = "camlidl_z3_Z3_get_datatype_sort_constructor_accessor" - -(** - Summary: Return arity of relation. - - {b Precondition}: get_sort_kind s == RELATION_SORT - - {b See also}: {!get_relation_column} - def_API('get_relation_arity', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_relation_arity : context -> sort -> int - = "camlidl_z3_Z3_get_relation_arity" - -(** - Summary: Return sort at i'th column of relation sort. - - {b Precondition}: get_sort_kind c s == RELATION_SORT - - {b Precondition}: col < get_relation_arity c s - - {b See also}: {!get_relation_arity} - def_API('get_relation_column', SORT, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_relation_column : context -> sort -> int -> sort - = "camlidl_z3_Z3_get_relation_column" - -(** - {3 {L Function Declarations}} -*) -(** - Summary: Convert a [func_decl] into [ast]. - - {b Remarks}: [func_decl_to_ast c f] can be replaced by [(f :> ast)]. - def_API('func_decl_to_ast', AST, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external func_decl_to_ast : context -> func_decl -> ast - = "camlidl_z3_Z3_func_decl_to_ast" - -(** - Summary: compare terms. - - {b Remarks}: [Pervasives.( = )] or [Pervasives.compare] can also be used. - def_API('is_eq_func_decl', BOOL, (_in(CONTEXT), _in(FUNC_DECL), _in(FUNC_DECL))) -*) -external is_eq_func_decl : context -> func_decl -> func_decl -> bool - = "camlidl_z3_Z3_is_eq_func_decl" - -(** - Summary: Return a unique identifier for [f]. - - {b Remarks}: Implicitly used by [Pervasives.( = )] and [Pervasives.compare]. - def_API('get_func_decl_id', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_func_decl_id : context -> func_decl -> int - = "camlidl_z3_Z3_get_func_decl_id" - -(** - Summary: Return the constant declaration name as a symbol. - def_API('get_decl_name', SYMBOL, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_decl_name : context -> func_decl -> symbol - = "camlidl_z3_Z3_get_decl_name" - -(** - Summary: Return declaration kind corresponding to declaration. - def_API('get_decl_kind', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_decl_kind : context -> func_decl -> decl_kind - = "camlidl_z3_Z3_get_decl_kind" - -(** - Summary: Return the number of parameters of the given declaration. - - {b See also}: {!get_arity} - def_API('get_domain_size', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_domain_size : context -> func_decl -> int - = "camlidl_z3_Z3_get_domain_size" - -(** - Summary: Alias for [get_domain_size]. - - {b See also}: {!get_domain_size} - def_API('get_arity', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_arity : context -> func_decl -> int - = "camlidl_z3_Z3_get_arity" - -(** - Summary: \[ [ get_domain c d i ] \] - Return the sort of the i-th parameter of the given function declaration. - - {b Precondition}: i < get_domain_size d - - {b See also}: {!get_domain_size} - def_API('get_domain', SORT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_domain : context -> func_decl -> int -> sort - = "camlidl_z3_Z3_get_domain" - - -(** - Summary: \[ [ get_domains c d ] \] is the array of parameters of [d]. - - {b See also}: {!get_domain_size} - - {b See also}: {!get_domain} -*) -val get_domains: context -> func_decl -> sort array - -(** - Summary: \[ [ get_range c d ] \] - Return the range of the given declaration. - If [d] is a constant (i.e., has zero arguments), then this - function returns the sort of the constant. - def_API('get_range', SORT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_range : context -> func_decl -> sort - = "camlidl_z3_Z3_get_range" - -(** - Summary: Return the number of parameters associated with a declaration. - def_API('get_decl_num_parameters', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_decl_num_parameters : context -> func_decl -> int - = "camlidl_z3_Z3_get_decl_num_parameters" - -(** - Summary: Return the parameter type associated with a declaration. - @param c the context - @param d the function declaration - @param idx is the index of the named parameter it should be between 0 and the number of parameters. - def_API('get_decl_parameter_kind', UINT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_parameter_kind : context -> func_decl -> int -> parameter_kind - = "camlidl_z3_Z3_get_decl_parameter_kind" - -(** - Summary: Return the integer value associated with an integer parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_INT - def_API('get_decl_int_parameter', INT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_int_parameter : context -> func_decl -> int -> int - = "camlidl_z3_Z3_get_decl_int_parameter" - -(** - Summary: Return the double value associated with an double parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_DOUBLE - def_API('get_decl_double_parameter', DOUBLE, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_double_parameter : context -> func_decl -> int -> float - = "camlidl_z3_Z3_get_decl_double_parameter" - -(** - Summary: Return the double value associated with an double parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_SYMBOL - def_API('get_decl_symbol_parameter', SYMBOL, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_symbol_parameter : context -> func_decl -> int -> symbol - = "camlidl_z3_Z3_get_decl_symbol_parameter" - -(** - Summary: Return the sort value associated with a sort parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_SORT - def_API('get_decl_sort_parameter', SORT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_sort_parameter : context -> func_decl -> int -> sort - = "camlidl_z3_Z3_get_decl_sort_parameter" - -(** - Summary: Return the expresson value associated with an expression parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_AST - def_API('get_decl_ast_parameter', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_ast_parameter : context -> func_decl -> int -> ast - = "camlidl_z3_Z3_get_decl_ast_parameter" - -(** - Summary: Return the expresson value associated with an expression parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_FUNC_DECL - def_API('get_decl_func_decl_parameter', FUNC_DECL, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_func_decl_parameter : context -> func_decl -> int -> func_decl - = "camlidl_z3_Z3_get_decl_func_decl_parameter" - -(** - Summary: Return the rational value, as a string, associated with a rational parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_RATIONAL - def_API('get_decl_rational_parameter', STRING, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_rational_parameter : context -> func_decl -> int -> string - = "camlidl_z3_Z3_get_decl_rational_parameter" - -(** - {3 {L Applications}} -*) -(** - Summary: Convert a [app] into [ast]. - - {b Remarks}: [app_to_ast c a] can be replaced by [(a :> ast)]. - def_API('app_to_ast', AST, (_in(CONTEXT), _in(APP))) -*) -external app_to_ast : context -> app -> ast - = "camlidl_z3_Z3_app_to_ast" - -(** - Summary: Return the declaration of a constant or function application. - def_API('get_app_decl', FUNC_DECL, (_in(CONTEXT), _in(APP))) -*) -external get_app_decl : context -> app -> func_decl - = "camlidl_z3_Z3_get_app_decl" - -(** - Summary: \[ [ get_app_num_args c a ] \] - Return the number of argument of an application. If [t] - is an constant, then the number of arguments is 0. - def_API('get_app_num_args', UINT, (_in(CONTEXT), _in(APP))) -*) -external get_app_num_args : context -> app -> int - = "camlidl_z3_Z3_get_app_num_args" - -(** - Summary: \[ [ get_app_arg c a i ] \] - Return the i-th argument of the given application. - - {b Precondition}: i < get_num_args c a - def_API('get_app_arg', AST, (_in(CONTEXT), _in(APP), _in(UINT))) -*) -external get_app_arg : context -> app -> int -> ast - = "camlidl_z3_Z3_get_app_arg" - - -(** - Summary: \[ [ get_app_args c a ] \] is the array of arguments of an application. If [t] is a constant, then the array is empty. - - {b See also}: {!get_app_num_args} - - {b See also}: {!get_app_arg} -*) -val get_app_args: context -> app -> ast array - -(** - {3 {L Terms}} -*) - -(** - Summary: \[ [ binder_type ] \] is a universal or existential quantifier. - - {b See also}: {!term_refined} -*) -type binder_type = Forall | Exists -(** - Summary: \[ [ term_refined ] \] is the refinement of a {!ast} . - - {b See also}: {!term_refine} -*) -type term_refined = - | Term_numeral of numeral_refined - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast - | Term_var of int * sort - - -(** - Summary: \[ [ mk_term c tr ] \] constructs the term described by [tr]. - - {b Precondition}: [tr] is not of form - - {b See also}: {!term_refine} -*) -(* val mk_term: context -> term_refined -> ast *) -(** - Summary: \[ [ term_refine c a ] \] is the refined view of [a]. -*) -val term_refine : context -> ast -> term_refined - -(** - Summary: compare terms. - - {b Remarks}: [Pervasives.( = )] or [Pervasives.compare] can also be used. - def_API('is_eq_ast', BOOL, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external is_eq_ast : context -> ast -> ast -> bool - = "camlidl_z3_Z3_is_eq_ast" - -(** - Summary: Return a unique identifier for [t]. - - {b Remarks}: Implicitly used by [Pervasives.compare] for values of type [ast], [app], [sort], [func_decl], and [pattern]. - def_API('get_ast_id', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_ast_id : context -> ast -> int - = "camlidl_z3_Z3_get_ast_id" - -(** - Summary: Return a hash code for the given AST. - - {b Remarks}: Implicitly used by [Hashtbl.hash] for values of type [ast], [app], [sort], [func_decl], and [pattern]. - def_API('get_ast_hash', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_ast_hash : context -> ast -> int - = "camlidl_z3_Z3_get_ast_hash" - -(** - Summary: Return the sort of an AST node. - The AST node must be a constant, application, numeral, bound variable, or quantifier. - def_API('get_sort', SORT, (_in(CONTEXT), _in(AST))) -*) -external get_sort : context -> ast -> sort - = "camlidl_z3_Z3_get_sort" - -(** - Summary: Return true if the given expression [t] is well sorted. - def_API('is_well_sorted', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_well_sorted : context -> ast -> bool - = "camlidl_z3_Z3_is_well_sorted" - -(** - Summary: Return L_TRUE if [a] is true, L_FALSE if it is false, and L_UNDEF otherwise. - def_API('get_bool_value', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_bool_value : context -> ast -> lbool - = "camlidl_z3_Z3_get_bool_value" - -(** - Summary: Return the kind of the given AST. - def_API('get_ast_kind', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_ast_kind : context -> ast -> ast_kind - = "camlidl_z3_Z3_get_ast_kind" - -(** - def_API('is_app', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_app : context -> ast -> bool - = "camlidl_z3_Z3_is_app" - -(** - def_API('is_numeral_ast', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_numeral_ast : context -> ast -> bool - = "camlidl_z3_Z3_is_numeral_ast" - -(** - Summary: Return true if the give AST is a real algebraic number. - def_API('is_algebraic_number', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_algebraic_number : context -> ast -> bool - = "camlidl_z3_Z3_is_algebraic_number" - -(** - Summary: Convert an [ast] into an [APP_AST]. - - {b Precondition}: {v get_ast_kind c a == [APP_AST] v} - def_API('to_app', APP, (_in(CONTEXT), _in(AST))) -*) -external to_app : context -> ast -> app - = "camlidl_z3_Z3_to_app" - -(** - Summary: Convert an AST into a FUNC_DECL_AST. This is just type casting. - - {b Precondition}: {v get_ast_kind c a == FUNC_DECL_AST v} - def_API('to_func_decl', FUNC_DECL, (_in(CONTEXT), _in(AST))) -*) -external to_func_decl : context -> ast -> func_decl - = "camlidl_z3_Z3_to_func_decl" - -(** - {4 {L Numerals}} -*) - -(** - Summary: \[ [ numeral_refine c a ] \] is the refined view of [a]. - - {b Precondition}: [get_ast_kind c a = NUMERAL_AST] -*) -val numeral_refine : context -> ast -> numeral_refined - -(** - {5 {L Low-level API}} -*) -(** - Summary: Return numeral value, as a string of a numeric constant term - - {b Precondition}: get_ast_kind c a == NUMERAL_AST - def_API('get_numeral_string', STRING, (_in(CONTEXT), _in(AST))) -*) -external get_numeral_string : context -> ast -> string - = "camlidl_z3_Z3_get_numeral_string" - -(** - Summary: Return numeral as a string in decimal notation. - The result has at most [precision] decimal places. - - {b Precondition}: get_ast_kind c a == NUMERAL_AST || is_algebraic_number c a - def_API('get_numeral_decimal_string', STRING, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_numeral_decimal_string : context -> ast -> int -> string - = "camlidl_z3_Z3_get_numeral_decimal_string" - -(** - Summary: Return the numerator (as a numeral AST) of a numeral AST of sort Real. - - {b Precondition}: get_ast_kind c a == NUMERAL_AST - def_API('get_numerator', AST, (_in(CONTEXT), _in(AST))) -*) -external get_numerator : context -> ast -> ast - = "camlidl_z3_Z3_get_numerator" - -(** - Summary: Return the denominator (as a numeral AST) of a numeral AST of sort Real. - - {b Precondition}: get_ast_kind c a == NUMERAL_AST - def_API('get_denominator', AST, (_in(CONTEXT), _in(AST))) -*) -external get_denominator : context -> ast -> ast - = "camlidl_z3_Z3_get_denominator" - -(** - Summary: Return numeral value, as a pair of 64 bit numbers if the representation fits. - @param c logical context. - @param a term. - @param num numerator. - @param den denominator. - Return [TRUE] if the numeral value fits in 64 bit numerals, [FALSE] otherwise. - - {b Precondition}: get_ast_kind a == NUMERAL_AST - def_API('get_numeral_small', BOOL, (_in(CONTEXT), _in(AST), _out(INT64), _out(INT64))) -*) -external get_numeral_small : context -> ast -> bool * int64 * int64 - = "camlidl_z3_Z3_get_numeral_small" - -(** - Summary: \[ [ get_numeral_int c v ] \] - Similar to {!get_numeral_string}, but only succeeds if - the value can fit in a machine int. Return TRUE if the call succeeded. - - {b Precondition}: get_ast_kind c v == NUMERAL_AST - - {b See also}: {!get_numeral_string} - def_API('get_numeral_int', BOOL, (_in(CONTEXT), _in(AST), _out(INT))) -*) -external get_numeral_int : context -> ast -> bool * int - = "camlidl_z3_Z3_get_numeral_int" - -(** - Summary: \[ [ get_numeral_int64 c v ] \] - Similar to {!get_numeral_string}, but only succeeds if - the value can fit in a machine long long int. Return TRUE if the call succeeded. - - {b Precondition}: get_ast_kind c v == NUMERAL_AST - - {b See also}: {!get_numeral_string} - def_API('get_numeral_int64', BOOL, (_in(CONTEXT), _in(AST), _out(INT64))) -*) -external get_numeral_int64 : context -> ast -> bool * int64 - = "camlidl_z3_Z3_get_numeral_int64" - -(** - Summary: \[ [ get_numeral_rational_int64 c x y] \] - Similar to {!get_numeral_string}, but only succeeds if - the value can fit as a rational number as machine long long int. Return TRUE if the call succeeded. - - {b Precondition}: get_ast_kind c v == NUMERAL_AST - - {b See also}: {!get_numeral_string} - def_API('get_numeral_rational_int64', BOOL, (_in(CONTEXT), _in(AST), _out(INT64), _out(INT64))) -*) -external get_numeral_rational_int64 : context -> ast -> bool * int64 * int64 - = "camlidl_z3_Z3_get_numeral_rational_int64" - -(** - Summary: Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - The result is a numeral AST of sort Real. - - {b Precondition}: is_algebraic_number c a - def_API('get_algebraic_number_lower', AST, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_algebraic_number_lower : context -> ast -> int -> ast - = "camlidl_z3_Z3_get_algebraic_number_lower" - -(** - Summary: Return a upper bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - The result is a numeral AST of sort Real. - - {b Precondition}: is_algebraic_number c a - def_API('get_algebraic_number_upper', AST, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_algebraic_number_upper : context -> ast -> int -> ast - = "camlidl_z3_Z3_get_algebraic_number_upper" - -(** - {4 {L Patterns}} -*) -(** - Summary: Convert a pattern into ast. - - {b Remarks}: [pattern_to_ast c p] can be replaced by [(p :> ast)]. - def_API('pattern_to_ast', AST, (_in(CONTEXT), _in(PATTERN))) -*) -external pattern_to_ast : context -> pattern -> ast - = "camlidl_z3_Z3_pattern_to_ast" - - -(** - Summary: \[ [ get_pattern_terms c p ] \] is the ast's in pattern. - - {b See also}: {!get_pattern_num_terms} - - {b See also}: {!get_pattern} -*) -val get_pattern_terms: context -> pattern -> ast array;; - -(** - Summary: Return number of terms in pattern. - def_API('get_pattern_num_terms', UINT, (_in(CONTEXT), _in(PATTERN))) -*) -external get_pattern_num_terms : context -> pattern -> int - = "camlidl_z3_Z3_get_pattern_num_terms" - -(** - Summary: Return i'th ast in pattern. - def_API('get_pattern', AST, (_in(CONTEXT), _in(PATTERN), _in(UINT))) -*) -external get_pattern : context -> pattern -> int -> ast - = "camlidl_z3_Z3_get_pattern" - -(** - {4 {L Quantifiers}} -*) -(** - Summary: Return index of de-Brujin bound variable. - - {b Precondition}: get_ast_kind a == VAR_AST - def_API('get_index_value', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_index_value : context -> ast -> int - = "camlidl_z3_Z3_get_index_value" - -(** - Summary: Determine if quantifier is universal. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('is_quantifier_forall', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_quantifier_forall : context -> ast -> bool - = "camlidl_z3_Z3_is_quantifier_forall" - -(** - Summary: Obtain weight of quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_weight', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_weight : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_weight" - -(** - Summary: Return number of patterns used in quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_num_patterns', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_num_patterns : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_num_patterns" - -(** - Summary: Return i'th pattern. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_pattern_ast', PATTERN, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_pattern_ast : context -> ast -> int -> pattern - = "camlidl_z3_Z3_get_quantifier_pattern_ast" - -(** - Summary: Return number of no_patterns used in quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_num_no_patterns', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_num_no_patterns : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_num_no_patterns" - -(** - Summary: Return i'th no_pattern. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_no_pattern_ast', AST, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_no_pattern_ast : context -> ast -> int -> ast - = "camlidl_z3_Z3_get_quantifier_no_pattern_ast" - -(** - Summary: Return number of bound variables of quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_num_bound', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_num_bound : context -> ast -> int - = "camlidl_z3_Z3_get_quantifier_num_bound" - -(** - Summary: Return symbol of the i'th bound variable. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_bound_name', SYMBOL, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_bound_name : context -> ast -> int -> symbol - = "camlidl_z3_Z3_get_quantifier_bound_name" - -(** - Summary: Return sort of the i'th bound variable. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_bound_sort', SORT, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_bound_sort : context -> ast -> int -> sort - = "camlidl_z3_Z3_get_quantifier_bound_sort" - -(** - Summary: Return body of quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_body', AST, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_body : context -> ast -> ast - = "camlidl_z3_Z3_get_quantifier_body" - -(** - {3 {L Simplification}} -*) -(** - Summary: Interface to simplifier. - Provides an interface to the AST simplifier used by Z3. - def_API('simplify', AST, (_in(CONTEXT), _in(AST))) -*) -external simplify : context -> ast -> ast - = "camlidl_z3_Z3_simplify" - -(** - Summary: Interface to simplifier. - Provides an interface to the AST simplifier used by Z3. - This procedure is similar to {!simplify}, but the behavior of the simplifier - can be configured using the given parameter set. - def_API('simplify_ex', AST, (_in(CONTEXT), _in(AST), _in(PARAMS))) -*) -external simplify_ex : context -> ast -> params -> ast - = "camlidl_z3_Z3_simplify_ex" - -(** - Summary: Return a string describing all available parameters. - def_API('simplify_get_help', STRING, (_in(CONTEXT),)) -*) -external simplify_get_help : context -> string - = "camlidl_z3_Z3_simplify_get_help" - -(** - Summary: Return the parameter description set for the simplify procedure. - def_API('simplify_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT),)) -*) -external simplify_get_param_descrs : context -> param_descrs - = "camlidl_z3_Z3_simplify_get_param_descrs" - -(** - {2 {L Modifiers}} -*) -(** - Summary: Update the arguments of term [a] using the arguments [args]. - The number of arguments [num_args] should coincide - with the number of arguments to [a]. - If [a] is a quantifier, then num_args has to be 1. - def_API('update_term', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST))) -*) -external update_term : context -> ast -> ast array -> ast - = "camlidl_z3_Z3_update_term" - -(** - Summary: Substitute every occurrence of {e from[i] } in [a] with {e to[i] }, for [i] smaller than [num_exprs]. - The result is the new AST. The arrays [from] and [to] must have size [num_exprs]. - For every [i] smaller than [num_exprs], we must have that sort of {e from[i] } must be equal to sort of {e to[i] }. - def_API('substitute', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST), _in_array(2, AST))) -*) -external substitute : context -> ast -> ast array -> ast array -> ast - = "camlidl_z3_Z3_substitute" - -(** - Summary: Substitute the free variables in [a] with the expressions in [to]. - For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term {e to[i] }. - def_API('substitute_vars', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST))) -*) -external substitute_vars : context -> ast -> ast array -> ast - = "camlidl_z3_Z3_substitute_vars" - -(** - Summary: Translate/Copy the AST [a] from context [source] to context [target]. - AST [a] must have been created using context [source]. - - {b Precondition}: source != target - def_API('translate', AST, (_in(CONTEXT), _in(AST), _in(CONTEXT))) -*) -external translate : context -> ast -> context -> ast - = "camlidl_z3_Z3_translate" - -(** - {2 {L Models}} -*) - -(** - A model assigns uninterpreted sorts to finite universes of distinct values, constants to values, - and arrays and functions to finite maps from argument values to result values plus a default - value for all other arguments. -*) -type model_refined = { - sorts : (sort, ast_vector) Hashtbl.t; - consts : (func_decl, ast) Hashtbl.t; - arrays : (func_decl, (ast, ast) Hashtbl.t * ast) Hashtbl.t; - funcs : (func_decl, (ast array, ast) Hashtbl.t * ast) Hashtbl.t; -} - - -(** - Summary: [model_refine c m] is the refined model of [m]. -*) -val model_refine : context -> model -> model_refined - -(** - Summary: \[ [ model_eval c m t ] \] - Evaluate the AST node [t] in the given model. - Return [None] if the term was not successfully evaluated. - If [model_completion] is TRUE, then Z3 will assign an interpretation for any constant or function that does - not have an interpretation in [m]. These constants and functions were essentially don't cares. - The evaluation may fail for the following reasons: - - [t] contains a quantifier. - - the model [m] is partial, that is, it doesn't have a complete interpretation for uninterpreted functions. - That is, the option {e MODEL_PARTIAL=true } was used. - - [t] is type incorrect. - def_API('model_eval', BOOL, (_in(CONTEXT), _in(MODEL), _in(AST), _in(BOOL), _out(AST))) -*) -external model_eval : context -> model -> ast -> bool -> ast option - = "camlidl_z3_Z3_model_eval" - -(** - {4 {L Low-level API}} -*) -(** - Summary: Return the interpretation (i.e., assignment) of constant [a] in the model [m]. - Return [None], - if the model does not assign an interpretation for [a]. - That should be interpreted as: the value of [a] does not matter. - - {b Precondition}: get_arity c a == 0 - def_API('model_get_const_interp', AST, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL))) -*) -external model_get_const_interp : context -> model -> func_decl -> ast option - = "camlidl_z3_Z3_model_get_const_interp" - -(** - Summary: Return the interpretation of the function [f] in the model [m]. - Return [None], - if the model does not assign an interpretation for [f]. - That should be interpreted as: the [f] does not matter. - - {b Precondition}: get_arity c f > 0 - def_API('model_get_func_interp', FUNC_INTERP, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL))) -*) -external model_get_func_interp : context -> model -> func_decl -> func_interp option - = "camlidl_z3_Z3_model_get_func_interp" - -(** - Summary: Return the number of constants assigned by the given model. - - {b See also}: {!model_get_const_decl} - def_API('model_get_num_consts', UINT, (_in(CONTEXT), _in(MODEL))) -*) -external model_get_num_consts : context -> model -> int - = "camlidl_z3_Z3_model_get_num_consts" - -(** - Summary: \[ [ model_get_const_decl c m i ] \] - Return the i-th constant in the given model. - - {b Precondition}: i < model_get_num_consts c m - - {b See also}: {!model_eval} - def_API('model_get_const_decl', FUNC_DECL, (_in(CONTEXT), _in(MODEL), _in(UINT))) -*) -external model_get_const_decl : context -> model -> int -> func_decl - = "camlidl_z3_Z3_model_get_const_decl" - -(** - Summary: Return the number of function interpretations in the given model. - A function interpretation is represented as a finite map and an 'else' value. - Each entry in the finite map represents the value of a function given a set of arguments. - def_API('model_get_num_funcs', UINT, (_in(CONTEXT), _in(MODEL))) -*) -external model_get_num_funcs : context -> model -> int - = "camlidl_z3_Z3_model_get_num_funcs" - -(** - Summary: \[ [ model_get_func_decl c m i ] \] - Return the declaration of the i-th function in the given model. - - {b Precondition}: i < model_get_num_funcs c m - - {b See also}: {!model_get_num_funcs} - def_API('model_get_func_decl', FUNC_DECL, (_in(CONTEXT), _in(MODEL), _in(UINT))) -*) -external model_get_func_decl : context -> model -> int -> func_decl - = "camlidl_z3_Z3_model_get_func_decl" - -(** - Summary: Return the number of uninterpreted sorts that [m] assigs an interpretation to. - Z3 also provides an intepretation for uninterpreted sorts used in a formua. - The interpretation for a sort [s] is a finite set of distinct values. We say this finite set is - the "universe" of [s]. - - {b See also}: {!model_get_sort} - - {b See also}: {!model_get_sort_universe} - def_API('model_get_num_sorts', UINT, (_in(CONTEXT), _in(MODEL))) -*) -external model_get_num_sorts : context -> model -> int - = "camlidl_z3_Z3_model_get_num_sorts" - -(** - Summary: Return a uninterpreted sort that [m] assigns an interpretation. - - {b Precondition}: i < model_get_num_sorts c m - - {b See also}: {!model_get_num_sorts} - - {b See also}: {!model_get_sort_universe} - def_API('model_get_sort', SORT, (_in(CONTEXT), _in(MODEL), _in(UINT))) -*) -external model_get_sort : context -> model -> int -> sort - = "camlidl_z3_Z3_model_get_sort" - -(** - Summary: Return the finite set of distinct values that represent the interpretation for sort [s]. - - {b See also}: {!model_get_num_sorts} - - {b See also}: {!model_get_sort} - def_API('model_get_sort_universe', AST_VECTOR, (_in(CONTEXT), _in(MODEL), _in(SORT))) -*) -external model_get_sort_universe : context -> model -> sort -> ast_vector - = "camlidl_z3_Z3_model_get_sort_universe" - -(** - Summary: The {e (_ as-array f) } AST node is a construct for assigning interpretations for arrays in Z3. - It is the array such that forall indices [i] we have that {e (select (_ as-array f) i) } is equal to {e (f i) }. - This procedure returns TRUE if the [a] is an [as-array] AST node. - Z3 current solvers have minimal support for [as_array] nodes. - - {b See also}: {!get_as_array_func_decl} - def_API('is_as_array', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_as_array : context -> ast -> bool - = "camlidl_z3_Z3_is_as_array" - -(** - Summary: Return the function declaration [f] associated with a {e (_ as_array f) } node. - - {b See also}: {!is_as_array} - def_API('get_as_array_func_decl', FUNC_DECL, (_in(CONTEXT), _in(AST))) -*) -external get_as_array_func_decl : context -> ast -> func_decl - = "camlidl_z3_Z3_get_as_array_func_decl" - -(** - Summary: Return the number of entries in the given function interpretation. - A function interpretation is represented as a finite map and an 'else' value. - Each entry in the finite map represents the value of a function given a set of arguments. - This procedure return the number of element in the finite map of [f]. - def_API('func_interp_get_num_entries', UINT, (_in(CONTEXT), _in(FUNC_INTERP))) -*) -external func_interp_get_num_entries : context -> func_interp -> int - = "camlidl_z3_Z3_func_interp_get_num_entries" - -(** - Summary: Return a "point" of the given function intepretation. It represents the - value of [f] in a particular point. - - {b Precondition}: i < func_interp_get_num_entries c f - - {b See also}: {!func_interp_get_num_entries} - def_API('func_interp_get_entry', FUNC_ENTRY, (_in(CONTEXT), _in(FUNC_INTERP), _in(UINT))) -*) -external func_interp_get_entry : context -> func_interp -> int -> func_entry - = "camlidl_z3_Z3_func_interp_get_entry" - -(** - Summary: Return the 'else' value of the given function interpretation. - A function interpretation is represented as a finite map and an 'else' value. - This procedure returns the 'else' value. - def_API('func_interp_get_else', AST, (_in(CONTEXT), _in(FUNC_INTERP))) -*) -external func_interp_get_else : context -> func_interp -> ast - = "camlidl_z3_Z3_func_interp_get_else" - -(** - Summary: Return the arity (number of arguments) of the given function interpretation. - def_API('func_interp_get_arity', UINT, (_in(CONTEXT), _in(FUNC_INTERP))) -*) -external func_interp_get_arity : context -> func_interp -> int - = "camlidl_z3_Z3_func_interp_get_arity" - -(** - Summary: Return the value of this point. - A func_entry object represents an element in the finite map used to encode - a function interpretation. - - {b See also}: {!func_interp_get_entry} - def_API('func_entry_get_value', AST, (_in(CONTEXT), _in(FUNC_ENTRY))) -*) -external func_entry_get_value : context -> func_entry -> ast - = "camlidl_z3_Z3_func_entry_get_value" - -(** - Summary: Return the number of arguments in a func_entry object. - - {b See also}: {!func_interp_get_entry} - def_API('func_entry_get_num_args', UINT, (_in(CONTEXT), _in(FUNC_ENTRY))) -*) -external func_entry_get_num_args : context -> func_entry -> int - = "camlidl_z3_Z3_func_entry_get_num_args" - -(** - Summary: Return an argument of a func_entry object. - - {b Precondition}: i < func_entry_get_num_args c e - - {b See also}: {!func_interp_get_entry} - def_API('func_entry_get_arg', AST, (_in(CONTEXT), _in(FUNC_ENTRY), _in(UINT))) -*) -external func_entry_get_arg : context -> func_entry -> int -> ast - = "camlidl_z3_Z3_func_entry_get_arg" - -(** - {2 {L Interaction logging.}} -*) -(** - Summary: Log interaction to a file. - extra_API('open_log', INT, (_in(STRING),)) -*) -external open_log : string -> bool - = "camlidl_z3_Z3_open_log" - -(** - Summary: Append user-defined string to interaction log. - The interaction log is opened using open_log. - It contains the formulas that are checked using Z3. - You can use this command to append comments, for instance. - extra_API('append_log', VOID, (_in(STRING),)) -*) -external append_log : string -> unit - = "camlidl_z3_Z3_append_log" - -(** - Summary: Close interaction log. - extra_API('close_log', VOID, ()) -*) -external close_log : unit -> unit - = "camlidl_z3_Z3_close_log" - -(** - Summary: Enable/disable printing warning messages to the console. - Warnings are printed after passing [true], warning messages are - suppressed after calling this method with [false]. - def_API('toggle_warning_messages', VOID, (_in(BOOL),)) -*) -external toggle_warning_messages : bool -> unit - = "camlidl_z3_Z3_toggle_warning_messages" - -(** - {2 {L String conversion}} -*) -(** - Summary: Select mode for the format used for pretty-printing AST nodes. - The default mode for pretty printing AST nodes is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - - {b See also}: {!ast_to_string} - - {b See also}: {!pattern_to_string} - - {b See also}: {!func_decl_to_string} - def_API('set_ast_print_mode', VOID, (_in(CONTEXT), _in(PRINT_MODE))) -*) -external set_ast_print_mode : context -> ast_print_mode -> unit - = "camlidl_z3_Z3_set_ast_print_mode" - -(** - Summary: Convert the given AST node into a string. - - {b See also}: {!pattern_to_string} - - {b See also}: {!sort_to_string} - def_API('ast_to_string', STRING, (_in(CONTEXT), _in(AST))) -*) -external ast_to_string : context -> ast -> string - = "camlidl_z3_Z3_ast_to_string" - -(** - def_API('pattern_to_string', STRING, (_in(CONTEXT), _in(PATTERN))) -*) -external pattern_to_string : context -> pattern -> string - = "camlidl_z3_Z3_pattern_to_string" - -(** - def_API('sort_to_string', STRING, (_in(CONTEXT), _in(SORT))) -*) -external sort_to_string : context -> sort -> string - = "camlidl_z3_Z3_sort_to_string" - -(** - def_API('func_decl_to_string', STRING, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external func_decl_to_string : context -> func_decl -> string - = "camlidl_z3_Z3_func_decl_to_string" - -(** - Summary: Convert the given model into a string. - def_API('model_to_string', STRING, (_in(CONTEXT), _in(MODEL))) -*) -external model_to_string : context -> model -> string - = "camlidl_z3_Z3_model_to_string" - -(** - Summary: Convert the given benchmark into SMT-LIB formatted string. - @param c - context. - @param name - name of benchmark. The argument is optional. - @param logic - the benchmark logic. - @param status - the status string (sat, unsat, or unknown) - @param attributes - other attributes, such as source, difficulty or category. - @param num_assumptions - number of assumptions. - @param assumptions - auxiliary assumptions. - @param formula - formula to be checked for consistency in conjunction with assumptions. - def_API('benchmark_to_smtlib_string', STRING, (_in(CONTEXT), _in(STRING), _in(STRING), _in(STRING), _in(STRING), _in(UINT), _in_array(5, AST), _in(AST))) -*) -external benchmark_to_smtlib_string : context -> string -> string -> string -> string -> ast array -> ast -> string - = "camlidl_z3_Z3_benchmark_to_smtlib_string_bytecode" "camlidl_z3_Z3_benchmark_to_smtlib_string" - -(** - {2 {L Parser interface}} -*) -(** - Summary: \[ [ parse_smtlib2_string c str ] \] - Parse the given string using the SMT-LIB2 parser. - It returns a formula comprising of the conjunction of assertions in the scope - (up to push/pop) at the end of the string. - def_API('parse_smtlib2_string', AST, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3_Z3_parse_smtlib2_string_bytecode" "camlidl_z3_Z3_parse_smtlib2_string" - -(** - Summary: Similar to {!parse_smtlib2_string}, but reads the benchmark from a file. - def_API('parse_smtlib2_file', AST, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3_Z3_parse_smtlib2_file_bytecode" "camlidl_z3_Z3_parse_smtlib2_file" - - -(** - Summary: \[ [ parse_smtlib_string_x c str sort_names sorts decl_names decls ] \] - Parse the given string using the SMT-LIB parser. - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays [sort_names] and [decl_names] don't need to match the names - of the sorts and declarations in the arrays [sorts] and [decls]. This is an useful feature - since we can use arbitrary names to reference sorts and declarations defined using the API. - - {b See also}: {!parse_smtlib_file_x} -*) -val parse_smtlib_string_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) -(** - Summary: Similar to {!parse_smtlib_string_x}, but reads the benchmark from a file. - - {b See also}: {!parse_smtlib_string_x} -*) -val parse_smtlib_file_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) -(** - Summary: \[ [ parse_smtlib_string_formula c ... ] \] calls [(parse_smtlib_string c ...)] and returns the single formula produced. - - {b See also}: {!parse_smtlib_file_formula} - - {b See also}: {!parse_smtlib_string_x} -*) -val parse_smtlib_string_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast -(** - Summary: \[ [ parse_smtlib_file_formula c ... ] \] calls [(parse_smtlib_file c ...)] and returns the single formula produced. - - {b See also}: {!parse_smtlib_string_formula} - - {b See also}: {!parse_smtlib_file_x} -*) -val parse_smtlib_file_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - -(** - {4 {L Low-level API}} -*) -(** - Summary: \[ [ parse_smtlib_string c str sort_names sorts decl_names decls ] \] - Parse the given string using the SMT-LIB parser. - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays [sort_names] and [decl_names] don't need to match the names - of the sorts and declarations in the arrays [sorts] and [decls]. This is an useful feature - since we can use arbitrary names to reference sorts and declarations defined using the C API. - The formulas, assumptions and declarations defined in [str] can be extracted using the functions: - {!get_smtlib_num_formulas}, {!get_smtlib_formula}, {!get_smtlib_num_assumptions}, {!get_smtlib_assumption}, - {!get_smtlib_num_decls}, and {!get_smtlib_decl}. - def_API('parse_smtlib_string', VOID, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3_Z3_parse_smtlib_string_bytecode" "camlidl_z3_Z3_parse_smtlib_string" - -(** - Summary: Similar to {!parse_smtlib_string}, but reads the benchmark from a file. - def_API('parse_smtlib_file', VOID, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3_Z3_parse_smtlib_file_bytecode" "camlidl_z3_Z3_parse_smtlib_file" - -(** - Summary: Return the number of SMTLIB formulas parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_formulas', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_formulas : context -> int - = "camlidl_z3_Z3_get_smtlib_num_formulas" - -(** - Summary: \[ [ get_smtlib_formula c i ] \] - Return the i-th formula parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_formulas c - def_API('get_smtlib_formula', AST, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_formula : context -> int -> ast - = "camlidl_z3_Z3_get_smtlib_formula" - -(** - Summary: Return the number of SMTLIB assumptions parsed by {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_assumptions', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_assumptions : context -> int - = "camlidl_z3_Z3_get_smtlib_num_assumptions" - -(** - Summary: \[ [ get_smtlib_assumption c i ] \] - Return the i-th assumption parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_assumptions c - def_API('get_smtlib_assumption', AST, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_assumption : context -> int -> ast - = "camlidl_z3_Z3_get_smtlib_assumption" - -(** - Summary: Return the number of declarations parsed by {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_decls', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_decls : context -> int - = "camlidl_z3_Z3_get_smtlib_num_decls" - -(** - Summary: \[ [ get_smtlib_decl c i ] \] - Return the i-th declaration parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_decls c - def_API('get_smtlib_decl', FUNC_DECL, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_decl : context -> int -> func_decl - = "camlidl_z3_Z3_get_smtlib_decl" - -(** - Summary: Return the number of sorts parsed by {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_sorts', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_sorts : context -> int - = "camlidl_z3_Z3_get_smtlib_num_sorts" - -(** - Summary: \[ [ get_smtlib_sort c i ] \] - Return the i-th sort parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_sorts c - def_API('get_smtlib_sort', SORT, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_sort : context -> int -> sort - = "camlidl_z3_Z3_get_smtlib_sort" - -(* -(** - Summary: \[ [ get_smtlib_error c ] \] - Retrieve that last error message information generated from parsing. - def_API('get_smtlib_error', STRING, (_in(CONTEXT), )) -*) -external get_smtlib_error : context -> string - = "camlidl_z3_Z3_get_smtlib_error" - -*) -(** - {2 {L Error Handling}} -*) -(** - Summary: Set an error. - def_API('set_error', VOID, (_in(CONTEXT), _in(ERROR_CODE))) -*) -external set_error : context -> error_code -> unit - = "camlidl_z3_Z3_set_error" - -(* -(** - Summary: Return a string describing the given error code. - def_API('get_error_msg_ex', STRING, (_in(CONTEXT), _in(ERROR_CODE))) -*) -external get_error_msg_ex : context -> error_code -> string - = "camlidl_z3_Z3_get_error_msg_ex" - -*) - -(** - Summary: Return a string describing the given error code. -*) -val get_error_msg: context -> error_code -> string - -(** - {2 {L Miscellaneous}} -*) -(** - Summary: Return Z3 version number information. - def_API('get_version', VOID, (_out(UINT), _out(UINT), _out(UINT), _out(UINT))) -*) -external get_version : unit -> int * int * int * int - = "camlidl_z3_Z3_get_version" - -(** - Summary: Enable tracing messages tagged as [tag] when Z3 is compiled in debug mode. - It is a NOOP otherwise - def_API('enable_trace', VOID, (_in(STRING),)) -*) -external enable_trace : string -> unit - = "camlidl_z3_Z3_enable_trace" - -(** - Summary: Disable tracing messages tagged as [tag] when Z3 is compiled in debug mode. - It is a NOOP otherwise - def_API('disable_trace', VOID, (_in(STRING),)) -*) -external disable_trace : string -> unit - = "camlidl_z3_Z3_disable_trace" - -(** - {2 {L Fixedpoint facilities}} -*) -(** - Summary: Create a new fixedpoint context. - def_API('mk_fixedpoint', FIXEDPOINT, (_in(CONTEXT), )) -*) -external mk_fixedpoint : context -> fixedpoint - = "camlidl_z3_Z3_mk_fixedpoint" - -(** - Summary: Add a universal Horn clause as a named rule. - The [horn_rule] should be of the form: - {v - horn_rule ::= (forall (bound-vars) horn_rule) - | (=> atoms horn_rule) - | atom - v} - def_API('fixedpoint_add_rule', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(AST), _in(SYMBOL))) -*) -external fixedpoint_add_rule : context -> fixedpoint -> ast -> symbol -> unit - = "camlidl_z3_Z3_fixedpoint_add_rule" - -(** - Summary: Add a Database fact. - @param c - context - @param d - fixed point context - @param r - relation signature for the row. - @param num_args - number of columns for the given row. - @param args - array of the row elements. - The number of arguments [num_args] should be equal to the number - of sorts in the domain of [r]. Each sort in the domain should be an integral - (bit-vector, Boolean or or finite domain sort). - The call has the same effect as adding a rule where [r] is applied to the arguments. - def_API('fixedpoint_add_fact', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL), _in(UINT), _in_array(3, UINT))) -*) -external fixedpoint_add_fact : context -> fixedpoint -> func_decl -> int array -> unit - = "camlidl_z3_Z3_fixedpoint_add_fact" - -(** - Summary: Assert a constraint to the fixedpoint context. - The constraints are used as background axioms when the fixedpoint engine uses the PDR mode. - They are ignored for standard Datalog mode. - def_API('fixedpoint_assert', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(AST))) -*) -external fixedpoint_assert : context -> fixedpoint -> ast -> unit - = "camlidl_z3_Z3_fixedpoint_assert" - -(** - Summary: Pose a query against the asserted rules. - {v - query ::= (exists (bound-vars) query) - | literals - v} - query returns - - L_FALSE if the query is unsatisfiable. - - L_TRUE if the query is satisfiable. Obtain the answer by calling {!fixedpoint_get_answer}. - - L_UNDEF if the query was interrupted, timed out or otherwise failed. - def_API('fixedpoint_query', INT, (_in(CONTEXT), _in(FIXEDPOINT), _in(AST))) -*) -external fixedpoint_query : context -> fixedpoint -> ast -> lbool - = "camlidl_z3_Z3_fixedpoint_query" - -(** - Summary: Pose multiple queries against the asserted rules. - The queries are encoded as relations (function declarations). - query returns - - L_FALSE if the query is unsatisfiable. - - L_TRUE if the query is satisfiable. Obtain the answer by calling {!fixedpoint_get_answer}. - - L_UNDEF if the query was interrupted, timed out or otherwise failed. - def_API('fixedpoint_query_relations', INT, (_in(CONTEXT), _in(FIXEDPOINT), _in(UINT), _in_array(2, FUNC_DECL))) -*) -external fixedpoint_query_relations : context -> fixedpoint -> func_decl array -> lbool - = "camlidl_z3_Z3_fixedpoint_query_relations" - -(** - Summary: Retrieve a formula that encodes satisfying answers to the query. - When used in Datalog mode, the returned answer is a disjunction of conjuncts. - Each conjunct encodes values of the bound variables of the query that are satisfied. - In PDR mode, the returned answer is a single conjunction. - The previous call to fixedpoint_query must have returned L_TRUE. - def_API('fixedpoint_get_answer', AST, (_in(CONTEXT), _in(FIXEDPOINT))) -*) -external fixedpoint_get_answer : context -> fixedpoint -> ast - = "camlidl_z3_Z3_fixedpoint_get_answer" - -(** - Summary: Retrieve a string that describes the last status returned by {!fixedpoint_query}. - Use this method when {!fixedpoint_query} returns L_UNDEF. - def_API('fixedpoint_get_reason_unknown', STRING, (_in(CONTEXT), _in(FIXEDPOINT) )) -*) -external fixedpoint_get_reason_unknown : context -> fixedpoint -> string - = "camlidl_z3_Z3_fixedpoint_get_reason_unknown" - -(** - Summary: Update a named rule. - A rule with the same name must have been previously created. - def_API('fixedpoint_update_rule', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(AST), _in(SYMBOL))) -*) -external fixedpoint_update_rule : context -> fixedpoint -> ast -> symbol -> unit - = "camlidl_z3_Z3_fixedpoint_update_rule" - -(** - Summary: Query the PDR engine for the maximal levels properties are known about predicate. - This call retrieves the maximal number of relevant unfoldings - of [pred] with respect to the current exploration state. - Note: this functionality is PDR specific. - def_API('fixedpoint_get_num_levels', UINT, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL))) -*) -external fixedpoint_get_num_levels : context -> fixedpoint -> func_decl -> int - = "camlidl_z3_Z3_fixedpoint_get_num_levels" - -(** - Retrieve the current cover of [pred] up to [level] unfoldings. - Return just the delta that is known at [level]. To - obtain the full set of properties of [pred] one should query - at [level+1] , [level+2] etc, and include [level=-1]. - Note: this functionality is PDR specific. - def_API('fixedpoint_get_cover_delta', AST, (_in(CONTEXT), _in(FIXEDPOINT), _in(INT), _in(FUNC_DECL))) -*) -external fixedpoint_get_cover_delta : context -> fixedpoint -> int -> func_decl -> ast - = "camlidl_z3_Z3_fixedpoint_get_cover_delta" - -(** - Summary: Add property about the predicate [pred]. - Add a property of predicate [pred] at [level]. - It gets pushed forward when possible. - Note: level = -1 is treated as the fixedpoint. So passing -1 for the [level] - means that the property is true of the fixed-point unfolding with respect to [pred]. - Note: this functionality is PDR specific. - def_API('fixedpoint_add_cover', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(INT), _in(FUNC_DECL), _in(AST))) -*) -external fixedpoint_add_cover : context -> fixedpoint -> int -> func_decl -> ast -> unit - = "camlidl_z3_Z3_fixedpoint_add_cover" - -(** - Summary: Retrieve statistics information from the last call to {!fixedpoint_query}. - def_API('fixedpoint_get_statistics', STATS, (_in(CONTEXT), _in(FIXEDPOINT))) -*) -external fixedpoint_get_statistics : context -> fixedpoint -> stats - = "camlidl_z3_Z3_fixedpoint_get_statistics" - -(** - Summary: Register relation as Fixedpoint defined. - Fixedpoint defined relations have least-fixedpoint semantics. - For example, the relation is empty if it does not occur - in a head or a fact. - def_API('fixedpoint_register_relation', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL))) -*) -external fixedpoint_register_relation : context -> fixedpoint -> func_decl -> unit - = "camlidl_z3_Z3_fixedpoint_register_relation" - -(** - Summary: Configure the predicate representation. - It sets the predicate to use a set of domains given by the list of symbols. - The domains given by the list of symbols must belong to a set - of built-in domains. - def_API('fixedpoint_set_predicate_representation', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL), _in(UINT), _in_array(3, SYMBOL))) -*) -external fixedpoint_set_predicate_representation : context -> fixedpoint -> func_decl -> symbol array -> unit - = "camlidl_z3_Z3_fixedpoint_set_predicate_representation" - -(** - Summary: Retrieve set of rules from fixedpoint context. - def_API('fixedpoint_get_rules', AST_VECTOR, (_in(CONTEXT),_in(FIXEDPOINT))) -*) -external fixedpoint_get_rules : context -> fixedpoint -> ast_vector - = "camlidl_z3_Z3_fixedpoint_get_rules" - -(** - Summary: Retrieve set of background assertions from fixedpoint context. - def_API('fixedpoint_get_assertions', AST_VECTOR, (_in(CONTEXT),_in(FIXEDPOINT))) -*) -external fixedpoint_get_assertions : context -> fixedpoint -> ast_vector - = "camlidl_z3_Z3_fixedpoint_get_assertions" - -(** - Summary: Set parameters on fixedpoint context. - def_API('fixedpoint_set_params', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(PARAMS))) -*) -external fixedpoint_set_params : context -> fixedpoint -> params -> unit - = "camlidl_z3_Z3_fixedpoint_set_params" - -(** - Summary: Return a string describing all fixedpoint available parameters. - def_API('fixedpoint_get_help', STRING, (_in(CONTEXT), _in(FIXEDPOINT))) -*) -external fixedpoint_get_help : context -> fixedpoint -> string - = "camlidl_z3_Z3_fixedpoint_get_help" - -(** - Summary: Return the parameter description set for the given fixedpoint object. - def_API('fixedpoint_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(FIXEDPOINT))) -*) -external fixedpoint_get_param_descrs : context -> fixedpoint -> param_descrs - = "camlidl_z3_Z3_fixedpoint_get_param_descrs" - -(** - Summary: Print the current rules and background axioms as a string. - @param c - context. - @param f - fixedpoint context. - @param num_queries - number of additional queries to print. - @param queries - additional queries. - def_API('fixedpoint_to_string', STRING, (_in(CONTEXT), _in(FIXEDPOINT), _in(UINT), _in_array(2, AST))) -*) -external fixedpoint_to_string : context -> fixedpoint -> ast array -> string - = "camlidl_z3_Z3_fixedpoint_to_string" - -(** - Summary: Parse an SMT-LIB2 string with fixedpoint rules. - Add the rules to the current fixedpoint context. - Return the set of queries in the file. - @param c - context. - @param f - fixedpoint context. - @param s - string containing SMT2 specification. - def_API('fixedpoint_from_string', AST_VECTOR, (_in(CONTEXT), _in(FIXEDPOINT), _in(STRING))) -*) -external fixedpoint_from_string : context -> fixedpoint -> string -> ast_vector - = "camlidl_z3_Z3_fixedpoint_from_string" - -(** - Summary: Parse an SMT-LIB2 file with fixedpoint rules. - Add the rules to the current fixedpoint context. - Return the set of queries in the file. - @param c - context. - @param f - fixedpoint context. - @param s - string containing SMT2 specification. - def_API('fixedpoint_from_file', AST_VECTOR, (_in(CONTEXT), _in(FIXEDPOINT), _in(STRING))) -*) -external fixedpoint_from_file : context -> fixedpoint -> string -> ast_vector - = "camlidl_z3_Z3_fixedpoint_from_file" - -(** - Summary: Create a backtracking point. - The fixedpoint solver contains a set of rules, added facts and assertions. - The set of rules, facts and assertions are restored upon calling {!fixedpoint_pop}. - - {b See also}: {!fixedpoint_pop} - def_API('fixedpoint_push', VOID, (_in(CONTEXT), _in(FIXEDPOINT))) -*) -external fixedpoint_push : context -> fixedpoint -> unit - = "camlidl_z3_Z3_fixedpoint_push" - -(** - Summary: Backtrack one backtracking point. - - {b See also}: {!fixedpoint_push} - - {b Precondition}: The number of calls to pop cannot exceed calls to push. - def_API('fixedpoint_pop', VOID, (_in(CONTEXT), _in(FIXEDPOINT))) -*) -external fixedpoint_pop : context -> fixedpoint -> unit - = "camlidl_z3_Z3_fixedpoint_pop" - -(** - {2 {L AST vectors}} -*) -(** - Summary: Return an empty AST vector. - def_API('mk_ast_vector', AST_VECTOR, (_in(CONTEXT),)) -*) -external mk_ast_vector : context -> ast_vector - = "camlidl_z3_Z3_mk_ast_vector" - -(** - Summary: Return the size of the given AST vector. - def_API('ast_vector_size', UINT, (_in(CONTEXT), _in(AST_VECTOR))) -*) -external ast_vector_size : context -> ast_vector -> int - = "camlidl_z3_Z3_ast_vector_size" - -(** - Summary: Return the AST at position [i] in the AST vector [v]. - - {b Precondition}: i < ast_vector_size c v - def_API('ast_vector_get', AST, (_in(CONTEXT), _in(AST_VECTOR), _in(UINT))) -*) -external ast_vector_get : context -> ast_vector -> int -> ast - = "camlidl_z3_Z3_ast_vector_get" - -(** - Summary: Update position [i] of the AST vector [v] with the AST [a]. - - {b Precondition}: i < ast_vector_size c v - def_API('ast_vector_set', VOID, (_in(CONTEXT), _in(AST_VECTOR), _in(UINT), _in(AST))) -*) -external ast_vector_set : context -> ast_vector -> int -> ast -> unit - = "camlidl_z3_Z3_ast_vector_set" - -(** - Summary: Resize the AST vector [v]. - def_API('ast_vector_resize', VOID, (_in(CONTEXT), _in(AST_VECTOR), _in(UINT))) -*) -external ast_vector_resize : context -> ast_vector -> int -> unit - = "camlidl_z3_Z3_ast_vector_resize" - -(** - Summary: Add the AST [a] in the end of the AST vector [v]. The size of [v] is increased by one. - def_API('ast_vector_push', VOID, (_in(CONTEXT), _in(AST_VECTOR), _in(AST))) -*) -external ast_vector_push : context -> ast_vector -> ast -> unit - = "camlidl_z3_Z3_ast_vector_push" - -(** - Summary: Translate the AST vector [v] from context [s] into an AST vector in context [t]. - def_API('ast_vector_translate', AST_VECTOR, (_in(CONTEXT), _in(AST_VECTOR), _in(CONTEXT))) -*) -external ast_vector_translate : context -> ast_vector -> context -> ast_vector - = "camlidl_z3_Z3_ast_vector_translate" - -(** - Summary: Convert AST vector into a string. - def_API('ast_vector_to_string', STRING, (_in(CONTEXT), _in(AST_VECTOR))) -*) -external ast_vector_to_string : context -> ast_vector -> string - = "camlidl_z3_Z3_ast_vector_to_string" - -(** - {2 {L AST maps}} -*) -(** - Summary: Return an empty mapping from AST to AST - def_API('mk_ast_map', AST_MAP, (_in(CONTEXT),) ) -*) -external mk_ast_map : context -> ast_map - = "camlidl_z3_Z3_mk_ast_map" - -(** - Summary: Return true if the map [m] contains the AST key [k]. - def_API('ast_map_contains', BOOL, (_in(CONTEXT), _in(AST_MAP), _in(AST))) -*) -external ast_map_contains : context -> ast_map -> ast -> bool - = "camlidl_z3_Z3_ast_map_contains" - -(** - Summary: Return the value associated with the key [k]. - The procedure invokes the error handler if [k] is not in the map. - def_API('ast_map_find', AST, (_in(CONTEXT), _in(AST_MAP), _in(AST))) -*) -external ast_map_find : context -> ast_map -> ast -> ast - = "camlidl_z3_Z3_ast_map_find" - -(** - Summary: Store/Replace a new key, value pair in the given map. - def_API('ast_map_insert', VOID, (_in(CONTEXT), _in(AST_MAP), _in(AST), _in(AST))) -*) -external ast_map_insert : context -> ast_map -> ast -> ast -> unit - = "camlidl_z3_Z3_ast_map_insert" - -(** - Summary: Erase a key from the map. - def_API('ast_map_erase', VOID, (_in(CONTEXT), _in(AST_MAP), _in(AST))) -*) -external ast_map_erase : context -> ast_map -> ast -> unit - = "camlidl_z3_Z3_ast_map_erase" - -(** - Summary: Remove all keys from the given map. - def_API('ast_map_reset', VOID, (_in(CONTEXT), _in(AST_MAP))) -*) -external ast_map_reset : context -> ast_map -> unit - = "camlidl_z3_Z3_ast_map_reset" - -(** - Summary: Return the size of the given map. - def_API('ast_map_size', UINT, (_in(CONTEXT), _in(AST_MAP))) -*) -external ast_map_size : context -> ast_map -> int - = "camlidl_z3_Z3_ast_map_size" - -(** - Summary: Return the keys stored in the given map. - def_API('ast_map_keys', AST_VECTOR, (_in(CONTEXT), _in(AST_MAP))) -*) -external ast_map_keys : context -> ast_map -> ast_vector - = "camlidl_z3_Z3_ast_map_keys" - -(** - Summary: Convert the given map into a string. - def_API('ast_map_to_string', STRING, (_in(CONTEXT), _in(AST_MAP))) -*) -external ast_map_to_string : context -> ast_map -> string - = "camlidl_z3_Z3_ast_map_to_string" - -(** - {2 {L Goals}} -*) -(** - Summary: Create a goal (aka problem). A goal is essentially a set - of formulas, that can be solved and/or transformed using - tactics and solvers. - If models == true, then model generation is enabled for the new goal. - If unsat_cores == true, then unsat core generation is enabled for the new goal. - If proofs == true, then proof generation is enabled for the new goal. Remark, the - Z3 context c must have been created with proof generation support. - def_API('mk_goal', GOAL, (_in(CONTEXT), _in(BOOL), _in(BOOL), _in(BOOL))) -*) -external mk_goal : context -> bool -> bool -> bool -> goal - = "camlidl_z3_Z3_mk_goal" - -(** - Summary: Return the "precision" of the given goal. Goals can be transformed using over and under approximations. - A under approximation is applied when the objective is to find a model for a given goal. - An over approximation is applied when the objective is to find a proof for a given goal. - def_API('goal_precision', UINT, (_in(CONTEXT), _in(GOAL))) -*) -external goal_precision : context -> goal -> goal_prec - = "camlidl_z3_Z3_goal_precision" - -(** - Summary: Add a new formula [a] to the given goal. - def_API('goal_assert', VOID, (_in(CONTEXT), _in(GOAL), _in(AST))) -*) -external goal_assert : context -> goal -> ast -> unit - = "camlidl_z3_Z3_goal_assert" - -(** - Summary: Return true if the given goal contains the formula [false]. - def_API('goal_inconsistent', BOOL, (_in(CONTEXT), _in(GOAL))) -*) -external goal_inconsistent : context -> goal -> bool - = "camlidl_z3_Z3_goal_inconsistent" - -(** - Summary: Return the depth of the given goal. It tracks how many transformations were applied to it. - def_API('goal_depth', UINT, (_in(CONTEXT), _in(GOAL))) -*) -external goal_depth : context -> goal -> int - = "camlidl_z3_Z3_goal_depth" - -(** - Summary: Erase all formulas from the given goal. - def_API('goal_reset', VOID, (_in(CONTEXT), _in(GOAL))) -*) -external goal_reset : context -> goal -> unit - = "camlidl_z3_Z3_goal_reset" - -(** - Summary: Return the number of formulas in the given goal. - def_API('goal_size', UINT, (_in(CONTEXT), _in(GOAL))) -*) -external goal_size : context -> goal -> int - = "camlidl_z3_Z3_goal_size" - -(** - Summary: Return a formula from the given goal. - - {b Precondition}: idx < goal_size c g - def_API('goal_formula', AST, (_in(CONTEXT), _in(GOAL), _in(UINT))) -*) -external goal_formula : context -> goal -> int -> ast - = "camlidl_z3_Z3_goal_formula" - -(** - Summary: Return the number of formulas, subformulas and terms in the given goal. - def_API('goal_num_exprs', UINT, (_in(CONTEXT), _in(GOAL))) -*) -external goal_num_exprs : context -> goal -> int - = "camlidl_z3_Z3_goal_num_exprs" - -(** - Summary: Return true if the goal is empty, and it is precise or the product of a under approximation. - def_API('goal_is_decided_sat', BOOL, (_in(CONTEXT), _in(GOAL))) -*) -external goal_is_decided_sat : context -> goal -> bool - = "camlidl_z3_Z3_goal_is_decided_sat" - -(** - Summary: Return true if the goal contains false, and it is precise or the product of an over approximation. - def_API('goal_is_decided_unsat', BOOL, (_in(CONTEXT), _in(GOAL))) -*) -external goal_is_decided_unsat : context -> goal -> bool - = "camlidl_z3_Z3_goal_is_decided_unsat" - -(** - Summary: Copy a goal [g] from the context [source] to a the context [target]. - def_API('goal_translate', GOAL, (_in(CONTEXT), _in(GOAL), _in(CONTEXT))) -*) -external goal_translate : context -> goal -> context -> goal - = "camlidl_z3_Z3_goal_translate" - -(** - Summary: Convert a goal into a string. - def_API('goal_to_string', STRING, (_in(CONTEXT), _in(GOAL))) -*) -external goal_to_string : context -> goal -> string - = "camlidl_z3_Z3_goal_to_string" - -(** - {2 {L Tactics and Probes}} -*) -(** - Summary: Return a tactic associated with the given name. - The complete list of tactics may be obtained using the procedures {!get_num_tactics} and {!get_tactic_name}. - It may also be obtained using the command {e (help-tactics) } in the SMT 2.0 front-end. - Tactics are the basic building block for creating custom solvers for specific problem domains. - def_API('mk_tactic', TACTIC, (_in(CONTEXT), _in(STRING))) -*) -external mk_tactic : context -> string -> tactic - = "camlidl_z3_Z3_mk_tactic" - -(** - Summary: Return a probe associated with the given name. - The complete list of probes may be obtained using the procedures {!get_num_probes} and {!get_probe_name}. - It may also be obtained using the command {e (help-tactics) } in the SMT 2.0 front-end. - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - def_API('mk_probe', PROBE, (_in(CONTEXT), _in(STRING))) -*) -external mk_probe : context -> string -> probe - = "camlidl_z3_Z3_mk_probe" - -(** - Summary: Return a tactic that applies [t1] to a given goal and [t2] - to every subgoal produced by t1. - def_API('tactic_and_then', TACTIC, (_in(CONTEXT), _in(TACTIC), _in(TACTIC))) -*) -external tactic_and_then : context -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_and_then" - -(** - Summary: Return a tactic that first applies [t1] to a given goal, - if it fails then returns the result of [t2] applied to the given goal. - def_API('tactic_or_else', TACTIC, (_in(CONTEXT), _in(TACTIC), _in(TACTIC))) -*) -external tactic_or_else : context -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_or_else" - -(** - Summary: Return a tactic that applies the given tactics in parallel. - def_API('tactic_par_or', TACTIC, (_in(CONTEXT), _in(UINT), _in_array(1, TACTIC))) -*) -external tactic_par_or : context -> tactic array -> tactic - = "camlidl_z3_Z3_tactic_par_or" - -(** - Summary: Return a tactic that applies [t1] to a given goal and then [t2] - to every subgoal produced by t1. The subgoals are processed in parallel. - def_API('tactic_par_and_then', TACTIC, (_in(CONTEXT), _in(TACTIC), _in(TACTIC))) -*) -external tactic_par_and_then : context -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_par_and_then" - -(** - Summary: Return a tactic that applies [t] to a given goal for [ms] milliseconds. - If [t] does not terminate in [ms] milliseconds, then it fails. - def_API('tactic_try_for', TACTIC, (_in(CONTEXT), _in(TACTIC), _in(UINT))) -*) -external tactic_try_for : context -> tactic -> int -> tactic - = "camlidl_z3_Z3_tactic_try_for" - -(** - Summary: Return a tactic that applies [t] to a given goal is the probe [p] evaluates to true. - If [p] evaluates to false, then the new tactic behaves like the skip tactic. - def_API('tactic_when', TACTIC, (_in(CONTEXT), _in(PROBE), _in(TACTIC))) -*) -external tactic_when : context -> probe -> tactic -> tactic - = "camlidl_z3_Z3_tactic_when" - -(** - Summary: Return a tactic that applies [t1] to a given goal if the probe [p] evaluates to true, - and [t2] if [p] evaluates to false. - def_API('tactic_cond', TACTIC, (_in(CONTEXT), _in(PROBE), _in(TACTIC), _in(TACTIC))) -*) -external tactic_cond : context -> probe -> tactic -> tactic -> tactic - = "camlidl_z3_Z3_tactic_cond" - -(** - Summary: Return a tactic that keeps applying [t] until the goal is not modified anymore or the maximum - number of iterations [max] is reached. - def_API('tactic_repeat', TACTIC, (_in(CONTEXT), _in(TACTIC), _in(UINT))) -*) -external tactic_repeat : context -> tactic -> int -> tactic - = "camlidl_z3_Z3_tactic_repeat" - -(** - Summary: Return a tactic that just return the given goal. - def_API('tactic_skip', TACTIC, (_in(CONTEXT),)) -*) -external tactic_skip : context -> tactic - = "camlidl_z3_Z3_tactic_skip" - -(** - Summary: Return a tactic that always fails. - def_API('tactic_fail', TACTIC, (_in(CONTEXT),)) -*) -external tactic_fail : context -> tactic - = "camlidl_z3_Z3_tactic_fail" - -(** - Summary: Return a tactic that fails if the probe [p] evaluates to false. - def_API('tactic_fail_if', TACTIC, (_in(CONTEXT), _in(PROBE))) -*) -external tactic_fail_if : context -> probe -> tactic - = "camlidl_z3_Z3_tactic_fail_if" - -(** - Summary: Return a tactic that fails if the goal is not trivially satisfiable (i.e., empty) or - trivially unsatisfiable (i.e., contains false). - def_API('tactic_fail_if_not_decided', TACTIC, (_in(CONTEXT),)) -*) -external tactic_fail_if_not_decided : context -> tactic - = "camlidl_z3_Z3_tactic_fail_if_not_decided" - -(** - Summary: Return a tactic that applies [t] using the given set of parameters. - def_API('tactic_using_params', TACTIC, (_in(CONTEXT), _in(TACTIC), _in(PARAMS))) -*) -external tactic_using_params : context -> tactic -> params -> tactic - = "camlidl_z3_Z3_tactic_using_params" - -(** - Summary: Return a probe that always evaluates to val. - def_API('probe_const', PROBE, (_in(CONTEXT), _in(DOUBLE))) -*) -external probe_const : context -> float -> probe - = "camlidl_z3_Z3_probe_const" - -(** - Summary: Return a probe that evaluates to "true" when the value returned by [p1] is less than the value returned by [p2]. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_lt', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_lt : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_lt" - -(** - Summary: Return a probe that evaluates to "true" when the value returned by [p1] is greater than the value returned by [p2]. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_gt', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_gt : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_gt" - -(** - Summary: Return a probe that evaluates to "true" when the value returned by [p1] is less than or equal to the value returned by [p2]. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_le', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_le : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_le" - -(** - Summary: Return a probe that evaluates to "true" when the value returned by [p1] is greater than or equal to the value returned by [p2]. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_ge', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_ge : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_ge" - -(** - Summary: Return a probe that evaluates to "true" when the value returned by [p1] is equal to the value returned by [p2]. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_eq', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_eq : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_eq" - -(** - Summary: Return a probe that evaluates to "true" when [p1] and [p2] evaluates to true. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_and', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_and : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_and" - -(** - Summary: Return a probe that evaluates to "true" when [p1] or [p2] evaluates to true. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_or', PROBE, (_in(CONTEXT), _in(PROBE), _in(PROBE))) -*) -external probe_or : context -> probe -> probe -> probe - = "camlidl_z3_Z3_probe_or" - -(** - Summary: Return a probe that evaluates to "true" when [p] does not evaluate to true. - - {b Remarks}: For probes, "true" is any value different from 0.0. - def_API('probe_not', PROBE, (_in(CONTEXT), _in(PROBE))) -*) -external probe_not : context -> probe -> probe - = "camlidl_z3_Z3_probe_not" - -(** - Summary: Return the number of builtin tactics available in Z3. - def_API('get_num_tactics', UINT, (_in(CONTEXT),)) -*) -external get_num_tactics : context -> int - = "camlidl_z3_Z3_get_num_tactics" - -(** - Summary: Return the name of the idx tactic. - - {b Precondition}: i < get_num_tactics c - def_API('get_tactic_name', STRING, (_in(CONTEXT), _in(UINT))) -*) -external get_tactic_name : context -> int -> string - = "camlidl_z3_Z3_get_tactic_name" - -(** - Summary: Return the number of builtin probes available in Z3. - def_API('get_num_probes', UINT, (_in(CONTEXT),)) -*) -external get_num_probes : context -> int - = "camlidl_z3_Z3_get_num_probes" - -(** - Summary: Return the name of the i probe. - - {b Precondition}: i < get_num_probes c - def_API('get_probe_name', STRING, (_in(CONTEXT), _in(UINT))) -*) -external get_probe_name : context -> int -> string - = "camlidl_z3_Z3_get_probe_name" - -(** - Summary: Return a string containing a description of parameters accepted by the given tactic. - def_API('tactic_get_help', STRING, (_in(CONTEXT), _in(TACTIC))) -*) -external tactic_get_help : context -> tactic -> string - = "camlidl_z3_Z3_tactic_get_help" - -(** - Summary: Return the parameter description set for the given tactic object. - def_API('tactic_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(TACTIC))) -*) -external tactic_get_param_descrs : context -> tactic -> param_descrs - = "camlidl_z3_Z3_tactic_get_param_descrs" - -(** - Summary: Return a string containing a description of the tactic with the given name. - def_API('tactic_get_descr', STRING, (_in(CONTEXT), _in(STRING))) -*) -external tactic_get_descr : context -> string -> string - = "camlidl_z3_Z3_tactic_get_descr" - -(** - Summary: Return a string containing a description of the probe with the given name. - def_API('probe_get_descr', STRING, (_in(CONTEXT), _in(STRING))) -*) -external probe_get_descr : context -> string -> string - = "camlidl_z3_Z3_probe_get_descr" - -(** - Summary: Execute the probe over the goal. The probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - def_API('probe_apply', DOUBLE, (_in(CONTEXT), _in(PROBE), _in(GOAL))) -*) -external probe_apply : context -> probe -> goal -> float - = "camlidl_z3_Z3_probe_apply" - -(** - Summary: Apply tactic [t] to the goal [g]. - def_API('tactic_apply', APPLY_RESULT, (_in(CONTEXT), _in(TACTIC), _in(GOAL))) -*) -external tactic_apply : context -> tactic -> goal -> apply_result - = "camlidl_z3_Z3_tactic_apply" - -(** - Summary: Apply tactic [t] to the goal [g] using the parameter set [p]. - def_API('tactic_apply_ex', APPLY_RESULT, (_in(CONTEXT), _in(TACTIC), _in(GOAL), _in(PARAMS))) -*) -external tactic_apply_ex : context -> tactic -> goal -> params -> apply_result - = "camlidl_z3_Z3_tactic_apply_ex" - -(** - Summary: Convert the [apply_result] object returned by {!tactic_apply} into a string. - def_API('apply_result_to_string', STRING, (_in(CONTEXT), _in(APPLY_RESULT))) -*) -external apply_result_to_string : context -> apply_result -> string - = "camlidl_z3_Z3_apply_result_to_string" - -(** - Summary: Return the number of subgoals in the [apply_result] object returned by {!tactic_apply}. - def_API('apply_result_get_num_subgoals', UINT, (_in(CONTEXT), _in(APPLY_RESULT))) -*) -external apply_result_get_num_subgoals : context -> apply_result -> int - = "camlidl_z3_Z3_apply_result_get_num_subgoals" - -(** - Summary: Return one of the subgoals in the [apply_result] object returned by {!tactic_apply}. - - {b Precondition}: i < apply_result_get_num_subgoals c r - def_API('apply_result_get_subgoal', GOAL, (_in(CONTEXT), _in(APPLY_RESULT), _in(UINT))) -*) -external apply_result_get_subgoal : context -> apply_result -> int -> goal - = "camlidl_z3_Z3_apply_result_get_subgoal" - -(** - Summary: Convert a model for the subgoal [apply_result_get_subgoal(c], r, i) into a model for the original goal [g]. - Where [g] is the goal used to create [r] using [tactic_apply(c], t, g). - def_API('apply_result_convert_model', MODEL, (_in(CONTEXT), _in(APPLY_RESULT), _in(UINT), _in(MODEL))) -*) -external apply_result_convert_model : context -> apply_result -> int -> model -> model - = "camlidl_z3_Z3_apply_result_convert_model" - -(** - {2 {L Solvers}} -*) -(** - Summary: Create a new (incremental) solver. This solver also uses a - set of builtin tactics for handling the first check-sat command, and - check-sat commands that take more than a given number of milliseconds to be solved. - def_API('mk_solver', SOLVER, (_in(CONTEXT),)) -*) -external mk_solver : context -> solver - = "camlidl_z3_Z3_mk_solver" - -(** - Summary: Create a new (incremental) solver. - def_API('mk_simple_solver', SOLVER, (_in(CONTEXT),)) -*) -external mk_simple_solver : context -> solver - = "camlidl_z3_Z3_mk_simple_solver" - -(** - Summary: Create a new solver customized for the given logic. - It behaves like {!mk_solver} if the logic is unknown or unsupported. - def_API('mk_solver_for_logic', SOLVER, (_in(CONTEXT), _in(SYMBOL))) -*) -external mk_solver_for_logic : context -> symbol -> solver - = "camlidl_z3_Z3_mk_solver_for_logic" - -(** - Summary: Create a new solver that is implemented using the given tactic. - The solver supports the commands {!solver_push} and {!solver_pop}, but it - will always solve each {!solver_check} from scratch. - def_API('mk_solver_from_tactic', SOLVER, (_in(CONTEXT), _in(TACTIC))) -*) -external mk_solver_from_tactic : context -> tactic -> solver - = "camlidl_z3_Z3_mk_solver_from_tactic" - -(** - Summary: Return a string describing all solver available parameters. - def_API('solver_get_help', STRING, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_help : context -> solver -> string - = "camlidl_z3_Z3_solver_get_help" - -(** - Summary: Return the parameter description set for the given solver object. - def_API('solver_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_param_descrs : context -> solver -> param_descrs - = "camlidl_z3_Z3_solver_get_param_descrs" - -(** - Summary: Set the given solver using the given parameters. - def_API('solver_set_params', VOID, (_in(CONTEXT), _in(SOLVER), _in(PARAMS))) -*) -external solver_set_params : context -> solver -> params -> unit - = "camlidl_z3_Z3_solver_set_params" - -(** - Summary: Create a backtracking point. - The solver contains a stack of assertions. - - {b See also}: {!solver_pop} - def_API('solver_push', VOID, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_push : context -> solver -> unit - = "camlidl_z3_Z3_solver_push" - -(** - Summary: Backtrack [n] backtracking points. - - {b See also}: {!solver_push} - - {b Precondition}: n <= solver_get_num_scopes c s - def_API('solver_pop', VOID, (_in(CONTEXT), _in(SOLVER), _in(UINT))) -*) -external solver_pop : context -> solver -> int -> unit - = "camlidl_z3_Z3_solver_pop" - -(** - Summary: Remove all assertions from the solver. - def_API('solver_reset', VOID, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_reset : context -> solver -> unit - = "camlidl_z3_Z3_solver_reset" - -(** - Summary: Return the number of backtracking points. - - {b See also}: {!solver_push} - - {b See also}: {!solver_pop} - def_API('solver_get_num_scopes', UINT, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_num_scopes : context -> solver -> int - = "camlidl_z3_Z3_solver_get_num_scopes" - -(** - Summary: Assert a constraint into the solver. - The functions {!solver_check} and {!solver_check_assumptions} should be - used to check whether the logical context is consistent or not. - def_API('solver_assert', VOID, (_in(CONTEXT), _in(SOLVER), _in(AST))) -*) -external solver_assert : context -> solver -> ast -> unit - = "camlidl_z3_Z3_solver_assert" - -(** - Summary: Assert a constraint [a] into the solver, and track it (in the unsat) core using - the Boolean constant [p]. - This API is an alternative to {!solver_check_assumptions} for extracting unsat cores. - Both APIs can be used in the same solver. The unsat core will contain a combination - of the Boolean variables provided using solver_assert_and_track and the Boolean literals - provided using {!solver_check_assumptions}. - - {b Precondition}: [a] must be a Boolean expression - - {b Precondition}: [p] must be a Boolean constant aka variable. - def_API('solver_assert_and_track', VOID, (_in(CONTEXT), _in(SOLVER), _in(AST), _in(AST))) -*) -external solver_assert_and_track : context -> solver -> ast -> ast -> unit - = "camlidl_z3_Z3_solver_assert_and_track" - -(** - Summary: Return the set of asserted formulas as a goal object. - def_API('solver_get_assertions', AST_VECTOR, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_assertions : context -> solver -> ast_vector - = "camlidl_z3_Z3_solver_get_assertions" - -(** - Summary: Check whether the assertions in a given solver are consistent or not. - The function {!solver_get_model} retrieves a model if the - assertions are not unsatisfiable (i.e., the result is not \c - L_FALSE) and model construction is enabled. - The function {!solver_get_proof} retrieves a proof if proof - generation was enabled when the context was created, and the - assertions are unsatisfiable (i.e., the result is [L_FALSE)]. - def_API('solver_check', INT, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_check : context -> solver -> lbool - = "camlidl_z3_Z3_solver_check" - -(** - Summary: Check whether the assertions in the given solver and - optional assumptions are consistent or not. - The function {!solver_get_unsat_core} retrieves the subset of the - assumptions used in the unsatisfiability proof produced by Z3. - - {b See also}: {!solver_check} - def_API('solver_check_assumptions', INT, (_in(CONTEXT), _in(SOLVER), _in(UINT), _in_array(2, AST))) -*) -external solver_check_assumptions : context -> solver -> ast array -> lbool - = "camlidl_z3_Z3_solver_check_assumptions" - -(** - Summary: Retrieve the model for the last {!solver_check} or {!solver_check_assumptions} - The error handler is invoked if a model is not available because - the commands above were not invoked for the given solver, or if the result was [L_FALSE]. - def_API('solver_get_model', MODEL, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_model : context -> solver -> model - = "camlidl_z3_Z3_solver_get_model" - -(** - Summary: Retrieve the proof for the last {!solver_check} or {!solver_check_assumptions} - The error handler is invoked if proof generation is not enabled, - or if the commands above were not invoked for the given solver, - or if the result was different from [L_FALSE]. - def_API('solver_get_proof', AST, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_proof : context -> solver -> ast - = "camlidl_z3_Z3_solver_get_proof" - -(** - Summary: Retrieve the unsat core for the last {!solver_check_assumptions} - The unsat core is a subset of the assumptions [a]. - def_API('solver_get_unsat_core', AST_VECTOR, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_unsat_core : context -> solver -> ast_vector - = "camlidl_z3_Z3_solver_get_unsat_core" - -(** - Summary: Return a brief justification for an "unknown" result (i.e., L_UNDEF) for - the commands {!solver_check} and {!solver_check_assumptions} - def_API('solver_get_reason_unknown', STRING, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_reason_unknown : context -> solver -> string - = "camlidl_z3_Z3_solver_get_reason_unknown" - -(** - Summary: Return statistics for the given solver. - def_API('solver_get_statistics', STATS, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_get_statistics : context -> solver -> stats - = "camlidl_z3_Z3_solver_get_statistics" - -(** - Summary: Convert a solver into a string. - def_API('solver_to_string', STRING, (_in(CONTEXT), _in(SOLVER))) -*) -external solver_to_string : context -> solver -> string - = "camlidl_z3_Z3_solver_to_string" - -(** - {2 {L Statistics}} -*) - -type stat_datum = Stat_int of int | Stat_float of float -type stats_refined = (string, stat_datum) Hashtbl.t - - -(** - Summary: [stats_refine c s] is the refined stats of [s]. -*) -val stats_refine : context -> stats -> stats_refined - -(** - Summary: Convert a statistics into a string. - def_API('stats_to_string', STRING, (_in(CONTEXT), _in(STATS))) -*) -external stats_to_string : context -> stats -> string - = "camlidl_z3_Z3_stats_to_string" - -(** - {4 {L Low-level API}} -*) -(** - Summary: Return the number of statistical data in [s]. - def_API('stats_size', UINT, (_in(CONTEXT), _in(STATS))) -*) -external stats_size : context -> stats -> int - = "camlidl_z3_Z3_stats_size" - -(** - Summary: Return the key (a string) for a particular statistical data. - - {b Precondition}: idx < stats_size c s - def_API('stats_get_key', STRING, (_in(CONTEXT), _in(STATS), _in(UINT))) -*) -external stats_get_key : context -> stats -> int -> string - = "camlidl_z3_Z3_stats_get_key" - -(** - Summary: Return TRUE if the given statistical data is a unsigned int integer. - - {b Precondition}: idx < stats_size c s - def_API('stats_is_uint', BOOL, (_in(CONTEXT), _in(STATS), _in(UINT))) -*) -external stats_is_uint : context -> stats -> int -> bool - = "camlidl_z3_Z3_stats_is_uint" - -(** - Summary: Return TRUE if the given statistical data is a double. - - {b Precondition}: idx < stats_size c s - def_API('stats_is_double', BOOL, (_in(CONTEXT), _in(STATS), _in(UINT))) -*) -external stats_is_double : context -> stats -> int -> bool - = "camlidl_z3_Z3_stats_is_double" - -(** - Summary: Return the unsigned int value of the given statistical data. - - {b Precondition}: idx < stats_size c s && stats_is_uint c s - def_API('stats_get_uint_value', UINT, (_in(CONTEXT), _in(STATS), _in(UINT))) -*) -external stats_get_uint_value : context -> stats -> int -> int - = "camlidl_z3_Z3_stats_get_uint_value" - -(** - Summary: Return the double value of the given statistical data. - - {b Precondition}: idx < stats_size c s && stats_is_double c s - def_API('stats_get_double_value', DOUBLE, (_in(CONTEXT), _in(STATS), _in(UINT))) -*) -external stats_get_double_value : context -> stats -> int -> float - = "camlidl_z3_Z3_stats_get_double_value" - -(** - {2 {L Deprecated Constraints API}} -*) -(** - Summary: Retrieve congruence class representatives for terms. - The function can be used for relying on Z3 to identify equal terms under the current - set of assumptions. The array of terms and array of class identifiers should have - the same length. The class identifiers are numerals that are assigned to the same - value for their corresponding terms if the current context forces the terms to be - equal. You cannot deduce that terms corresponding to different numerals must be all different, - (especially when using non-convex theories). - All implied equalities are returned by this call. - This means that two terms map to the same class identifier if and only if - the current context implies that they are equal. - A side-effect of the function is a satisfiability check on the assertions on the solver that is passed in. - The function return L_FALSE if the current assertions are not satisfiable. - - {b See also}: {!check_and_get_model} - - {b See also}: {!check} - @deprecated To be moved outside of API. - def_API('get_implied_equalities', UINT, (_in(CONTEXT), _in(SOLVER), _in(UINT), _in_array(2, AST), _out_array(2, UINT))) -*) -external get_implied_equalities : context -> solver -> ast array -> lbool * int array - = "camlidl_z3_Z3_get_implied_equalities" - - -(** - {2 {L Legacy V3 API}} -*) -module V3 : sig -(** - {2 {L Legacy V3 API}} -*) - -(* File generated from z3V3.idl *) - -type symbol -and literals -and theory -and config -and context -and sort -and func_decl -and ast -and app -and pattern -and model -and constructor -and constructor_list - -and lbool = - | L_FALSE - | L_UNDEF - | L_TRUE - -and symbol_kind = - | INT_SYMBOL - | STRING_SYMBOL - -and parameter_kind = - | PARAMETER_INT - | PARAMETER_DOUBLE - | PARAMETER_RATIONAL - | PARAMETER_SYMBOL - | PARAMETER_SORT - | PARAMETER_AST - | PARAMETER_FUNC_DECL - -and sort_kind = - | UNINTERPRETED_SORT - | BOOL_SORT - | INT_SORT - | REAL_SORT - | BV_SORT - | ARRAY_SORT - | DATATYPE_SORT - | RELATION_SORT - | FINITE_DOMAIN_SORT - | UNKNOWN_SORT - -and ast_kind = - | NUMERAL_AST - | APP_AST - | VAR_AST - | QUANTIFIER_AST - | SORT_AST - | FUNC_DECL_AST - | UNKNOWN_AST - -and decl_kind = - | OP_TRUE - | OP_FALSE - | OP_EQ - | OP_DISTINCT - | OP_ITE - | OP_AND - | OP_OR - | OP_IFF - | OP_XOR - | OP_NOT - | OP_IMPLIES - | OP_OEQ - | OP_ANUM - | OP_AGNUM - | OP_LE - | OP_GE - | OP_LT - | OP_GT - | OP_ADD - | OP_SUB - | OP_UMINUS - | OP_MUL - | OP_DIV - | OP_IDIV - | OP_REM - | OP_MOD - | OP_TO_REAL - | OP_TO_INT - | OP_IS_INT - | OP_POWER - | OP_STORE - | OP_SELECT - | OP_CONST_ARRAY - | OP_ARRAY_MAP - | OP_ARRAY_DEFAULT - | OP_SET_UNION - | OP_SET_INTERSECT - | OP_SET_DIFFERENCE - | OP_SET_COMPLEMENT - | OP_SET_SUBSET - | OP_AS_ARRAY - | OP_BNUM - | OP_BIT1 - | OP_BIT0 - | OP_BNEG - | OP_BADD - | OP_BSUB - | OP_BMUL - | OP_BSDIV - | OP_BUDIV - | OP_BSREM - | OP_BUREM - | OP_BSMOD - | OP_BSDIV0 - | OP_BUDIV0 - | OP_BSREM0 - | OP_BUREM0 - | OP_BSMOD0 - | OP_ULEQ - | OP_SLEQ - | OP_UGEQ - | OP_SGEQ - | OP_ULT - | OP_SLT - | OP_UGT - | OP_SGT - | OP_BAND - | OP_BOR - | OP_BNOT - | OP_BXOR - | OP_BNAND - | OP_BNOR - | OP_BXNOR - | OP_CONCAT - | OP_SIGN_EXT - | OP_ZERO_EXT - | OP_EXTRACT - | OP_REPEAT - | OP_BREDOR - | OP_BREDAND - | OP_BCOMP - | OP_BSHL - | OP_BLSHR - | OP_BASHR - | OP_ROTATE_LEFT - | OP_ROTATE_RIGHT - | OP_EXT_ROTATE_LEFT - | OP_EXT_ROTATE_RIGHT - | OP_INT2BV - | OP_BV2INT - | OP_CARRY - | OP_XOR3 - | OP_PR_UNDEF - | OP_PR_TRUE - | OP_PR_ASSERTED - | OP_PR_GOAL - | OP_PR_MODUS_PONENS - | OP_PR_REFLEXIVITY - | OP_PR_SYMMETRY - | OP_PR_TRANSITIVITY - | OP_PR_TRANSITIVITY_STAR - | OP_PR_MONOTONICITY - | OP_PR_QUANT_INTRO - | OP_PR_DISTRIBUTIVITY - | OP_PR_AND_ELIM - | OP_PR_NOT_OR_ELIM - | OP_PR_REWRITE - | OP_PR_REWRITE_STAR - | OP_PR_PULL_QUANT - | OP_PR_PULL_QUANT_STAR - | OP_PR_PUSH_QUANT - | OP_PR_ELIM_UNUSED_VARS - | OP_PR_DER - | OP_PR_QUANT_INST - | OP_PR_HYPOTHESIS - | OP_PR_LEMMA - | OP_PR_UNIT_RESOLUTION - | OP_PR_IFF_TRUE - | OP_PR_IFF_FALSE - | OP_PR_COMMUTATIVITY - | OP_PR_DEF_AXIOM - | OP_PR_DEF_INTRO - | OP_PR_APPLY_DEF - | OP_PR_IFF_OEQ - | OP_PR_NNF_POS - | OP_PR_NNF_NEG - | OP_PR_NNF_STAR - | OP_PR_CNF_STAR - | OP_PR_SKOLEMIZE - | OP_PR_MODUS_PONENS_OEQ - | OP_PR_TH_LEMMA - | OP_PR_HYPER_RESOLVE - | OP_RA_STORE - | OP_RA_EMPTY - | OP_RA_IS_EMPTY - | OP_RA_JOIN - | OP_RA_UNION - | OP_RA_WIDEN - | OP_RA_PROJECT - | OP_RA_FILTER - | OP_RA_NEGATION_FILTER - | OP_RA_RENAME - | OP_RA_COMPLEMENT - | OP_RA_SELECT - | OP_RA_CLONE - | OP_FD_LT - | OP_LABEL - | OP_LABEL_LIT - | OP_DT_CONSTRUCTOR - | OP_DT_RECOGNISER - | OP_DT_ACCESSOR - | OP_UNINTERPRETED - -and param_kind = - | PK_UINT - | PK_BOOL - | PK_DOUBLE - | PK_SYMBOL - | PK_STRING - | PK_OTHER - | PK_INVALID - -and search_failure = - | NO_FAILURE - | UNKNOWN - | TIMEOUT - | MEMOUT_WATERMARK - | CANCELED - | NUM_CONFLICTS - | THEORY - | QUANTIFIERS - -and ast_print_mode = - | PRINT_SMTLIB_FULL - | PRINT_LOW_LEVEL - | PRINT_SMTLIB_COMPLIANT - | PRINT_SMTLIB2_COMPLIANT - - -(** -*) -(** - {2 {L Types}} - Most of the types in the API are abstract. - - [context]: manager of all other Z3 objects, global configuration options, etc. - - [symbol]: Lisp-like symbol used to name types, constants, and functions. A symbol can be created using string or integers. - - [ast]: abstract syntax tree node. That is, the data-structure used in Z3 to represent terms, formulas and types. - - [sort]: kind of AST used to represent types. - - [func_decl]: kind of AST used to represent function symbols. - - [app]: kind of AST used to represent function applications. - - [pattern]: kind of AST used to represent pattern and multi-patterns used to guide quantifier instantiation. - - [params]: parameter set used to configure many components such as: simplifiers, tactics, solvers, etc. - - [model]: model for the constraints asserted into the logical context. - - [func_interp]: interpretation of a function in a model. - - [func_entry]: representation of the value of a [func_interp] at a particular point. - - [fixedpoint]: context for the recursive predicate solver. - - [ast_vector]: vector of [ast] objects. - - [ast_map]: mapping from [ast] to [ast] objects. - - [goal]: set of formulas that can be solved and/or transformed using tactics and solvers. - - [tactic]: basic building block for creating custom solvers for specific problem domains. - - [probe]: function/predicate used to inspect a goal and collect information that may be used to decide which solver and/or preprocessing step will be used. - - [apply_result]: collection of subgoals resulting from applying of a tactic to a goal. - - [solver]: (incremental) solver, possibly specialized by a particular tactic or logic. - - [stats]: statistical data for a solver. -*) -(** - {!lbool} - Lifted Boolean type: [false], [undefined], [true]. -*) -(** - {!symbol_kind} - The different kinds of symbol. - In Z3, a symbol can be represented using integers and strings (See {!get_symbol_kind}). - - {b See also}: {!mk_int_symbol} - - {b See also}: {!mk_string_symbol} -*) -(** - {!parameter_kind} - The different kinds of parameters that can be associated with function symbols. - - {b See also}: {!get_decl_num_parameters} - - {b See also}: {!get_decl_parameter_kind} - - PARAMETER_INT is used for integer parameters. - - PARAMETER_DOUBLE is used for double parameters. - - PARAMETER_RATIONAL is used for parameters that are rational numbers. - - PARAMETER_SYMBOL is used for parameters that are symbols. - - PARAMETER_SORT is used for sort parameters. - - PARAMETER_AST is used for expression parameters. - - PARAMETER_FUNC_DECL is used for function declaration parameters. -*) -(** - {!sort_kind} - The different kinds of Z3 types (See {!get_sort_kind}). -*) -(** - {!ast_kind} - The different kinds of Z3 AST (abstract syntax trees). That is, terms, formulas and types. - - - APP_AST: constant and applications - - NUMERAL_AST: numeral constants - - VAR_AST: bound variables - - QUANTIFIER_AST: quantifiers - - SORT_AST: sort - - FUNC_DECL_AST: function declaration - - UNKNOWN_AST: internal -*) -(** - {!decl_kind} - The different kinds of interpreted function kinds. - - - OP_TRUE The constant true. - - - OP_FALSE The constant false. - - - OP_EQ The equality predicate. - - - OP_DISTINCT The n-ary distinct predicate (every argument is mutually distinct). - - - OP_ITE The ternary if-then-else term. - - - OP_AND n-ary conjunction. - - - OP_OR n-ary disjunction. - - - OP_IFF equivalence (binary). - - - OP_XOR Exclusive or. - - - OP_NOT Negation. - - - OP_IMPLIES Implication. - - - OP_OEQ Binary equivalence modulo namings. This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. - - - OP_ANUM Arithmetic numeral. - - - OP_AGNUM Arithmetic algebraic numeral. Algebraic numbers are used to represent irrational numbers in Z3. - - - OP_LE <=. - - - OP_GE >=. - - - OP_LT <. - - - OP_GT >. - - - OP_ADD Addition - Binary. - - - OP_SUB Binary subtraction. - - - OP_UMINUS Unary minus. - - - OP_MUL Multiplication - Binary. - - - OP_DIV Division - Binary. - - - OP_IDIV Integer division - Binary. - - - OP_REM Remainder - Binary. - - - OP_MOD Modulus - Binary. - - - OP_TO_REAL Coercion of integer to real - Unary. - - - OP_TO_INT Coercion of real to integer - Unary. - - - OP_IS_INT Check if real is also an integer - Unary. - - - OP_POWER Power operator x^y. - - - OP_STORE Array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. - - - OP_SELECT Array select. - - - OP_CONST_ARRAY The constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary. - - - OP_ARRAY_DEFAULT Default value of arrays. For example default(const(v)) = v. The function is unary. - - - OP_ARRAY_MAP Array map operator. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. - - - OP_SET_UNION Set union between two Booelan arrays (two arrays whose range type is Boolean). The function is binary. - - - OP_SET_INTERSECT Set intersection between two Boolean arrays. The function is binary. - - - OP_SET_DIFFERENCE Set difference between two Boolean arrays. The function is binary. - - - OP_SET_COMPLEMENT Set complement of a Boolean array. The function is unary. - - - OP_SET_SUBSET Subset predicate between two Boolean arrays. The relation is binary. - - - OP_AS_ARRAY An array value that behaves as the function graph of the - function passed as parameter. - - - OP_BNUM Bit-vector numeral. - - - OP_BIT1 One bit bit-vector. - - - OP_BIT0 Zero bit bit-vector. - - - OP_BNEG Unary minus. - - - OP_BADD Binary addition. - - - OP_BSUB Binary subtraction. - - - OP_BMUL Binary multiplication. - - - OP_BSDIV Binary signed division. - - - OP_BUDIV Binary unsigned int division. - - - OP_BSREM Binary signed remainder. - - - OP_BUREM Binary unsigned int remainder. - - - OP_BSMOD Binary signed modulus. - - - OP_BSDIV0 Unary function. bsdiv(x,0) is congruent to bsdiv0(x). - - - OP_BUDIV0 Unary function. budiv(x,0) is congruent to budiv0(x). - - - OP_BSREM0 Unary function. bsrem(x,0) is congruent to bsrem0(x). - - - OP_BUREM0 Unary function. burem(x,0) is congruent to burem0(x). - - - OP_BSMOD0 Unary function. bsmod(x,0) is congruent to bsmod0(x). - - - OP_ULEQ Unsigned bit-vector <= - Binary relation. - - - OP_SLEQ Signed bit-vector <= - Binary relation. - - - OP_UGEQ Unsigned bit-vector >= - Binary relation. - - - OP_SGEQ Signed bit-vector >= - Binary relation. - - - OP_ULT Unsigned bit-vector < - Binary relation. - - - OP_SLT Signed bit-vector < - Binary relation. - - - OP_UGT Unsigned bit-vector > - Binary relation. - - - OP_SGT Signed bit-vector > - Binary relation. - - - OP_BAND Bit-wise and - Binary. - - - OP_BOR Bit-wise or - Binary. - - - OP_BNOT Bit-wise not - Unary. - - - OP_BXOR Bit-wise xor - Binary. - - - OP_BNAND Bit-wise nand - Binary. - - - OP_BNOR Bit-wise nor - Binary. - - - OP_BXNOR Bit-wise xnor - Binary. - - - OP_CONCAT Bit-vector concatenation - Binary. - - - OP_SIGN_EXT Bit-vector sign extension. - - - OP_ZERO_EXT Bit-vector zero extension. - - - OP_EXTRACT Bit-vector extraction. - - - OP_REPEAT Repeat bit-vector n times. - - - OP_BREDOR Bit-vector reduce or - Unary. - - - OP_BREDAND Bit-vector reduce and - Unary. - - - OP_BCOMP . - - - OP_BSHL Shift left. - - - OP_BLSHR Logical shift right. - - - OP_BASHR Arithmetical shift right. - - - OP_ROTATE_LEFT Left rotation. - - - OP_ROTATE_RIGHT Right rotation. - - - OP_EXT_ROTATE_LEFT (extended) Left rotation. Similar to OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. - - - OP_EXT_ROTATE_RIGHT (extended) Right rotation. Similar to OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. - - - OP_INT2BV Coerce integer to bit-vector. NB. This function - is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - - - OP_BV2INT Coerce bit-vector to integer. NB. This function - is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - - - OP_CARRY Compute the carry bit in a full-adder. - The meaning is given by the equivalence - (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) - - - OP_XOR3 Compute ternary XOR. - The meaning is given by the equivalence - (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) - - - OP_PR_UNDEF: Undef/Null proof object. - - - OP_PR_TRUE: Proof for the expression 'true'. - - - OP_PR_ASSERTED: Proof for a fact asserted by the user. - - - OP_PR_GOAL: Proof for a fact (tagged as goal) asserted by the user. - - - OP_PR_MODUS_PONENS: Given a proof for p and a proof for (implies p q), produces a proof for q. - {e - T1: p - T2: (implies p q) - [mp T1 T2]: q - } - The second antecedents may also be a proof for (iff p q). - - - OP_PR_REFLEXIVITY: A proof for (R t t), where R is a reflexive relation. This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. - - - OP_PR_SYMMETRY: Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - {e - T1: (R t s) - [symmetry T1]: (R s t) - } - T1 is the antecedent of this proof object. - - - OP_PR_TRANSITIVITY: Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - {e - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) - } - - - OP_PR_TRANSITIVITY_STAR: Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - - Example: - {e - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - } - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. - - - OP_PR_MONOTONICITY: Monotonicity proof object. - {e - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - } - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. - - - OP_PR_QUANT_INTRO: Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - - - OP_PR_DISTRIBUTIVITY: Distributivity proof object. - Given that f (= or) distributes over g (= and), produces a proof for - - (= (f a (g c d)) - (g (f a c) (f a d))) - - If f and g are associative, this proof also justifies the following equality: - - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. - - - OP_PR_AND_ELIM: Given a proof for (and l_1 ... l_n), produces a proof for l_i - - {e - T1: (and l_1 ... l_n) - [and-elim T1]: l_i - } - - OP_PR_NOT_OR_ELIM: Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - - {e - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) - } - - - OP_PR_REWRITE: A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - - Examples: - {e - (= (+ x 0) x) - (= (+ x 1 2) (+ 3 x)) - (iff (or x false) x) - } - - - OP_PR_REWRITE_STAR: A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - - - OP_PR_PULL_QUANT: A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - - - OP_PR_PULL_QUANT_STAR: A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents. - - - OP_PR_PUSH_QUANT: A proof for: - - {e - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - } - This proof object has no antecedents. - - - OP_PR_ELIM_UNUSED_VARS: - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. - - - OP_PR_DER: A proof for destructive equality resolution: - (iff (forall (x) (or (not (= x t)) P[x])) P[t]) - if x does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. - - - OP_PR_QUANT_INST: A proof of (or (not (forall (x) (P x))) (P a)) - - - OP_PR_HYPOTHESIS: Mark a hypothesis in a natural deduction style proof. - - - OP_PR_LEMMA: - - {e - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - } - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. - - - OP_PR_UNIT_RESOLUTION: - {e - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - } - - - OP_PR_IFF_TRUE: - {e - T1: p - [iff-true T1]: (iff p true) - } - - - OP_PR_IFF_FALSE: - {e - T1: (not p) - [iff-false T1]: (iff p false) - } - - - OP_PR_COMMUTATIVITY: - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. - - - OP_PR_DEF_AXIOM: Proof object used to justify Tseitin's like axioms: - - {e - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - } - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). - - - OP_PR_DEF_INTRO: Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) - - - OP_PR_APPLY_DEF: - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. - - - OP_PR_IFF_OEQ: - T1: (iff p q) - [iff~ T1]: (~ p q) - - - OP_PR_NNF_POS: Proof for a (positive) NNF step. Example: - {e - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - } - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - {e - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - } - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. - - - - OP_PR_NFF_NEG: Proof for a (negative) NNF step. Examples: - {e - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) - } - - OP_PR_NNF_STAR: A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - - - OP_PR_CNF_STAR: A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - - - OP_PR_SKOLEMIZE: Proof for: - - {e - [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y))) - [sk]: (~ (exists x (p x y)) (p (sk y) y)) - } - - This proof object has no antecedents. - - - OP_PR_MODUS_PONENS_OEQ: Modus ponens style rule for equi-satisfiability. - {e - T1: p - T2: (~ p q) - [mp~ T1 T2]: q - } - - - OP_PR_TH_LEMMA: Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - - triangle-eq - Indicates a lemma related to the equivalence: - {e - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - } - - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - - - - OP_PR_HYPER_RESOLVE: Hyper-resolution rule. - - The premises of the rules is a sequence of clauses. - The first clause argument is the main clause of the rule. - One literal from the second, third, .. clause is resolved - with a literal from the first (main) clause. - - Premises of the rules are of the form - {e - (or l0 l1 l2 .. ln) - } - or - {e - (=> (and ln+1 ln+2 .. ln+m) l0) - } - or in the most general (ground) form: - {e - (=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln-1)) - } - In other words we use the following (Prolog style) convention for Horn - implications: - The head of a Horn implication is position 0, - the first conjunct in the body of an implication is position 1 - the second conjunct in the body of an implication is position 2 - - For general implications where the head is a disjunction, the - first n positions correspond to the n disjuncts in the head. - The next m positions correspond to the m conjuncts in the body. - - The premises can be universally quantified so that the most - general non-ground form is: - - {e - (forall (vars) (=> (and ln+1 ln+2 .. ln+m) (or l0 l1 .. ln-1))) - } - - The hyper-resolution rule takes a sequence of parameters. - The parameters are substitutions of bound variables separated by pairs - of literal positions from the main clause and side clause. - - - - OP_RA_STORE: Insert a record into a relation. - The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements - correspond to the [n] columns of the relation. - - - OP_RA_EMPTY: Creates the empty relation. - - - OP_RA_IS_EMPTY: Tests if the relation is empty. - - - OP_RA_JOIN: Create the relational join. - - - OP_RA_UNION: Create the union or convex hull of two relations. - The function takes two arguments. - - - OP_RA_WIDEN: Widen two relations. - The function takes two arguments. - - - OP_RA_PROJECT: Project the columns (provided as numbers in the parameters). - The function takes one argument. - - - OP_RA_FILTER: Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. - - - OP_RA_NEGATION_FILTER: Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in x in pos, such that there is no y in neg that agrees with - x on the columns c1, d1, .., cN, dN. - - - - OP_RA_RENAME: rename columns in the relation. - The function takes one argument. - The parameters contain the renaming as a cycle. - - - OP_RA_COMPLEMENT: Complement the relation. - - - OP_RA_SELECT: Check if a record is an element of the relation. - The function takes [n+1] arguments, where the first argument is a relation, - and the remaining [n] arguments correspond to a record. - - - OP_RA_CLONE: Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for [OP_RA_UNION] - to perform destructive updates to the first argument. - - - - OP_FD_LT: A less than predicate over the finite domain FINITE_DOMAIN_SORT. - - - OP_LABEL: A label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. - It takes one argument, a formula. - - - OP_LABEL_LIT: A label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - - - OP_DT_CONSTRUCTOR: datatype constructor. - - - OP_DT_RECOGNISER: datatype recognizer. - - - OP_DT_ACCESSOR: datatype accessor. - - - OP_UNINTERPRETED: kind used for uninterpreted symbols. -*) -(** - {!param_kind} - - The different kinds of parameters that can be associated with parameter sets. - (see {!mk_params}). - - - PK_UINT integer parameters. - - PK_BOOL boolean parameters. - - PK_DOUBLE double parameters. - - PK_SYMBOL symbol parameters. - - PK_STRING string parameters. - - PK_OTHER all internal parameter kinds which are not exposed in the API. - - PK_INVALID invalid parameter. -*) -(** - {!search_failure} - The different kinds of search failure types. - - - NO_FAILURE: The last search was successful - - UNKNOWN: Undocumented failure reason - - TIMEOUT: Timeout - - MEMOUT_WATERMAK: Search hit a memory high-watermak limit - - CANCELED: External cancel flag was set - - NUM_CONFLICTS: Maximum number of conflicts was reached - - THEORY: Theory is incomplete - - QUANTIFIERS: Logical context contains universal quantifiers -*) -(** - {!ast_print_mode} - Z3 pretty printing modes (See {!set_ast_print_mode}). - - - PRINT_SMTLIB_FULL: Print AST nodes in SMTLIB verbose format. - - PRINT_LOW_LEVEL: Print AST nodes using a low-level format. - - PRINT_SMTLIB_COMPLIANT: Print AST nodes in SMTLIB 1.x compliant format. - - PRINT_SMTLIB2_COMPLIANT: Print AST nodes in SMTLIB 2.x compliant format. -*) -(** - Definitions for update_api.py - def_Type('CONFIG', 'config', 'Config') - def_Type('CONTEXT', 'context', 'ContextObj') - def_Type('AST', 'ast', 'Ast') - def_Type('APP', 'app', 'Ast') - def_Type('SORT', 'sort', 'Sort') - def_Type('FUNC_DECL', 'func_decl', 'FuncDecl') - def_Type('PATTERN', 'pattern', 'Pattern') - def_Type('MODEL', 'model', 'Model') - def_Type('LITERALS', 'literals', 'Literals') - def_Type('CONSTRUCTOR', 'constructor', 'Constructor') - def_Type('CONSTRUCTOR_LIST', 'constructor_list', 'ConstructorList') - def_Type('THEORY', 'theory', 'ctypes.c_void_p') - def_Type('THEORY_DATA', 'theory_data', 'ctypes.c_void_p') - def_Type('SOLVER', 'solver', 'SolverObj') - def_Type('GOAL', 'goal', 'GoalObj') - def_Type('TACTIC', 'tactic', 'TacticObj') - def_Type('PARAMS', 'params', 'Params') - def_Type('PROBE', 'probe', 'ProbeObj') - def_Type('STATS', 'stats', 'StatsObj') - def_Type('AST_VECTOR', 'ast_vector', 'AstVectorObj') - def_Type('AST_MAP', 'ast_map', 'AstMapObj') - def_Type('APPLY_RESULT', 'apply_result', 'ApplyResultObj') - def_Type('FUNC_INTERP', 'func_interp', 'FuncInterpObj') - def_Type('FUNC_ENTRY', 'func_entry', 'FuncEntryObj') - def_Type('FIXEDPOINT', 'fixedpoint', 'FixedpointObj') - def_Type('PARAM_DESCRS', 'param_descrs', 'ParamDescrs') -*) -(** - {2 {L Configuration}} -*) -(** - Summary: Set a global (or module) parameter. - This setting is shared by all Z3 contexts. - When a Z3 module is initialized it will use the value of these parameters - when params objects are not provided. - The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. - The character '.' is a delimiter (more later). - The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. - Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". - This function can be used to set parameters for a specific Z3 module. - This can be done by using .. - For example: - global_param_set('pp.decimal', 'true') - will set the parameter "decimal" in the module "pp" to true. - def_API('global_param_set', VOID, (_in(STRING), _in(STRING))) -*) -external global_param_set : string -> string -> unit - = "camlidl_z3V3_Z3_global_param_set" - -(** - Summary: Restore the value of all global (and module) parameters. - This command will not affect already created objects (such as tactics and solvers). - - {b See also}: {!global_param_set} - def_API('global_param_reset_all', VOID, ()) -*) -external global_param_reset_all : unit -> unit - = "camlidl_z3V3_Z3_global_param_reset_all" - -(** - Summary: Get a global (or module) parameter. - Returns [None] - if the parameter value does not exist. - - {b See also}: {!global_param_set} - The caller must invoke {!global_param_del_value} to delete the value returned at [param_value]. - - {b Remarks}: This function cannot be invoked simultaneously from different threads without synchronization. - The result string stored in param_value is stored in shared location. - def_API('global_param_get', BOOL, (_in(STRING), _out(STRING))) -*) -external global_param_get : string -> string option - = "camlidl_z3V3_Z3_global_param_get" - -(** - {2 {L Create configuration}} -*) -(** - Summary: Create a configuration object for the Z3 context object. - Configurations are created in order to assign parameters prior to creating - contexts for Z3 interaction. For example, if the users wishes to use proof - generation, then call: - [set_param_value cfg "proof" "true"] - - {b Remarks}: Consider using {!mk_context_x} instead of using - explicit configuration objects. The function {!mk_context_x} - receives an array of string pairs. This array represents the - configuration options. - - {b Remarks}: In previous versions of Z3, the [config] was used to store - global and module configurations. Now, we should use [global_param_set]. - The following parameters can be set: - - proof (Boolean) Enable proof generation - - debug_ref_count (Boolean) Enable debug support for ast reference counting - - trace (Boolean) Tracing support for VCC - - trace_file_name (String) Trace out file for VCC traces - - timeout (unsigned) default timeout (in milliseconds) used for solvers - - well_sorted_check type checker - - auto_config use heuristics to automatically select solver and configure it - - model model generation for solvers, this parameter can be overwritten when creating a solver - - model_validate validate models produced by solvers - - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver - - {b See also}: {!set_param_value} - - {b See also}: {!del_config} - def_API('mk_config', CONFIG, ()) -*) -external mk_config : unit -> config - = "camlidl_z3V3_Z3_mk_config" - -(** - Summary: Delete the given configuration object. - - {b See also}: {!mk_config} - def_API('del_config', VOID, (_in(CONFIG),)) -*) -external del_config : config -> unit - = "camlidl_z3V3_Z3_del_config" - -(** - Summary: Set a configuration parameter. - The following parameters can be set for - - {b See also}: {!mk_config} - def_API('set_param_value', VOID, (_in(CONFIG), _in(STRING), _in(STRING))) -*) -external set_param_value : config -> string -> string -> unit - = "camlidl_z3V3_Z3_set_param_value" - -(** - {2 {L Create context}} -*) -(** - Summary: Create a context using the given configuration. - After a context is created, the configuration cannot be changed, - although some parameters can be changed using {!update_param_value}. - All main interaction with Z3 happens in the context of a [context]. - def_API('mk_context', CONTEXT, (_in(CONFIG),)) -*) -external mk_context : config -> context - = "camlidl_z3V3_Z3_mk_context" - -(** - Summary: Delete the given logical context. - - {b See also}: {!mk_context} - def_API('del_context', VOID, (_in(CONTEXT),)) -*) -external del_context : context -> unit - = "camlidl_z3V3_Z3_del_context" - -(** - Summary: Set a value of a context parameter. - - {b See also}: {!global_param_set} - def_API('update_param_value', VOID, (_in(CONTEXT), _in(STRING), _in(STRING))) -*) -external update_param_value : context -> string -> string -> unit - = "camlidl_z3V3_Z3_update_param_value" - -(** - Summary: Return the value of a context parameter. - - {b See also}: {!global_param_get} - def_API('get_param_value', BOOL, (_in(CONTEXT), _in(STRING), _out(STRING))) -*) -external get_param_value : context -> string -> string option - = "camlidl_z3V3_Z3_get_param_value" - -(** - {2 {L Symbols}} -*) -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Create a Z3 symbol using an integer. - Symbols are used to name several term and type constructors. - NB. Not all integers can be passed to this function. - The legal range of unsigned int integers is 0 to 2^30-1. - - {b See also}: {!mk_string_symbol} - def_API('mk_int_symbol', SYMBOL, (_in(CONTEXT), _in(INT))) -*) -external mk_int_symbol : context -> int -> symbol - = "camlidl_z3V3_Z3_mk_int_symbol" - -(** - Summary: Create a Z3 symbol using a C string. - Symbols are used to name several term and type constructors. - - {b See also}: {!mk_int_symbol} - def_API('mk_string_symbol', SYMBOL, (_in(CONTEXT), _in(STRING))) -*) -external mk_string_symbol : context -> string -> symbol - = "camlidl_z3V3_Z3_mk_string_symbol" - -(** - {2 {L Sorts}} -*) -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Create a free (uninterpreted) type using the given name (symbol). - Two free types are considered the same iff the have the same name. - def_API('mk_uninterpreted_sort', SORT, (_in(CONTEXT), _in(SYMBOL))) -*) -external mk_uninterpreted_sort : context -> symbol -> sort - = "camlidl_z3V3_Z3_mk_uninterpreted_sort" - -(** - Summary: Create the Boolean type. - This type is used to create propositional variables and predicates. - def_API('mk_bool_sort', SORT, (_in(CONTEXT), )) -*) -external mk_bool_sort : context -> sort - = "camlidl_z3V3_Z3_mk_bool_sort" - -(** - Summary: Create the integer type. - This type is not the int type found in programming languages. - A machine integer can be represented using bit-vectors. The function - {!mk_bv_sort} creates a bit-vector type. - - {b See also}: {!mk_bv_sort} - def_API('mk_int_sort', SORT, (_in(CONTEXT), )) -*) -external mk_int_sort : context -> sort - = "camlidl_z3V3_Z3_mk_int_sort" - -(** - Summary: Create the real type. - This type is not a floating point number. - Z3 does not have support for floating point numbers yet. - def_API('mk_real_sort', SORT, (_in(CONTEXT), )) -*) -external mk_real_sort : context -> sort - = "camlidl_z3V3_Z3_mk_real_sort" - -(** - Summary: Create a bit-vector type of the given size. - This type can also be seen as a machine integer. - - {b Remarks}: The size of the bitvector type must be greater than zero. - def_API('mk_bv_sort', SORT, (_in(CONTEXT), _in(UINT))) -*) -external mk_bv_sort : context -> int -> sort - = "camlidl_z3V3_Z3_mk_bv_sort" - -(** - Summary: Create a named finite domain sort. - To create constants that belong to the finite domain, - use the APIs for creating numerals and pass a numeric - constant together with the sort returned by this call. - - {b See also}: {!get_finite_domain_sort_size} - def_API('mk_finite_domain_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT64))) -*) -external mk_finite_domain_sort : context -> symbol -> int64 -> sort - = "camlidl_z3V3_Z3_mk_finite_domain_sort" - -(** - Summary: Create an array type. - We usually represent the array type as: {e [domain -> range] }. - Arrays are usually used to model the heap/memory in software verification. - - {b See also}: {!mk_select} - - {b See also}: {!mk_store} - def_API('mk_array_sort', SORT, (_in(CONTEXT), _in(SORT), _in(SORT))) -*) -external mk_array_sort : context -> sort -> sort -> sort - = "camlidl_z3V3_Z3_mk_array_sort" - -(** - Summary: Create a tuple type. - [mk_tuple_sort c name field_names field_sorts] creates a tuple with a constructor named [name], - a [n] fields, where [n] is the size of the arrays [field_names] and [field_sorts]. - @param c logical context - @param mk_tuple_name name of the constructor function associated with the tuple type. - @param num_fields number of fields in the tuple type. - @param field_names name of the projection functions. - @param field_sorts type of the tuple fields. - @param mk_tuple_decl output parameter that will contain the constructor declaration. - @param proj_decl output parameter that will contain the projection function declarations. This field must be a buffer of size [num_fields] allocated by the user. - def_API('mk_tuple_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _out(FUNC_DECL), _out_array(2, FUNC_DECL))) -*) -external mk_tuple_sort : context -> symbol -> symbol array -> sort array -> sort * func_decl * func_decl array - = "camlidl_z3V3_Z3_mk_tuple_sort" - -(** - Summary: Create a enumeration sort. - [mk_enumeration_sort c enums] creates an enumeration sort with enumeration names [enums], - it also returns [n] predicates, where [n] is the number of [enums] corresponding - to testing whether an element is one of the enumerants. - @param c logical context - @param name name of the enumeration sort. - @param n number of elemenets in enumeration sort. - @param enum_names names of the enumerated elements. - @param enum_consts constants corresponding to the enumerated elements. - @param enum_testers predicates testing if terms of the enumeration sort correspond to an enumeration. - For example, if this function is called with three symbols A, B, C and the name S, then - [s] is a sort whose name is S, and the function returns three terms corresponding to A, B, C in - [enum_consts]. The array [enum_testers] has three predicates of type {e (s -> Bool) }. - The first predicate (corresponding to A) is true when applied to A, and false otherwise. - Similarly for the other predicates. - def_API('mk_enumeration_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SYMBOL), _out_array(2, FUNC_DECL), _out_array(2, FUNC_DECL))) -*) -external mk_enumeration_sort : context -> symbol -> symbol array -> sort * func_decl array * func_decl array - = "camlidl_z3V3_Z3_mk_enumeration_sort" - -(** - Summary: Create a list sort - [mk_list_sort c name elem_sort] creates a list sort of [name], over elements of sort [elem_sort]. - @param c logical context - @param name name of the list sort. - @param elem_sort sort of list elements. - @param nil_decl declaration for the empty list. - @param is_nil_decl test for the empty list. - @param cons_decl declaration for a cons cell. - @param is_cons_decl cons cell test. - @param head_decl list head. - @param tail_decl list tail. - def_API('mk_list_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(SORT), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL), _out(FUNC_DECL))) -*) -external mk_list_sort : context -> symbol -> sort -> sort * func_decl * func_decl * func_decl * func_decl * func_decl * func_decl - = "camlidl_z3V3_Z3_mk_list_sort" - -(** - Summary: Create a constructor. - @param c logical context. - @param name constructor name. - @param recognizer name of recognizer function. - @param num_fields number of fields in constructor. - @param field_names names of the constructor fields. - @param sorts field sorts, [None] - if the field sort refers to a recursive sort. - @param sort_refs reference to datatype sort that is an argument to the constructor; if the corresponding - sort reference is [None], - then the value in sort_refs should be an index referring to - one of the recursive datatypes that is declared. - def_API('mk_constructor', CONSTRUCTOR, (_in(CONTEXT), _in(SYMBOL), _in(SYMBOL), _in(UINT), _in_array(3, SYMBOL), _in_array(3, SORT), _in_array(3, UINT))) -*) -external mk_constructor : context -> symbol -> symbol -> symbol array -> sort array -> int array -> constructor - = "camlidl_z3V3_Z3_mk_constructor_bytecode" "camlidl_z3V3_Z3_mk_constructor" - -(** - Summary: Reclaim memory allocated to constructor. - @param c logical context. - @param constr constructor. - def_API('del_constructor', VOID, (_in(CONTEXT), _in(CONSTRUCTOR))) -*) -external del_constructor : context -> constructor -> unit - = "camlidl_z3V3_Z3_del_constructor" - -(** - Summary: Create datatype, such as lists, trees, records, enumerations or unions of records. - The datatype may be recursive. Return the datatype sort. - @param c logical context. - @param name name of datatype. - @param num_constructors number of constructors passed in. - @param constructors array of constructor containers. - def_API('mk_datatype', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _inout_array(2, CONSTRUCTOR))) -*) -external mk_datatype : context -> symbol -> constructor array -> sort * constructor array - = "camlidl_z3V3_Z3_mk_datatype" - -(** - Summary: Create list of constructors. - @param c logical context. - @param num_constructors number of constructors in list. - @param constructors list of constructors. - def_API('mk_constructor_list', CONSTRUCTOR_LIST, (_in(CONTEXT), _in(UINT), _in_array(1, CONSTRUCTOR))) -*) -external mk_constructor_list : context -> constructor array -> constructor_list - = "camlidl_z3V3_Z3_mk_constructor_list" - -(** - Summary: Reclaim memory allocated for constructor list. - Each constructor inside the constructor list must be independently reclaimed using {!del_constructor}. - @param c logical context. - @param clist constructor list container. - def_API('del_constructor_list', VOID, (_in(CONTEXT), _in(CONSTRUCTOR_LIST))) -*) -external del_constructor_list : context -> constructor_list -> unit - = "camlidl_z3V3_Z3_del_constructor_list" - -(** - Summary: Create mutually recursive datatypes. - @param c logical context. - @param num_sorts number of datatype sorts. - @param sort_names names of datatype sorts. - @param sorts array of datatype sorts. - @param constructor_lists list of constructors, one list per sort. - def_API('mk_datatypes', VOID, (_in(CONTEXT), _in(UINT), _in_array(1, SYMBOL), _out_array(1, SORT), _inout_array(1, CONSTRUCTOR_LIST))) -*) -external mk_datatypes : context -> symbol array -> constructor_list array -> sort array * constructor_list array - = "camlidl_z3V3_Z3_mk_datatypes" - -(** - Summary: Query constructor for declared functions. - @param c logical context. - @param constr constructor container. The container must have been passed in to a {!mk_datatype} call. - @param num_fields number of accessor fields in the constructor. - @param constructor constructor function declaration. - @param tester constructor test function declaration. - @param accessors array of accessor function declarations. - def_API('query_constructor', VOID, (_in(CONTEXT), _in(CONSTRUCTOR), _in(UINT), _out(FUNC_DECL), _out(FUNC_DECL), _out_array(2, FUNC_DECL))) -*) -external query_constructor : context -> constructor -> int -> func_decl * func_decl * func_decl array - = "camlidl_z3V3_Z3_query_constructor" - -(** - {2 {L Constants and Applications}} -*) -(** - Summary: Declare a constant or function. - [mk_func_decl c n d r] creates a function with name [n], domain [d], and range [r]. - The arity of the function is the size of the array [d]. - @param c logical context. - @param s name of the constant or function. - @param domain_size number of arguments. It is 0 when declaring a constant. - @param domain array containing the sort of each argument. The array must contain domain_size elements. It is 0 when declaring a constant. - @param range sort of the constant or the return sort of the function. - After declaring a constant or function, the function - {!mk_app} can be used to create a constant or function - application. - - {b See also}: {!mk_app} - def_API('mk_func_decl', FUNC_DECL, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SORT), _in(SORT))) -*) -external mk_func_decl : context -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_mk_func_decl" - -(** - Summary: Create a constant or function application. - - {b See also}: {!mk_func_decl} - def_API('mk_app', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT), _in_array(2, AST))) -*) -external mk_app : context -> func_decl -> ast array -> ast - = "camlidl_z3V3_Z3_mk_app" - -(** - Summary: Declare and create a constant. - [mk_const c s t] is a shorthand for [mk_app c (mk_func_decl c s [||] t) [||]] - - {b See also}: {!mk_func_decl} - - {b See also}: {!mk_app} - def_API('mk_const', AST, (_in(CONTEXT), _in(SYMBOL), _in(SORT))) -*) -external mk_const : context -> symbol -> sort -> ast - = "camlidl_z3V3_Z3_mk_const" - -(** - Summary: Declare a fresh constant or function. - Z3 will generate an unique name for this function declaration. - - {b See also}: {!mk_func_decl} - def_API('mk_fresh_func_decl', FUNC_DECL, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SORT), _in(SORT))) -*) -external mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_mk_fresh_func_decl" - -(** - Summary: Declare and create a fresh constant. - [mk_fresh_const c p t] is a shorthand for [mk_app c (mk_fresh_func_decl c p [||] t) [||]]. - - {b See also}: {!mk_func_decl} - - {b See also}: {!mk_app} - def_API('mk_fresh_const', AST, (_in(CONTEXT), _in(STRING), _in(SORT))) -*) -external mk_fresh_const : context -> string -> sort -> ast - = "camlidl_z3V3_Z3_mk_fresh_const" - -(** - {2 {L Propositional Logic and Equality}} -*) -(** - Summary: Create an AST node representing [true]. - def_API('mk_true', AST, (_in(CONTEXT), )) -*) -external mk_true : context -> ast - = "camlidl_z3V3_Z3_mk_true" - -(** - Summary: Create an AST node representing [false]. - def_API('mk_false', AST, (_in(CONTEXT), )) -*) -external mk_false : context -> ast - = "camlidl_z3V3_Z3_mk_false" - -(** - Summary: \[ [ mk_eq c l r ] \] - Create an AST node representing {e l = r }. - The nodes [l] and [r] must have the same type. - def_API('mk_eq', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_eq : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_eq" - -(** - Summary: \[ [mk_distinct c [| t_1; ...; t_n |]] \] Create an AST - node represeting a distinct construct. It is used for declaring - the arguments t_i pairwise distinct. - The [distinct] construct is used for declaring the arguments pairwise distinct. - That is, {e Forall 0 <= i < j < num_args. not args[i] = args[j] }. - All arguments must have the same sort. - - {b Remarks}: The number of arguments of a distinct construct must be greater than one. - def_API('mk_distinct', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_distinct : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_distinct" - -(** - Summary: \[ [ mk_not c a ] \] - Create an AST node representing {e not(a) }. - The node [a] must have Boolean sort. - def_API('mk_not', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_not : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_not" - -(** - Summary: \[ [ mk_ite c t1 t2 t2 ] \] - Create an AST node representing an if-then-else: {e ite(t1, t2, - t3) }. - The node [t1] must have Boolean sort, [t2] and [t3] must have the same sort. - The sort of the new node is equal to the sort of [t2] and [t3]. - def_API('mk_ite', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(AST))) -*) -external mk_ite : context -> ast -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ite" - -(** - Summary: \[ [ mk_iff c t1 t2 ] \] - Create an AST node representing {e t1 iff t2 }. - The nodes [t1] and [t2] must have Boolean sort. - def_API('mk_iff', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_iff : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_iff" - -(** - Summary: \[ [ mk_implies c t1 t2 ] \] - Create an AST node representing {e t1 implies t2 }. - The nodes [t1] and [t2] must have Boolean sort. - def_API('mk_implies', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_implies : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_implies" - -(** - Summary: \[ [ mk_xor c t1 t2 ] \] - Create an AST node representing {e t1 xor t2 }. - The nodes [t1] and [t2] must have Boolean sort. - def_API('mk_xor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_xor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_xor" - -(** - Summary: \[ [mk_and c [| t_1; ...; t_n |]] \] Create the conjunction: {e t_1 and ... and t_n}. - All arguments must have Boolean sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_and', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_and : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_and" - -(** - Summary: \[ [mk_or c [| t_1; ...; t_n |]] \] Create the disjunction: {e t_1 or ... or t_n}. - All arguments must have Boolean sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_or', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_or : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_or" - -(** - {2 {L Arithmetic: Integers and Reals}} -*) -(** - Summary: \[ [mk_add c [| t_1; ...; t_n |]] \] Create the term: {e t_1 + ... + t_n}. - All arguments must have int or real sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_add', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_add : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_add" - -(** - Summary: \[ [mk_mul c [| t_1; ...; t_n |]] \] Create the term: {e t_1 * ... * t_n}. - All arguments must have int or real sort. - - {b Remarks}: Z3 has limited support for non-linear arithmetic. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_mul', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_mul : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_mul" - -(** - Summary: \[ [mk_sub c [| t_1; ...; t_n |]] \] Create the term: {e t_1 - ... - t_n}. - All arguments must have int or real sort. - - {b Remarks}: The number of arguments must be greater than zero. - def_API('mk_sub', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_sub : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_sub" - -(** - Summary: \[ [mk_unary_minus c arg] \] Create the term: {e - arg}. - The arguments must have int or real type. - def_API('mk_unary_minus', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_unary_minus : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_unary_minus" - -(** - Summary: \[ [mk_div c t_1 t_2] \] Create the term: {e t_1 div t_2}. - The arguments must either both have int type or both have real type. - If the arguments have int type, then the result type is an int type, otherwise the - the result type is real. - def_API('mk_div', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_div : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_div" - -(** - Summary: \[ [mk_mod c t_1 t_2] \] Create the term: {e t_1 mod t_2}. - The arguments must have int type. - def_API('mk_mod', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_mod : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_mod" - -(** - Summary: \[ [mk_rem c t_1 t_2] \] Create the term: {e t_1 rem t_2}. - The arguments must have int type. - def_API('mk_rem', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_rem : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_rem" - -(** - The arguments must have int or real type. - def_API('mk_power', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_power : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_power" - -(** - Summary: \[ [ mk_lt c t1 t2 ] \] - Create less than. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_lt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_lt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_lt" - -(** - Summary: \[ [ mk_le c t1 t2 ] \] - Create less than or equal to. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_le', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_le : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_le" - -(** - Summary: \[ [ mk_gt c t1 t2 ] \] - Create greater than. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_gt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_gt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_gt" - -(** - Summary: \[ [ mk_ge c t1 t2 ] \] - Create greater than or equal to. - The nodes [t1] and [t2] must have the same sort, and must be int or real. - def_API('mk_ge', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_ge : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ge" - -(** - Summary: \[ [ mk_int2real c t1 ] \] - Coerce an integer to a real. - There is also a converse operation exposed. - It follows the semantics prescribed by the SMT-LIB standard. - You can take the floor of a real by - creating an auxiliary integer constant [k] and - and asserting {e mk_int2real(k) <= t1 < mk_int2real(k)+1 }. - The node [t1] must have sort integer. - - {b See also}: {!mk_real2int} - - {b See also}: {!mk_is_int} - def_API('mk_int2real', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_int2real : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_int2real" - -(** - Summary: \[ [ mk_real2int c t1 ] \] - Coerce a real to an integer. - The semantics of this function follows the SMT-LIB standard - for the function to_int - - {b See also}: {!mk_int2real} - - {b See also}: {!mk_is_int} - def_API('mk_real2int', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_real2int : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_real2int" - -(** - Summary: \[ [ mk_is_int c t1 ] \] - Check if a real number is an integer. - - {b See also}: {!mk_int2real} - - {b See also}: {!mk_real2int} - def_API('mk_is_int', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_is_int : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_is_int" - -(** - {2 {L Bit-vectors}} -*) -(** - Summary: \[ [ mk_bvnot c t1 ] \] - Bitwise negation. - The node [t1] must have a bit-vector sort. - def_API('mk_bvnot', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvnot : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvnot" - -(** - Summary: \[ [ mk_bvredand c t1 ] \] - Take conjunction of bits in vector, return vector of length 1. - The node [t1] must have a bit-vector sort. - def_API('mk_bvredand', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvredand : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvredand" - -(** - Summary: \[ [ mk_bvredor c t1 ] \] - Take disjunction of bits in vector, return vector of length 1. - The node [t1] must have a bit-vector sort. - def_API('mk_bvredor', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvredor : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvredor" - -(** - Summary: \[ [ mk_bvand c t1 t2 ] \] - Bitwise and. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvand', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvand : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvand" - -(** - Summary: \[ [ mk_bvor c t1 t2 ] \] - Bitwise or. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvor" - -(** - Summary: \[ [ mk_bvxor c t1 t2 ] \] - Bitwise exclusive-or. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvxor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvxor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvxor" - -(** - Summary: \[ [ mk_bvnand c t1 t2 ] \] - Bitwise nand. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvnand', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvnand : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvnand" - -(** - Summary: \[ [ mk_bvnor c t1 t2 ] \] - Bitwise nor. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvnor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvnor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvnor" - -(** - Summary: \[ [ mk_bvxnor c t1 t2 ] \] - Bitwise xnor. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvxnor', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvxnor : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvxnor" - -(** - Summary: \[ [ mk_bvneg c t1 ] \] - Standard two's complement unary minus. - The node [t1] must have bit-vector sort. - def_API('mk_bvneg', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvneg : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvneg" - -(** - Summary: \[ [ mk_bvadd c t1 t2 ] \] - Standard two's complement addition. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvadd', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvadd : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvadd" - -(** - Summary: \[ [ mk_bvsub c t1 t2 ] \] - Standard two's complement subtraction. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsub', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsub : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsub" - -(** - Summary: \[ [ mk_bvmul c t1 t2 ] \] - Standard two's complement multiplication. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvmul', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvmul : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvmul" - -(** - Summary: \[ [ mk_bvudiv c t1 t2 ] \] - Unsigned division. - It is defined as the [floor] of {e t1/t2 } if [t2] is - different from zero. If {e t2 } is zero, then the result - is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvudiv', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvudiv : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvudiv" - -(** - Summary: \[ [ mk_bvsdiv c t1 t2 ] \] - Two's complement signed division. - It is defined in the following way: - - The [floor] of {e t1/t2 } if [t2] is different from zero, and {e t1*t2 >= 0 }. - - The [ceiling] of {e t1/t2 } if [t2] is different from zero, and {e t1*t2 < 0 }. - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsdiv', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsdiv : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsdiv" - -(** - Summary: \[ [ mk_bvurem c t1 t2 ] \] - Unsigned remainder. - It is defined as {e t1 - (t1 /u t2) * t2 }, where {e /u } represents unsigned int division. - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvurem', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvurem : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvurem" - -(** - Summary: \[ [ mk_bvsrem c t1 t2 ] \] - Two's complement signed remainder (sign follows dividend). - It is defined as {e t1 - (t1 /s t2) * t2 }, where {e /s } represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of [t1]. - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - - {b See also}: {!mk_bvsmod} - def_API('mk_bvsrem', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsrem : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsrem" - -(** - Summary: \[ [ mk_bvsmod c t1 t2 ] \] - Two's complement signed remainder (sign follows divisor). - If {e t2 } is zero, then the result is undefined. - The nodes [t1] and [t2] must have the same bit-vector sort. - - {b See also}: {!mk_bvsrem} - def_API('mk_bvsmod', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsmod : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsmod" - -(** - Summary: \[ [ mk_bvult c t1 t2 ] \] - Unsigned less than. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvult', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvult : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvult" - -(** - Summary: \[ [ mk_bvslt c t1 t2 ] \] - Two's complement signed less than. - It abbreviates: - {v - (or (and (= (extract[|m-1|:|m-1|] t1) bit1) - (= (extract[|m-1|:|m-1|] t2) bit0)) - (and (= (extract[|m-1|:|m-1|] t1) (extract[|m-1|:|m-1|] t2)) - (bvult t1 t2))) - v} - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvslt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvslt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvslt" - -(** - Summary: \[ [ mk_bvule c t1 t2 ] \] - Unsigned less than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvule', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvule : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvule" - -(** - Summary: \[ [ mk_bvsle c t1 t2 ] \] - Two's complement signed less than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsle', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsle : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsle" - -(** - Summary: \[ [ mk_bvuge c t1 t2 ] \] - Unsigned greater than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvuge', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvuge : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvuge" - -(** - Summary: \[ [ mk_bvsge c t1 t2 ] \] - Two's complement signed greater than or equal to. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsge', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsge : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsge" - -(** - Summary: \[ [ mk_bvugt c t1 t2 ] \] - Unsigned greater than. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvugt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvugt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvugt" - -(** - Summary: \[ [ mk_bvsgt c t1 t2 ] \] - Two's complement signed greater than. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsgt', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsgt : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsgt" - -(** - Summary: \[ [ mk_concat c t1 t2 ] \] - Concatenate the given bit-vectors. - The nodes [t1] and [t2] must have (possibly different) bit-vector sorts - The result is a bit-vector of size {e n1+n2 }, where [n1] ([n2)] is the size - of [t1] ([t2)]. - def_API('mk_concat', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_concat : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_concat" - -(** - Summary: \[ [ mk_extract c high low t1 ] \] - Extract the bits [high] down to [low] from a bitvector of - size [m] to yield a new bitvector of size [n], where {e n = - high - low + 1 }. - The node [t1] must have a bit-vector sort. - def_API('mk_extract', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in(AST))) -*) -external mk_extract : context -> int -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_extract" - -(** - Summary: \[ [ mk_sign_ext c i t1 ] \] - Sign-extend of the given bit-vector to the (signed) equivalent bitvector of - size {e m+i }, where [m] is the size of the given - bit-vector. - The node [t1] must have a bit-vector sort. - def_API('mk_sign_ext', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_sign_ext : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_sign_ext" - -(** - Summary: \[ [ mk_zero_ext c i t1 ] \] - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size {e m+i }, where [m] is the size of the - given bit-vector. - The node [t1] must have a bit-vector sort. - def_API('mk_zero_ext', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_zero_ext : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_zero_ext" - -(** - Summary: \[ [ mk_repeat c i t1 ] \] - Repeat the given bit-vector up length {e i }. - The node [t1] must have a bit-vector sort. - def_API('mk_repeat', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_repeat : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_repeat" - -(** - Summary: \[ [ mk_bvshl c t1 t2 ] \] - Shift left. - It is equivalent to multiplication by {e 2^x } where [x] is the value of the - third argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvshl', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvshl : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvshl" - -(** - Summary: \[ [ mk_bvlshr c t1 t2 ] \] - Logical shift right. - It is equivalent to unsigned int division by {e 2^x } where [x] is the - value of the third argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvlshr', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvlshr : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvlshr" - -(** - Summary: \[ [ mk_bvashr c t1 t2 ] \] - Arithmetic shift right. - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvashr', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvashr : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvashr" - -(** - Summary: \[ [ mk_rotate_left c i t1 ] \] - Rotate bits of [t1] to the left [i] times. - The node [t1] must have a bit-vector sort. - def_API('mk_rotate_left', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_rotate_left : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_rotate_left" - -(** - Summary: \[ [ mk_rotate_right c i t1 ] \] - Rotate bits of [t1] to the right [i] times. - The node [t1] must have a bit-vector sort. - def_API('mk_rotate_right', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_rotate_right : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_rotate_right" - -(** - Summary: \[ [ mk_ext_rotate_left c t1 t2 ] \] - Rotate bits of [t1] to the left [t2] times. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_ext_rotate_left', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_ext_rotate_left : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ext_rotate_left" - -(** - Summary: \[ [ mk_ext_rotate_right c t1 t2 ] \] - Rotate bits of [t1] to the right [t2] times. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_ext_rotate_right', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_ext_rotate_right : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_ext_rotate_right" - -(** - Summary: \[ [ mk_int2bv c n t1 ] \] - Create an [n] bit bit-vector from the integer argument [t1]. - NB. This function is essentially treated as uninterpreted. + (** Create an n-bit bit-vector from an integer argument. + + + NB. This function is essentially treated as uninterpreted. So you cannot expect Z3 to precisely reflect the semantics of this function when solving constraints with this function. - The node [t1] must have integer sort. - def_API('mk_int2bv', AST, (_in(CONTEXT), _in(UINT), _in(AST))) -*) -external mk_int2bv : context -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_int2bv" - -(** - Summary: \[ [ mk_bv2int c t1 is_signed ] \] - Create an integer from the bit-vector argument [t1]. - If [is_signed] is false, then the bit-vector [t1] is treated as unsigned int. - So the result is non-negative - and in the range {e [0..2^N-1] }, where N are the number of bits in [t1]. - If [is_signed] is true, [t1] is treated as a signed bit-vector. - This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - The node [t1] must have a bit-vector sort. - def_API('mk_bv2int', AST, (_in(CONTEXT), _in(AST), _in(BOOL))) -*) -external mk_bv2int : context -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bv2int" - -(** - Summary: \[ [ mk_bvadd_no_overflow c t1 t2 is_signed ] \] - Create a predicate that checks that the bit-wise addition - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvadd_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) -*) -external mk_bvadd_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bvadd_no_overflow" - -(** - Summary: \[ [ mk_bvadd_no_underflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed addition - of [t1] and [t2] does not underflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvadd_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvadd_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvadd_no_underflow" - -(** - Summary: \[ [ mk_bvsub_no_overflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed subtraction - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsub_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsub_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsub_no_overflow" - -(** - Summary: \[ [ mk_bvsub_no_underflow c t1 t2 is_signed ] \] - Create a predicate that checks that the bit-wise subtraction - of [t1] and [t2] does not underflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsub_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) -*) -external mk_bvsub_no_underflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bvsub_no_underflow" - -(** - Summary: \[ [ mk_bvsdiv_no_overflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed division - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvsdiv_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvsdiv_no_overflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvsdiv_no_overflow" - -(** - Summary: \[ [ mk_bvneg_no_overflow c t1 ] \] - Check that bit-wise negation does not overflow when - [t1] is interpreted as a signed bit-vector. - The node [t1] must have bit-vector sort. - def_API('mk_bvneg_no_overflow', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_bvneg_no_overflow : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvneg_no_overflow" - -(** - Summary: \[ [ mk_bvmul_no_overflow c t1 t2 is_signed ] \] - Create a predicate that checks that the bit-wise multiplication - of [t1] and [t2] does not overflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvmul_no_overflow', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(BOOL))) -*) -external mk_bvmul_no_overflow : context -> ast -> ast -> bool -> ast - = "camlidl_z3V3_Z3_mk_bvmul_no_overflow" - -(** - Summary: \[ [ mk_bvmul_no_underflow c t1 t2 ] \] - Create a predicate that checks that the bit-wise signed multiplication - of [t1] and [t2] does not underflow. - The nodes [t1] and [t2] must have the same bit-vector sort. - def_API('mk_bvmul_no_underflow', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_bvmul_no_underflow : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_bvmul_no_underflow" + + The argument must be of integer sort. *) + val mk_int2bv : context -> int -> Expr.expr -> Expr.expr + end + + (** Real Arithmetic *) + module Real : + sig + (** Create a real sort. *) + val mk_sort : context -> Sort.sort + + (** The numerator of a rational numeral. *) + val get_numerator : Expr.expr-> Expr.expr + + (** The denominator of a rational numeral. *) + val get_denominator : Expr.expr-> Expr.expr + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as indicated by the int argument.*) + val to_decimal_string : Expr.expr-> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : Expr.expr-> string + + (** Creates a real constant. *) + val mk_const : context -> Symbol.symbol -> Expr.expr -(** - {2 {L Arrays}} -*) -(** - Summary: \[ [ mk_select c a i ] \] - Array read. - The argument [a] is the array and [i] is the index of the array that gets read. - The node [a] must have an array sort {e [domain -> range] }, - and [i] must have the sort [domain]. - The sort of the result is [range]. - - {b See also}: {!mk_array_sort} - - {b See also}: {!mk_store} - def_API('mk_select', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_select : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_select" - -(** - Summary: \[ [ mk_store c a i v ] \] - Array update. - The node [a] must have an array sort {e [domain -> range] }, [i] must have sort [domain], - [v] must have sort range. The sort of the result is {e [domain -> range] }. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to [a] (with respect to [select)] - on all indices except for [i], where it maps to [v] (and the [select] of [a] with - respect to [i] may be a different value). - - {b See also}: {!mk_array_sort} - - {b See also}: {!mk_select} - def_API('mk_store', AST, (_in(CONTEXT), _in(AST), _in(AST), _in(AST))) -*) -external mk_store : context -> ast -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_store" - -(** - Summary: Create the constant array. - The resulting term is an array, such that a [select] on an arbitrary index - produces the value [v]. - @param c logical context. - @param domain domain sort for the array. - @param v value that the array maps to. - def_API('mk_const_array', AST, (_in(CONTEXT), _in(SORT), _in(AST))) -*) -external mk_const_array : context -> sort -> ast -> ast - = "camlidl_z3V3_Z3_mk_const_array" - -(** - Summary: \[ [ mk_map f n args ] \] - map f on the the argument arrays. - The [n] nodes [args] must be of array sorts {e [domain_i -> range_i] }. - The function declaration [f] must have type {e range_1 .. range_n -> range }. - [v] must have sort range. The sort of the result is {e [domain_i -> range] }. - - {b See also}: {!mk_array_sort} - - {b See also}: {!mk_store} - - {b See also}: {!mk_select} - def_API('mk_map', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT), _in_array(2, AST))) -*) -external mk_map : context -> func_decl -> int -> ast -> ast - = "camlidl_z3V3_Z3_mk_map" - -(** - Summary: Access the array default value. - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. - @param c logical context. - @param array array value whose default range value is accessed. - def_API('mk_array_default', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_array_default : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_array_default" + (** Creates a real constant. *) + val mk_const_s : context -> string -> Expr.expr -(** - {2 {L Sets}} -*) -(** - Summary: Create Set type. - def_API('mk_set_sort', SORT, (_in(CONTEXT), _in(SORT))) -*) -external mk_set_sort : context -> sort -> sort - = "camlidl_z3V3_Z3_mk_set_sort" + (** Create a real numeral from a fraction. + @return A Term with rational value and sort Real + {!mk_numeral_s} *) + val mk_numeral_nd : context -> int -> int -> Expr.expr -(** - Summary: Create the empty set. - def_API('mk_empty_set', AST, (_in(CONTEXT), _in(SORT))) -*) -external mk_empty_set : context -> sort -> ast - = "camlidl_z3V3_Z3_mk_empty_set" + (** Create a real numeral. + @return A Term with the given value and sort Real *) + val mk_numeral_s : context -> string -> Expr.expr -(** - Summary: Create the full set. - def_API('mk_full_set', AST, (_in(CONTEXT), _in(SORT))) -*) -external mk_full_set : context -> sort -> ast - = "camlidl_z3V3_Z3_mk_full_set" + (** Create a real numeral. + @return A Term with the given value and sort Real *) + val mk_numeral_i : context -> int -> Expr.expr -(** - Summary: Add an element to a set. - The first argument must be a set, the second an element. - def_API('mk_set_add', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_add : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_add" + (** Creates an expression that checks whether a real number is an integer. *) + val mk_is_integer : context -> Expr.expr -> Expr.expr -(** - Summary: Remove an element to a set. - The first argument must be a set, the second an element. - def_API('mk_set_del', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_del : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_del" + (** Coerce a real to an integer. -(** - Summary: Take the union of a list of sets. - def_API('mk_set_union', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_set_union : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_set_union" + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) + val mk_real2int : context -> Expr.expr -> Expr.expr + + (** Algebraic Numbers *) + module AlgebraicNumber : + sig + (** Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_upper : Expr.expr -> int -> Expr.expr + + (** Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_lower : Expr.expr -> int -> Expr.expr + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as the int argument provided.*) + val to_decimal_string : Expr.expr -> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : Expr.expr -> string + end + end -(** - Summary: Take the intersection of a list of sets. - def_API('mk_set_intersect', AST, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_set_intersect : context -> ast array -> ast - = "camlidl_z3V3_Z3_mk_set_intersect" + (** Indicates whether the term is of integer sort. *) + val is_int : Expr.expr -> bool -(** - Summary: Take the set difference between two sets. - def_API('mk_set_difference', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_difference : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_difference" + (** Indicates whether the term is an arithmetic numeral. *) + val is_arithmetic_numeral : Expr.expr -> bool -(** - Summary: Take the complement of a set. - def_API('mk_set_complement', AST, (_in(CONTEXT), _in(AST))) -*) -external mk_set_complement : context -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_complement" + (** Indicates whether the term is a less-than-or-equal *) + val is_le : Expr.expr -> bool -(** - Summary: Check for set membership. - The first argument should be an element type of the set. - def_API('mk_set_member', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_member : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_member" + (** Indicates whether the term is a greater-than-or-equal *) + val is_ge : Expr.expr -> bool -(** - Summary: Check for subsetness of sets. - def_API('mk_set_subset', AST, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external mk_set_subset : context -> ast -> ast -> ast - = "camlidl_z3V3_Z3_mk_set_subset" + (** Indicates whether the term is a less-than *) + val is_lt : Expr.expr -> bool -(** - {2 {L Numerals}} -*) -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Create a numeral of a given sort. - @param c logical context. - @param numeral A string representing the numeral value in decimal notation. If the given sort is a real, then the numeral can be a rational, that is, a string of the form {e [num]* / [num]* }. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, finite-domain, or bit-vectors of arbitrary size. - - {b See also}: {!mk_int} - def_API('mk_numeral', AST, (_in(CONTEXT), _in(STRING), _in(SORT))) -*) -external mk_numeral : context -> string -> sort -> ast - = "camlidl_z3V3_Z3_mk_numeral" - -(** - Summary: Create a real from a fraction. - @param c logical context. - @param num numerator of rational. - @param den denomerator of rational. - - {b Precondition}: den != 0 - - {b See also}: {!mk_numeral} - - {b See also}: {!mk_int} - def_API('mk_real', AST, (_in(CONTEXT), _in(INT), _in(INT))) -*) -external mk_real : context -> int -> int -> ast - = "camlidl_z3V3_Z3_mk_real" - -(** - Summary: Create a numeral of an int, bit-vector, or finite-domain sort. - This function can be use to create numerals that fit in a machine integer. - It is slightly faster than {!mk_numeral} since it is not necessary to parse a string. - - {b See also}: {!mk_numeral} - def_API('mk_int', AST, (_in(CONTEXT), _in(INT), _in(SORT))) -*) -external mk_int : context -> int -> sort -> ast - = "camlidl_z3V3_Z3_mk_int" - -(** - Summary: Create a numeral of a int, bit-vector, or finite-domain sort. - This function can be use to create numerals that fit in a machine long long integer. - It is slightly faster than {!mk_numeral} since it is not necessary to parse a string. - - {b See also}: {!mk_numeral} - def_API('mk_int64', AST, (_in(CONTEXT), _in(INT64), _in(SORT))) -*) -external mk_int64 : context -> int64 -> sort -> ast - = "camlidl_z3V3_Z3_mk_int64" + (** Indicates whether the term is a greater-than *) + val is_gt : Expr.expr -> bool -(** - {2 {L Quantifiers}} -*) -(** - Summary: Create a pattern for quantifier instantiation. - Z3 uses pattern matching to instantiate quantifiers. If a - pattern is not provided for a quantifier, then Z3 will - automatically compute a set of patterns for it. However, for - optimal performance, the user should provide the patterns. - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - a called a multi-pattern. - In general, one can pass in a list of (multi-)patterns in the - quantifier constructor. - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_pattern', PATTERN, (_in(CONTEXT), _in(UINT), _in_array(1, AST))) -*) -external mk_pattern : context -> ast array -> pattern - = "camlidl_z3V3_Z3_mk_pattern" - -(** - Summary: Create a bound variable. - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - {v - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - v} - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper x appears, the higher is its - index. - @param c logical context - @param index de-Bruijn index - @param ty sort of the bound variable - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_bound', AST, (_in(CONTEXT), _in(UINT), _in(SORT))) -*) -external mk_bound : context -> int -> sort -> ast - = "camlidl_z3V3_Z3_mk_bound" - -(** - Summary: Create a forall formula. It takes an expression [body] that contains bound variables - of the same sorts as the sorts listed in the array [sorts]. The bound variables are de-Bruijn indices created - using {!mk_bound}. The array [decl_names] contains the names that the quantified formula uses for the - bound variables. Z3 applies the convention that the last element in the [decl_names] and [sorts] array - refers to the variable with index 0, the second to last element of [decl_names] and [sorts] refers - to the variable with index 1, etc. - [mk_forall c w p t n b] creates a forall formula, where - [w] is the weight, [p] is an array of patterns, [t] is an array - with the sorts of the bound variables, [n] is an array with the - 'names' of the bound variables, and [b] is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during - instantiation. - @param c logical context. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @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 quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_exists} - def_API('mk_forall', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, PATTERN), _in(UINT), _in_array(4, SORT), _in_array(4, SYMBOL), _in(AST))) -*) -external mk_forall : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_forall_bytecode" "camlidl_z3V3_Z3_mk_forall" - -(** - Summary: Create an exists formula. Similar to {!mk_forall}. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_forall} - - {b See also}: {!mk_quantifier} - def_API('mk_exists', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, PATTERN), _in(UINT), _in_array(4, SORT), _in_array(4, SYMBOL), _in(AST))) -*) -external mk_exists : context -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_exists_bytecode" "camlidl_z3V3_Z3_mk_exists" - -(** - Summary: Create a quantifier - universal or existential, with pattern hints. - See the documentation for {!mk_forall} for an explanation of the parameters. - @param c logical context. - @param is_forall flag to indicate if this is a universal or existential quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param num_decls number of variables to be bound. - @param sorts array of sorts of the bound variables. - @param decl_names names of the bound variables. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_quantifier', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(UINT), _in_array(3, PATTERN), _in(UINT), _in_array(5, SORT), _in_array(5, SYMBOL), _in(AST))) -*) -external mk_quantifier : context -> bool -> int -> pattern array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_bytecode" "camlidl_z3V3_Z3_mk_quantifier" - -(** - Summary: Create a quantifier - universal or existential, with pattern hints, no patterns, and attributes - @param c logical context. - @param is_forall flag to indicate if this is a universal or existential quantifier. - @param quantifier_id identifier to identify quantifier - @param skolem_id identifier to identify skolem constants introduced by quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param num_no_patterns number of no_patterns. - @param no_patterns array containing subexpressions to be excluded from inferred patterns. - @param num_decls number of variables to be bound. - @param sorts array of sorts of the bound variables. - @param decl_names names of the bound variables. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_bound} - - {b See also}: {!mk_forall} - - {b See also}: {!mk_exists} - def_API('mk_quantifier_ex', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(SYMBOL), _in(SYMBOL), _in(UINT), _in_array(5, PATTERN), _in(UINT), _in_array(7, AST), _in(UINT), _in_array(9, SORT), _in_array(9, SYMBOL), _in(AST))) -*) -external mk_quantifier_ex : context -> bool -> int -> symbol -> symbol -> pattern array -> ast array -> sort array -> symbol array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_ex_bytecode" "camlidl_z3V3_Z3_mk_quantifier_ex" - -(** - Summary: Create a universal quantifier using a list of constants that - will form the set of bound variables. - @param c logical context. - @param weight quantifiers are associated with weights indicating the importance of using - the quantifier during instantiation. By default, pass the weight 0. - @param num_bound number of constants to be abstracted into bound variables. - @param bound array of constants to be abstracted into bound variables. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_exists_const} - def_API('mk_forall_const', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, APP), _in(UINT), _in_array(4, PATTERN), _in(AST))) -*) -external mk_forall_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3V3_Z3_mk_forall_const" - -(** - Summary: Similar to {!mk_forall_const}. - Summary: Create an existential quantifier using a list of constants that - will form the set of bound variables. - @param c logical context. - @param weight quantifiers are associated with weights indicating the importance of using - the quantifier during instantiation. By default, pass the weight 0. - @param num_bound number of constants to be abstracted into bound variables. - @param bound array of constants to be abstracted into bound variables. - @param num_patterns number of patterns. - @param patterns array containing the patterns created using {!mk_pattern}. - @param body the body of the quantifier. - - {b See also}: {!mk_pattern} - - {b See also}: {!mk_forall_const} - def_API('mk_exists_const', AST, (_in(CONTEXT), _in(UINT), _in(UINT), _in_array(2, APP), _in(UINT), _in_array(4, PATTERN), _in(AST))) -*) -external mk_exists_const : context -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3V3_Z3_mk_exists_const" - -(** - Summary: Create a universal or existential - quantifier using a list of constants that - will form the set of bound variables. - def_API('mk_quantifier_const', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(UINT), _in_array(3, APP), _in(UINT), _in_array(5, PATTERN), _in(AST))) -*) -external mk_quantifier_const : context -> bool -> int -> app array -> pattern array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_const_bytecode" "camlidl_z3V3_Z3_mk_quantifier_const" - -(** - Summary: Create a universal or existential - quantifier using a list of constants that - will form the set of bound variables. - def_API('mk_quantifier_const_ex', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(SYMBOL), _in(SYMBOL), _in(UINT), _in_array(5, APP), _in(UINT), _in_array(7, PATTERN), _in(UINT), _in_array(9, AST), _in(AST))) -*) -external mk_quantifier_const_ex : context -> bool -> int -> symbol -> symbol -> app array -> pattern array -> ast array -> ast -> ast - = "camlidl_z3V3_Z3_mk_quantifier_const_ex_bytecode" "camlidl_z3V3_Z3_mk_quantifier_const_ex" + (** Indicates whether the term is addition (binary) *) + val is_add : Expr.expr -> bool -(** - {2 {L Accessors}} -*) -(** - {3 {L Symbols}} -*) -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Return [INT_SYMBOL] if the symbol was constructed - using {!mk_int_symbol}, and [STRING_SYMBOL] if the symbol - was constructed using {!mk_string_symbol}. - def_API('get_symbol_kind', UINT, (_in(CONTEXT), _in(SYMBOL))) -*) -external get_symbol_kind : context -> symbol -> symbol_kind - = "camlidl_z3V3_Z3_get_symbol_kind" - -(** - Summary: \[ [ get_symbol_int c s ] \] - Return the symbol int value. - - {b Precondition}: get_symbol_kind s == INT_SYMBOL - - {b See also}: {!mk_int_symbol} - def_API('get_symbol_int', INT, (_in(CONTEXT), _in(SYMBOL))) -*) -external get_symbol_int : context -> symbol -> int - = "camlidl_z3V3_Z3_get_symbol_int" - -(** - Summary: \[ [ get_symbol_string c s ] \] - Return the symbol name. - - {b Precondition}: get_symbol_string s == STRING_SYMBOL - - {b See also}: {!mk_string_symbol} - def_API('get_symbol_string', STRING, (_in(CONTEXT), _in(SYMBOL))) -*) -external get_symbol_string : context -> symbol -> string - = "camlidl_z3V3_Z3_get_symbol_string" + (** Indicates whether the term is subtraction (binary) *) + val is_sub : Expr.expr -> bool -(** - {3 {L Sorts}} -*) -(** - Summary: Return the sort name as a symbol. - def_API('get_sort_name', SYMBOL, (_in(CONTEXT), _in(SORT))) -*) -external get_sort_name : context -> sort -> symbol - = "camlidl_z3V3_Z3_get_sort_name" + (** Indicates whether the term is a unary minus *) + val is_uminus : Expr.expr -> bool -(** - Summary: Return a unique identifier for [s]. - - {b Remarks}: Implicitly used by [Pervasives.( = )] and [Pervasives.compare]. - def_API('get_sort_id', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_sort_id : context -> sort -> int - = "camlidl_z3V3_Z3_get_sort_id" + (** Indicates whether the term is multiplication (binary) *) + val is_mul : Expr.expr -> bool -(** - {4 {L Redundant low-level API}} -*) -(** - Summary: Convert a [sort] into [ast]. - - {b Remarks}: [sort_to_ast c s] can be replaced by [(s :> ast)]. - def_API('sort_to_ast', AST, (_in(CONTEXT), _in(SORT))) -*) -external sort_to_ast : context -> sort -> ast - = "camlidl_z3V3_Z3_sort_to_ast" + (** Indicates whether the term is division (binary) *) + val is_div : Expr.expr -> bool -(** - Summary: compare sorts. - - {b Remarks}: [Pervasives.( = )] or [Pervasives.compare] can also be used. - def_API('is_eq_sort', BOOL, (_in(CONTEXT), _in(SORT), _in(SORT))) -*) -external is_eq_sort : context -> sort -> sort -> bool - = "camlidl_z3V3_Z3_is_eq_sort" + (** Indicates whether the term is integer division (binary) *) + val is_idiv : Expr.expr -> bool -(** - Summary: Return the sort kind (e.g., array, tuple, int, bool, etc). - - {b See also}: {!sort_kind} - def_API('get_sort_kind', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_sort_kind : context -> sort -> sort_kind - = "camlidl_z3V3_Z3_get_sort_kind" - -(** - Summary: \[ [ get_bv_sort_size c t ] \] - Return the size of the given bit-vector sort. - - {b Precondition}: get_sort_kind c t == BV_SORT - - {b See also}: {!mk_bv_sort} - - {b See also}: {!get_sort_kind} - def_API('get_bv_sort_size', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_bv_sort_size : context -> sort -> int - = "camlidl_z3V3_Z3_get_bv_sort_size" + (** Indicates whether the term is remainder (binary) *) + val is_remainder : Expr.expr -> bool -(** - Summary: Return the size of the sort in [r]. Return [None] if the call failed. - That is, get_sort_kind(s) == FINITE_DOMAIN_SORT - def_API('get_finite_domain_sort_size', BOOL, (_in(CONTEXT), _in(SORT), _out(UINT64))) -*) -external get_finite_domain_sort_size : context -> sort -> int64 option - = "camlidl_z3V3_Z3_get_finite_domain_sort_size" - -(** - Summary: \[ [ get_array_sort_domain c t ] \] - Return the domain of the given array sort. - - {b Precondition}: get_sort_kind c t == ARRAY_SORT - - {b See also}: {!mk_array_sort} - - {b See also}: {!get_sort_kind} - def_API('get_array_sort_domain', SORT, (_in(CONTEXT), _in(SORT))) -*) -external get_array_sort_domain : context -> sort -> sort - = "camlidl_z3V3_Z3_get_array_sort_domain" - -(** - Summary: \[ [ get_array_sort_range c t ] \] - Return the range of the given array sort. - - {b Precondition}: get_sort_kind c t == ARRAY_SORT - - {b See also}: {!mk_array_sort} - - {b See also}: {!get_sort_kind} - def_API('get_array_sort_range', SORT, (_in(CONTEXT), _in(SORT))) -*) -external get_array_sort_range : context -> sort -> sort - = "camlidl_z3V3_Z3_get_array_sort_range" - -(** - Summary: \[ [ get_tuple_sort_mk_decl c t ] \] - Return the constructor declaration of the given tuple - sort. - - {b Precondition}: get_sort_kind c t == DATATYPE_SORT - - {b See also}: {!mk_tuple_sort} - - {b See also}: {!get_sort_kind} - def_API('get_tuple_sort_mk_decl', FUNC_DECL, (_in(CONTEXT), _in(SORT))) -*) -external get_tuple_sort_mk_decl : context -> sort -> func_decl - = "camlidl_z3V3_Z3_get_tuple_sort_mk_decl" - -(** - Summary: \[ [ get_tuple_sort_num_fields c t ] \] - Return the number of fields of the given tuple sort. - - {b Precondition}: get_sort_kind c t == DATATYPE_SORT - - {b See also}: {!mk_tuple_sort} - - {b See also}: {!get_sort_kind} - def_API('get_tuple_sort_num_fields', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_tuple_sort_num_fields : context -> sort -> int - = "camlidl_z3V3_Z3_get_tuple_sort_num_fields" - -(** - Summary: \[ [ get_tuple_sort_field_decl c t i ] \] - Return the i-th field declaration (i.e., projection function declaration) - of the given tuple sort. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: i < get_tuple_sort_num_fields c t - - {b See also}: {!mk_tuple_sort} - - {b See also}: {!get_sort_kind} - def_API('get_tuple_sort_field_decl', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_tuple_sort_field_decl : context -> sort -> int -> func_decl - = "camlidl_z3V3_Z3_get_tuple_sort_field_decl" - -(** - Summary: Return number of constructors for datatype. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_recognizer} - - {b See also}: {!get_datatype_sort_constructor_accessor} - def_API('get_datatype_sort_num_constructors', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_datatype_sort_num_constructors : context -> sort -> int - = "camlidl_z3V3_Z3_get_datatype_sort_num_constructors" - -(** - Summary: Return idx'th constructor. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: idx < get_datatype_sort_num_constructors c t - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_recognizer} - - {b See also}: {!get_datatype_sort_constructor_accessor} - def_API('get_datatype_sort_constructor', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_datatype_sort_constructor : context -> sort -> int -> func_decl - = "camlidl_z3V3_Z3_get_datatype_sort_constructor" - -(** - Summary: Return idx'th recognizer. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: idx < get_datatype_sort_num_constructors c t - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_constructor_accessor} - def_API('get_datatype_sort_recognizer', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_datatype_sort_recognizer : context -> sort -> int -> func_decl - = "camlidl_z3V3_Z3_get_datatype_sort_recognizer" - -(** - Summary: Return idx_a'th accessor for the idx_c'th constructor. - - {b Precondition}: get_sort_kind t == DATATYPE_SORT - - {b Precondition}: idx_c < get_datatype_sort_num_constructors c t - - {b Precondition}: idx_a < get_domain_size c get_datatype_sort_constructor c idx_c - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_recognizer} - def_API('get_datatype_sort_constructor_accessor', FUNC_DECL, (_in(CONTEXT), _in(SORT), _in(UINT), _in(UINT))) -*) -external get_datatype_sort_constructor_accessor : context -> sort -> int -> int -> func_decl - = "camlidl_z3V3_Z3_get_datatype_sort_constructor_accessor" - -(** - Summary: Return arity of relation. - - {b Precondition}: get_sort_kind s == RELATION_SORT - - {b See also}: {!get_relation_column} - def_API('get_relation_arity', UINT, (_in(CONTEXT), _in(SORT))) -*) -external get_relation_arity : context -> sort -> int - = "camlidl_z3V3_Z3_get_relation_arity" - -(** - Summary: Return sort at i'th column of relation sort. - - {b Precondition}: get_sort_kind c s == RELATION_SORT - - {b Precondition}: col < get_relation_arity c s - - {b See also}: {!get_relation_arity} - def_API('get_relation_column', SORT, (_in(CONTEXT), _in(SORT), _in(UINT))) -*) -external get_relation_column : context -> sort -> int -> sort - = "camlidl_z3V3_Z3_get_relation_column" + (** Indicates whether the term is modulus (binary) *) + val is_modulus : Expr.expr -> bool -(** - {3 {L Function Declarations}} -*) -(** - Summary: Convert a [func_decl] into [ast]. - - {b Remarks}: [func_decl_to_ast c f] can be replaced by [(f :> ast)]. - def_API('func_decl_to_ast', AST, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external func_decl_to_ast : context -> func_decl -> ast - = "camlidl_z3V3_Z3_func_decl_to_ast" + (** Indicates whether the term is a coercion of integer to real (unary) *) + val is_inttoreal : Expr.expr -> bool -(** - Summary: compare terms. - - {b Remarks}: [Pervasives.( = )] or [Pervasives.compare] can also be used. - def_API('is_eq_func_decl', BOOL, (_in(CONTEXT), _in(FUNC_DECL), _in(FUNC_DECL))) -*) -external is_eq_func_decl : context -> func_decl -> func_decl -> bool - = "camlidl_z3V3_Z3_is_eq_func_decl" + (** Indicates whether the term is a coercion of real to integer (unary) *) + val is_real_to_int : Expr.expr -> bool -(** - Summary: Return a unique identifier for [f]. - - {b Remarks}: Implicitly used by [Pervasives.( = )] and [Pervasives.compare]. - def_API('get_func_decl_id', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_func_decl_id : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_func_decl_id" + (** Indicates whether the term is a check that tests whether a real is integral (unary) *) + val is_real_is_int : Expr.expr -> bool -(** - Summary: Return the constant declaration name as a symbol. - def_API('get_decl_name', SYMBOL, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_decl_name : context -> func_decl -> symbol - = "camlidl_z3V3_Z3_get_decl_name" + (** Indicates whether the term is of sort real. *) + val is_real : Expr.expr -> bool -(** - Summary: Return declaration kind corresponding to declaration. - def_API('get_decl_kind', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_decl_kind : context -> func_decl -> decl_kind - = "camlidl_z3V3_Z3_get_decl_kind" + (** Indicates whether the term is an integer numeral. *) + val is_int_numeral : Expr.expr -> bool -(** - Summary: Return the number of parameters of the given declaration. - - {b See also}: {!get_arity} - def_API('get_domain_size', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_domain_size : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_domain_size" + (** Indicates whether the term is a real numeral. *) + val is_rat_num : Expr.expr -> bool -(** - Summary: Alias for [get_domain_size]. - - {b See also}: {!get_domain_size} - def_API('get_arity', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_arity : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_arity" - -(** - Summary: \[ [ get_domain c d i ] \] - Return the sort of the i-th parameter of the given function declaration. - - {b Precondition}: i < get_domain_size d - - {b See also}: {!get_domain_size} - def_API('get_domain', SORT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_domain : context -> func_decl -> int -> sort - = "camlidl_z3V3_Z3_get_domain" - -(** - Summary: \[ [ get_range c d ] \] - Return the range of the given declaration. - If [d] is a constant (i.e., has zero arguments), then this - function returns the sort of the constant. - def_API('get_range', SORT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_range : context -> func_decl -> sort - = "camlidl_z3V3_Z3_get_range" + (** Indicates whether the term is an algebraic number *) + val is_algebraic_number : Expr.expr -> bool -(** - Summary: Return the number of parameters associated with a declaration. - def_API('get_decl_num_parameters', UINT, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external get_decl_num_parameters : context -> func_decl -> int - = "camlidl_z3V3_Z3_get_decl_num_parameters" - -(** - Summary: Return the parameter type associated with a declaration. - @param c the context - @param d the function declaration - @param idx is the index of the named parameter it should be between 0 and the number of parameters. - def_API('get_decl_parameter_kind', UINT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_parameter_kind : context -> func_decl -> int -> parameter_kind - = "camlidl_z3V3_Z3_get_decl_parameter_kind" + (** Create an expression representing t[0] + t[1] + .... *) + val mk_add : context -> Expr.expr list -> Expr.expr -(** - Summary: Return the integer value associated with an integer parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_INT - def_API('get_decl_int_parameter', INT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_int_parameter : context -> func_decl -> int -> int - = "camlidl_z3V3_Z3_get_decl_int_parameter" + (** Create an expression representing t[0] * t[1] * .... *) + val mk_mul : context -> Expr.expr list -> Expr.expr -(** - Summary: Return the double value associated with an double parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_DOUBLE - def_API('get_decl_double_parameter', DOUBLE, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_double_parameter : context -> func_decl -> int -> float - = "camlidl_z3V3_Z3_get_decl_double_parameter" + (** Create an expression representing t[0] - t[1] - .... *) + val mk_sub : context -> Expr.expr list -> Expr.expr -(** - Summary: Return the double value associated with an double parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_SYMBOL - def_API('get_decl_symbol_parameter', SYMBOL, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_symbol_parameter : context -> func_decl -> int -> symbol - = "camlidl_z3V3_Z3_get_decl_symbol_parameter" + (** Create an expression representing -t. *) + val mk_unary_minus : context -> Expr.expr -> Expr.expr -(** - Summary: Return the sort value associated with a sort parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_SORT - def_API('get_decl_sort_parameter', SORT, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_sort_parameter : context -> func_decl -> int -> sort - = "camlidl_z3V3_Z3_get_decl_sort_parameter" + (** Create an expression representing t1 / t2. *) + val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: Return the expresson value associated with an expression parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_AST - def_API('get_decl_ast_parameter', AST, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_ast_parameter : context -> func_decl -> int -> ast - = "camlidl_z3V3_Z3_get_decl_ast_parameter" + (** Create an expression representing t1 ^ t2. *) + val mk_power : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: Return the expresson value associated with an expression parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_FUNC_DECL - def_API('get_decl_func_decl_parameter', FUNC_DECL, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_func_decl_parameter : context -> func_decl -> int -> func_decl - = "camlidl_z3V3_Z3_get_decl_func_decl_parameter" + (** Create an expression representing t1 < t2 *) + val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: Return the rational value, as a string, associated with a rational parameter. - - {b Precondition}: get_decl_parameter_kind c d idx == PARAMETER_RATIONAL - def_API('get_decl_rational_parameter', STRING, (_in(CONTEXT), _in(FUNC_DECL), _in(UINT))) -*) -external get_decl_rational_parameter : context -> func_decl -> int -> string - = "camlidl_z3V3_Z3_get_decl_rational_parameter" + (** Create an expression representing t1 <= t2 *) + val mk_le : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - {3 {L Applications}} -*) -(** - Summary: Convert a [app] into [ast]. - - {b Remarks}: [app_to_ast c a] can be replaced by [(a :> ast)]. - def_API('app_to_ast', AST, (_in(CONTEXT), _in(APP))) -*) -external app_to_ast : context -> app -> ast - = "camlidl_z3V3_Z3_app_to_ast" + (** Create an expression representing t1 > t2 *) + val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr -(** - Summary: Return the declaration of a constant or function application. - def_API('get_app_decl', FUNC_DECL, (_in(CONTEXT), _in(APP))) -*) -external get_app_decl : context -> app -> func_decl - = "camlidl_z3V3_Z3_get_app_decl" - -(** - Summary: \[ [ get_app_num_args c a ] \] - Return the number of argument of an application. If [t] - is an constant, then the number of arguments is 0. - def_API('get_app_num_args', UINT, (_in(CONTEXT), _in(APP))) -*) -external get_app_num_args : context -> app -> int - = "camlidl_z3V3_Z3_get_app_num_args" - -(** - Summary: \[ [ get_app_arg c a i ] \] - Return the i-th argument of the given application. - - {b Precondition}: i < get_num_args c a - def_API('get_app_arg', AST, (_in(CONTEXT), _in(APP), _in(UINT))) -*) -external get_app_arg : context -> app -> int -> ast - = "camlidl_z3V3_Z3_get_app_arg" + (** Create an expression representing t1 >= t2 *) + val mk_ge : context -> Expr.expr -> Expr.expr -> Expr.expr +end -(** - {3 {L Terms}} -*) -(** - Summary: compare terms. - - {b Remarks}: [Pervasives.( = )] or [Pervasives.compare] can also be used. - def_API('is_eq_ast', BOOL, (_in(CONTEXT), _in(AST), _in(AST))) -*) -external is_eq_ast : context -> ast -> ast -> bool - = "camlidl_z3V3_Z3_is_eq_ast" +(** Functions to manipulate bit-vector expressions *) +module BitVector : +sig + (** Create a new bit-vector sort. *) + val mk_sort : context -> int -> Sort.sort -(** - Summary: Return a unique identifier for [t]. - - {b Remarks}: Implicitly used by [Pervasives.compare] for values of type [ast], [app], [sort], [func_decl], and [pattern]. - def_API('get_ast_id', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_ast_id : context -> ast -> int - = "camlidl_z3V3_Z3_get_ast_id" + (** Indicates whether the terms is of bit-vector sort. *) + val is_bv : Expr.expr -> bool -(** - Summary: Return a hash code for the given AST. - - {b Remarks}: Implicitly used by [Hashtbl.hash] for values of type [ast], [app], [sort], [func_decl], and [pattern]. - def_API('get_ast_hash', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_ast_hash : context -> ast -> int - = "camlidl_z3V3_Z3_get_ast_hash" + (** Indicates whether the term is a bit-vector numeral *) + val is_bv_numeral : Expr.expr -> bool -(** - Summary: Return the sort of an AST node. - The AST node must be a constant, application, numeral, bound variable, or quantifier. - def_API('get_sort', SORT, (_in(CONTEXT), _in(AST))) -*) -external get_sort : context -> ast -> sort - = "camlidl_z3V3_Z3_get_sort" + (** Indicates whether the term is a one-bit bit-vector with value one *) + val is_bv_bit1 : Expr.expr -> bool -(** - Summary: Return true if the given expression [t] is well sorted. - def_API('is_well_sorted', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_well_sorted : context -> ast -> bool - = "camlidl_z3V3_Z3_is_well_sorted" + (** Indicates whether the term is a one-bit bit-vector with value zero *) + val is_bv_bit0 : Expr.expr -> bool -(** - Summary: Return L_TRUE if [a] is true, L_FALSE if it is false, and L_UNDEF otherwise. - def_API('get_bool_value', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_bool_value : context -> ast -> lbool - = "camlidl_z3V3_Z3_get_bool_value" + (** Indicates whether the term is a bit-vector unary minus *) + val is_bv_uminus : Expr.expr -> bool -(** - Summary: Return the kind of the given AST. - def_API('get_ast_kind', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_ast_kind : context -> ast -> ast_kind - = "camlidl_z3V3_Z3_get_ast_kind" + (** Indicates whether the term is a bit-vector addition (binary) *) + val is_bv_add : Expr.expr -> bool -(** - def_API('is_app', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_app : context -> ast -> bool - = "camlidl_z3V3_Z3_is_app" + (** Indicates whether the term is a bit-vector subtraction (binary) *) + val is_bv_sub : Expr.expr -> bool -(** - def_API('is_numeral_ast', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_numeral_ast : context -> ast -> bool - = "camlidl_z3V3_Z3_is_numeral_ast" + (** Indicates whether the term is a bit-vector multiplication (binary) *) + val is_bv_mul : Expr.expr -> bool -(** - Summary: Return true if the give AST is a real algebraic number. - def_API('is_algebraic_number', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_algebraic_number : context -> ast -> bool - = "camlidl_z3V3_Z3_is_algebraic_number" + (** Indicates whether the term is a bit-vector signed division (binary) *) + val is_bv_sdiv : Expr.expr -> bool -(** - Summary: Convert an [ast] into an [APP_AST]. - - {b Precondition}: {v get_ast_kind c a == [APP_AST] v} - def_API('to_app', APP, (_in(CONTEXT), _in(AST))) -*) -external to_app : context -> ast -> app - = "camlidl_z3V3_Z3_to_app" + (** Indicates whether the term is a bit-vector unsigned division (binary) *) + val is_bv_udiv : Expr.expr -> bool -(** - Summary: Convert an AST into a FUNC_DECL_AST. This is just type casting. - - {b Precondition}: {v get_ast_kind c a == FUNC_DECL_AST v} - def_API('to_func_decl', FUNC_DECL, (_in(CONTEXT), _in(AST))) -*) -external to_func_decl : context -> ast -> func_decl - = "camlidl_z3V3_Z3_to_func_decl" + (** Indicates whether the term is a bit-vector signed remainder (binary) *) + val is_bv_SRem : Expr.expr -> bool -(** - {4 {L Numerals}} -*) -(** - {5 {L Low-level API}} -*) -(** - Summary: Return numeral value, as a string of a numeric constant term - - {b Precondition}: get_ast_kind c a == NUMERAL_AST - def_API('get_numeral_string', STRING, (_in(CONTEXT), _in(AST))) -*) -external get_numeral_string : context -> ast -> string - = "camlidl_z3V3_Z3_get_numeral_string" - -(** - Summary: Return numeral as a string in decimal notation. - The result has at most [precision] decimal places. - - {b Precondition}: get_ast_kind c a == NUMERAL_AST || is_algebraic_number c a - def_API('get_numeral_decimal_string', STRING, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_numeral_decimal_string : context -> ast -> int -> string - = "camlidl_z3V3_Z3_get_numeral_decimal_string" + (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) + val is_bv_urem : Expr.expr -> bool -(** - Summary: Return the numerator (as a numeral AST) of a numeral AST of sort Real. - - {b Precondition}: get_ast_kind c a == NUMERAL_AST - def_API('get_numerator', AST, (_in(CONTEXT), _in(AST))) -*) -external get_numerator : context -> ast -> ast - = "camlidl_z3V3_Z3_get_numerator" + (** Indicates whether the term is a bit-vector signed modulus *) + val is_bv_smod : Expr.expr -> bool -(** - Summary: Return the denominator (as a numeral AST) of a numeral AST of sort Real. - - {b Precondition}: get_ast_kind c a == NUMERAL_AST - def_API('get_denominator', AST, (_in(CONTEXT), _in(AST))) -*) -external get_denominator : context -> ast -> ast - = "camlidl_z3V3_Z3_get_denominator" - -(** - Summary: Return numeral value, as a pair of 64 bit numbers if the representation fits. - @param c logical context. - @param a term. - @param num numerator. - @param den denominator. - Return [TRUE] if the numeral value fits in 64 bit numerals, [FALSE] otherwise. - - {b Precondition}: get_ast_kind a == NUMERAL_AST - def_API('get_numeral_small', BOOL, (_in(CONTEXT), _in(AST), _out(INT64), _out(INT64))) -*) -external get_numeral_small : context -> ast -> bool * int64 * int64 - = "camlidl_z3V3_Z3_get_numeral_small" - -(** - Summary: \[ [ get_numeral_int c v ] \] - Similar to {!get_numeral_string}, but only succeeds if - the value can fit in a machine int. Return TRUE if the call succeeded. - - {b Precondition}: get_ast_kind c v == NUMERAL_AST - - {b See also}: {!get_numeral_string} - def_API('get_numeral_int', BOOL, (_in(CONTEXT), _in(AST), _out(INT))) -*) -external get_numeral_int : context -> ast -> bool * int - = "camlidl_z3V3_Z3_get_numeral_int" - -(** - Summary: \[ [ get_numeral_int64 c v ] \] - Similar to {!get_numeral_string}, but only succeeds if - the value can fit in a machine long long int. Return TRUE if the call succeeded. - - {b Precondition}: get_ast_kind c v == NUMERAL_AST - - {b See also}: {!get_numeral_string} - def_API('get_numeral_int64', BOOL, (_in(CONTEXT), _in(AST), _out(INT64))) -*) -external get_numeral_int64 : context -> ast -> bool * int64 - = "camlidl_z3V3_Z3_get_numeral_int64" - -(** - Summary: \[ [ get_numeral_rational_int64 c x y] \] - Similar to {!get_numeral_string}, but only succeeds if - the value can fit as a rational number as machine long long int. Return TRUE if the call succeeded. - - {b Precondition}: get_ast_kind c v == NUMERAL_AST - - {b See also}: {!get_numeral_string} - def_API('get_numeral_rational_int64', BOOL, (_in(CONTEXT), _in(AST), _out(INT64), _out(INT64))) -*) -external get_numeral_rational_int64 : context -> ast -> bool * int64 * int64 - = "camlidl_z3V3_Z3_get_numeral_rational_int64" - -(** - Summary: Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - The result is a numeral AST of sort Real. - - {b Precondition}: is_algebraic_number c a - def_API('get_algebraic_number_lower', AST, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_algebraic_number_lower : context -> ast -> int -> ast - = "camlidl_z3V3_Z3_get_algebraic_number_lower" - -(** - Summary: Return a upper bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - The result is a numeral AST of sort Real. - - {b Precondition}: is_algebraic_number c a - def_API('get_algebraic_number_upper', AST, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_algebraic_number_upper : context -> ast -> int -> ast - = "camlidl_z3V3_Z3_get_algebraic_number_upper" + (** Indicates whether the term is a bit-vector signed division by zero *) + val is_bv_sdiv0 : Expr.expr -> bool -(** - {4 {L Patterns}} -*) -(** - Summary: Convert a pattern into ast. - - {b Remarks}: [pattern_to_ast c p] can be replaced by [(p :> ast)]. - def_API('pattern_to_ast', AST, (_in(CONTEXT), _in(PATTERN))) -*) -external pattern_to_ast : context -> pattern -> ast - = "camlidl_z3V3_Z3_pattern_to_ast" + (** Indicates whether the term is a bit-vector unsigned division by zero *) + val is_bv_udiv0 : Expr.expr -> bool -(** - Summary: Return number of terms in pattern. - def_API('get_pattern_num_terms', UINT, (_in(CONTEXT), _in(PATTERN))) -*) -external get_pattern_num_terms : context -> pattern -> int - = "camlidl_z3V3_Z3_get_pattern_num_terms" + (** Indicates whether the term is a bit-vector signed remainder by zero *) + val is_bv_srem0 : Expr.expr -> bool -(** - Summary: Return i'th ast in pattern. - def_API('get_pattern', AST, (_in(CONTEXT), _in(PATTERN), _in(UINT))) -*) -external get_pattern : context -> pattern -> int -> ast - = "camlidl_z3V3_Z3_get_pattern" + (** Indicates whether the term is a bit-vector unsigned remainder by zero *) + val is_bv_urem0 : Expr.expr -> bool -(** - {4 {L Quantifiers}} -*) -(** - Summary: Return index of de-Brujin bound variable. - - {b Precondition}: get_ast_kind a == VAR_AST - def_API('get_index_value', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_index_value : context -> ast -> int - = "camlidl_z3V3_Z3_get_index_value" + (** Indicates whether the term is a bit-vector signed modulus by zero *) + val is_bv_smod0 : Expr.expr -> bool -(** - Summary: Determine if quantifier is universal. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('is_quantifier_forall', BOOL, (_in(CONTEXT), _in(AST))) -*) -external is_quantifier_forall : context -> ast -> bool - = "camlidl_z3V3_Z3_is_quantifier_forall" + (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) + val is_bv_ule : Expr.expr -> bool -(** - Summary: Obtain weight of quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_weight', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_weight : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_weight" + (** Indicates whether the term is a signed bit-vector less-than-or-equal *) + val is_bv_sle : Expr.expr -> bool -(** - Summary: Return number of patterns used in quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_num_patterns', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_num_patterns : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_num_patterns" + (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) + val is_bv_uge : Expr.expr -> bool -(** - Summary: Return i'th pattern. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_pattern_ast', PATTERN, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_pattern_ast : context -> ast -> int -> pattern - = "camlidl_z3V3_Z3_get_quantifier_pattern_ast" + (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) + val is_bv_sge : Expr.expr -> bool -(** - Summary: Return number of no_patterns used in quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_num_no_patterns', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_num_no_patterns : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_num_no_patterns" + (** Indicates whether the term is an unsigned bit-vector less-than *) + val is_bv_ult : Expr.expr -> bool -(** - Summary: Return i'th no_pattern. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_no_pattern_ast', AST, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_no_pattern_ast : context -> ast -> int -> ast - = "camlidl_z3V3_Z3_get_quantifier_no_pattern_ast" + (** Indicates whether the term is a signed bit-vector less-than *) + val is_bv_slt : Expr.expr -> bool -(** - Summary: Return number of bound variables of quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_num_bound', UINT, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_num_bound : context -> ast -> int - = "camlidl_z3V3_Z3_get_quantifier_num_bound" + (** Indicates whether the term is an unsigned bit-vector greater-than *) + val is_bv_ugt : Expr.expr -> bool -(** - Summary: Return symbol of the i'th bound variable. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_bound_name', SYMBOL, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_bound_name : context -> ast -> int -> symbol - = "camlidl_z3V3_Z3_get_quantifier_bound_name" + (** Indicates whether the term is a signed bit-vector greater-than *) + val is_bv_sgt : Expr.expr -> bool -(** - Summary: Return sort of the i'th bound variable. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_bound_sort', SORT, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external get_quantifier_bound_sort : context -> ast -> int -> sort - = "camlidl_z3V3_Z3_get_quantifier_bound_sort" + (** Indicates whether the term is a bit-wise AND *) + val is_bv_and : Expr.expr -> bool -(** - Summary: Return body of quantifier. - - {b Precondition}: get_ast_kind a == QUANTIFIER_AST - def_API('get_quantifier_body', AST, (_in(CONTEXT), _in(AST))) -*) -external get_quantifier_body : context -> ast -> ast - = "camlidl_z3V3_Z3_get_quantifier_body" + (** Indicates whether the term is a bit-wise OR *) + val is_bv_or : Expr.expr -> bool -(** - {3 {L Simplification}} -*) -(** - Summary: Interface to simplifier. - Provides an interface to the AST simplifier used by Z3. - def_API('simplify', AST, (_in(CONTEXT), _in(AST))) -*) -external simplify : context -> ast -> ast - = "camlidl_z3V3_Z3_simplify" + (** Indicates whether the term is a bit-wise NOT *) + val is_bv_not : Expr.expr -> bool -(** - {2 {L Modifiers}} -*) -(** - Summary: Update the arguments of term [a] using the arguments [args]. - The number of arguments [num_args] should coincide - with the number of arguments to [a]. - If [a] is a quantifier, then num_args has to be 1. - def_API('update_term', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST))) -*) -external update_term : context -> ast -> ast array -> ast - = "camlidl_z3V3_Z3_update_term" - -(** - Summary: Substitute every occurrence of {e from[i] } in [a] with {e to[i] }, for [i] smaller than [num_exprs]. - The result is the new AST. The arrays [from] and [to] must have size [num_exprs]. - For every [i] smaller than [num_exprs], we must have that sort of {e from[i] } must be equal to sort of {e to[i] }. - def_API('substitute', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST), _in_array(2, AST))) -*) -external substitute : context -> ast -> ast array -> ast array -> ast - = "camlidl_z3V3_Z3_substitute" + (** Indicates whether the term is a bit-wise XOR *) + val is_bv_xor : Expr.expr -> bool -(** - Summary: Substitute the free variables in [a] with the expressions in [to]. - For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term {e to[i] }. - def_API('substitute_vars', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST))) -*) -external substitute_vars : context -> ast -> ast array -> ast - = "camlidl_z3V3_Z3_substitute_vars" + (** Indicates whether the term is a bit-wise NAND *) + val is_bv_nand : Expr.expr -> bool -(** - {2 {L Interaction logging.}} -*) -(** - Summary: Log interaction to a file. - extra_API('open_log', INT, (_in(STRING),)) -*) -external open_log : string -> bool - = "camlidl_z3V3_Z3_open_log" - -(** - Summary: Append user-defined string to interaction log. - The interaction log is opened using open_log. - It contains the formulas that are checked using Z3. - You can use this command to append comments, for instance. - extra_API('append_log', VOID, (_in(STRING),)) -*) -external append_log : string -> unit - = "camlidl_z3V3_Z3_append_log" + (** Indicates whether the term is a bit-wise NOR *) + val is_bv_nor : Expr.expr -> bool -(** - Summary: Close interaction log. - extra_API('close_log', VOID, ()) -*) -external close_log : unit -> unit - = "camlidl_z3V3_Z3_close_log" - -(** - Summary: Enable/disable printing warning messages to the console. - Warnings are printed after passing [true], warning messages are - suppressed after calling this method with [false]. - def_API('toggle_warning_messages', VOID, (_in(BOOL),)) -*) -external toggle_warning_messages : bool -> unit - = "camlidl_z3V3_Z3_toggle_warning_messages" + (** Indicates whether the term is a bit-wise XNOR *) + val is_bv_xnor : Expr.expr -> bool -(** - {2 {L String conversion}} -*) -(** - Summary: Select mode for the format used for pretty-printing AST nodes. - The default mode for pretty printing AST nodes is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - - {b See also}: {!ast_to_string} - - {b See also}: {!pattern_to_string} - - {b See also}: {!func_decl_to_string} - def_API('set_ast_print_mode', VOID, (_in(CONTEXT), _in(PRINT_MODE))) -*) -external set_ast_print_mode : context -> ast_print_mode -> unit - = "camlidl_z3V3_Z3_set_ast_print_mode" - -(** - Summary: Convert the given AST node into a string. - - {b See also}: {!pattern_to_string} - - {b See also}: {!sort_to_string} - def_API('ast_to_string', STRING, (_in(CONTEXT), _in(AST))) -*) -external ast_to_string : context -> ast -> string - = "camlidl_z3V3_Z3_ast_to_string" + (** Indicates whether the term is a bit-vector concatenation (binary) *) + val is_bv_concat : Expr.expr -> bool -(** - def_API('pattern_to_string', STRING, (_in(CONTEXT), _in(PATTERN))) -*) -external pattern_to_string : context -> pattern -> string - = "camlidl_z3V3_Z3_pattern_to_string" + (** Indicates whether the term is a bit-vector sign extension *) + val is_bv_signextension : Expr.expr -> bool -(** - def_API('sort_to_string', STRING, (_in(CONTEXT), _in(SORT))) -*) -external sort_to_string : context -> sort -> string - = "camlidl_z3V3_Z3_sort_to_string" + (** Indicates whether the term is a bit-vector zero extension *) + val is_bv_zeroextension : Expr.expr -> bool -(** - def_API('func_decl_to_string', STRING, (_in(CONTEXT), _in(FUNC_DECL))) -*) -external func_decl_to_string : context -> func_decl -> string - = "camlidl_z3V3_Z3_func_decl_to_string" + (** Indicates whether the term is a bit-vector extraction *) + val is_bv_extract : Expr.expr -> bool -(** - Summary: Convert the given model into a string. - def_API('model_to_string', STRING, (_in(CONTEXT), _in(MODEL))) -*) -external model_to_string : context -> model -> string - = "camlidl_z3V3_Z3_model_to_string" - -(** - Summary: Convert the given benchmark into SMT-LIB formatted string. - @param c - context. - @param name - name of benchmark. The argument is optional. - @param logic - the benchmark logic. - @param status - the status string (sat, unsat, or unknown) - @param attributes - other attributes, such as source, difficulty or category. - @param num_assumptions - number of assumptions. - @param assumptions - auxiliary assumptions. - @param formula - formula to be checked for consistency in conjunction with assumptions. - def_API('benchmark_to_smtlib_string', STRING, (_in(CONTEXT), _in(STRING), _in(STRING), _in(STRING), _in(STRING), _in(UINT), _in_array(5, AST), _in(AST))) -*) -external benchmark_to_smtlib_string : context -> string -> string -> string -> string -> ast array -> ast -> string - = "camlidl_z3V3_Z3_benchmark_to_smtlib_string_bytecode" "camlidl_z3V3_Z3_benchmark_to_smtlib_string" + (** Indicates whether the term is a bit-vector repetition *) + val is_bv_repeat : Expr.expr -> bool -(** - {2 {L Parser interface}} -*) -(** - Summary: \[ [ parse_smtlib2_string c str ] \] - Parse the given string using the SMT-LIB2 parser. - It returns a formula comprising of the conjunction of assertions in the scope - (up to push/pop) at the end of the string. - def_API('parse_smtlib2_string', AST, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3V3_Z3_parse_smtlib2_string_bytecode" "camlidl_z3V3_Z3_parse_smtlib2_string" + (** Indicates whether the term is a bit-vector reduce OR *) + val is_bv_reduceor : Expr.expr -> bool -(** - Summary: Similar to {!parse_smtlib2_string}, but reads the benchmark from a file. - def_API('parse_smtlib2_file', AST, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - = "camlidl_z3V3_Z3_parse_smtlib2_file_bytecode" "camlidl_z3V3_Z3_parse_smtlib2_file" + (** Indicates whether the term is a bit-vector reduce AND *) + val is_bv_reduceand : Expr.expr -> bool -(** - {4 {L Low-level API}} -*) -(** - Summary: \[ [ parse_smtlib_string c str sort_names sorts decl_names decls ] \] - Parse the given string using the SMT-LIB parser. - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays [sort_names] and [decl_names] don't need to match the names - of the sorts and declarations in the arrays [sorts] and [decls]. This is an useful feature - since we can use arbitrary names to reference sorts and declarations defined using the C API. - The formulas, assumptions and declarations defined in [str] can be extracted using the functions: - {!get_smtlib_num_formulas}, {!get_smtlib_formula}, {!get_smtlib_num_assumptions}, {!get_smtlib_assumption}, - {!get_smtlib_num_decls}, and {!get_smtlib_decl}. - def_API('parse_smtlib_string', VOID, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3V3_Z3_parse_smtlib_string_bytecode" "camlidl_z3V3_Z3_parse_smtlib_string" + (** Indicates whether the term is a bit-vector comparison *) + val is_bv_comp : Expr.expr -> bool -(** - Summary: Similar to {!parse_smtlib_string}, but reads the benchmark from a file. - def_API('parse_smtlib_file', VOID, (_in(CONTEXT), _in(STRING), _in(UINT), _in_array(2, SYMBOL), _in_array(2, SORT), _in(UINT), _in_array(5, SYMBOL), _in_array(5, FUNC_DECL))) -*) -external parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - = "camlidl_z3V3_Z3_parse_smtlib_file_bytecode" "camlidl_z3V3_Z3_parse_smtlib_file" + (** Indicates whether the term is a bit-vector shift left *) + val is_bv_shiftleft : Expr.expr -> bool -(** - Summary: Return the number of SMTLIB formulas parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_formulas', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_formulas : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_formulas" - -(** - Summary: \[ [ get_smtlib_formula c i ] \] - Return the i-th formula parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_formulas c - def_API('get_smtlib_formula', AST, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_formula : context -> int -> ast - = "camlidl_z3V3_Z3_get_smtlib_formula" + (** Indicates whether the term is a bit-vector logical shift right *) + val is_bv_shiftrightlogical : Expr.expr -> bool -(** - Summary: Return the number of SMTLIB assumptions parsed by {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_assumptions', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_assumptions : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_assumptions" - -(** - Summary: \[ [ get_smtlib_assumption c i ] \] - Return the i-th assumption parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_assumptions c - def_API('get_smtlib_assumption', AST, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_assumption : context -> int -> ast - = "camlidl_z3V3_Z3_get_smtlib_assumption" + (** Indicates whether the term is a bit-vector arithmetic shift left *) + val is_bv_shiftrightarithmetic : Expr.expr -> bool -(** - Summary: Return the number of declarations parsed by {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_decls', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_decls : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_decls" - -(** - Summary: \[ [ get_smtlib_decl c i ] \] - Return the i-th declaration parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_decls c - def_API('get_smtlib_decl', FUNC_DECL, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_decl : context -> int -> func_decl - = "camlidl_z3V3_Z3_get_smtlib_decl" + (** Indicates whether the term is a bit-vector rotate left *) + val is_bv_rotateleft : Expr.expr -> bool -(** - Summary: Return the number of sorts parsed by {!parse_smtlib_string} or {!parse_smtlib_file}. - def_API('get_smtlib_num_sorts', UINT, (_in(CONTEXT), )) -*) -external get_smtlib_num_sorts : context -> int - = "camlidl_z3V3_Z3_get_smtlib_num_sorts" - -(** - Summary: \[ [ get_smtlib_sort c i ] \] - Return the i-th sort parsed by the last call to {!parse_smtlib_string} or {!parse_smtlib_file}. - - {b Precondition}: i < get_smtlib_num_sorts c - def_API('get_smtlib_sort', SORT, (_in(CONTEXT), _in(UINT))) -*) -external get_smtlib_sort : context -> int -> sort - = "camlidl_z3V3_Z3_get_smtlib_sort" + (** Indicates whether the term is a bit-vector rotate right *) + val is_bv_rotateright : Expr.expr -> bool -(** - Summary: \[ [ get_smtlib_error c ] \] - Retrieve that last error message information generated from parsing. - def_API('get_smtlib_error', STRING, (_in(CONTEXT), )) -*) -external get_smtlib_error : context -> string - = "camlidl_z3V3_Z3_get_smtlib_error" + (** Indicates whether the term is a bit-vector rotate left (extended) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) + val is_bv_rotateleftextended : Expr.expr -> bool -(** - {2 {L Miscellaneous}} -*) -(** - Summary: Return Z3 version number information. - def_API('get_version', VOID, (_out(UINT), _out(UINT), _out(UINT), _out(UINT))) -*) -external get_version : unit -> int * int * int * int - = "camlidl_z3V3_Z3_get_version" + (** Indicates whether the term is a bit-vector rotate right (extended) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) + val is_bv_rotaterightextended : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) -(** - Summary: Enable tracing messages tagged as [tag] when Z3 is compiled in debug mode. - It is a NOOP otherwise - def_API('enable_trace', VOID, (_in(STRING),)) -*) -external enable_trace : string -> unit - = "camlidl_z3V3_Z3_enable_trace" + (** Indicates whether the term is a coercion from bit-vector to integer + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + val is_int_to_bv : Expr.expr -> bool -(** - Summary: Disable tracing messages tagged as [tag] when Z3 is compiled in debug mode. - It is a NOOP otherwise - def_API('disable_trace', VOID, (_in(STRING),)) -*) -external disable_trace : string -> unit - = "camlidl_z3V3_Z3_disable_trace" - -(** - Summary: Reset all allocated resources. - Use this facility on out-of memory errors. - It allows discharging the previous state and resuming afresh. - Any pointers previously returned by the API - become invalid. - def_API('reset_memory', VOID, ()) -*) -external reset_memory : unit -> unit - = "camlidl_z3V3_Z3_reset_memory" + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + val is_bv_to_int : Expr.expr -> bool -(** - {2 {L External Theory Plugins}} -*) -(** - Summary: Create an interpreted theory sort. -*) -external theory_mk_sort : context -> theory -> symbol -> sort - = "camlidl_z3V3_Z3_theory_mk_sort" + (** Indicates whether the term is a bit-vector carry + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) + val is_bv_carry : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector ternary XOR + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) + val is_bv_xor3 : Expr.expr -> bool -(** - Summary: Create an interpreted theory constant value. Values are assumed to be different from each other. -*) -external theory_mk_value : context -> theory -> symbol -> sort -> ast - = "camlidl_z3V3_Z3_theory_mk_value" + (** The size of a bit-vector sort. *) + val get_size : Sort.sort -> int -(** - Summary: Create an interpreted constant for the given theory. -*) -external theory_mk_constant : context -> theory -> symbol -> sort -> ast - = "camlidl_z3V3_Z3_theory_mk_constant" + (** Retrieve the int value. *) + val get_int : Expr.expr -> int + + (** Returns a string representation of the numeral. *) + val to_string : Expr.expr -> string -(** - Summary: Create an interpreted function declaration for the given theory. -*) -external theory_mk_func_decl : context -> theory -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_theory_mk_func_decl" + (** Creates a bit-vector constant. *) + val mk_const : context -> Symbol.symbol -> int -> Expr.expr -(** - Summary: Return the context where the given theory is installed. -*) -external theory_get_context : theory -> context - = "camlidl_z3V3_Z3_theory_get_context" - -(** - Summary: Assert a theory axiom/lemmas during the search. - An axiom added at search level [n] will remain in the logical context until - level [n] is backtracked. - The callbacks for push ({!set_push_callback}) and pop - ({!set_pop_callback}) can be used to track when the search - level is increased (i.e., new case-split) and decreased (i.e., - case-split is backtracked). - Z3 tracks the theory axioms asserted. So, multiple assertions of the same axiom are - ignored. -*) -external theory_assert_axiom : theory -> ast -> unit - = "camlidl_z3V3_Z3_theory_assert_axiom" - -(** - Summary: Inform to the logical context that [lhs] and [rhs] have the same interpretation - in the model being built by theory [t]. If lhs = rhs is inconsistent with other theories, - then the logical context will backtrack. - For more information, see the paper "Model-Based Theory Combination" in the Z3 website. -*) -external theory_assume_eq : theory -> ast -> ast -> unit - = "camlidl_z3V3_Z3_theory_assume_eq" - -(** - Summary: Enable/disable the simplification of theory axioms asserted using {!theory_assert_axiom}. - By default, the simplification of theory specific operators is disabled. - That is, the reduce theory callbacks are not invoked for theory axioms. - The default behavior is useful when asserting axioms stating properties of theory operators. -*) -external theory_enable_axiom_simplification : theory -> bool -> unit - = "camlidl_z3V3_Z3_theory_enable_axiom_simplification" + (** Creates a bit-vector constant. *) + val mk_const_s : context -> string -> int -> Expr.expr -(** - Summary: Return the root of the equivalence class containing [n]. -*) -external theory_get_eqc_root : theory -> ast -> ast - = "camlidl_z3V3_Z3_theory_get_eqc_root" - -(** - Summary: Return the next element in the equivalence class containing [n]. - The elements in an equivalence class are organized in a circular list. - You can traverse the list by calling this function multiple times - using the result from the previous call. This is illustrated in the - code snippet below. - {v - ast curr = n; - do - curr = theory_get_eqc_next(theory, curr); - while (curr != n); - v} -*) -external theory_get_eqc_next : theory -> ast -> ast - = "camlidl_z3V3_Z3_theory_get_eqc_next" + (** Bitwise negation. + The argument must have a bit-vector sort. *) + val mk_not : context -> Expr.expr -> Expr.expr -(** - Summary: Return the number of parents of [n] that are operators of the given theory. -*) -external theory_get_num_parents : theory -> ast -> int - = "camlidl_z3V3_Z3_theory_get_num_parents" + (** Take conjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) + val mk_redand : context -> Expr.expr -> Expr.expr -(** - Summary: Return the i-th parent of [n]. - See {!theory_get_num_parents}. -*) -external theory_get_parent : theory -> ast -> int -> ast - = "camlidl_z3V3_Z3_theory_get_parent" + (** Take disjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) + val mk_redor : context -> Expr.expr -> Expr.expr + + (** Bitwise conjunction. + The arguments must have a bit-vector sort. *) + val mk_and : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bitwise disjunction. + The arguments must have a bit-vector sort. *) + val mk_or : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bitwise XOR. + The arguments must have a bit-vector sort. *) + val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bitwise NAND. + The arguments must have a bit-vector sort. *) + val mk_nand : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bitwise NOR. + The arguments must have a bit-vector sort. *) + val mk_nor : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bitwise XNOR. + The arguments must have a bit-vector sort. *) + val mk_xnor : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Standard two's complement unary minus. + The arguments must have a bit-vector sort. *) + val mk_neg : context -> Expr.expr -> Expr.expr + + (** Two's complement addition. + The arguments must have the same bit-vector sort. *) + val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement subtraction. + The arguments must have the same bit-vector sort. *) + val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement multiplication. + The arguments must have the same bit-vector sort. *) + val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Unsigned division. + + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. *) + val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Signed remainder. + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Unsigned less-than + + The arguments must have the same bit-vector sort. *) + val mk_ult : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement signed less-than + + The arguments must have the same bit-vector sort. *) + val mk_slt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Unsigned less-than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_ule : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement signed less-than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_sle : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Unsigned greater than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_uge : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement signed greater than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_sge : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Unsigned greater-than. + + The arguments must have the same bit-vector sort. *) + val mk_ugt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Two's complement signed greater-than. + + The arguments must have the same bit-vector sort. *) + val mk_sgt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bit-vector concatenation. + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). *) + val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Bit-vector extraction. + + Extract the bits between two limits from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. *) + val mk_extract : context -> int -> int -> Expr.expr -> Expr.expr + + (** Bit-vector sign extension. + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. *) + val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr + + (** Bit-vector zero extension. + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. *) + val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr + + (** Bit-vector repetition. *) + val mk_repeat : context -> int -> Expr.expr -> Expr.expr + + (** Shift left. + + It is equivalent to multiplication by 2^x where \c x is the value of third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling.*) + val mk_shl : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Logical shift right + + It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) + val mk_lshr : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Arithmetic shift right + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) + val mk_ashr : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Rotate Left. + Rotate bits of \c t to the left \c i times. *) + val mk_rotate_left : context -> int -> Expr.expr -> Expr.expr + + (** Rotate Right. + Rotate bits of \c t to the right \c i times.*) + val mk_rotate_right : context -> int -> Expr.expr -> Expr.expr + + (** Rotate Left. + Rotate bits of the second argument to the left.*) + val mk_ext_rotate_left : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Rotate Right. + Rotate bits of the second argument to the right. *) + val mk_ext_rotate_right : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an integer from the bit-vector argument + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in the argument. + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function.*) + val mk_bv2int : context -> Expr.expr -> bool -> Expr.expr + + (** Create a predicate that checks that the bit-wise addition does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_add_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr + + (** Create a predicate that checks that the bit-wise addition does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_add_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a predicate that checks that the bit-wise subtraction does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_sub_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a predicate that checks that the bit-wise subtraction does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_sub_no_underflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr + + (** Create a predicate that checks that the bit-wise signed division does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_sdiv_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a predicate that checks that the bit-wise negation does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_neg_no_overflow : context -> Expr.expr -> Expr.expr + + (** Create a predicate that checks that the bit-wise multiplication does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_mul_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr + + (** Create a predicate that checks that the bit-wise multiplication does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a bit-vector numeral. *) + val mk_numeral : context -> string -> int -> Expr.expr +end + +(** Functions to manipulate proof expressions *) +module Proof : +sig + (** Indicates whether the term is a Proof for the expression 'true'. *) + val is_true : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact asserted by the user. *) + val is_asserted : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) + val is_goal : Expr.expr -> bool + + (** Indicates whether the term is proof via modus ponens + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). *) + val is_modus_ponens : Expr.expr -> bool + + (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. *) + val is_reflexivity : Expr.expr -> bool + + (** Indicates whether the term is proof by symmetricity of a relation + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. *) + val is_symmetry : Expr.expr -> bool + + (** Indicates whether the term is a proof by transitivity of a relation + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) *) + val is_transitivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by condensed transitivity of a relation + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. *) + val is_Transitivity_star : Expr.expr -> bool + + (** Indicates whether the term is a monotonicity proof object. + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. *) + val is_monotonicity : Expr.expr -> bool + + (** Indicates whether the term is a quant-intro proof + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) + val is_quant_intro : Expr.expr -> bool + + (** Indicates whether the term is a distributivity proof object. + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. *) + val is_distributivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by elimination of AND + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i *) + val is_and_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by eliminiation of not-or + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) *) + val is_or_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) + val is_rewrite : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) + val is_rewrite_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) + val is_pull_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents *) + val is_pull_quant_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pushing quantifiers in. + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents *) + val is_push_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for elimination of unused variables. + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. *) + val is_elim_unused_vars : Expr.expr -> bool + + (** Indicates whether the term is a proof for destructive equality resolution + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. *) + val is_der : Expr.expr -> bool + + (** Indicates whether the term is a proof for quantifier instantiation + + A proof of (or (not (forall (x) (P x))) (P a)) *) + val is_quant_inst : Expr.expr -> bool + + (** Indicates whether the term is a hypthesis marker. + Mark a hypothesis in a natural deduction style proof. *) + val is_hypothesis : Expr.expr -> bool + + (** Indicates whether the term is a proof by lemma + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. *) + val is_lemma : Expr.expr -> bool + + (** Indicates whether the term is a proof by unit resolution + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) + val is_unit_resolution : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-true + + T1: p + [iff-true T1]: (iff p true) *) + val is_iff_true : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-false + + T1: (not p) + [iff-false T1]: (iff p false) *) + val is_iff_false : Expr.expr -> bool + + (** Indicates whether the term is a proof by commutativity + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. *) + val is_commutativity : Expr.expr -> bool + + (** Indicates whether the term is a proof for Tseitin-like axioms + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). *) + val is_def_axiom : Expr.expr -> bool + + (** Indicates whether the term is a proof for introduction of a name + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) *) + val is_def_intro : Expr.expr -> bool + + (** Indicates whether the term is a proof for application of a definition + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. *) + val is_apply_def : Expr.expr -> bool + + (** Indicates whether the term is a proof iff-oeq + + T1: (iff p q) + [iff~ T1]: (~ p q) *) + val is_iff_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for a positive NNF step + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. *) + val is_nnf_pos : Expr.expr -> bool + + (** Indicates whether the term is a proof for a negative NNF step + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) *) + val is_nnf_neg : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + val is_nnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + val is_cnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for a Skolemization step + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. *) + val is_skolemize : Expr.expr -> bool + + (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q *) + val is_modus_ponens_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for theory lemma + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) + val is_theory_lemma : Expr.expr -> bool +end + +(** Goals + + A goal (aka problem). A goal is essentially a + of formulas, that can be solved and/or transformed using + tactics and solvers. *) +module Goal : +sig + type goal + + (** The precision of the goal. + + Goals can be transformed using over and under approximations. + An under approximation is applied when the objective is to find a model for a given goal. + An over approximation is applied when the objective is to find a proof for a given goal. *) + val get_precision : goal -> Z3enums.goal_prec + + (** Indicates whether the goal is precise. *) + val is_precise : goal -> bool + + (** Indicates whether the goal is an under-approximation. *) + val is_underapproximation : goal -> bool + + (** Indicates whether the goal is an over-approximation. *) + val is_overapproximation : goal -> bool + + (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) + val is_garbage : goal -> bool + + (** Adds the constraints to the given goal. *) + val add : goal -> Expr.expr list -> unit + + (** Indicates whether the goal contains `false'. *) + val is_inconsistent : goal -> bool + + (** The depth of the goal. + This tracks how many transformations were applied to it. *) + val get_depth : goal -> int + + (** Erases all formulas from the given goal. *) + val reset : goal -> unit + + (** The number of formulas in the goal. *) + val get_size : goal -> int + + (** The formulas in the goal. *) + val get_formulas : goal -> Expr.expr list + + (** The number of formulas, subformulas and terms in the goal. *) + val get_num_exprs : goal -> int + + (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) + val is_decided_sat : goal -> bool + + (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) + val is_decided_unsat : goal -> bool + + (** Translates (copies) the Goal to another context.. *) + val translate : goal -> context -> goal + + (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) + val simplify : goal -> Params.params option -> goal + + (** Creates a new Goal. + + Note that the Context must have been created with proof generation support if + the fourth argument is set to true here. *) + val mk_goal : context -> bool -> bool -> bool -> goal + + (** A string representation of the Goal. *) + val to_string : goal -> string +end + +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model : +sig + type model + + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. *) + module FuncInterp : + sig + type func_interp + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. *) + module FuncEntry : + sig + type func_entry + + (** Return the (symbolic) value of this entry. + *) + val get_value : func_entry -> Expr.expr + + (** The number of arguments of the entry. + *) + val get_num_args : func_entry -> int + + (** The arguments of the function entry. + *) + val get_args : func_entry -> Expr.expr list + + (** A string representation of the function entry. + *) + val to_string : func_entry -> string + end -(** - Summary: Return [TRUE] if [n] is an interpreted theory value. -*) -external theory_is_value : theory -> ast -> bool - = "camlidl_z3V3_Z3_theory_is_value" + (** The number of entries in the function interpretation. *) + val get_num_entries : func_interp -> int -(** - Summary: Return [TRUE] if [d] is an interpreted theory declaration. -*) -external theory_is_decl : theory -> func_decl -> bool - = "camlidl_z3V3_Z3_theory_is_decl" + (** The entries in the function interpretation *) + val get_entries : func_interp -> FuncEntry.func_entry list -(** - Summary: Return the number of expressions of the given theory in - the logical context. These are the expressions notified using the - callback {!set_new_elem_callback}. -*) -external theory_get_num_elems : theory -> int - = "camlidl_z3V3_Z3_theory_get_num_elems" + (** The (symbolic) `else' value of the function interpretation. *) + val get_else : func_interp -> Expr.expr -(** - Summary: Return the i-th elem of the given theory in the logical context. - - {b See}: {!theory_get_num_elems} -*) -external theory_get_elem : theory -> int -> ast - = "camlidl_z3V3_Z3_theory_get_elem" + (** The arity of the function interpretation *) + val get_arity : func_interp -> int -(** - Summary: Return the number of theory applications in the logical - context. These are the expressions notified using the callback - {!set_new_app_callback}. -*) -external theory_get_num_apps : theory -> int - = "camlidl_z3V3_Z3_theory_get_num_apps" + (** A string representation of the function interpretation. *) + val to_string : func_interp -> string + end -(** - Summary: Return the i-th application of the given theory in the logical context. - - {b See}: {!theory_get_num_apps} -*) -external theory_get_app : theory -> int -> ast - = "camlidl_z3V3_Z3_theory_get_app" + (** Retrieves the interpretation (the assignment) of a func_decl in the model. + An expression if the function has an interpretation in the model, null otherwise. *) + val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option -<<<<<<< HEAD -(** - {2 {L Deprecated Injective functions API}} -*) -(** - Summary: Create injective function declaration - @deprecated This method just asserts a (universally quantified) formula that asserts that - the new function is injective. It is compatible with the old interface for solving: - {!assert_cnstr}, {!check_assumptions}, etc. - def_API('mk_injective_function', FUNC_DECL, (_in(CONTEXT), _in(SYMBOL), _in(UINT), _in_array(2, SORT), _in(SORT))) -*) -external mk_injective_function : context -> symbol -> sort array -> sort -> func_decl - = "camlidl_z3V3_Z3_mk_injective_function" + (** Retrieves the interpretation (the assignment) of an expression in the model. + An expression if the constant has an interpretation in the model, null otherwise. *) + val get_const_interp_e : model -> Expr.expr -> Expr.expr option -(** - {2 {L Deprecated Constraints API}} -*) -(** - Summary: Set the SMTLIB logic to be used in the given logical context. - It is incorrect to invoke this function after invoking - {!check}, {!check_and_get_model}, {!check_assumptions} and {!push}. - Return [TRUE] if the logic was changed successfully, and [FALSE] otherwise. - @deprecated Subsumed by {!mk_solver_for_logic} - def_API('set_logic', VOID, (_in(CONTEXT), _in(STRING))) -*) -external set_logic : context -> string -> bool - = "camlidl_z3V3_Z3_set_logic" - -(** - Summary: Create a backtracking point. - The logical context can be viewed as a stack of contexts. The - scope level is the number of elements on this stack. The stack - of contexts is simulated using trail (undo) stacks. - - {b See also}: {!pop} - @deprecated Subsumed by {!solver_push} - def_API('push', VOID, (_in(CONTEXT),)) -*) -external push : context -> unit - = "camlidl_z3V3_Z3_push" - -(** - Summary: Backtrack. - Restores the context from the top of the stack, and pops it off the - stack. Any changes to the logical context (by {!assert_cnstr} or - other functions) between the matching {!push} and [pop] - operators are flushed, and the context is completely restored to - what it was right before the {!push}. - - {b See also}: {!push} - @deprecated Subsumed by {!solver_pop} - def_API('pop', VOID, (_in(CONTEXT), _in(UINT))) -*) -external pop : context -> int -> unit - = "camlidl_z3V3_Z3_pop" - -(** - Summary: Retrieve the current scope level. - It retrieves the number of scopes that have been pushed, but not yet popped. - - {b See also}: {!push} - - {b See also}: {!pop} - @deprecated Subsumed by {!solver_get_num_scopes}. - def_API('get_num_scopes', UINT, (_in(CONTEXT),)) -*) -external get_num_scopes : context -> int - = "camlidl_z3V3_Z3_get_num_scopes" + (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option -(** - @deprecated This function has no effect. - def_API('persist_ast', VOID, (_in(CONTEXT), _in(AST), _in(UINT))) -*) -external persist_ast : context -> ast -> int -> unit - = "camlidl_z3V3_Z3_persist_ast" - -(** - Summary: Assert a constraint into the logical context. - After one assertion, the logical context may become - inconsistent. - The functions {!check} or {!check_and_get_model} should be - used to check whether the logical context is consistent or not. - - {b See also}: {!check} - - {b See also}: {!check_and_get_model} - @deprecated Subsumed by {!solver_assert} - def_API('assert_cnstr', VOID, (_in(CONTEXT), _in(AST))) -*) -external assert_cnstr : context -> ast -> unit - = "camlidl_z3V3_Z3_assert_cnstr" - -(** - Summary: Check whether the given logical context is consistent or not. - If the logical context is not unsatisfiable (i.e., the return value is different from [L_FALSE)] - and model construction is enabled (see {!mk_config}), - then a valid model is returned. Otherwise, it is unsafe to use the returned model. - - {b Remarks}: Model construction must be enabled using configuration - parameters (See, {!mk_config}). - - {b See also}: {!check} - @deprecated Subsumed by {!solver_check} - def_API('check_and_get_model', INT, (_in(CONTEXT), _out(MODEL))) -*) -external check_and_get_model : context -> lbool * model - = "camlidl_z3V3_Z3_check_and_get_model" - -(** - Summary: Check whether the given logical context is consistent or not. - The function {!check_and_get_model} should be used when models are needed. - - {b See also}: {!check_and_get_model} - @deprecated Subsumed by {!solver_check} - def_API('check', INT, (_in(CONTEXT),)) -*) -external check : context -> lbool - = "camlidl_z3V3_Z3_check" - -(** - Summary: Check whether the given logical context and optional assumptions is consistent or not. - If the logical context is not unsatisfiable (i.e., the return value is different from [L_FALSE)], - and model construction is enabled (see {!mk_config}), - then a valid model is returned. Otherwise, it is unsafe to use the returned model. - @param c logical context. - @param num_assumptions number of auxiliary assumptions. - @param assumptions array of auxiliary assumptions - @param m optional pointer to a model. - @param proof optional pointer to a proof term. - @param core_size size of unsatisfiable core. - @param core pointer to an array receiving unsatisfiable core. - The unsatisfiable core is a subset of the assumptions, so the array has the same size as the assumptions. - The [core] array is not populated if [core_size] is set to 0. - - {b Precondition}: assumptions comprises of propositional literals. - In other words, you cannot use compound formulas for assumptions, - but should use propositional variables or negations of propositional variables. - - {b See also}: {!check} - @deprecated Subsumed by {!solver_check_assumptions} - def_API('check_assumptions', INT, (_in(CONTEXT), _in(UINT), _in_array(1, AST), _out(MODEL), _out(AST), _out(UINT), _out_array2(1, 5, AST))) -*) -external check_assumptions : context -> ast array -> int -> ast array -> lbool * model * ast * int * ast array - = "camlidl_z3V3_Z3_check_assumptions" - -(** - Summary: Delete a model object. - - {b See also}: {!check_and_get_model} - @deprecated Subsumed by solver API - def_API('del_model', VOID, (_in(CONTEXT), _in(MODEL))) -*) -external del_model : context -> model -> unit - = "camlidl_z3V3_Z3_del_model" + (** The number of constant interpretations in the model. *) + val get_num_consts : model -> int -(** - {2 {L Deprecated Search control API}} -*) -(** - Summary: Cancel an ongoing check. - Notifies the current check to abort and return. - This method should be called from a different thread - than the one performing the check. - @deprecated Use {!interrupt} instead. - def_API('soft_check_cancel', VOID, (_in(CONTEXT), )) -*) -external soft_check_cancel : context -> unit - = "camlidl_z3V3_Z3_soft_check_cancel" - -(** - Summary: Retrieve reason for search failure. - If a call to {!check} or {!check_and_get_model} returns L_UNDEF, - use this facility to determine the more detailed cause of search failure. - @deprecated Subsumed by {!solver_get_reason_unknown} - def_API('get_search_failure', UINT, (_in(CONTEXT), )) -*) -external get_search_failure : context -> search_failure - = "camlidl_z3V3_Z3_get_search_failure" + (** The function declarations of the constants in the model. *) + val get_const_decls : model -> FuncDecl.func_decl list -(** - {2 {L Deprecated Labels API}} -*) -(** - Summary: Create a labeled formula. - @param c logical context. - @param s name of the label. - @param is_pos label polarity. - @param f formula being labeled. - A label behaves as an identity function, so the truth value of the - labeled formula is unchanged. Labels are used for identifying - useful sub-formulas when generating counter-examples. - @deprecated Labels are only supported by the old Solver API. - This feature is not essential (it can be simulated using auxiliary Boolean variables). - It is only available for backward compatibility. - def_API('mk_label', AST, (_in(CONTEXT), _in(SYMBOL), _in(BOOL), _in(AST))) -*) -external mk_label : context -> symbol -> bool -> ast -> ast - = "camlidl_z3V3_Z3_mk_label" - -(** - Summary: Retrieve the set of labels that were relevant in - the context of the current satisfied context. - - {b See also}: {!del_literals} - - {b See also}: {!get_num_literals} - - {b See also}: {!get_label_symbol} - - {b See also}: {!get_literal} - @deprecated This procedure is based on the old Solver API. - def_API('get_relevant_labels', LITERALS, (_in(CONTEXT), )) -*) -external get_relevant_labels : context -> literals - = "camlidl_z3V3_Z3_get_relevant_labels" - -(** - Summary: Retrieve the set of literals that satisfy the current context. - - {b See also}: {!del_literals} - - {b See also}: {!get_num_literals} - - {b See also}: {!get_label_symbol} - - {b See also}: {!get_literal} - @deprecated This procedure is based on the old Solver API. - def_API('get_relevant_literals', LITERALS, (_in(CONTEXT), )) -*) -external get_relevant_literals : context -> literals - = "camlidl_z3V3_Z3_get_relevant_literals" - -(** - Summary: Retrieve the set of literals that whose assignment were - guess, but not propagated during the search. - - {b See also}: {!del_literals} - - {b See also}: {!get_num_literals} - - {b See also}: {!get_label_symbol} - - {b See also}: {!get_literal} - @deprecated This procedure is based on the old Solver API. - def_API('get_guessed_literals', LITERALS, (_in(CONTEXT), )) -*) -external get_guessed_literals : context -> literals - = "camlidl_z3V3_Z3_get_guessed_literals" - -(** - Summary: Delete a labels context. - - {b See also}: {!get_relevant_labels} - @deprecated This procedure is based on the old Solver API. - def_API('del_literals', VOID, (_in(CONTEXT), _in(LITERALS))) -*) -external del_literals : context -> literals -> unit - = "camlidl_z3V3_Z3_del_literals" - -(** - Summary: Retrieve the number of label symbols that were returned. - - {b See also}: {!get_relevant_labels} - @deprecated This procedure is based on the old Solver API. - def_API('get_num_literals', UINT, (_in(CONTEXT), _in(LITERALS))) -*) -external get_num_literals : context -> literals -> int - = "camlidl_z3V3_Z3_get_num_literals" + (** The number of function interpretations in the model. *) + val get_num_funcs : model -> int -(** - Summary: Retrieve label symbol at idx. - @deprecated This procedure is based on the old Solver API. - def_API('get_label_symbol', SYMBOL, (_in(CONTEXT), _in(LITERALS), _in(UINT))) -*) -external get_label_symbol : context -> literals -> int -> symbol - = "camlidl_z3V3_Z3_get_label_symbol" + (** The function declarations of the function interpretations in the model. *) + val get_func_decls : model -> FuncDecl.func_decl list -(** - Summary: Retrieve literal expression at idx. - @deprecated This procedure is based on the old Solver API. - def_API('get_literal', AST, (_in(CONTEXT), _in(LITERALS), _in(UINT))) -*) -external get_literal : context -> literals -> int -> ast - = "camlidl_z3V3_Z3_get_literal" - -(** - Summary: Disable label. - The disabled label is not going to be used when blocking the subsequent search. - - {b See also}: {!block_literals} - @deprecated This procedure is based on the old Solver API. - def_API('disable_literal', VOID, (_in(CONTEXT), _in(LITERALS), _in(UINT))) -*) -external disable_literal : context -> literals -> int -> unit - = "camlidl_z3V3_Z3_disable_literal" + (** All symbols that have an interpretation in the model. *) + val get_decls : model -> FuncDecl.func_decl list -(** - Summary: Block subsequent checks using the remaining enabled labels. - @deprecated This procedure is based on the old Solver API. - def_API('block_literals', VOID, (_in(CONTEXT), _in(LITERALS))) -*) -external block_literals : context -> literals -> unit - = "camlidl_z3V3_Z3_block_literals" + (** Evaluates an expression in the current model. + + This function may fail if the argument contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + *) + val eval : model -> Expr.expr -> bool -> Expr.expr option -(** - {2 {L Deprecated Model API}} -*) -(** - Summary: Return the number of constants assigned by the given model. - - {b Remarks}: Consider using {!get_model_constants}. - - {b See also}: {!get_model_constant} - @deprecated use {!model_get_num_consts} - def_API('get_model_num_constants', UINT, (_in(CONTEXT), _in(MODEL))) -*) -external get_model_num_constants : context -> model -> int - = "camlidl_z3V3_Z3_get_model_num_constants" - -(** - Summary: \[ [ get_model_constant c m i ] \] - Return the i-th constant in the given model. - - {b Remarks}: Consider using {!get_model_constants}. - - {b Precondition}: i < get_model_num_constants c m - @deprecated use {!model_get_const_decl} - def_API('get_model_constant', FUNC_DECL, (_in(CONTEXT), _in(MODEL), _in(UINT))) -*) -external get_model_constant : context -> model -> int -> func_decl - = "camlidl_z3V3_Z3_get_model_constant" - -(** - Summary: Return the number of function interpretations in the given model. - A function interpretation is represented as a finite map and an 'else' value. - Each entry in the finite map represents the value of a function given a set of arguments. - @deprecated use {!model_get_num_funcs} - def_API('get_model_num_funcs', UINT, (_in(CONTEXT), _in(MODEL))) -*) -external get_model_num_funcs : context -> model -> int - = "camlidl_z3V3_Z3_get_model_num_funcs" - -(** - Summary: \[ [ get_model_func_decl c m i ] \] - Return the declaration of the i-th function in the given model. - - {b Precondition}: i < get_model_num_funcs c m - - {b See also}: {!get_model_num_funcs} - @deprecated use {!model_get_func_decl} - def_API('get_model_func_decl', FUNC_DECL, (_in(CONTEXT), _in(MODEL), _in(UINT))) + (** Alias for eval. *) + val evaluate : model -> Expr.expr -> bool -> Expr.expr option + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + val get_num_sorts : model -> int + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + {!get_num_sorts} + {!sort_universe} *) + val get_sorts : model -> Sort.sort list + + (** The finite set of distinct values that represent the interpretation of a sort. + {!get_sorts} + @returns A list of expressions, where each is an element of the universe of the sort *) + val sort_universe : model -> Sort.sort -> AST.ast list + + (** Conversion of models to strings. + A string representation of the model. *) + val to_string : model -> string +end + +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. *) -external get_model_func_decl : context -> model -> int -> func_decl - = "camlidl_z3V3_Z3_get_model_func_decl" - -(** - Summary: Return the value of the given constant or function - in the given model. - @deprecated Consider using {!model_eval} or {!model_get_func_interp} - def_API('eval_func_decl', BOOL, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _out(AST))) +module Probe : +sig + type probe + + (** Execute the probe over the goal. + A probe always produce a float value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + val apply : probe -> Goal.goal -> float + + (** The number of supported Probes. *) + val get_num_probes : context -> int + + (** The names of all supported Probes. *) + val get_probe_names : context -> string list + + (** Returns a string containing a description of the probe with the given name. *) + val get_probe_description : context -> string -> string + + (** Creates a new Probe. *) + val mk_probe : context -> string -> probe + + (** Create a probe that always evaluates to a float value. *) + val const : context -> float -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than the value returned by second argument *) + val lt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than the value returned by second argument *) + val gt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than or equal the value returned by second argument *) + val le : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than or equal the value returned by second argument *) + val ge : context -> probe -> probe -> probe + + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is equal the value returned by second argument *) + val eq : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) + val and_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) + val or_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) + val not_ : context -> probe -> probe +end + +(** Tactics + + Tactics are the basic building block for creating custom solvers for specific problem domains. + The complete list of tactics may be obtained using Context.get_num_tactics + and Context.get_tactic_names. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. *) -external eval_func_decl : context -> model -> func_decl -> bool * ast - = "camlidl_z3V3_Z3_eval_func_decl" -======= +module Tactic : +sig + type tactic + + (** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) + module ApplyResult : + sig + type apply_result + + (** The number of Subgoals. *) + val get_num_subgoals : apply_result -> int + + (** Retrieves the subgoals from the apply_result. *) + val get_subgoals : apply_result -> Goal.goal list + + (** Retrieves a subgoal from the apply_result. *) + val get_subgoal : apply_result -> int -> Goal.goal + + (** Convert a model for a subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g *) + val convert_model : apply_result -> int -> Model.model -> Model.model + + (** A string representation of the ApplyResult. *) + val to_string : apply_result -> string + end + + (** A string containing a description of parameters accepted by the tactic. *) + val get_help : tactic -> string + + (** Retrieves parameter descriptions for Tactics. *) + val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs + + (** Apply the tactic to the goal. *) + val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result + + (** The number of supported tactics. *) + val get_num_tactics : context -> int + + (** The names of all supported tactics. *) + val get_tactic_names : context -> string list + + (** Returns a string containing a description of the tactic with the given name. *) + val get_tactic_description : context -> string -> string + + (** Creates a new Tactic. *) + val mk_tactic : context -> string -> tactic + + (** Create a tactic that applies one tactic to a Goal and + then another one to every subgoal produced by the first one. *) + val and_then : context -> tactic -> tactic -> tactic list -> tactic + + (** Create a tactic that first applies one tactic to a Goal and + if it fails then returns the result of another tactic applied to the Goal. *) + val or_else : context -> tactic -> tactic -> tactic + + (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). + + If the tactic does not terminate within the timeout, then it fails. *) + val try_for : context -> tactic -> int -> tactic + + (** Create a tactic that applies one tactic to a given goal if the probe + evaluates to true. + + If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) + val when_ : context -> Probe.probe -> tactic -> tactic + + (** Create a tactic that applies a tactic to a given goal if the probe + evaluates to true and another tactic otherwise. *) + val cond : context -> Probe.probe -> tactic -> tactic -> tactic + + (** Create a tactic that keeps applying one tactic until the goal is not + modified anymore or the maximum number of iterations is reached. *) + val repeat : context -> tactic -> int -> tactic + + (** Create a tactic that just returns the given goal. *) + val skip : context -> tactic + + (** Create a tactic always fails. *) + val fail : context -> tactic + + (** Create a tactic that fails if the probe evaluates to false. *) + val fail_if : context -> Probe.probe -> tactic + + (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) + val fail_if_not_decided : context -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. *) + val using_params : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. + Alias for UsingParams*) + val with_ : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies the given tactics in parallel. *) + val par_or : context -> tactic list -> tactic + + (** Create a tactic that applies a tactic to a given goal and then another tactic + to every subgoal produced by the first one. The subgoals are processed in parallel. *) + val par_and_then : context -> tactic -> tactic -> tactic + + (** Interrupt the execution of a Z3 procedure. + This procedure can be used to interrupt: solvers, simplifiers and tactics. *) + val interrupt : context -> unit +end + +(** Solvers *) +module Solver : +sig + type solver + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + val string_of_status : status -> string + + (** Objects that track statistical information about solvers. *) + module Statistics : + sig + type statistics + + (** Statistical data is organized into pairs of \[Key, Entry\], where every + Entry is either a floating point or integer value. + *) + module Entry : + sig + type statistics_entry + + (** The key of the entry. *) + val get_key : statistics_entry -> string + + (** The int-value of the entry. *) + val get_int : statistics_entry -> int + + (** The float-value of the entry. *) + val get_float : statistics_entry -> float + + (** True if the entry is uint-valued. *) + val is_int : statistics_entry -> bool + + (** True if the entry is float-valued. *) + val is_float : statistics_entry -> bool + + (** The string representation of the the entry's value. *) + val to_string_value : statistics_entry -> string + + (** The string representation of the entry (key and value) *) + val to_string : statistics_entry -> string + end + + (** A string representation of the statistical data. *) + val to_string : statistics -> string + + (** The number of statistical data. *) + val get_size : statistics -> int + + (** The data entries. *) + val get_entries : statistics -> Entry.statistics_entry list + + (** The statistical counters. *) + val get_keys : statistics -> string list + + (** The value of a particular statistical counter. *) + val get : statistics -> string -> Entry.statistics_entry option + end + + (** A string that describes all available solver parameters. *) + val get_help : solver -> string + + (** Sets the solver parameters. *) + val set_parameters : solver -> Params.params -> unit + + (** Retrieves parameter descriptions for solver. *) + val get_param_descrs : solver -> Params.ParamDescrs.param_descrs + + (** The current number of backtracking points (scopes). + {!pop} + {!push} *) + val get_num_scopes : solver -> int + + (** Creates a backtracking point. + {!pop} *) + val push : solver -> unit + + (** Backtracks a number of backtracking points. + Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} + {!push} *) + val pop : solver -> int -> unit + + (** Resets the Solver. + This removes all assertions from the solver. *) + val reset : solver -> unit + + (** Assert a constraint (or multiple) into the solver. *) + val add : solver -> Expr.expr list -> unit + + (** * Assert multiple constraints (cs) into the solver, and track them (in the + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track_l : solver -> Expr.expr list -> Expr.expr list -> unit + + (** * Assert a constraint (c) into the solver, and track it (in the unsat) core + * using the Boolean constant p. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track : solver -> Expr.expr -> Expr.expr -> unit + + (** The number of assertions in the solver. *) + val get_num_assertions : solver -> int + + (** The set of asserted formulas. *) + val get_assertions : solver -> Expr.expr list + + (** Checks whether the assertions in the solver are consistent or not. + + {!Model} + {!get_unsat_core} + {!Proof} *) + val check : solver -> Expr.expr list -> status + + (** The model of the last Check. + + The result is None if Check was not invoked before, + if its results was not SATISFIABLE, or if model production is not enabled. *) + val get_model : solver -> Model.model option + + (** The proof of the last Check. + + The result is null if Check was not invoked before, + if its results was not UNSATISFIABLE, or if proof production is disabled. *) + val get_proof : solver -> Expr.expr option + + (** The unsat core of the last Check. + + The unsat core is a subset of Assertions + The result is empty if Check was not invoked before, + if its results was not UNSATISFIABLE, or if core production is disabled. *) + val get_unsat_core : solver -> AST.ast list + + (** A brief justification of why the last call to Check returned UNKNOWN. *) + val get_reason_unknown : solver -> string + + (** Solver statistics. *) + val get_statistics : solver -> Statistics.statistics + + (** Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) + val mk_solver : context -> Symbol.symbol option -> solver + + (** Creates a new (incremental) solver. + {!mk_solver} *) + val mk_solver_s : context -> string -> solver + + (** Creates a new (incremental) solver. *) + val mk_simple_solver : context -> solver + + (** Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) + val mk_solver_t : context -> Tactic.tactic -> solver + + (** A string representation of the solver. *) + val to_string : solver -> string +end + +(** Fixedpoint solving *) +module Fixedpoint : +sig + type fixedpoint + + (** A string that describes all available fixedpoint solver parameters. *) + val get_help : fixedpoint -> string + + (** Sets the fixedpoint solver parameters. *) + val set_params : fixedpoint -> Params.params -> unit + + (** Retrieves parameter descriptions for Fixedpoint solver. *) + val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs + + (** Assert a constraints into the fixedpoint solver. *) + val add : fixedpoint -> Expr.expr list -> unit + + (** Register predicate as recursive relation. *) + val register_relation : fixedpoint -> FuncDecl.func_decl -> unit + + (** Add rule into the fixedpoint solver. *) + val add_rule : fixedpoint -> Expr.expr -> Symbol.symbol option -> unit + + (** Add table fact to the fixedpoint solver. *) + val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit + + (** Query the fixedpoint solver. + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. *) + val query : fixedpoint -> Expr.expr -> Solver.status + + (** Query the fixedpoint solver. + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. *) + val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status + + (** Creates a backtracking point. + {!pop} *) + val push : fixedpoint -> unit + + (** Backtrack one backtracking point. + + Note that an exception is thrown if Pop is called without a corresponding Push + {!push} *) + val pop : fixedpoint -> unit + + (** Update named rule into in the fixedpoint solver. *) + val update_rule : fixedpoint -> Expr.expr -> Symbol.symbol -> unit + + (** Retrieve satisfying instance or instances of solver, + or definitions for the recursive predicates that show unsatisfiability. *) + val get_answer : fixedpoint -> Expr.expr option + + (** Retrieve explanation why fixedpoint engine returned status Unknown. *) + val get_reason_unknown : fixedpoint -> string + + (** Retrieve the number of levels explored for a given predicate. *) + val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int + + (** Retrieve the cover of a predicate. *) + val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option + + (** Add property about the predicate. + The property is added at level. *) + val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit + + (** Retrieve internal string representation of fixedpoint object. *) + val to_string : fixedpoint -> string + + (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) + val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit + + (** Convert benchmark given as set of axioms, rules and queries to a string. *) + val to_string_q : fixedpoint -> Expr.expr list -> string + + (** Retrieve set of rules added to fixedpoint context. *) + val get_rules : fixedpoint -> Expr.expr list + + (** Retrieve set of assertions added to fixedpoint context. *) + val get_assertions : fixedpoint -> Expr.expr list + + (** Create a Fixedpoint context. *) + val mk_fixedpoint : context -> fixedpoint +end + (** Functions for handling SMT and SMT2 expressions and files *) module SMT : sig (** Convert a benchmark into an SMT-LIB formatted string. ->>>>>>> Updates to ML API. -(** - Summary: \[ [ is_array_value c v ] \] - Determine whether the term encodes an array value. - A term encodes an array value if it is a nested sequence of - applications of store on top of a constant array. - The indices to the stores have to be values (for example, integer constants) - so that equality between the indices can be evaluated. - Array values are useful for representing interpretations for arrays. - Return the number of entries mapping to non-default values of the array. - @deprecated Use {!is_as_array} - def_API('is_array_value', BOOL, (_in(CONTEXT), _in(MODEL), _in(AST), _out(UINT))) -*) -external is_array_value : context -> model -> ast -> bool * int - = "camlidl_z3V3_Z3_is_array_value" + @return A string representation of the benchmark. *) + val benchmark_to_smtstring : context -> string -> string -> string -> string -> Expr.expr list -> Expr.expr -> string -(** - Summary: \[ [ get_array_value c v ] \] - An array values is represented as a dictionary plus a - default (else) value. This function returns the array graph. - - {b Precondition}: TRUE == is_array_value c v &num_entries - @deprecated Use func_interp objects and {!get_as_array_func_decl} - def_API('get_array_value', VOID, (_in(CONTEXT), _in(MODEL), _in(AST), _in(UINT), _out_array(3, AST), _out_array(3, AST), _out (AST))) -*) -external get_array_value : context -> model -> ast -> ast array -> ast array -> ast array * ast array * ast - = "camlidl_z3V3_Z3_get_array_value" + (** Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays in the third and fifth argument + don't need to match the names of the sorts and declarations in the arrays in the fourth + and sixth argument. This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) + val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit -(** - Summary: \[ [ get_model_func_else c m i ] \] - Return the 'else' value of the i-th function interpretation in the given model. - A function interpretation is represented as a finite map and an 'else' value. - - {b Remarks}: Consider using {!get_model_funcs}. - - {b Precondition}: i < get_model_num_funcs c m - - {b See also}: {!get_model_num_funcs} - - {b See also}: {!get_model_func_num_entries} - - {b See also}: {!get_model_func_entry_num_args} - - {b See also}: {!get_model_func_entry_arg} - @deprecated Use func_interp objects - def_API('get_model_func_else', AST, (_in(CONTEXT), _in(MODEL), _in(UINT))) -*) -external get_model_func_else : context -> model -> int -> ast - = "camlidl_z3V3_Z3_get_model_func_else" + (** Parse the given file using the SMT-LIB parser. + {!parse_smtlib_string} *) + val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit -(** - Summary: \[ [ get_model_func_num_entries c m i ] \] - Return the number of entries of the i-th function interpretation in the given model. - A function interpretation is represented as a finite map and an 'else' value. - - {b Remarks}: Consider using {!get_model_funcs}. - - {b Precondition}: i < get_model_num_funcs c m - - {b See also}: {!get_model_num_funcs} - - {b See also}: {!get_model_func_else} - - {b See also}: {!get_model_func_entry_num_args} - - {b See also}: {!get_model_func_entry_arg} - @deprecated Use func_interp objects - def_API('get_model_func_num_entries', UINT, (_in(CONTEXT), _in(MODEL), _in(UINT))) -*) -external get_model_func_num_entries : context -> model -> int -> int - = "camlidl_z3V3_Z3_get_model_func_num_entries" + (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_formulas : context -> int -(** - Summary: \[ [ get_model_func_entry_num_args c m i j ] \] - Return the number of arguments of the j-th entry of the i-th function interpretation in the given - model. - A function interpretation is represented as a finite map and an 'else' value. - This function returns the j-th entry of this map. - An entry represents the value of a function given a set of arguments. - - {b Remarks}: Consider using {!get_model_funcs}. - - {b Precondition}: i < get_model_num_funcs c m - - {b Precondition}: j < get_model_func_num_entries c m i - - {b See also}: {!get_model_num_funcs} - - {b See also}: {!get_model_func_num_entries } - - {b See also}: {!get_model_func_entry_arg} - @deprecated Use func_interp objects - def_API('get_model_func_entry_num_args', UINT, (_in(CONTEXT), _in(MODEL), _in(UINT), _in(UINT))) -*) -external get_model_func_entry_num_args : context -> model -> int -> int -> int - = "camlidl_z3V3_Z3_get_model_func_entry_num_args" + (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_formulas : context -> Expr.expr list -(** - Summary: \[ [ get_model_func_entry_arg c m i j k ] \] - Return the k-th argument of the j-th entry of the i-th function interpretation in the given - model. - A function interpretation is represented as a finite map and an 'else' value. - This function returns the j-th entry of this map. - An entry represents the value of a function given a set of arguments. - - {b Remarks}: Consider using {!get_model_funcs}. - - {b Precondition}: i < get_model_num_funcs c m - - {b Precondition}: j < get_model_func_num_entries c m i - - {b Precondition}: k < get_model_func_entry_num_args c m i j - - {b See also}: {!get_model_num_funcs} - - {b See also}: {!get_model_func_num_entries } - - {b See also}: {!get_model_func_entry_num_args} - @deprecated Use func_interp objects - def_API('get_model_func_entry_arg', AST, (_in(CONTEXT), _in(MODEL), _in(UINT), _in(UINT), _in(UINT))) -*) -external get_model_func_entry_arg : context -> model -> int -> int -> int -> ast - = "camlidl_z3V3_Z3_get_model_func_entry_arg" + (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_assumptions : context -> int -(** - Summary: \[ [ get_model_func_entry_value c m i j ] \] - Return the return value of the j-th entry of the i-th function interpretation in the given - model. - A function interpretation is represented as a finite map and an 'else' value. - This function returns the j-th entry of this map. - An entry represents the value of a function given a set of arguments. - - {b Remarks}: Consider using {!get_model_funcs}. - - {b Precondition}: i < get_model_num_funcs c m - - {b Precondition}: j < get_model_func_num_entries c m i - - {b See also}: {!get_model_num_funcs} - - {b See also}: {!get_model_func_num_entries } - @deprecated Use func_interp objects - def_API('get_model_func_entry_value', AST, (_in(CONTEXT), _in(MODEL), _in(UINT), _in(UINT))) -*) -external get_model_func_entry_value : context -> model -> int -> int -> ast - = "camlidl_z3V3_Z3_get_model_func_entry_value" + (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_assumptions : context -> Expr.expr list -(** - Summary: \[ [ eval c m t ] \] - Evaluate the AST node [t] in the given model. - Return a pair: Boolean and value. The Boolean is true if the term was successfully evaluated. - The evaluation may fail for the following reasons: - - [t] contains a quantifier. - - the model [m] is partial, that is, it doesn't have a complete interpretation for uninterpreted functions. - That is, the option {e MODEL_PARTIAL=true } was used. - - [t] is type incorrect. - @deprecated Use {!model_eval} - def_API('eval', BOOL, (_in(CONTEXT), _in(MODEL), _in(AST), _out(AST))) -*) -external eval : context -> model -> ast -> bool * ast - = "camlidl_z3V3_Z3_eval" + (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_decls : context -> int -(** - Summary: Evaluate declaration given values. - Provides direct way to evaluate declarations - without going over terms. - @deprecated Consider using {!model_eval} and {!substitute_vars} - def_API('eval_decl', BOOL, (_in(CONTEXT), _in(MODEL), _in(FUNC_DECL), _in(UINT), _in_array(3, AST), _out(AST))) -*) -external eval_decl : context -> model -> func_decl -> ast array -> bool * ast - = "camlidl_z3V3_Z3_eval_decl" + (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_decls : context -> FuncDecl.func_decl list -(** - {2 {L Deprecated String conversion API}} -*) -(** - Summary: Convert the given logical context into a string. - This function is mainly used for debugging purposes. It displays - the internal structure of a logical context. - @deprecated This method is obsolete. It just displays the internal representation of - the global solver available for backward compatibility reasons. - def_API('context_to_string', STRING, (_in(CONTEXT),)) -*) -external context_to_string : context -> string - = "camlidl_z3V3_Z3_context_to_string" + (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_sorts : context -> int -(** - Summary: Return runtime statistics as a string. - This function is mainly used for debugging purposes. It displays - statistics of the search activity. - @deprecated This method is based on the old solver API. - Use {!stats_to_string} when using the new solver API. - def_API('statistics_to_string', STRING, (_in(CONTEXT),)) -*) -external statistics_to_string : context -> string - = "camlidl_z3V3_Z3_statistics_to_string" + (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_sorts : context -> Sort.sort list -(** - Summary: Extract satisfying assignment from context as a conjunction. - This function can be used for debugging purposes. It returns a conjunction - of formulas that are assigned to true in the current context. - This conjunction will contain not only the assertions that are set to true - under the current assignment, but will also include additional literals - if there has been a call to {!check} or {!check_and_get_model}. - @deprecated This method is based on the old solver API. - def_API('get_context_assignment', AST, (_in(CONTEXT),)) -*) -external get_context_assignment : context -> ast - = "camlidl_z3V3_Z3_get_context_assignment" - - -(** {2 {L ML Extensions}} *) -(** - \[ [ mk_context_x configs] \] is a shorthand for the context with configurations in [configs]. -*) -val mk_context_x: (string * string) array -> context;; -(** - \[ [ get_app_args c a ] \] is the array of arguments of an application. If [t] is a constant, then the array is empty. - - {b See also}: {!get_app_num_args} - - {b See also}: {!get_app_arg} -*) -val get_app_args: context -> app -> ast array -(** - \[ [ get_app_args c d ] \] is the array of parameters of [d]. - - {b See also}: {!get_domain_size} - - {b See also}: {!get_domain} -*) -val get_domains: context -> func_decl -> sort array -(** - \[ [ get_array_sort c t ] \] is the domain and the range of [t]. - - {b See also}: {!get_array_sort_domain} - - {b See also}: {!get_array_sort_range} -*) -val get_array_sort: context -> sort -> sort * sort -(** - \[ [ get_tuple_sort c ty ] \] is the pair [(mk_decl, fields)] where [mk_decl] is the constructor declaration of [ty], and [fields] is the array of fields in [ty]. - - {b See also}: {!get_tuple_sort_mk_decl} - - {b See also}: {!get_tuple_sort_num_fields} - - {b See also}: {!get_tuple_sort_field_decl} -*) -val get_tuple_sort: context -> sort -> (func_decl * func_decl array) -(** - \[ [ datatype_constructor_refined ] \] is the refinement of a datatype constructor. - It contains the constructor declaration, recognizer, and list of accessor functions. -*) -type datatype_constructor_refined = { - constructor : func_decl; - recognizer : func_decl; - accessors : func_decl array -} -(** - \[ [ get_datatype_sort c ty ] \] is the array of triples [(constructor, recognizer, fields)] where [constructor] is the constructor declaration of [ty], [recognizer] is the recognizer for the [constructor], and [fields] is the array of fields in [ty]. - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_recognizer} - - {b See also}: {!get_datatype_sort_constructor_accessor} -*) -val get_datatype_sort: context -> sort -> datatype_constructor_refined array -(** - \[ [ get_model_constants c m ] \] is the array of constants in the model [m]. - - {b See also}: {!get_model_num_constants} - - {b See also}: {!get_model_constant} -*) -val get_model_constants: context -> model -> func_decl array -(** - \[ [ get_model_func_entry c m i j ] \] is the [j]'th entry in the [i]'th function in the model [m]. - - {b See also}: {!get_model_func_entry_num_args} - - {b See also}: {!get_model_func_entry_arg} - - {b See also}: {!get_model_func_entry_value} -*) -val get_model_func_entry: context -> model -> int -> int -> (ast array * ast);; -(** - \[ [ get_model_func_entries c m i ] \] is the array of entries in the [i]'th function in the model [m]. - - {b See also}: {!get_model_func_num_entries} - - {b See also}: {!get_model_func_entry} -*) -val get_model_func_entries: context -> model -> int -> (ast array * ast) array;; -(** - \[ [ get_model_funcs c m ] \] is the array of functions in the model [m]. Each function is represented by the triple [(decl, entries, else)], where [decl] is the declaration name for the function, [entries] is the array of entries in the function, and [else] is the default (else) value for the function. - - {b See also}: {!get_model_num_funcs} - - {b See also}: {!get_model_func_decl} - - {b See also}: {!get_model_func_entries} - - {b See also}: {!get_model_func_else} -*) -val get_model_funcs: context -> model -> - (symbol * - (ast array * ast) array * - ast) array -(** - \[ [ get_smtlib_formulas c ] \] is the array of formulas created by a preceding call to {!parse_smtlib_string} or {!parse_smtlib_file}. - Recommend use {!parse_smtlib_string_x} or {!parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_string_x} - - {b See also}: {!parse_smtlib_file_x} - - {b See also}: {!parse_smtlib_string} - - {b See also}: {!parse_smtlib_file} - - {b See also}: {!get_smtlib_num_formulas} - - {b See also}: {!get_smtlib_formula} -*) -val get_smtlib_formulas: context -> ast array -(** - \[ [get_smtlib_assumptions c] \] is the array of assumptions created by a preceding call to {!parse_smtlib_string} or {!parse_smtlib_file}. - Recommend use {!parse_smtlib_string_x} or {!parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_string_x} - - {b See also}: {!parse_smtlib_file_x} - - {b See also}: {!parse_smtlib_string} - - {b See also}: {!parse_smtlib_file} - - {b See also}: {!get_smtlib_num_assumptions} - - {b See also}: {!get_smtlib_assumption} -*) -val get_smtlib_assumptions: context -> ast array -(** - \[ [ get_smtlib_decls c ] \] is the array of declarations created by a preceding call to {!parse_smtlib_string} or {!parse_smtlib_file}. - Recommend use {!parse_smtlib_string_x} or {!parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_string_x} - - {b See also}: {!parse_smtlib_file_x} - - {b See also}: {!parse_smtlib_string} - - {b See also}: {!parse_smtlib_file} - - {b See also}: {!get_smtlib_num_decls} - - {b See also}: {!get_smtlib_decl} -*) -val get_smtlib_decls: context -> func_decl array -(** - \[ [ get_smtlib_parse_results c ] \] is the triple [(get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c)]. - Recommend use {!parse_smtlib_string_x} or {!parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_string_x} - - {b See also}: {!parse_smtlib_file_x} - - {b See also}: {!parse_smtlib_string} - - {b See also}: {!parse_smtlib_file} - - {b See also}: {!get_smtlib_formulas} - - {b See also}: {!get_smtlib_assumptions} - - {b See also}: {!get_smtlib_decls} -*) -val get_smtlib_parse_results: context -> (ast array * ast array * func_decl array) -(** - \[ [ parse_smtlib_string_formula c ... ] \] calls [(parse_smtlib_string c ...)] and returns the single formula produced. - Recommended for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_file_formula} - - {b See also}: {!parse_smtlib_string_x} -*) -val parse_smtlib_string_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast -(** - \[ [ parse_smtlib_file_formula c ... ] \] calls [(parse_smtlib_file c ...)] and returns the single formula produced. - Recommended for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_file_formula} - - {b See also}: {!parse_smtlib_file_x} -*) -val parse_smtlib_file_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast -(** - \[ [ parse_smtlib_string_x c ... ] \] is [(parse_smtlib_string c ...; get_smtlib_parse_results c)] - Recommended for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_file_x} - - {b See also}: {!parse_smtlib_string} - - {b See also}: {!get_smtlib_parse_results} -*) -val parse_smtlib_string_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) -(** - \[ [ parse_smtlib_file_x c ... ] \] is [(parse_smtlib_file c ...; get_smtlib_parse_results c)] - Recommended for functional style interface to the SMT-LIB parser. - - {b See also}: {!parse_smtlib_string_x} - - {b See also}: {!parse_smtlib_file} - - {b See also}: {!get_smtlib_parse_results} -*) -val parse_smtlib_file_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) -(** - \[ [ symbol_refined ] \] is the refinement of a {!symbol} . - - {b See also}: {!symbol_refine} - - {b See also}: {!get_symbol_kind} -*) -type symbol_refined = - | Symbol_int of int - | Symbol_string of string - | Symbol_unknown;; -(** - \[ [ symbol_refine c s ] \] is the refined symbol of [s]. - - {b See also}: {!symbol_refined} - - {b See also}: {!get_symbol_kind} -*) -val symbol_refine: context -> symbol -> symbol_refined;; -(** - \[ [ sort_refined ] \] is the refinement of a {!sort} . - - {b See also}: {!sort_refine} - - {b See also}: {!get_sort_kind} -*) -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_real - | Sort_bv of int - | Sort_array of (sort * sort) - | Sort_datatype of datatype_constructor_refined array - | Sort_relation - | Sort_finite_domain - | Sort_unknown of symbol -(** - \[ [ sort_refine c t ] \] is the refined sort of [t]. - - {b See also}: {!sort_refined} - - {b See also}: {!get_sort_kind} -*) -val sort_refine: context -> sort -> sort_refined;; -(** - \[ [ binder_type ] \] is a universal or existential quantifier. - - {b See also}: {!term_refined} -*) -type binder_type = | Forall | Exists -(** - \[ [ numeral_refined ] \] is the refinement of a numeral . - Numerals whose fractional representation can be fit with - 64 bit integers are treated as small. -*) -type numeral_refined = - | Numeral_small of int64 * int64 - | Numeral_large of string -(** - \[ [ term_refined ] \] is the refinement of a {!ast} . - - {b See also}: {!term_refine} -*) -type term_refined = - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast - | Term_numeral of numeral_refined * sort - | Term_var of int * sort -(** - \[ [ term_refine c a ] \] is the refined term of [a]. - - {b See also}: {!term_refined} -*) -val term_refine : context -> ast -> term_refined -(** - \[ [mk_theory c name ] \] create a custom theory. -*) -val mk_theory : context -> string -> theory -(** - \[ [set_delete_callback th cb] \] set callback when theory gets deleted. -*) -val set_delete_callback : theory -> (unit -> unit) -> unit -(** - \[ [set_reduce_app_callback th cb] \] set callback for simplifying theory terms. -*) -val set_reduce_app_callback : theory -> (func_decl -> ast array -> ast option) -> unit -(** - \[ [set_reduce_eq_callback th cb] \] set callback for simplifying equalities over theory terms. -*) -val set_reduce_eq_callback : theory -> (ast -> ast -> ast option) -> unit -(** - \[ [set_reduce_distinct_callback th cb] \] set callback for simplifying disequalities over theory terms. -*) -val set_reduce_distinct_callback : theory -> (ast array -> ast option) -> unit -(** - \[ [set_new_app_callback th cb] \] set callback for registering new application. -*) -val set_new_app_callback : theory -> (ast -> unit) -> unit -(** - \[ [set_new_elem_callback th cb] \] set callback for registering new element. - - {b See also}: the help for the corresponding C API function. -*) -val set_new_elem_callback : theory -> (ast -> unit) -> unit -(** - \[ [set_init_search_callback th cb] \] set callback when Z3 starts searching for a satisfying assignment. -*) -val set_init_search_callback : theory -> (unit -> unit) -> unit -(** - \[ [set_push_callback th cb] \] set callback for a logical context push. -*) -val set_push_callback : theory -> (unit -> unit) -> unit -(** - \[ [set_pop_callback th cb] \] set callback for a logical context pop. -*) -val set_pop_callback : theory -> (unit -> unit) -> unit -(** - \[ [set_restart_callback th cb] \] set callback for search restart. -*) -val set_restart_callback : theory -> (unit -> unit) -> unit -val set_reset_callback : theory -> (unit -> unit) -> unit -val set_final_check_callback : theory -> (unit -> bool) -> unit -val set_new_eq_callback : theory -> (ast -> ast -> unit) -> unit -val set_new_diseq_callback : theory -> (ast -> ast -> unit) -> unit -val set_new_assignment_callback : theory -> (ast -> bool -> unit) -> unit -val set_new_relevant_callback : theory -> (ast -> unit) -> unit + (** Parse the given string using the SMT-LIB2 parser. + {!parse_smtlib_string} + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) + val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr + (** Parse the given file using the SMT-LIB2 parser. + {!parse_smtlib2_string} *) + val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr end -<<<<<<< HEAD -======= (** Set a global (or module) parameter, which is shared by all Z3 contexts. When a Z3 module is initialized it will use the value of these parameters @@ -9811,11 +2932,11 @@ val get_global_param : string -> string option {!set_global_param} *) -val global_param_reset_all : unit - - (** Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. *) - val toggle_warning_messages : bool -> unit ->>>>>>> Updates to ML API. +val global_param_reset_all : unit -> unit + +(** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) +val toggle_warning_messages : bool -> unit + From 755ba2a2f7fe710bb4966bd19fbbd457596270d5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 4 Jun 2013 16:46:47 +0100 Subject: [PATCH 292/507] ML API: removing rich layer for now. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3_rich.ml | 3399 ---------------------------------------- src/api/ml/z3_rich.mli | 3071 ------------------------------------ 2 files changed, 6470 deletions(-) delete mode 100644 src/api/ml/z3_rich.ml delete mode 100644 src/api/ml/z3_rich.mli diff --git a/src/api/ml/z3_rich.ml b/src/api/ml/z3_rich.ml deleted file mode 100644 index 0c2f95b6b..000000000 --- a/src/api/ml/z3_rich.ml +++ /dev/null @@ -1,3399 +0,0 @@ -\(** - The Z3 ML/Ocaml Interface. - - Copyright (C) 2012 Microsoft Corporation - @author CM Wintersteiger (cwinter) 2012-12-17 -*) - -open Z3enums - -(* Some helpers. *) -let null = Z3native.mk_null() -let is_null o = (Z3native.is_null o) - -(* Internal types *) -type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } -type context = z3_native_context - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - - -(** Internal stuff *) -module Internal = -struct - let dispose_context ctx = - if ctx.m_n_obj_cnt == 0 then ( - (Z3native.del_context ctx.m_n_ctx) - ) else ( - Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; - ) - - let create_context settings = - let cfg = Z3native.mk_config in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - Z3native.set_internal_error_handler v ; - let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in - let f = fun o -> dispose_context o in - Gc.finalise f res; - res - - let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) - let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) - let context_gno ctx = ctx.m_n_ctx - - - let z3obj_gc o = o.m_ctx - let z3obj_gnc o = (context_gno o.m_ctx) - - let z3obj_gno o = o.m_n_obj - let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - - let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - - let z3obj_create o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - - let z3obj_nil_ref x y = () - - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> - let res : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res -end - -open Internal - -module Log = -struct - let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - let close = Z3native.close_log - let append s = Z3native.append_log s -end - - -module Version = -struct - let major = let (x, _, _, _) = Z3native.get_version in x - let minor = let (_, x, _, _) = Z3native.get_version in x - let build = let (_, _, x, _) = Z3native.get_version in x - let revision = let (_, _, _, x) = Z3native.get_version in x - let to_string = - let (mj, mn, bld, rev) = Z3native.get_version in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev ^ "." -end - - -let mk_list ( f : int -> 'a ) ( n : int ) = - let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = - if (i >= n) then - tail - else - (mk_list' f (i+1) n ((f i) :: tail)) - in - mk_list' f 0 n [] - -let list_of_array ( x : _ array ) = - let f i = (Array.get x i) in - mk_list f (Array.length x) - -let mk_context ( cfg : ( string * string ) list ) = - create_context cfg - - -module Symbol = -struct - (* Symbol types *) - type int_symbol = z3_native_object - type string_symbol = z3_native_object - - type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - - - let create_i ( ctx : context ) ( no : Z3native.ptr ) = - let res : int_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let create_s ( ctx : context ) ( no : Z3native.ptr ) = - let res : string_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> S_Int (create_i ctx no) - | STRING_SYMBOL -> S_Str (create_s ctx no) - - let gc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gc n) - | S_Str(n) -> (z3obj_gc n) - - let gnc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gnc n) - | S_Str(n) -> (z3obj_gnc n) - - let gno ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gno n) - | S_Str(n) -> (z3obj_gno n) - - let symbol_lton ( a : symbol list ) = - let f ( e : symbol ) = (gno e) in - Array.of_list (List.map f a) - - let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) - let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL - let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) - let to_string ( o : symbol ) = - match (kind o) with - | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) - | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) - - let mk_int ( ctx : context ) ( i : int ) = - S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) - - let mk_string ( ctx : context ) ( s : string ) = - S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - - let mk_ints ( ctx : context ) ( names : int list ) = - let f elem = mk_int ( ctx : context ) elem in - (List.map f names) - - let mk_strings ( ctx : context ) ( names : string list ) = - let f elem = mk_string ( ctx : context ) elem in - (List.map f names) -end - - -module AST = -struct - type ast = z3_native_object - - let context_of_ast ( x : ast ) = (z3obj_gc x) - let nc_of_ast ( x : ast ) = (z3obj_gnc x) - let ptr_of_ast ( x : ast ) = (z3obj_gno x) - - let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST - | SORT_AST - | QUANTIFIER_AST - | APP_AST - | NUMERAL_AST - | VAR_AST -> z3_native_object_of_ast_ptr ctx no - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") - - module ASTVector = - struct - type ast_vector = z3_native_object - - let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_vector = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_vector_inc_ref ; - dec_ref = Z3native.ast_vector_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_size ( x : ast_vector ) = - Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) - - let get ( x : ast_vector ) ( i : int ) = - ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) - - let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) - - let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size - - let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) - - let translate ( x : ast_vector ) ( to_ctx : context ) = - ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) - end - - module ASTMap = - struct - type ast_map = z3_native_object - - let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_map = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_map_inc_ref ; - dec_ref = Z3native.ast_map_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let contains ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - - let find ( x : ast_map ) ( key : ast ) = - ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - - let insert ( x : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) - - let erase ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - - let reset ( x : ast_map ) = - Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : ast_map ) = - Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) - - let get_keys ( x : ast_map ) = - let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in - let f i = (ASTVector.get av i) in - mk_list f (ASTVector.get_size av) - - let to_string ( x : ast_map ) = - Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) - let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) - let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) - - let is_expr ( x : ast ) = - match get_ast_kind ( x : ast ) with - | APP_AST - | NUMERAL_AST - | QUANTIFIER_AST - | VAR_AST -> true - | _ -> false - - let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST - let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST - let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST - let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST - - let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - - - let ( = ) ( a : ast ) ( b : ast ) = (a == b) || - if (z3obj_gnc a) != (z3obj_gnc b) then - false - else - Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) - - let compare a b = - if (get_id a) < (get_id b) then -1 else - if (get_id a) > (get_id b) then 1 else - 0 - - let ( < ) (a : ast) (b : ast) = (compare a b) - - let translate ( x : ast ) ( to_ctx : context ) = - if (z3obj_gnc x) == (context_gno to_ctx) then - x - else - ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr - let unwrap_ast ( x : ast ) = (z3obj_gno x) -end - -open AST - - -module Sort = -struct - type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort - - let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> - let q = (z3_native_object_of_ast_ptr ctx no) in - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then - raise (Z3native.Exception "Invalid coercion") - else - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - - let ast_of_sort s = match s with Sort(x) -> x - let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x - - let uninterpreted_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - UninterpretedSort(s) - - let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) - let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) - let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - - let sort_lton ( a : sort list ) = - let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let ( = ) : sort -> sort -> bool = fun a b -> - (a == b) || - if (gnc a) != (gnc b) then - false - else - (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) - - - let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) - let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) - let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) - let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) - - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; - (z3obj_create res) ; - UninterpretedSort(Sort(res)) - - let mk_uninterpreted_s ( ctx : context ) ( s : string ) = - mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) -end - -open Sort - - -module rec FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - val ast_of_func_decl : FuncDecl.func_decl -> AST.ast - val func_decl_of_ptr : context -> Z3native.ptr -> func_decl - val gc : func_decl -> context - val gnc : func_decl -> Z3native.ptr - val gno : func_decl -> Z3native.ptr - module Parameter : - sig - type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - val get_kind : parameter -> Z3enums.parameter_kind - val get_int : parameter -> int - val get_float : parameter -> float - val get_symbol : parameter -> Symbol.symbol - val get_sort : parameter -> Sort.sort - val get_ast : parameter -> AST.ast - val get_func_decl : parameter -> func_decl - val get_rational : parameter -> string - end - val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl - val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl - val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl - val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl - val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - val ( = ) : func_decl -> func_decl -> bool - val to_string : func_decl -> string - val get_id : func_decl -> int - val get_arity : func_decl -> int - val get_domain_size : func_decl -> int - val get_domain : func_decl -> Sort.sort list - val get_range : func_decl -> Sort.sort - val get_decl_kind : func_decl -> Z3enums.decl_kind - val get_name : func_decl -> Symbol.symbol - val get_num_parameters : func_decl -> int - val get_parameters : func_decl -> Parameter.parameter list - val apply : func_decl -> Expr.expr list -> Expr.expr -end = struct - type func_decl = FuncDecl of AST.ast - - let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - FuncDecl(z3_native_object_of_ast_ptr ctx no) - - let ast_of_func_decl f = match f with FuncDecl(x) -> x - - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; - (z3obj_create res) ; - FuncDecl(res) - - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; - (z3obj_create res) ; - FuncDecl(res) - - let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) - let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) - let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - - module Parameter = - struct - type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - let get_kind ( x : parameter ) = - (match x with - | P_Int(_) -> PARAMETER_INT - | P_Dbl(_) -> PARAMETER_DOUBLE - | P_Sym(_) -> PARAMETER_SYMBOL - | P_Srt(_) -> PARAMETER_SORT - | P_Ast(_) -> PARAMETER_AST - | P_Fdl(_) -> PARAMETER_FUNC_DECL - | P_Rat(_) -> PARAMETER_RATIONAL) - - let get_int ( x : parameter ) = - match x with - | P_Int(x) -> x - | _ -> raise (Z3native.Exception "parameter is not an int") - - let get_float ( x : parameter ) = - match x with - | P_Dbl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a double") - - let get_symbol ( x : parameter ) = - match x with - | P_Sym(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a symbol") - - let get_sort ( x : parameter ) = - match x with - | P_Srt(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a sort") - - let get_ast ( x : parameter ) = - match x with - | P_Ast(x) -> x - | _ -> raise (Z3native.Exception "parameter is not an ast") - - let get_func_decl ( x : parameter ) = - match x with - | P_Fdl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a func_decl") - - let get_rational ( x : parameter ) = - match x with - | P_Rat(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a rational string") - end - - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = - create_ndr ctx name domain range - - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = - mk_func_decl ctx (Symbol.mk_string ctx name) domain range - - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = - create_pdr ctx prefix domain range - - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_ndr ctx name [] range - - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = - create_ndr ctx (Symbol.mk_string ctx name) [] range - - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = - create_pdr ctx prefix [] range - - - let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || - if (gnc a) != (gnc b) then - false - else - (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) - - let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) - - let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) - - let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) - - let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) - - let get_domain ( x : func_decl ) = - let n = (get_domain_size x) in - let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in - mk_list f n - - let get_range ( x : func_decl ) = - sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) - - let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) - - let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) - - let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) - - let get_parameters ( x : func_decl ) = - let n = (get_num_parameters x) in - let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) - ) in - mk_list f n - - let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args -end - - -and Params : -sig - type params = z3_native_object - module ParamDescrs : - sig - type param_descrs - val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - val get_names : param_descrs -> Symbol.symbol list - val get_size : param_descrs -> int - val to_string : param_descrs -> string - end - val add_bool : params -> Symbol.symbol -> bool -> unit - val add_int : params -> Symbol.symbol -> int -> unit - val add_double : params -> Symbol.symbol -> float -> unit - val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - val add_s_bool : params -> string -> bool -> unit - val add_s_int : params -> string -> int -> unit - val add_s_double : params -> string -> float -> unit - val add_s_symbol : params -> string -> Symbol.symbol -> unit - val mk_params : context -> params - val to_string : params -> string -end = struct - type params = z3_native_object - - module ParamDescrs = - struct - type param_descrs = z3_native_object - - let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : param_descrs = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.param_descrs_inc_ref ; - dec_ref = Z3native.param_descrs_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let validate ( x : param_descrs ) ( p : params ) = - Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) - - let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) - - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in - let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = - Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = - Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = - Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = - Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - - let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = - add_bool x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_int ( x : params) ( name : string ) ( value : int ) = - add_int x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_double ( x : params ) ( name : string ) ( value : float ) = - add_double x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = - add_symbol x (Symbol.mk_string (z3obj_gc x) name) value - - let mk_params ( ctx : context ) = - let res : params = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.params_inc_ref ; - dec_ref = Z3native.params_dec_ref } in - (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; - (z3obj_create res) ; - res - - let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) -end - -(** General expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - val expr_of_ptr : context -> Z3native.ptr -> expr - val gc : expr -> context - val gnc : expr -> Z3native.ptr - val gno : expr -> Z3native.ptr - val expr_lton : expr list -> Z3native.ptr array - val ast_of_expr : expr -> AST.ast - val expr_of_ast : AST.ast -> expr - val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr - val simplify : expr -> Params.params option -> expr - val get_simplify_help : context -> string - val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs - val get_func_decl : expr -> FuncDecl.func_decl - val get_bool_value : expr -> Z3enums.lbool - val get_num_args : expr -> int - val get_args : expr -> expr list - val update : expr -> expr list -> expr - val substitute : expr -> expr list -> expr list -> expr - val substitute_one : expr -> expr -> expr -> expr - val substitute_vars : expr -> expr list -> expr - val translate : expr -> context -> expr - val to_string : expr -> string - val is_numeral : expr -> bool - val is_well_sorted : expr -> bool - val get_sort : expr -> Sort.sort - val is_bool : expr -> bool - val is_const : expr -> bool - val is_true : expr -> bool - val is_false : expr -> bool - val is_eq : expr -> bool - val is_distinct : expr -> bool - val is_ite : expr -> bool - val is_and : expr -> bool - val is_or : expr -> bool - val is_iff : expr -> bool - val is_xor : expr -> bool - val is_not : expr -> bool - val is_implies : expr -> bool - val is_label : expr -> bool - val is_label_lit : expr -> bool - val is_oeq : expr -> bool - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - val mk_const_s : context -> string -> Sort.sort -> expr - val mk_const_f : context -> FuncDecl.func_decl -> expr - val mk_fresh_const : context -> string -> Sort.sort -> expr - val mk_app : context -> FuncDecl.func_decl -> expr list -> expr - val mk_numeral_string : context -> string -> Sort.sort -> expr - val mk_numeral_int : context -> int -> Sort.sort -> expr -end = struct - type expr = Expr of AST.ast - - let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) - let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) - let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) - - let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then - Expr(z3_native_object_of_ast_ptr ctx no) - else - let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) no) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - raise (Z3native.Exception "Unsupported numeral object") - else - Expr(z3_native_object_of_ast_ptr ctx no) - - let expr_of_ast a = - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Expr(a) - - let ast_of_expr e = match e with Expr(a) -> a - - let expr_lton ( a : expr list ) = - let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> - match f with FuncDecl.FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in - expr_of_ptr ctx o - - let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (Expr.gnc x) (Expr.gno x)) - | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (Expr.gnc x) (Expr.gno x) (z3obj_gno pp)) - - let get_simplify_help ( ctx : context ) = - Z3native.simplify_get_help (context_gno ctx) - - let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (Expr.gnc x) (Expr.gno x)) - - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (Expr.gnc x) (Expr.gno x)) - - let get_num_args ( x : expr ) = Z3native.get_app_num_args (Expr.gnc x) (Expr.gno x) - - let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (Expr.gnc x) (Expr.gno x) i) in - mk_list f n - - let update ( x : expr ) ( args : expr list ) = - if (List.length args <> (get_num_args x)) then - raise (Z3native.Exception "Number of arguments does not match") - else - expr_of_ptr (Expr.gc x) (Z3native.update_term (Expr.gnc x) (Expr.gno x) (List.length args) (expr_lton args)) - - let substitute ( x : expr ) from to_ = - if (List.length from) <> (List.length to_) then - raise (Z3native.Exception "Argument sizes do not match") - else - expr_of_ptr (Expr.gc x) (Z3native.substitute (Expr.gnc x) (Expr.gno x) (List.length from) (expr_lton from) (expr_lton to_)) - - let substitute_one ( x : expr ) from to_ = - substitute ( x : expr ) [ from ] [ to_ ] - - let substitute_vars ( x : expr ) to_ = - expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (Expr.gnc x) (Expr.gno x) (List.length to_) (expr_lton to_)) - - let translate ( x : expr ) to_ctx = - if (Expr.gc x) == to_ctx then - x - else - expr_of_ptr to_ctx (Z3native.translate (Expr.gnc x) (Expr.gno x) (context_gno to_ctx)) - - let to_string ( x : expr ) = Z3native.ast_to_string (Expr.gnc x) (Expr.gno x) - - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) - - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (Expr.gnc x) (Expr.gno x) - - let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)) - - let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (Expr.gnc x) - (Z3native.mk_bool_sort (Expr.gnc x)) - (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) - - let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (get_num_args x) == 0 && - (FuncDecl.get_domain_size (get_func_decl x)) == 0 - - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) - let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) - - let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name) range - - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] - - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = - expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args - - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) - - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) -end - -open FuncDecl -open Expr - -module Boolean = -struct - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.ast_of_ptr ctx no) in - BoolExpr(Expr.Expr(a)) - - let bool_expr_of_expr e = - match e with Expr.Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolExpr(e) - - let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - BoolSort(sort_of_ptr ctx no) - - let sort_of_bool_sort s = match s with BoolSort(x) -> x - - let bool_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolSort(s) - - let expr_of_bool_expr e = match e with BoolExpr(x) -> x - - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) - - let mk_sort ( ctx : context ) = - BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - let s = (match (mk_sort ctx) with BoolSort(q) -> q) in - BoolExpr(Expr.mk_const ctx name s) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_true ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) - - let mk_false ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) - - let mk_val ( ctx : context ) ( value : bool ) = - if value then mk_true ctx else mk_false ctx - - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) - - let mk_distinct ( ctx : context ) ( args : expr list ) = - bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_not ( ctx : context ) ( a : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - - let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - - let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - - let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - - let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - - let mk_and ( ctx : context ) ( args : bool_expr list ) = - let f x = (Expr.gno (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - - let mk_or ( ctx : context ) ( args : bool_expr list ) = - let f x = (Expr.gno (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) -end - - -module Quantifier = -struct - type quantifier = Quantifier of expr - - let expr_of_quantifier e = match e with Quantifier(x) -> x - - let quantifier_of_expr e = - match e with Expr.Expr(a) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.QUANTIFIER_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Quantifier(e) - - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - - module Pattern = - struct - type pattern = Pattern of ast - - let ast_of_pattern e = match e with Pattern(x) -> x - - let pattern_of_ast a = - (* CMW: Unchecked ok? *) - Pattern(a) - - let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) - let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) - let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - mk_list f n - - let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) - end - - let get_index ( x : expr ) = - if not (AST.is_var (match x with Expr.Expr(a) -> a)) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value (Expr.gnc x) (Expr.gno x) - - let is_universal ( x : quantifier ) = - Z3native.is_quantifier_forall (gnc x) (gno x) - - let is_existential ( x : quantifier ) = not (is_universal x) - - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) - - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) - - let get_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in - mk_list f n - - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) - - let get_no_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in - mk_list f n - - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) - - let get_bound_variable_names ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in - mk_list f n - - let get_bound_variable_sorts ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in - mk_list f n - - let get_body ( x : quantifier ) = - Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) - - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - - let mk_pattern ( ctx : context ) ( terms : expr list ) = - if (List.length terms) == 0 then - raise (Z3native.Exception "Cannot create a pattern from zero terms") - else - Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) - - let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (List.length sorts) != (List.length names) then - raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - - let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (Expr.gno body))) - - let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (List.length sorts) != (List.length names) then - raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - - let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (Expr.gno body))) - - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (universal) then - (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - else - (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (universal) then - mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id - else - mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id -end - - -module Array_ = -struct - type array_sort = ArraySort of sort - type array_expr = ArrayExpr of expr - - let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (expr_of_ptr ctx no) in - ArrayExpr(e) - - let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - ArraySort(s) - - let sort_of_array_sort s = match s with ArraySort(x) -> x - - let array_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArraySort(s) - - let array_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArrayExpr(e) - - let expr_of_array_expr e = match e with ArrayExpr(x) -> x - - let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) - - let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) - let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) - let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - - let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) - let is_array ( x : expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) - - let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) - let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) - - let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name) domain range - - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) - - let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) - - let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) - - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = - let m x = (Expr.gno (expr_of_array_expr x)) in - array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) - - let mk_term_array ( ctx : context ) ( arg : array_expr ) = - array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) -end - - -module Set = -struct - type set_sort = SetSort of sort - - let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - SetSort(s) - - let sort_of_set_sort s = match s with SetSort(x) -> x - - let mk_sort ( ctx : context ) ( ty : sort ) = - set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) - - - let mk_empty ( ctx : context ) ( domain : sort ) = - (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) - - let mk_full ( ctx : context ) ( domain : sort ) = - expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) - - let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) - - let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) - - let mk_union ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_intersection ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) - - let mk_complement ( ctx : context ) ( arg : expr ) = - expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) - - let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) - - let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) - -end - - -module FiniteDomain = -struct - type finite_domain_sort = FiniteDomainSort of sort - - let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x - - let finite_domain_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - FiniteDomainSort(s) - - let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in - FiniteDomainSort(s) - - let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_sort ctx (Symbol.mk_string ctx name) size - - - let is_finite_domain ( x : expr ) = - let nc = (Expr.gnc x) in - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) - - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - - let get_size ( x : finite_domain_sort ) = - let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in - if r then v - else raise (Z3native.Exception "Conversion failed.") -end - - -module Relation = -struct - type relation_sort = RelationSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - RelationSort(s) - - let sort_of_relation_sort s = match s with RelationSort(x) -> x - - let relation_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RelationSort(s) - - let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - - - let is_relation ( x : expr ) = - let nc = (Expr.gnc x) in - ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) - - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - - let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) - - let get_column_sorts ( x : relation_sort ) = - let n = get_arity x in - let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in - mk_list f n - -end - - -module Datatype = -struct - type datatype_sort = DatatypeSort of sort - type datatype_expr = DatatypeExpr of expr - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - DatatypeSort(s) - - let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x - - let datatype_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeSort(s) - - let datatype_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeExpr(e) - - let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x - - let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - - module Constructor = - struct - type constructor = z3_native_object - - let _sizes = Hashtbl.create 0 - - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = - let n = (List.length field_names) in - if n != (List.length sorts) then - raise (Z3native.Exception "Number of field names does not match number of sorts") - else - if n != (List.length sort_refs) then - raise (Z3native.Exception "Number of field names does not match number of sort refs") - else - let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) - (Symbol.gno recognizer) - n - (Symbol.symbol_lton field_names) - (sort_lton sorts) - (Array.of_list sort_refs)) in - let no : constructor = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - (z3obj_sno no ctx ptr) ; - (z3obj_create no) ; - let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in - Gc.finalise f no ; - Hashtbl.add _sizes no n ; - no - - let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x - - let get_constructor_decl ( x : constructor ) = - let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - func_decl_of_ptr (z3obj_gc x) a - - let get_tester_decl ( x : constructor ) = - let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - func_decl_of_ptr (z3obj_gc x) b - - let get_accessor_decls ( x : constructor ) = - let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in - mk_list f (Array.length c) - - end - - module ConstructorList = - struct - type constructor_list = z3_native_object - - let create ( ctx : context ) ( c : Constructor.constructor list ) = - let res : constructor_list = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - let f x =(z3obj_gno x) in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; - (z3obj_create res) ; - let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in - Gc.finalise f res; - res - end - - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = - Constructor.create ctx name recognizer field_names sorts sort_refs - - - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = - mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = - let f x = (z3obj_gno x) in - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in - sort_of_ptr ctx x - - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = - mk_sort ctx (Symbol.mk_string ctx name) constructors - - let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = - let n = (List.length names) in - let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in - let cla = (Array.of_list (List.map f c)) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in - let g i = (sort_of_ptr ctx (Array.get r i)) in - mk_list g (Array.length r) - - let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = - mk_sorts ctx - ( - let f e = (Symbol.mk_string ctx e) in - List.map f names - ) - c - - let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) - - let get_constructors ( x : datatype_sort ) = - let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in - mk_list f n - - let get_recognizers ( x : datatype_sort ) = - let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in - mk_list f n - - let get_accessors ( x : datatype_sort ) = - let n = (get_num_constructors x) in - let f i = ( - let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in - let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in - mk_list g ds - ) in - mk_list f n -end - - -module Enumeration = -struct - type enum_sort = EnumSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = - let s = (sort_of_ptr ctx no) in - let res = EnumSort(s) in - res - - let sort_of_enum_sort s = match s with EnumSort(x) -> x - - let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in - sort_of_ptr ctx a (list_of_array b) (list_of_array c) - - let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = - mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - - let get_const_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in - mk_list f n - - let get_tester_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in - mk_list f n - -end - - -module List_ = -struct - type list_sort = ListSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - let res = ListSort(s) in - res - - let sort_of_list_sort s = match s with ListSort(x) -> x - - let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - sort_of_ptr ctx r a b c d e f - - let mk_list_s ( ctx : context ) (name : string) elem_sort = - mk_sort ctx (Symbol.mk_string ctx name) elem_sort - - let get_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) - - let get_is_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) - - let get_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) - - let get_is_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) - - let get_head_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) - - let get_tail_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) - - let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] -end - - -module Tuple = -struct - type tuple_sort = TupleSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - TupleSort(s) - - let sort_of_tuple_sort s = match s with TupleSort(x) -> x - - let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = - let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in - sort_of_ptr ctx r - - let get_mk_decl ( x : tuple_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) - - let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) - - let get_field_decls ( x : tuple_sort ) = - let n = get_num_fields x in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in - mk_list f n -end - - -module rec Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> arith_sort - val expr_of_arith_expr : arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> arith_expr - - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_const : context -> Symbol.symbol -> int_expr - val mk_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_numeral_s : context -> string -> int_num - val mk_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_const : context -> Symbol.symbol -> real_expr - val mk_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end - - val is_int : Expr.expr -> bool - val is_arithmetic_numeral : Expr.expr -> bool - val is_le : Expr.expr -> bool - val is_ge : Expr.expr -> bool - val is_lt : Expr.expr -> bool - val is_gt : Expr.expr -> bool - val is_add : Expr.expr -> bool - val is_sub : Expr.expr -> bool - val is_uminus : Expr.expr -> bool - val is_mul : Expr.expr -> bool - val is_div : Expr.expr -> bool - val is_idiv : Expr.expr -> bool - val is_remainder : Expr.expr -> bool - val is_modulus : Expr.expr -> bool - val is_inttoreal : Expr.expr -> bool - val is_real_to_int : Expr.expr -> bool - val is_real_is_int : Expr.expr -> bool - val is_real : Expr.expr -> bool - val is_int_numeral : Expr.expr -> bool - val is_rat_num : Expr.expr -> bool - val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr list -> arith_expr - val mk_mul : context -> arith_expr list -> arith_expr - val mk_sub : context -> arith_expr list -> arith_expr - val mk_unary_minus : context -> arith_expr -> arith_expr - val mk_div : context -> arith_expr -> arith_expr -> arith_expr - val mk_power : context -> arith_expr -> arith_expr -> arith_expr - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr -end = struct - type arith_sort = ArithSort of sort - type arith_expr = ArithExpr of expr - - let arith_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithExpr(e) - - let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_expr_of_expr (expr_of_ptr ctx no) - - let sort_of_arith_sort s = match s with ArithSort(x) -> x - let expr_of_arith_expr e = match e with ArithExpr(x) -> x - - let arith_sort_of_sort s = match s with Sort(a) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithSort(s) - - let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_sort_of_sort (sort_of_ptr ctx no) - - let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) - let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) - let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) - let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) - - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_const : context -> Symbol.symbol -> int_expr - val mk_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_numeral_s : context -> string -> int_num - val mk_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end = struct - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntExpr(e) - - let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - IntNum(e) - - let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_num_of_int_expr (int_expr_of_ptr ctx no) - - let arith_sort_of_int_sort s = match s with IntSort(x) -> x - let arith_expr_of_int_expr e = match e with IntExpr(x) -> x - let int_expr_of_int_num e = match e with IntNum(x) -> x - - let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntSort(s) - - let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) - - let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) - let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) - let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) - let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) - let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) - let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) - let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) - let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) - let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - - let mk_sort ( ctx : context ) = - int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - - let get_int ( x : int_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in - if r then v - else raise (Z3native.Exception "Conversion failed.") - - let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) - - let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) - - let mk_numeral_s ( ctx : context ) ( v : string ) = - int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_numeral_i ( ctx : context ) ( v : int ) = - int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_int2real ( ctx : context ) ( t : int_expr ) = - Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) - - let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) - end - - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : real_sort -> arith_sort - val real_sort_of_arith_sort : arith_sort -> real_sort - val arith_expr_of_real_expr : real_expr -> arith_expr - val real_expr_of_rat_num : rat_num -> real_expr - val real_expr_of_arith_expr : arith_expr -> real_expr - val rat_num_of_real_expr : real_expr -> rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_const : context -> Symbol.symbol -> real_expr - val mk_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end = struct - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - let arith_sort_of_real_sort s = match s with RealSort(x) -> x - let arith_expr_of_real_expr e = match e with RealExpr(x) -> x - let real_expr_of_rat_num e = match e with RatNum(x) -> x - - let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealExpr(e) - - let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - RatNum(e) - - let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - rat_num_of_real_expr (real_expr_of_ptr ctx no) - - let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealSort(s) - - let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) - let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) - let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) - let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) - let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) - let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) - let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) - let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) - let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - - - let mk_sort ( ctx : context ) = - real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - - let get_numerator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) - - let get_denominator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) - - let to_decimal_string ( x : rat_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - - let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = - if (den == 0) then - raise (Z3native.Exception "Denominator is zero") - else - rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) - - let mk_numeral_s ( ctx : context ) ( v : string ) = - rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_numeral_i ( ctx : context ) ( v : int ) = - rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_is_integer ( ctx : context ) ( t : real_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) - - let mk_real2int ( ctx : context ) ( t : real_expr ) = - Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) - end - - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end = struct - type algebraic_num = AlgebraicNum of arith_expr - - let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x - - let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - AlgebraicNum(e) - - let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) - - let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) - let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) - let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - - - let to_upper ( x : algebraic_num ) ( precision : int ) = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) - - let to_lower ( x : algebraic_num ) precision = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) - - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - end - - let is_int ( x : expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - - let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - - let mk_add ( ctx : context ) ( t : arith_expr list ) = - let f x = (Expr.gno (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_mul ( ctx : context ) ( t : arith_expr list ) = - let f x = (Expr.gno (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_sub ( ctx : context ) ( t : arith_expr list ) = - let f x = (Expr.gno (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) - - let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) - - let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) - - let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) - - let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) - - let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) - - let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) -end - - -and BitVector : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - - val mk_sort : context -> int -> bitvec_sort - val is_bv : Expr.expr -> bool - val is_bv_numeral : Expr.expr -> bool - val is_bv_bit1 : Expr.expr -> bool - val is_bv_bit0 : Expr.expr -> bool - val is_bv_uminus : Expr.expr -> bool - val is_bv_add : Expr.expr -> bool - val is_bv_sub : Expr.expr -> bool - val is_bv_mul : Expr.expr -> bool - val is_bv_sdiv : Expr.expr -> bool - val is_bv_udiv : Expr.expr -> bool - val is_bv_SRem : Expr.expr -> bool - val is_bv_urem : Expr.expr -> bool - val is_bv_smod : Expr.expr -> bool - val is_bv_sdiv0 : Expr.expr -> bool - val is_bv_udiv0 : Expr.expr -> bool - val is_bv_srem0 : Expr.expr -> bool - val is_bv_urem0 : Expr.expr -> bool - val is_bv_smod0 : Expr.expr -> bool - val is_bv_ule : Expr.expr -> bool - val is_bv_sle : Expr.expr -> bool - val is_bv_uge : Expr.expr -> bool - val is_bv_sge : Expr.expr -> bool - val is_bv_ult : Expr.expr -> bool - val is_bv_slt : Expr.expr -> bool - val is_bv_ugt : Expr.expr -> bool - val is_bv_sgt : Expr.expr -> bool - val is_bv_and : Expr.expr -> bool - val is_bv_or : Expr.expr -> bool - val is_bv_not : Expr.expr -> bool - val is_bv_xor : Expr.expr -> bool - val is_bv_nand : Expr.expr -> bool - val is_bv_nor : Expr.expr -> bool - val is_bv_xnor : Expr.expr -> bool - val is_bv_concat : Expr.expr -> bool - val is_bv_signextension : Expr.expr -> bool - val is_bv_zeroextension : Expr.expr -> bool - val is_bv_extract : Expr.expr -> bool - val is_bv_repeat : Expr.expr -> bool - val is_bv_reduceor : Expr.expr -> bool - val is_bv_reduceand : Expr.expr -> bool - val is_bv_comp : Expr.expr -> bool - val is_bv_shiftleft : Expr.expr -> bool - val is_bv_shiftrightlogical : Expr.expr -> bool - val is_bv_shiftrightarithmetic : Expr.expr -> bool - val is_bv_rotateleft : Expr.expr -> bool - val is_bv_rotateright : Expr.expr -> bool - val is_bv_rotateleftextended : Expr.expr -> bool - val is_bv_rotaterightextended : Expr.expr -> bool - val is_int_to_bv : Expr.expr -> bool - val is_bv_to_int : Expr.expr -> bool - val is_bv_carry : Expr.expr -> bool - val is_bv_xor3 : Expr.expr -> bool - val get_size : bitvec_sort -> int - val get_int : bitvec_num -> int - val to_string : bitvec_num -> string - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr - val mk_const_s : context -> string -> int -> bitvec_expr - val mk_not : context -> bitvec_expr -> Expr.expr - val mk_redand : context -> bitvec_expr -> Expr.expr - val mk_redor : context -> bitvec_expr -> Expr.expr - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_neg : context -> bitvec_expr -> bitvec_expr - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_numeral : context -> string -> int -> bitvec_num -end = struct - type bitvec_sort = BitVecSort of sort - type bitvec_expr = BitVecExpr of expr - type bitvec_num = BitVecNum of bitvec_expr - - let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x - - let bitvec_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecSort(s) - - let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_sort_of_sort (sort_of_ptr ctx no) - - let bitvec_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecExpr(e) - - let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_expr_of_expr (expr_of_ptr ctx no) - - let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(a)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecNum(e) - - let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) - - let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x - let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x - - - let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) - let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) - let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) - let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) - let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) - let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) - let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) - let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) - let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - - - let mk_sort ( ctx : context ) size = - bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) - let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) - let get_int ( x : bitvec_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in - if r then v - else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) - let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_const ctx (Symbol.mk_string ctx name) size - let mk_not ( ctx : context ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) - let mk_redand ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) - let mk_redor ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) - let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) - let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) - let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) - let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) - let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) - let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) - let mk_neg ( ctx : context ) ( t : bitvec_expr) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) - let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) - let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) - let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) - let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) - let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) - let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) - let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) - let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) - let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) - let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) - let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) - let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) - let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) - let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) - let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) - let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) - let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) - let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) - let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) - let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) - let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) - let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) - let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) - let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) - let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) - let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) - let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) - let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) - let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) - let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) - let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) -end - - -module Proof = -struct - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) -end - - -module Goal = -struct - type goal = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : goal = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.goal_inc_ref ; - dec_ref = Z3native.goal_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_precision ( x : goal ) = - goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) - - let is_precise ( x : goal ) = - (get_precision x) == GOAL_PRECISE - - let is_underapproximation ( x : goal ) = - (get_precision x) == GOAL_UNDER - - let is_overapproximation ( x : goal ) = - (get_precision x) == GOAL_OVER - - let is_garbage ( x : goal ) = - (get_precision x) == GOAL_UNDER_OVER - - let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in - ignore (List.map f constraints) ; - () - - let is_inconsistent ( x : goal ) = - Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) - - let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) - - let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) - - let get_formulas ( x : goal ) = - let n = get_size x in - let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) - (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in - mk_list f n - - let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) - - let is_decided_sat ( x : goal ) = - Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) - - let is_decided_unsat ( x : goal ) = - Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) - - let translate ( x : goal ) ( to_ctx : context ) = - create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let simplify ( x : goal ) ( p : Params.params option ) = - let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in - Z3native.tactic_inc_ref (z3obj_gnc x) tn ; - let arn = match p with - | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) - | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) - in - Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; - let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in - let res = if sg == 0 then - raise (Z3native.Exception "No subgoals") - else - Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in - Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; - Z3native.tactic_dec_ref (z3obj_gnc x) tn ; - create (z3obj_gc x) res - - let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) - - let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Model = -struct - type model = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : model = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.model_inc_ref ; - dec_ref = Z3native.model_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module FuncInterp = - struct - type func_interp = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : func_interp = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.func_interp_inc_ref ; - dec_ref = Z3native.func_interp_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module FuncEntry = - struct - type func_entry = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : func_entry = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.func_entry_inc_ref ; - dec_ref = Z3native.func_entry_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_value ( x : func_entry ) = - expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) - - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) - - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) - - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) - - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) - - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (List.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in - if (Z3native.is_null np) then - None - else - Some (expr_of_ptr (z3obj_gc x) np) - - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if not (Z3native.is_as_array (z3obj_gnc x) n) then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in - if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) - - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) - - let get_func_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - (mk_list f n_funcs) @ (mk_list g n_consts) - - exception ModelEvaluationFailedException of string - - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in - if not r then - raise (ModelEvaluationFailedException "evaluation failed") - else - expr_of_ptr (z3obj_gc x) v - - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) - - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - mk_list f n - - let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Probe = -struct - type probe = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : probe = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.probe_inc_ref ; - dec_ref = Z3native.probe_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - - let apply ( x : probe ) ( g : Goal.goal ) = - Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) - - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes (context_gno ctx) - - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name (context_gno ctx) i) in - mk_list f n - - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr (context_gno ctx) name - - let mk_probe ( ctx : context ) ( name : string ) = - (create ctx (Z3native.mk_probe (context_gno ctx) name)) - - let const ( ctx : context ) ( v : float ) = - (create ctx (Z3native.probe_const (context_gno ctx) v)) - - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let not_ ( ctx : context ) ( p : probe ) = - (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) -end - - -module Tactic = -struct - type tactic = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : tactic = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.tactic_inc_ref ; - dec_ref = Z3native.tactic_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module ApplyResult = - struct - type apply_result = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : apply_result = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.apply_result_inc_ref ; - dec_ref = Z3native.apply_result_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) - - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_subgoal ( x : apply_result ) ( i : int ) = - Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) - - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) - - let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) - - let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = - match p with - | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) - | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) - - let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) - - let get_tactic_names ( ctx : context ) = - let n = (get_num_tactics ctx ) in - let f i = (Z3native.get_tactic_name (context_gno ctx) i) in - mk_list f n - - let get_tactic_description ( ctx : context ) ( name : string ) = - Z3native.tactic_get_descr (context_gno ctx) name - - let mk_tactic ( ctx : context ) ( name : string ) = - create ctx (Z3native.mk_tactic (context_gno ctx) name) - - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = - let f p c = (match p with - | None -> (Some (z3obj_gno c)) - | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in - match (List.fold_left f None ts) with - | None -> - create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - | Some(x) -> - let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in - create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) - - let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - - let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) - - let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) - - let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) - - let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) - - let skip ( ctx : context ) = - create ctx (Z3native.tactic_skip (context_gno ctx)) - - let fail ( ctx : context ) = - create ctx (Z3native.tactic_fail (context_gno ctx)) - - let fail_if ( ctx : context ) ( p : Probe.probe ) = - create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) - - let fail_if_not_decided ( ctx : context ) = - create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) - - let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) - - let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - using_params ctx t p - - let par_or ( ctx : context ) ( t : tactic list ) = - let f e = (z3obj_gno e) in - create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) - - let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - - let interrupt ( ctx : context ) = - Z3native.interrupt (context_gno ctx) -end - - -module Solver = -struct - type solver = z3_native_object - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : solver = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.solver_inc_ref ; - dec_ref = Z3native.solver_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let string_of_status ( s : status) = match s with - | UNSATISFIABLE -> "unsatisfiable" - | SATISFIABLE -> "satisfiable" - | _ -> "unknown" - - module Statistics = - struct - type statistics = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : statistics = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.stats_inc_ref ; - dec_ref = Z3native.stats_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - - module Entry = - struct - type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } - - let create_si k v = - let res : statistics_entry = { - m_key = k ; - m_is_int = true ; - m_is_float = false ; - m_int = v ; - m_float = 0.0 - } in - res - - let create_sd k v = - let res : statistics_entry = { - m_key = k ; - m_is_int = false ; - m_is_float = true ; - m_int = 0 ; - m_float = v - } in - res - - - let get_key (x : statistics_entry) = x.m_key - let get_int (x : statistics_entry) = x.m_int - let get_float (x : statistics_entry) = x.m_float - let is_int (x : statistics_entry) = x.m_is_int - let is_float (x : statistics_entry) = x.m_is_float - let to_string_value (x : statistics_entry) = - if (is_int x) then - string_of_int (get_int x) - else if (is_float x) then - string_of_float (get_float x) - else - raise (Z3native.Exception "Unknown statistical entry type") - let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) - end - - let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) - - let get_entries ( x : statistics ) = - let n = (get_size x ) in - let f i = ( - let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in - if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) - else - (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) - ) in - mk_list f n - - let get_keys ( x : statistics ) = - let n = (get_size x) in - let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get ( x : statistics ) ( key : string ) = - let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in - List.fold_left f None (get_entries x) - end - - let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) - - let set_parameters ( x : solver ) ( p : Params.params )= - Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - - let get_param_descrs ( x : solver ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) - - let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) - - let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n - - let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - - let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (List.map f constraints) - - let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = - if ((List.length cs) != (List.length ps)) then - raise (Z3native.Exception "Argument size mismatch") - else - let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in - ignore (List.iter2 f cs ps) - - let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) - - let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVector.get_size a) - - let get_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size a) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in - mk_list f n - - let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = - let r = - if ((List.length assumptions) == 0) then - lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) - else - let f x = (Expr.gno (Boolean.expr_of_bool_expr x)) in - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) - in - match r with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN - - let get_model ( x : solver ) = - let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in - if (Z3native.is_null q) then - None - else - Some (Model.create (z3obj_gc x) q) - - let get_proof ( x : solver ) = - let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size cn) in - let f i = (AST.ASTVector.get cn i) in - mk_list f n - - let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - let get_statistics ( x : solver ) = - (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) - - let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = - match logic with - | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) - - let mk_solver_s ( ctx : context ) ( logic : string ) = - mk_solver ctx (Some (Symbol.mk_string ctx logic)) - - let mk_simple_solver ( ctx : context ) = - (create ctx (Z3native.mk_simple_solver (context_gno ctx))) - - let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = - (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) - - let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Fixedpoint = -struct - type fixedpoint = z3_native_object - - let create ( ctx : context ) = - let res : fixedpoint = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.fixedpoint_inc_ref ; - dec_ref = Z3native.fixedpoint_dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; - (z3obj_create res) ; - res - - - let get_help ( x : fixedpoint ) = - Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) - - let set_params ( x : fixedpoint ) ( p : Params.params )= - Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - - let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (List.map f constraints) ; - () - - let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - - let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = - match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) - - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) - - let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN - - let query_r ( x : fixedpoint ) ( relations : func_decl list ) = - let f x = ptr_of_ast (ast_of_func_decl x) in - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN - - let push ( x : fixedpoint ) = - Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) - - let pop ( x : fixedpoint ) = - Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - - let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) - - let get_answer ( x : fixedpoint ) = - let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let get_reason_unknown ( x : fixedpoint ) = - Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) - - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) - - let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - - let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = - let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) - - let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - mk_list f n - - let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - mk_list f n - - let mk_fixedpoint ( ctx : context ) = create ctx -end - -module Options = -struct - - let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value (context_gno ctx) id value - - let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in - if not r then - None - else - Some v - - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) - - let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages enabled -end - - -module SMT = -struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = - Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) - (Boolean.gno formula) - - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Z3native.parse_smtlib_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Z3native.parse_smtlib_file (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - - let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) - - let get_smtlib_formulas ( ctx : context ) = - let n = (get_num_smtlib_formulas ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in - mk_list f n - - let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) - - let get_smtlib_assumptions ( ctx : context ) = - let n = (get_num_smtlib_assumptions ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in - mk_list f n - - let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) - - let get_smtlib_decls ( ctx : context ) = - let n = (get_num_smtlib_decls ctx) in - let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in - mk_list f n - - let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - - let get_smtlib_sorts ( ctx : context ) = - let n = (get_num_smtlib_sorts ctx) in - let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in - mk_list f n - - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) -end - - -let set_global_param ( id : string ) ( value : string ) = - (Z3native.global_param_set id value) - -let get_global_param ( id : string ) = - let (r, v) = (Z3native.global_param_get id) in - if not r then - None - else - Some v - -let global_param_reset_all = - Z3native.global_param_reset_all diff --git a/src/api/ml/z3_rich.mli b/src/api/ml/z3_rich.mli deleted file mode 100644 index f2ecd326d..000000000 --- a/src/api/ml/z3_rich.mli +++ /dev/null @@ -1,3071 +0,0 @@ -(** - The Z3 ML/Ocaml Interface. - - Copyright (C) 2012 Microsoft Corporation - @author CM Wintersteiger (cwinter) 2012-12-17 - - NOTE: This is the *rich* version of the interface, using more - type information directly in the type system. Coercion functions - are provided to tran coerce on type into another where applicable. -*) - -(** Context objects. - - Most interactions with Z3 are interpreted in some context; many users will only - require one such object, but power users may require more than one. To start using - Z3, do - - - let ctx = (mk_context []) in - (...) - - - where a list of pairs of strings may be passed to set options on - the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (mk_context cfg) in - (...) - -*) -type context - -(** Create a context object *) -val mk_context : (string * string) list -> context - -(** Interaction logging for Z3 - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) -module Log : -sig - (** Open an interaction log file. - @return True if opening the log file succeeds, false otherwise. *) - (* CMW: "open" seems to be a reserved keyword? *) - val open_ : string -> bool - - (** Closes the interaction log. *) - val close : unit - - (** Appends a user-provided string to the interaction log. *) - val append : string -> unit -end - -(** Version information *) -module Version : -sig - (** The major version. *) - val major : int - - (** The minor version. *) - val minor : int - - (** The build version. *) - val build : int - - (** The revision. *) - val revision : int - - (** A string representation of the version information. *) - val to_string : string -end - -(** Symbols are used to name several term and type constructors *) -module Symbol : -sig - (** Numbered Symbols *) - type int_symbol - - (** Named Symbols *) - type string_symbol - - (** Symbols *) - type symbol = S_Int of int_symbol | S_Str of string_symbol - - (** The kind of the symbol (int or string) *) - val kind : symbol -> Z3enums.symbol_kind - - (** Indicates whether the symbol is of Int kind *) - val is_int_symbol : symbol -> bool - - (** Indicates whether the symbol is of string kind. *) - val is_string_symbol : symbol -> bool - - (** The int value of the symbol. *) - val get_int : int_symbol -> int - - (** The string value of the symbol. *) - val get_string : string_symbol -> string - - (** A string representation of the symbol. *) - val to_string : symbol -> string - - (** Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. *) - val mk_int : context -> int -> symbol - - (** Creates a new symbol using a string. *) - val mk_string : context -> string -> symbol - - (** Create a list of symbols. *) - val mk_ints : context -> int list -> symbol list - - (** Create a list of symbols. *) - val mk_strings : context -> string list -> symbol list -end - -(** The abstract syntax tree (AST) module *) -module AST : -sig - type ast - - (** Vectors of ASTs *) - module ASTVector : - sig - type ast_vector - - (** The size of the vector *) - val get_size : ast_vector -> int - - (** - Retrieves the i-th object in the vector. - @return An AST *) - val get : ast_vector -> int -> ast - - (** Sets the i-th object in the vector. *) - val set : ast_vector -> int -> ast -> unit - - (** Resize the vector to a new size. *) - val resize : ast_vector -> int -> unit - - (** Add an ast to the back of the vector. The size - is increased by 1. *) - val push : ast_vector -> ast -> unit - - (** Translates all ASTs in the vector to another context. - @return A new ASTVector *) - val translate : ast_vector -> context -> ast_vector - - (** Retrieves a string representation of the vector. *) - val to_string : ast_vector -> string - end - - (** Map from AST to AST *) - module ASTMap : - sig - type ast_map - - (** Checks whether the map contains a key. - @return True if the key in the map, false otherwise. *) - val contains : ast_map -> ast -> bool - - (** Finds the value associated with the key. - This function signs an error when the key is not a key in the map. *) - val find : ast_map -> ast -> ast - - (** Stores or replaces a new key/value pair in the map. *) - val insert : ast_map -> ast -> ast -> unit - - (** Erases the key from the map.*) - val erase : ast_map -> ast -> unit - - (** Removes all keys from the map. *) - val reset : ast_map -> unit - - (** The size of the map *) - val get_size : ast_map -> int - - (** The keys stored in the map. *) - val get_keys : ast_map -> ast list - - (** Retrieves a string representation of the map.*) - val to_string : ast_map -> string - end - - (** The AST's hash code. - @return A hash code *) - val get_hash_code : ast -> int - - (** A unique identifier for the AST (unique among all ASTs). *) - val get_id : ast -> int - - (** The kind of the AST. *) - val get_ast_kind : ast -> Z3enums.ast_kind - - (** Indicates whether the AST is an Expr *) - val is_expr : ast -> bool - - (** Indicates whether the AST is a bound variable*) - val is_var : ast -> bool - - (** Indicates whether the AST is a Quantifier *) - val is_quantifier : ast -> bool - - (** Indicates whether the AST is a Sort *) - val is_sort : ast -> bool - - (** Indicates whether the AST is a func_decl *) - val is_func_decl : ast -> bool - - (** A string representation of the AST. *) - val to_string : ast -> string - - (** A string representation of the AST in s-expression notation. *) - val to_sexpr : ast -> string - - (** Comparison operator. - @return True if the two ast's are from the same context - and represent the same sort; false otherwise. *) - val ( = ) : ast -> ast -> bool - - (** Object Comparison. - @return Negative if the first ast should be sorted before the second, positive if after else zero. *) - val compare : ast -> ast -> int - - (** Operator < *) - val ( < ) : ast -> ast -> int - - (** Translates (copies) the AST to another context. - @return A copy of the AST which is associated with the other context. *) - val translate : ast -> context -> ast - - (** Wraps an AST. - - This function is used for transitions between native and - managed objects. Note that the native ast that is passed must be a - native object obtained from Z3 (e.g., through {!unwrap_ast}) - and that it must have a correct reference count (see e.g., - Z3native.inc_ref). *) - val wrap_ast : context -> Z3native.z3_ast -> ast - - (** Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - Z3native.inc_ref). - {!wrap_ast} *) - val unwrap_ast : ast -> Z3native.ptr -end - -(** The Sort module implements type information for ASTs *) -module Sort : -sig - (** Sorts *) - type sort = Sort of AST.ast - - (** Uninterpreted Sorts *) - type uninterpreted_sort = UninterpretedSort of sort - - val ast_of_sort : sort -> AST.ast - val sort_of_uninterpreted_sort : uninterpreted_sort -> sort - val uninterpreted_sort_of_sort : sort -> uninterpreted_sort - - (** Comparison operator. - @return True if the two sorts are from the same context - and represent the same sort; false otherwise. *) - val ( = ) : sort -> sort -> bool - - (** Returns a unique identifier for the sort. *) - val get_id : sort -> int - - (** The kind of the sort. *) - val get_sort_kind : sort -> Z3enums.sort_kind - - (** The name of the sort *) - val get_name : sort -> Symbol.symbol - - (** A string representation of the sort. *) - val to_string : sort -> string - - (** Create a new uninterpreted sort. *) - val mk_uninterpreted : context -> Symbol.symbol -> uninterpreted_sort - - (** Create a new uninterpreted sort. *) - val mk_uninterpreted_s : context -> string -> uninterpreted_sort -end - -(** Function declarations *) -module rec FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - - val ast_of_func_decl : FuncDecl.func_decl -> AST.ast - - (** Parameters of Func_Decls *) - module Parameter : - sig - (** Parameters of func_decls *) - type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - (** The kind of the parameter. *) - val get_kind : parameter -> Z3enums.parameter_kind - - (** The int value of the parameter.*) - val get_int : parameter -> int - - (** The double value of the parameter.*) - val get_float : parameter -> float - - (** The Symbol.Symbol value of the parameter.*) - val get_symbol : parameter -> Symbol.symbol - - (** The Sort value of the parameter.*) - val get_sort : parameter -> Sort.sort - - (** The AST value of the parameter.*) - val get_ast : parameter -> AST.ast - - (** The FunctionDeclaration value of the parameter.*) - val get_func_decl : parameter -> func_decl - - (** The rational string value of the parameter.*) - val get_rational : parameter -> string - end - - (** Creates a new function declaration. *) - val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl - - (** Creates a new function declaration. *) - val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl - (** Creates a fresh function declaration with a name prefixed with a prefix string. *) - - val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl - - (** Creates a new constant function declaration. *) - val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl - - (** Creates a new constant function declaration. *) - val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - - (** Creates a fresh constant function declaration with a name prefixed with a prefix string. - {!mk_func_decl} - {!mk_func_decl} *) - val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - - (** Comparison operator. - @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) - val ( = ) : func_decl -> func_decl -> bool - - (** A string representations of the function declaration. *) - val to_string : func_decl -> string - - (** Returns a unique identifier for the function declaration. *) - val get_id : func_decl -> int - - (** The arity of the function declaration *) - val get_arity : func_decl -> int - - (** The size of the domain of the function declaration - {!get_arity} *) - val get_domain_size : func_decl -> int - - (** The domain of the function declaration *) - val get_domain : func_decl -> Sort.sort list - - (** The range of the function declaration *) - val get_range : func_decl -> Sort.sort - - (** The kind of the function declaration. *) - val get_decl_kind : func_decl -> Z3enums.decl_kind - - (** The name of the function declaration*) - val get_name : func_decl -> Symbol.symbol - - (** The number of parameters of the function declaration *) - val get_num_parameters : func_decl -> int - - (** The parameters of the function declaration *) - val get_parameters : func_decl -> Parameter.parameter list - - (** Create expression that applies function to arguments. *) - val apply : func_decl -> Expr.expr list -> Expr.expr -end - -(** Parameter sets (of Solvers, Tactics, ...) - - A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) -and Params : -sig - type params - - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs : - sig - type param_descrs - - (** Validate a set of parameters. *) - val validate : param_descrs -> params -> unit - - (** Retrieve kind of parameter. *) - val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - - (** Retrieve all names of parameters. *) - val get_names : param_descrs -> Symbol.symbol list - - (** The size of the ParamDescrs. *) - val get_size : param_descrs -> int - - (** Retrieves a string representation of the ParamDescrs. *) - val to_string : param_descrs -> string - end - - (** Adds a parameter setting. *) - val add_bool : params -> Symbol.symbol -> bool -> unit - - (** Adds a parameter setting. *) - val add_int : params -> Symbol.symbol -> int -> unit - - (** Adds a parameter setting. *) - val add_double : params -> Symbol.symbol -> float -> unit - - (** Adds a parameter setting. *) - val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - - (** Adds a parameter setting. *) - val add_s_bool : params -> string -> bool -> unit - - (** Adds a parameter setting. *) - val add_s_int : params -> string -> int -> unit - - (** Adds a parameter setting. *) - val add_s_double : params -> string -> float -> unit - - (** Adds a parameter setting. *) - val add_s_symbol : params -> string -> Symbol.symbol -> unit - - (** Creates a new parameter set *) - val mk_params : context -> params - - (** A string representation of the parameter set. *) - val to_string : params -> string -end - -(** General Expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - - val ast_of_expr : Expr.expr -> AST.ast - val expr_of_ast : AST.ast -> Expr.expr - - (** Returns a simplified version of the expression. - {!get_simplify_help} *) - val simplify : Expr.expr -> Params.params option -> expr - - (** A string describing all available parameters to Expr.Simplify. *) - val get_simplify_help : context -> string - - (** Retrieves parameter descriptions for simplifier. *) - val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs - - (** The function declaration of the function that is applied in this expression. *) - val get_func_decl : Expr.expr -> FuncDecl.func_decl - - (** Indicates whether the expression is the true or false expression - or something else (L_UNDEF). *) - val get_bool_value : Expr.expr -> Z3enums.lbool - - (** The number of arguments of the expression. *) - val get_num_args : Expr.expr -> int - - (** The arguments of the expression. *) - val get_args : Expr.expr -> Expr.expr list - - (** Update the arguments of the expression using an array of expressions. - The number of new arguments should coincide with the current number of arguments. *) - val update : Expr.expr -> Expr.expr list -> expr - - (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. - - The result is the new expression. The arrays from and to must have size num_exprs. - For every i smaller than num_exprs, we must have that - sort of from[i] must be equal to sort of to[i]. *) - val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr - - (** Substitute every occurrence of from in the expression with to. - {!substitute} *) - val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr - - (** Substitute the free variables in the expression with the expressions in the expr array - - For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) - val substitute_vars : Expr.expr -> Expr.expr list -> expr - - (** Translates (copies) the term to another context. - @return A copy of the term which is associated with the other context *) - val translate : Expr.expr -> context -> expr - - (** Returns a string representation of the expression. *) - val to_string : Expr.expr -> string - - (** Indicates whether the term is a numeral *) - val is_numeral : Expr.expr -> bool - - (** Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. *) - val is_well_sorted : Expr.expr -> bool - - (** The Sort of the term. *) - val get_sort : Expr.expr -> Sort.sort - - (** Indicates whether the term has Boolean sort. *) - val is_bool : Expr.expr -> bool - - (** Indicates whether the term represents a constant. *) - val is_const : Expr.expr -> bool - - (** Indicates whether the term is the constant true. *) - val is_true : Expr.expr -> bool - - (** Indicates whether the term is the constant false. *) - val is_false : Expr.expr -> bool - - (** Indicates whether the term is an equality predicate. *) - val is_eq : Expr.expr -> bool - - (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) - val is_distinct : Expr.expr -> bool - - (** Indicates whether the term is a ternary if-then-else term *) - val is_ite : Expr.expr -> bool - - (** Indicates whether the term is an n-ary conjunction *) - val is_and : Expr.expr -> bool - - (** Indicates whether the term is an n-ary disjunction *) - val is_or : Expr.expr -> bool - - (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) - val is_iff : Expr.expr -> bool - - (** Indicates whether the term is an exclusive or *) - val is_xor : Expr.expr -> bool - - (** Indicates whether the term is a negation *) - val is_not : Expr.expr -> bool - - (** Indicates whether the term is an implication *) - val is_implies : Expr.expr -> bool - - (** Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) - val is_label : Expr.expr -> bool - - (** Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) - val is_label_lit : Expr.expr -> bool - - (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) - val is_oeq : Expr.expr -> bool - - (** Creates a new constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - - (** Creates a new constant. *) - val mk_const_s : context -> string -> Sort.sort -> expr - - (** Creates a constant from the func_decl. *) - val mk_const_f : context -> FuncDecl.func_decl -> expr - - (** Creates a fresh constant with a name prefixed with a string. *) - val mk_fresh_const : context -> string -> Sort.sort -> expr - - (** Create a new function application. *) - val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - - (** Create a numeral of a given sort. - @return A Term with the goven value and sort *) - val mk_numeral_string : context -> string -> Sort.sort -> expr - - (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. - @return A Term with the given value and sort *) - val mk_numeral_int : context -> int -> Sort.sort -> expr -end - -(** Boolean expressions *) -module Boolean : -sig - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - val expr_of_bool_expr : bool_expr -> Expr.expr - val sort_of_bool_sort : bool_sort -> Sort.sort - val bool_sort_of_sort : Sort.sort -> bool_sort - val bool_expr_of_expr : Expr.expr -> bool_expr - - (** Create a Boolean sort *) - val mk_sort : context -> bool_sort - - (** Create a Boolean constant. *) - val mk_const : context -> Symbol.symbol -> bool_expr - - (** Create a Boolean constant. *) - val mk_const_s : context -> string -> bool_expr - - (** The true Term. *) - val mk_true : context -> bool_expr - - (** The false Term. *) - val mk_false : context -> bool_expr - - (** Creates a Boolean value. *) - val mk_val : context -> bool -> bool_expr - - (** Creates the equality between two expr's. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr - - (** Creates a distinct term. *) - val mk_distinct : context -> Expr.expr list -> bool_expr - - (** Mk an expression representing not(a). *) - val mk_not : context -> bool_expr -> bool_expr - - (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) - val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing t1 iff t2. *) - val mk_iff : context -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing t1 -> t2. *) - val mk_implies : context -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing t1 xor t2. *) - val mk_xor : context -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing the AND of args *) - val mk_and : context -> bool_expr list -> bool_expr - - (** Create an expression representing the OR of args *) - val mk_or : context -> bool_expr list -> bool_expr -end - -(** Quantifier expressions *) -module Quantifier : -sig - type quantifier = Quantifier of Expr.expr - - val expr_of_quantifier : quantifier -> Expr.expr - val quantifier_of_expr : Expr.expr -> quantifier - - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. *) - module Pattern : - sig - type pattern = Pattern of AST.ast - - val ast_of_pattern : pattern -> AST.ast - val pattern_of_ast : AST.ast -> pattern - - (** The number of terms in the pattern. *) - val get_num_terms : pattern -> int - - (** The terms in the pattern. *) - val get_terms : pattern -> Expr.expr list - - (** A string representation of the pattern. *) - val to_string : pattern -> string - end - - - (** The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. *) - val get_index : Expr.expr -> int - - (** Indicates whether the quantifier is universal. *) - val is_universal : quantifier -> bool - - (** Indicates whether the quantifier is existential. *) - val is_existential : quantifier -> bool - - (** The weight of the quantifier. *) - val get_weight : quantifier -> int - - (** The number of patterns. *) - val get_num_patterns : quantifier -> int - - (** The patterns. *) - val get_patterns : quantifier -> Pattern.pattern list - - (** The number of no-patterns. *) - val get_num_no_patterns : quantifier -> int - - (** The no-patterns. *) - val get_no_patterns : quantifier -> Pattern.pattern list - - (** The number of bound variables. *) - val get_num_bound : quantifier -> int - - (** The symbols for the bound variables. *) - val get_bound_variable_names : quantifier -> Symbol.symbol list - - (** The sorts of the bound variables. *) - val get_bound_variable_sorts : quantifier -> Sort.sort list - - (** The body of the quantifier. *) - val get_body : quantifier -> Boolean.bool_expr - - (** Creates a new bound variable. *) - val mk_bound : context -> int -> Sort.sort -> Expr.expr - - (** Create a quantifier pattern. *) - val mk_pattern : context -> Expr.expr list -> Pattern.pattern - - (** Create a universal Quantifier. *) - val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a universal Quantifier. *) - val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create an existential Quantifier. *) - val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create an existential Quantifier. *) - val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a Quantifier. *) - val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a Quantifier. *) - val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier -end - -(** Functions to manipulate Array expressions *) -module Array_ : -sig - type array_sort = ArraySort of Sort.sort - type array_expr = ArrayExpr of Expr.expr - - val sort_of_array_sort : array_sort -> Sort.sort - val array_sort_of_sort : Sort.sort -> array_sort - val expr_of_array_expr : array_expr -> Expr.expr - - val array_expr_of_expr : Expr.expr -> array_expr - - (** Create a new array sort. *) - val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort - - (** Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. *) - val is_store : Expr.expr -> bool - - (** Indicates whether the term is an array select. *) - val is_select : Expr.expr -> bool - - (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - val is_constant_array : Expr.expr -> bool - - (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. *) - val is_default_array : Expr.expr -> bool - - (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - val is_array_map : Expr.expr -> bool - - (** Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. *) - val is_as_array : Expr.expr -> bool - - (** Indicates whether the term is of an array sort. *) - val is_array : Expr.expr -> bool - - (** The domain of the array sort. *) - val get_domain : array_sort -> Sort.sort - - (** The range of the array sort. *) - val get_range : array_sort -> Sort.sort - - (** Create an array constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr - - (** Create an array constant. *) - val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr - - (** Array read. - - The argument a is the array and i is the index - of the array that gets read. - - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. - {!Array_.mk_sort} - {!mk_store} *) - val mk_select : context -> array_expr -> Expr.expr -> array_expr - - (** Array update. - - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). - {!Array_.mk_sort} - {!mk_select} *) - val mk_store : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr - - (** Create a constant array. - - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. - {!Array_.mk_sort} - {!mk_select} *) - val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr - - (** Maps f on the argument arrays. - - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. - {!Array_.mk_sort} - {!mk_select} - {!mk_store} *) - val mk_map : context -> FuncDecl.func_decl -> array_expr list -> array_expr - - (** Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. *) - val mk_term_array : context -> array_expr -> array_expr -end - -(** Functions to manipulate Set expressions *) -module Set : -sig - type set_sort = SetSort of Sort.sort - - val sort_of_set_sort : set_sort -> Sort.sort - - (** Create a set type. *) - val mk_sort : context -> Sort.sort -> set_sort - - (** Indicates whether the term is set union *) - val is_union : Expr.expr -> bool - - (** Indicates whether the term is set intersection *) - val is_intersect : Expr.expr -> bool - - (** Indicates whether the term is set difference *) - val is_difference : Expr.expr -> bool - - (** Indicates whether the term is set complement *) - val is_complement : Expr.expr -> bool - - (** Indicates whether the term is set subset *) - val is_subset : Expr.expr -> bool - - (** Create an empty set. *) - val mk_empty : context -> Sort.sort -> Expr.expr - - (** Create the full set. *) - val mk_full : context -> Sort.sort -> Expr.expr - - (** Add an element to the set. *) - val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Remove an element from a set. *) - val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Take the union of a list of sets. *) - val mk_union : context -> Expr.expr list -> Expr.expr - - (** Take the intersection of a list of sets. *) - val mk_intersection : context -> Expr.expr list -> Expr.expr - - (** Take the difference between two sets. *) - val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Take the complement of a set. *) - val mk_complement : context -> Expr.expr -> Expr.expr - - (** Check for set membership. *) - val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Check for subsetness of sets. *) - val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr -end - -(** Functions to manipulate Finite Domain expressions *) -module FiniteDomain : -sig - type finite_domain_sort = FiniteDomainSort of Sort.sort - - val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort - val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort - - (** Create a new finite domain sort. *) - val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort - - (** Create a new finite domain sort. *) - val mk_sort_s : context -> string -> int -> finite_domain_sort - - (** Indicates whether the term is of an array sort. *) - val is_finite_domain : Expr.expr -> bool - - (** Indicates whether the term is a less than predicate over a finite domain. *) - val is_lt : Expr.expr -> bool - - (** The size of the finite domain sort. *) - val get_size : finite_domain_sort -> int -end - - -(** Functions to manipulate Relation expressions *) -module Relation : -sig - type relation_sort = RelationSort of Sort.sort - - val sort_of_relation_sort : relation_sort -> Sort.sort - val relation_sort_of_sort : Sort.sort -> relation_sort - - (** Indicates whether the term is of a relation sort. *) - val is_relation : Expr.expr -> bool - - (** Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. *) - val is_store : Expr.expr -> bool - - (** Indicates whether the term is an empty relation *) - val is_empty : Expr.expr -> bool - - (** Indicates whether the term is a test for the emptiness of a relation *) - val is_is_empty : Expr.expr -> bool - - (** Indicates whether the term is a relational join *) - val is_join : Expr.expr -> bool - - (** Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. *) - val is_union : Expr.expr -> bool - - (** Indicates whether the term is the widening of two relations - The function takes two arguments. *) - val is_widen : Expr.expr -> bool - - (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. *) - val is_project : Expr.expr -> bool - - (** Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. *) - val is_filter : Expr.expr -> bool - - (** Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. *) - val is_negation_filter : Expr.expr -> bool - - (** Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. *) - val is_rename : Expr.expr -> bool - - (** Indicates whether the term is the complement of a relation *) - val is_complement : Expr.expr -> bool - - (** Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. *) - val is_select : Expr.expr -> bool - - (** Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind {!is_union} - to perform destructive updates to the first argument. *) - val is_clone : Expr.expr -> bool - - (** The arity of the relation sort. *) - val get_arity : relation_sort -> int - - (** The sorts of the columns of the relation sort. *) - val get_column_sorts : relation_sort -> relation_sort list -end - -(** Functions to manipulate Datatype expressions *) -module Datatype : -sig - type datatype_sort = DatatypeSort of Sort.sort - type datatype_expr = DatatypeExpr of Expr.expr - - val sort_of_datatype_sort : datatype_sort -> Sort.sort - val datatype_sort_of_sort : Sort.sort -> datatype_sort - val expr_of_datatype_expr : datatype_expr -> Expr.expr - val datatype_expr_of_expr : Expr.expr -> datatype_expr - - (** Datatype Constructors *) - module Constructor : - sig - type constructor - - (** The number of fields of the constructor. *) - val get_num_fields : constructor -> int - - (** The function declaration of the constructor. *) - val get_constructor_decl : constructor -> FuncDecl.func_decl - - (** The function declaration of the tester. *) - val get_tester_decl : constructor -> FuncDecl.func_decl - - (** The function declarations of the accessors *) - val get_accessor_decls : constructor -> FuncDecl.func_decl list - end - - (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) - val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor - - (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) - val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor - - (** Create a new datatype sort. *) - val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> datatype_sort - - (** Create a new datatype sort. *) - val mk_sort_s : context -> string -> Constructor.constructor list -> datatype_sort - - (** Create mutually recursive datatypes. *) - val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> datatype_sort list - - (** Create mutually recursive data-types. *) - val mk_sorts_s : context -> string list -> Constructor.constructor list list -> datatype_sort list - - - (** The number of constructors of the datatype sort. *) - val get_num_constructors : datatype_sort -> int - - (** The constructors. *) - val get_constructors : datatype_sort -> FuncDecl.func_decl list - - (** The recognizers. *) - val get_recognizers : datatype_sort -> FuncDecl.func_decl list - - (** The constructor accessors. *) - val get_accessors : datatype_sort -> FuncDecl.func_decl list list -end - -(** Functions to manipulate Enumeration expressions *) -module Enumeration : -sig - type enum_sort = EnumSort of Sort.sort - - val sort_of_enum_sort : enum_sort -> Sort.sort - - (** Create a new enumeration sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> enum_sort - - (** Create a new enumeration sort. *) - val mk_sort_s : context -> string -> string list -> enum_sort - - (** The function declarations of the constants in the enumeration. *) - val get_const_decls : enum_sort -> FuncDecl.func_decl list - - (** The test predicates for the constants in the enumeration. *) - val get_tester_decls : enum_sort -> FuncDecl.func_decl list -end - -(** Functions to manipulate List expressions *) -module List_ : -sig - type list_sort = ListSort of Sort.sort - - val sort_of_list_sort : list_sort -> Sort.sort - - (** Create a new list sort. *) - val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort - - (** Create a new list sort. *) - val mk_list_s : context -> string -> Sort.sort -> list_sort - - (** The declaration of the nil function of this list sort. *) - val get_nil_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the isNil function of this list sort. *) - val get_is_nil_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the cons function of this list sort. *) - val get_cons_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the isCons function of this list sort. *) - val get_is_cons_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the head function of this list sort. *) - val get_head_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the tail function of this list sort. *) - val get_tail_decl : list_sort -> FuncDecl.func_decl - - (** The empty list. *) - val nil : list_sort -> Expr.expr -end - -(** Functions to manipulate Tuple expressions *) -module Tuple : -sig - type tuple_sort = TupleSort of Sort.sort - - val sort_of_tuple_sort : tuple_sort -> Sort.sort - - (** Create a new tuple sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> tuple_sort - - (** The constructor function of the tuple. *) - val get_mk_decl : tuple_sort -> FuncDecl.func_decl - - (** The number of fields in the tuple. *) - val get_num_fields : tuple_sort -> int - - (** The field declarations. *) - val get_field_decls : tuple_sort -> FuncDecl.func_decl list -end - -(** Functions to manipulate arithmetic expressions *) -module rec Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : Arithmetic.arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> Arithmetic.arith_sort - val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr - - (** Integer Arithmetic *) - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val arith_sort_of_int_sort : Arithmetic.Integer.int_sort -> Arithmetic.arith_sort - val int_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Integer.int_sort - val arith_expr_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.arith_expr - val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr - val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr - val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num - - (** Create a new integer sort. *) - val mk_sort : context -> int_sort - - (** Retrieve the int value. *) - val get_int : int_num -> int - - (** Returns a string representation of the numeral. *) - val to_string : int_num -> string - - (** Creates an integer constant. *) - val mk_const : context -> Symbol.symbol -> int_expr - - (** Creates an integer constant. *) - val mk_const_s : context -> string -> int_expr - - (** Create an expression representing t1 mod t2. - The arguments must have int type. *) - val mk_mod : context -> int_expr -> int_expr -> int_expr - - (** Create an expression representing t1 rem t2. - The arguments must have int type. *) - val mk_rem : context -> int_expr -> int_expr -> int_expr - - (** Create an integer numeral. *) - val mk_numeral_s : context -> string -> int_num - - (** Create an integer numeral. - @return A Term with the given value and sort Integer *) - val mk_numeral_i : context -> int -> int_num - - (** Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. *) - val mk_int2real : context -> int_expr -> Real.real_expr - - (** Create an n-bit bit-vector from an integer argument. - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. *) - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end - - (** Real Arithmetic *) - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - - (** Create a real sort. *) - val mk_sort : context -> real_sort - - (** The numerator of a rational numeral. *) - val get_numerator : rat_num -> Integer.int_num - - (** The denominator of a rational numeral. *) - val get_denominator : rat_num -> Integer.int_num - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as indicated by the int argument.*) - val to_decimal_string : rat_num -> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : rat_num -> string - - (** Creates a real constant. *) - val mk_const : context -> Symbol.symbol -> real_expr - - (** Creates a real constant. *) - val mk_const_s : context -> string -> real_expr - - (** Create a real numeral from a fraction. - @return A Term with rational value and sort Real - {!mk_numeral_s} *) - val mk_numeral_nd : context -> int -> int -> rat_num - - (** Create a real numeral. - @return A Term with the given value and sort Real *) - val mk_numeral_s : context -> string -> rat_num - - (** Create a real numeral. - @return A Term with the given value and sort Real *) - val mk_numeral_i : context -> int -> rat_num - - (** Creates an expression that checks whether a real number is an integer. *) - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - - (** Coerce a real to an integer. - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. *) - val mk_real2int : context -> real_expr -> Integer.int_expr - end - - (** Algebraic Numbers *) - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr - val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num - - (** Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_upper : algebraic_num -> int -> Real.rat_num - - (** Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_lower : algebraic_num -> int -> Real.rat_num - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as the int argument provided.*) - val to_decimal_string : algebraic_num -> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : algebraic_num -> string - end - - (** Indicates whether the term is of integer sort. *) - val is_int : Expr.expr -> bool - - (** Indicates whether the term is an arithmetic numeral. *) - val is_arithmetic_numeral : Expr.expr -> bool - - (** Indicates whether the term is a less-than-or-equal *) - val is_le : Expr.expr -> bool - - (** Indicates whether the term is a greater-than-or-equal *) - val is_ge : Expr.expr -> bool - - (** Indicates whether the term is a less-than *) - val is_lt : Expr.expr -> bool - - (** Indicates whether the term is a greater-than *) - val is_gt : Expr.expr -> bool - - (** Indicates whether the term is addition (binary) *) - val is_add : Expr.expr -> bool - - (** Indicates whether the term is subtraction (binary) *) - val is_sub : Expr.expr -> bool - - (** Indicates whether the term is a unary minus *) - val is_uminus : Expr.expr -> bool - - (** Indicates whether the term is multiplication (binary) *) - val is_mul : Expr.expr -> bool - - (** Indicates whether the term is division (binary) *) - val is_div : Expr.expr -> bool - - (** Indicates whether the term is integer division (binary) *) - val is_idiv : Expr.expr -> bool - - (** Indicates whether the term is remainder (binary) *) - val is_remainder : Expr.expr -> bool - - (** Indicates whether the term is modulus (binary) *) - val is_modulus : Expr.expr -> bool - - (** Indicates whether the term is a coercion of integer to real (unary) *) - val is_inttoreal : Expr.expr -> bool - - (** Indicates whether the term is a coercion of real to integer (unary) *) - val is_real_to_int : Expr.expr -> bool - - (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - val is_real_is_int : Expr.expr -> bool - - (** Indicates whether the term is of sort real. *) - val is_real : Expr.expr -> bool - - (** Indicates whether the term is an integer numeral. *) - val is_int_numeral : Expr.expr -> bool - - (** Indicates whether the term is a real numeral. *) - val is_rat_num : Expr.expr -> bool - - (** Indicates whether the term is an algebraic number *) - val is_algebraic_number : Expr.expr -> bool - - (** Create an expression representing t[0] + t[1] + .... *) - val mk_add : context -> arith_expr list -> arith_expr - - (** Create an expression representing t[0] * t[1] * .... *) - val mk_mul : context -> arith_expr list -> arith_expr - - (** Create an expression representing t[0] - t[1] - .... *) - val mk_sub : context -> arith_expr list -> arith_expr - - (** Create an expression representing -t. *) - val mk_unary_minus : context -> arith_expr -> arith_expr - - (** Create an expression representing t1 / t2. *) - val mk_div : context -> arith_expr -> arith_expr -> arith_expr - - (** Create an expression representing t1 ^ t2. *) - val mk_power : context -> arith_expr -> arith_expr -> arith_expr - - (** Create an expression representing t1 < t2 *) - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - - (** Create an expression representing t1 <= t2 *) - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr - - (** Create an expression representing t1 > t2 *) - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - - (** Create an expression representing t1 >= t2 *) - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr -end - -(** Functions to manipulate bit-vector expressions *) -and BitVector : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - - (** Create a new bit-vector sort. *) - val mk_sort : context -> int -> bitvec_sort - - (** Indicates whether the terms is of bit-vector sort. *) - val is_bv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector numeral *) - val is_bv_numeral : Expr.expr -> bool - - (** Indicates whether the term is a one-bit bit-vector with value one *) - val is_bv_bit1 : Expr.expr -> bool - - (** Indicates whether the term is a one-bit bit-vector with value zero *) - val is_bv_bit0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unary minus *) - val is_bv_uminus : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector addition (binary) *) - val is_bv_add : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector subtraction (binary) *) - val is_bv_sub : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector multiplication (binary) *) - val is_bv_mul : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed division (binary) *) - val is_bv_sdiv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned division (binary) *) - val is_bv_udiv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed remainder (binary) *) - val is_bv_SRem : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - val is_bv_urem : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed modulus *) - val is_bv_smod : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed division by zero *) - val is_bv_sdiv0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned division by zero *) - val is_bv_udiv0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed remainder by zero *) - val is_bv_srem0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - val is_bv_urem0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed modulus by zero *) - val is_bv_smod0 : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - val is_bv_ule : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - val is_bv_sle : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - val is_bv_uge : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - val is_bv_sge : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector less-than *) - val is_bv_ult : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector less-than *) - val is_bv_slt : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector greater-than *) - val is_bv_ugt : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector greater-than *) - val is_bv_sgt : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise AND *) - val is_bv_and : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise OR *) - val is_bv_or : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NOT *) - val is_bv_not : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise XOR *) - val is_bv_xor : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NAND *) - val is_bv_nand : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NOR *) - val is_bv_nor : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise XNOR *) - val is_bv_xnor : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector concatenation (binary) *) - val is_bv_concat : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector sign extension *) - val is_bv_signextension : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector zero extension *) - val is_bv_zeroextension : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector extraction *) - val is_bv_extract : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector repetition *) - val is_bv_repeat : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector reduce OR *) - val is_bv_reduceor : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector reduce AND *) - val is_bv_reduceand : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector comparison *) - val is_bv_comp : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector shift left *) - val is_bv_shiftleft : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector logical shift right *) - val is_bv_shiftrightlogical : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector arithmetic shift left *) - val is_bv_shiftrightarithmetic : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate left *) - val is_bv_rotateleft : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate right *) - val is_bv_rotateright : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - val is_bv_rotateleftextended : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - val is_bv_rotaterightextended : Expr.expr -> bool - - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - - (** Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - val is_int_to_bv : Expr.expr -> bool - - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - val is_bv_to_int : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - val is_bv_carry : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - val is_bv_xor3 : Expr.expr -> bool - - (** The size of a bit-vector sort. *) - val get_size : bitvec_sort -> int - - (** Retrieve the int value. *) - val get_int : bitvec_num -> int - - (** Returns a string representation of the numeral. *) - val to_string : bitvec_num -> string - - (** Creates a bit-vector constant. *) - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr - - (** Creates a bit-vector constant. *) - val mk_const_s : context -> string -> int -> bitvec_expr - - (** Bitwise negation. - The argument must have a bit-vector sort. *) - val mk_not : context -> bitvec_expr -> Expr.expr - - (** Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) - val mk_redand : context -> bitvec_expr -> Expr.expr - - (** Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) - val mk_redor : context -> bitvec_expr -> Expr.expr - - (** Bitwise conjunction. - The arguments must have a bit-vector sort. *) - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise disjunction. - The arguments must have a bit-vector sort. *) - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise XOR. - The arguments must have a bit-vector sort. *) - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise NAND. - The arguments must have a bit-vector sort. *) - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise NOR. - The arguments must have a bit-vector sort. *) - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise XNOR. - The arguments must have a bit-vector sort. *) - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Standard two's complement unary minus. - The arguments must have a bit-vector sort. *) - val mk_neg : context -> bitvec_expr -> bitvec_expr - - (** Two's complement addition. - The arguments must have the same bit-vector sort. *) - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Two's complement subtraction. - The arguments must have the same bit-vector sort. *) - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Two's complement multiplication. - The arguments must have the same bit-vector sort. *) - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Unsigned division. - - - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. *) - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Signed division. - - It is defined in the following way: - - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Unsigned remainder. - - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Signed remainder. - - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Two's complement signed remainder (sign follows divisor). - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Unsigned less-than - - The arguments must have the same bit-vector sort. *) - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed less-than - - The arguments must have the same bit-vector sort. *) - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Unsigned greater-than. - - The arguments must have the same bit-vector sort. *) - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. *) - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). *) - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bit-vector extraction. - - Extract the bits between two limits from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. *) - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr - - (** Bit-vector sign extension. - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. *) - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr - - (** Bit-vector zero extension. - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the - given bit-vector. *) - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr - - (** Bit-vector repetition. *) - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr - - (** Shift left. - - It is equivalent to multiplication by 2^x where \c x is the value of third argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling.*) - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Logical shift right - - It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. *) - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. *) - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Rotate Left. - Rotate bits of \c t to the left \c i times. *) - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr - - (** Rotate Right. - Rotate bits of \c t to the right \c i times.*) - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr - - (** Rotate Left. - Rotate bits of the second argument to the left.*) - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Rotate Right. - Rotate bits of the second argument to the right. *) - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Create an integer from the bit-vector argument - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where - N are the number of bits in the argument. - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function.*) - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr - - (** Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a bit-vector numeral. *) - val mk_numeral : context -> string -> int -> bitvec_num -end - -(** Functions to manipulate proof expressions *) -module Proof : -sig - (** Indicates whether the term is a Proof for the expression 'true'. *) - val is_true : Expr.expr -> bool - - (** Indicates whether the term is a proof for a fact asserted by the user. *) - val is_asserted : Expr.expr -> bool - - (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - val is_goal : Expr.expr -> bool - - (** Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). *) - val is_modus_ponens : Expr.expr -> bool - - (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. *) - val is_reflexivity : Expr.expr -> bool - - (** Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. *) - val is_symmetry : Expr.expr -> bool - - (** Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) *) - val is_transitivity : Expr.expr -> bool - - (** Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. *) - val is_Transitivity_star : Expr.expr -> bool - - (** Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. *) - val is_monotonicity : Expr.expr -> bool - - (** Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - val is_quant_intro : Expr.expr -> bool - - (** Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. *) - val is_distributivity : Expr.expr -> bool - - (** Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i *) - val is_and_elimination : Expr.expr -> bool - - (** Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) *) - val is_or_elimination : Expr.expr -> bool - - (** Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) *) - val is_rewrite : Expr.expr -> bool - - (** Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - val is_rewrite_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - val is_pull_quant : Expr.expr -> bool - - (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents *) - val is_pull_quant_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents *) - val is_push_quant : Expr.expr -> bool - - (** Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. *) - val is_elim_unused_vars : Expr.expr -> bool - - (** Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. *) - val is_der : Expr.expr -> bool - - (** Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) *) - val is_quant_inst : Expr.expr -> bool - - (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. *) - val is_hypothesis : Expr.expr -> bool - - (** Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. *) - val is_lemma : Expr.expr -> bool - - (** Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - val is_unit_resolution : Expr.expr -> bool - - (** Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) *) - val is_iff_true : Expr.expr -> bool - - (** Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) *) - val is_iff_false : Expr.expr -> bool - - (** Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. *) - val is_commutativity : Expr.expr -> bool - - (** Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). *) - val is_def_axiom : Expr.expr -> bool - - (** Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) *) - val is_def_intro : Expr.expr -> bool - - (** Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. *) - val is_apply_def : Expr.expr -> bool - - (** Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) *) - val is_iff_oeq : Expr.expr -> bool - - (** Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. *) - val is_nnf_pos : Expr.expr -> bool - - (** Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) *) - val is_nnf_neg : Expr.expr -> bool - - (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - val is_nnf_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - val is_cnf_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. *) - val is_skolemize : Expr.expr -> bool - - (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q *) - val is_modus_ponens_oeq : Expr.expr -> bool - - (** Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - val is_theory_lemma : Expr.expr -> bool -end - -(** Goals - - A goal (aka problem). A goal is essentially a - of formulas, that can be solved and/or transformed using - tactics and solvers. *) -module Goal : -sig - type goal - - (** The precision of the goal. - - Goals can be transformed using over and under approximations. - An under approximation is applied when the objective is to find a model for a given goal. - An over approximation is applied when the objective is to find a proof for a given goal. *) - val get_precision : goal -> Z3enums.goal_prec - - (** Indicates whether the goal is precise. *) - val is_precise : goal -> bool - - (** Indicates whether the goal is an under-approximation. *) - val is_underapproximation : goal -> bool - - (** Indicates whether the goal is an over-approximation. *) - val is_overapproximation : goal -> bool - - (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) - val is_garbage : goal -> bool - - (** Adds the constraints to the given goal. *) - val assert_ : goal -> Boolean.bool_expr list -> unit - - (** Indicates whether the goal contains `false'. *) - val is_inconsistent : goal -> bool - - (** The depth of the goal. - This tracks how many transformations were applied to it. *) - val get_depth : goal -> int - - (** Erases all formulas from the given goal. *) - val reset : goal -> unit - - (** The number of formulas in the goal. *) - val get_size : goal -> int - - (** The formulas in the goal. *) - val get_formulas : goal -> Boolean.bool_expr list - - (** The number of formulas, subformulas and terms in the goal. *) - val get_num_exprs : goal -> int - - (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) - val is_decided_sat : goal -> bool - - (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) - val is_decided_unsat : goal -> bool - - (** Translates (copies) the Goal to another context.. *) - val translate : goal -> context -> goal - - (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - val simplify : goal -> Params.params option -> goal - - (** Creates a new Goal. - - Note that the Context must have been created with proof generation support if - the fourth argument is set to true here. *) - val mk_goal : context -> bool -> bool -> bool -> goal - - (** A string representation of the Goal. *) - val to_string : goal -> string -end - -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) -module Model : -sig - type model - - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. *) - module FuncInterp : - sig - type func_interp - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. *) - module FuncEntry : - sig - type func_entry - - (** Return the (symbolic) value of this entry. - *) - val get_value : func_entry -> Expr.expr - - (** The number of arguments of the entry. - *) - val get_num_args : func_entry -> int - - (** The arguments of the function entry. - *) - val get_args : func_entry -> Expr.expr list - - (** A string representation of the function entry. - *) - val to_string : func_entry -> string - end - - (** The number of entries in the function interpretation. *) - val get_num_entries : func_interp -> int - - (** The entries in the function interpretation *) - val get_entries : func_interp -> FuncEntry.func_entry list - - (** The (symbolic) `else' value of the function interpretation. *) - val get_else : func_interp -> Expr.expr - - (** The arity of the function interpretation *) - val get_arity : func_interp -> int - - (** A string representation of the function interpretation. *) - val to_string : func_interp -> string - end - - (** Retrieves the interpretation (the assignment) of a func_decl in the model. - An expression if the function has an interpretation in the model, null otherwise. *) - val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option - - (** Retrieves the interpretation (the assignment) of an expression in the model. - An expression if the constant has an interpretation in the model, null otherwise. *) - val get_const_interp_e : model -> Expr.expr -> Expr.expr option - - (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option - - (** The number of constant interpretations in the model. *) - val get_num_consts : model -> int - - (** The function declarations of the constants in the model. *) - val get_const_decls : model -> FuncDecl.func_decl list - - (** The number of function interpretations in the model. *) - val get_num_funcs : model -> int - - (** The function declarations of the function interpretations in the model. *) - val get_func_decls : model -> FuncDecl.func_decl list - - (** All symbols that have an interpretation in the model. *) - val get_decls : model -> FuncDecl.func_decl list - - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - - (** Evaluates an expression in the current model. - - This function may fail if the argument contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - *) - val eval : model -> Expr.expr -> bool -> Expr.expr - - (** Alias for eval. *) - val evaluate : model -> Expr.expr -> bool -> Expr.expr - - (** The number of uninterpreted sorts that the model has an interpretation for. *) - val get_num_sorts : model -> int - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - {!get_num_sorts} - {!sort_universe} *) - val get_sorts : model -> Sort.sort list - - (** The finite set of distinct values that represent the interpretation of a sort. - {!get_sorts} - @returns A list of expressions, where each is an element of the universe of the sort *) - val sort_universe : model -> Sort.sort -> AST.ast list - - (** Conversion of models to strings. - A string representation of the model. *) - val to_string : model -> string -end - -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Probe : -sig - type probe - - (** Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - val apply : probe -> Goal.goal -> float - - (** The number of supported Probes. *) - val get_num_probes : context -> int - - (** The names of all supported Probes. *) - val get_probe_names : context -> string list - - (** Returns a string containing a description of the probe with the given name. *) - val get_probe_description : context -> string -> string - - (** Creates a new Probe. *) - val mk_probe : context -> string -> probe - - (** Create a probe that always evaluates to a float value. *) - val const : context -> float -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is less than the value returned by second argument *) - val lt : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is greater than the value returned by second argument *) - val gt : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is less than or equal the value returned by second argument *) - val le : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is greater than or equal the value returned by second argument *) - val ge : context -> probe -> probe -> probe - - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is equal the value returned by second argument *) - val eq : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) - val and_ : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) - val or_ : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) - val not_ : context -> probe -> probe -end - -(** Tactics - - Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using Context.get_num_tactics - and Context.get_tactic_names. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Tactic : -sig - type tactic - - (** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) - module ApplyResult : - sig - type apply_result - - (** The number of Subgoals. *) - val get_num_subgoals : apply_result -> int - - (** Retrieves the subgoals from the apply_result. *) - val get_subgoals : apply_result -> Goal.goal list - - (** Retrieves a subgoal from the apply_result. *) - val get_subgoal : apply_result -> int -> Goal.goal - - (** Convert a model for a subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g *) - val convert_model : apply_result -> int -> Model.model -> Model.model - - (** A string representation of the ApplyResult. *) - val to_string : apply_result -> string - end - - (** A string containing a description of parameters accepted by the tactic. *) - val get_help : tactic -> string - - (** Retrieves parameter descriptions for Tactics. *) - val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs - - (** Apply the tactic to the goal. *) - val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result - - (** The number of supported tactics. *) - val get_num_tactics : context -> int - - (** The names of all supported tactics. *) - val get_tactic_names : context -> string list - - (** Returns a string containing a description of the tactic with the given name. *) - val get_tactic_description : context -> string -> string - - (** Creates a new Tactic. *) - val mk_tactic : context -> string -> tactic - - (** Create a tactic that applies one tactic to a Goal and - then another one to every subgoal produced by the first one. *) - val and_then : context -> tactic -> tactic -> tactic list -> tactic - - (** Create a tactic that first applies one tactic to a Goal and - if it fails then returns the result of another tactic applied to the Goal. *) - val or_else : context -> tactic -> tactic -> tactic - - (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). - - If the tactic does not terminate within the timeout, then it fails. *) - val try_for : context -> tactic -> int -> tactic - - (** Create a tactic that applies one tactic to a given goal if the probe - evaluates to true. - - If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) - val when_ : context -> Probe.probe -> tactic -> tactic - - (** Create a tactic that applies a tactic to a given goal if the probe - evaluates to true and another tactic otherwise. *) - val cond : context -> Probe.probe -> tactic -> tactic -> tactic - - (** Create a tactic that keeps applying one tactic until the goal is not - modified anymore or the maximum number of iterations is reached. *) - val repeat : context -> tactic -> int -> tactic - - (** Create a tactic that just returns the given goal. *) - val skip : context -> tactic - - (** Create a tactic always fails. *) - val fail : context -> tactic - - (** Create a tactic that fails if the probe evaluates to false. *) - val fail_if : context -> Probe.probe -> tactic - - (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). *) - val fail_if_not_decided : context -> tactic - - (** Create a tactic that applies a tactic using the given set of parameters. *) - val using_params : context -> tactic -> Params.params -> tactic - - (** Create a tactic that applies a tactic using the given set of parameters. - Alias for UsingParams*) - val with_ : context -> tactic -> Params.params -> tactic - - (** Create a tactic that applies the given tactics in parallel. *) - val par_or : context -> tactic list -> tactic - - (** Create a tactic that applies a tactic to a given goal and then another tactic - to every subgoal produced by the first one. The subgoals are processed in parallel. *) - val par_and_then : context -> tactic -> tactic -> tactic - - (** Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. *) - val interrupt : context -> unit -end - -(** Solvers *) -module Solver : -sig - type solver - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - - val string_of_status : status -> string - - (** Objects that track statistical information about solvers. *) - module Statistics : - sig - type statistics - - (** Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - *) - module Entry : - sig - type statistics_entry - - (** The key of the entry. *) - val get_key : statistics_entry -> string - - (** The int-value of the entry. *) - val get_int : statistics_entry -> int - - (** The float-value of the entry. *) - val get_float : statistics_entry -> float - - (** True if the entry is uint-valued. *) - val is_int : statistics_entry -> bool - - (** True if the entry is double-valued. *) - val is_float : statistics_entry -> bool - - (** The string representation of the the entry's value. *) - val to_string_value : statistics_entry -> string - - (** The string representation of the entry (key and value) *) - val to_string : statistics_entry -> string - end - - (** A string representation of the statistical data. *) - val to_string : statistics -> string - - (** The number of statistical data. *) - val get_size : statistics -> int - - (** The data entries. *) - val get_entries : statistics -> Entry.statistics_entry list - - (** The statistical counters. *) - val get_keys : statistics -> string list - - (** The value of a particular statistical counter. *) - val get : statistics -> string -> Entry.statistics_entry option - end - - (** A string that describes all available solver parameters. *) - val get_help : solver -> string - - (** Sets the solver parameters. *) - val set_parameters : solver -> Params.params -> unit - - (** Retrieves parameter descriptions for solver. *) - val get_param_descrs : solver -> Params.ParamDescrs.param_descrs - - (** The current number of backtracking points (scopes). - {!pop} - {!push} *) - val get_num_scopes : solver -> int - - (** Creates a backtracking point. - {!pop} *) - val push : solver -> unit - - (** Backtracks a number of backtracking points. - Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} - {!push} *) - val pop : solver -> int -> unit - - (** Resets the Solver. - This removes all assertions from the solver. *) - val reset : solver -> unit - - (** Assert a constraint (or multiple) into the solver. *) - val assert_ : solver -> Boolean.bool_expr list -> unit - - (** * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) - val assert_and_track_a : solver -> Boolean.bool_expr list -> Boolean.bool_expr list -> unit - - (** * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) - val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit - - (** The number of assertions in the solver. *) - val get_num_assertions : solver -> int - - (** The set of asserted formulas. *) - val get_assertions : solver -> Boolean.bool_expr list - - (** Checks whether the assertions in the solver are consistent or not. - - {!Model} - {!get_unsat_core} - {!Proof} *) - val check : solver -> Boolean.bool_expr list -> status - - (** The model of the last Check. - - The result is None if Check was not invoked before, - if its results was not SATISFIABLE, or if model production is not enabled. *) - val get_model : solver -> Model.model option - - (** The proof of the last Check. - - The result is null if Check was not invoked before, - if its results was not UNSATISFIABLE, or if proof production is disabled. *) - val get_proof : solver -> Expr.expr option - - (** The unsat core of the last Check. - - The unsat core is a subset of Assertions - The result is empty if Check was not invoked before, - if its results was not UNSATISFIABLE, or if core production is disabled. *) - val get_unsat_core : solver -> AST.ast list - - (** A brief justification of why the last call to Check returned UNKNOWN. *) - val get_reason_unknown : solver -> string - - (** Solver statistics. *) - val get_statistics : solver -> Statistics.statistics - - (** Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. *) - val mk_solver : context -> Symbol.symbol option -> solver - - (** Creates a new (incremental) solver. - {!mk_solver} *) - val mk_solver_s : context -> string -> solver - - (** Creates a new (incremental) solver. *) - val mk_simple_solver : context -> solver - - (** Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. *) - val mk_solver_t : context -> Tactic.tactic -> solver - - (** A string representation of the solver. *) - val to_string : solver -> string -end - -(** Fixedpoint solving *) -module Fixedpoint : -sig - type fixedpoint - - (** A string that describes all available fixedpoint solver parameters. *) - val get_help : fixedpoint -> string - - (** Sets the fixedpoint solver parameters. *) - val set_params : fixedpoint -> Params.params -> unit - - (** Retrieves parameter descriptions for Fixedpoint solver. *) - val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs - - (** Assert a constraints into the fixedpoint solver. *) - val assert_ : fixedpoint -> Boolean.bool_expr list -> unit - - (** Register predicate as recursive relation. *) - val register_relation : fixedpoint -> FuncDecl.func_decl -> unit - - (** Add rule into the fixedpoint solver. *) - val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit - - (** Add table fact to the fixedpoint solver. *) - val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit - - (** Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. *) - val query : fixedpoint -> Boolean.bool_expr -> Solver.status - - (** Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status - - (** Creates a backtracking point. - {!pop} *) - val push : fixedpoint -> unit - - (** Backtrack one backtracking point. - - Note that an exception is thrown if Pop is called without a corresponding Push - {!push} *) - val pop : fixedpoint -> unit - - (** Update named rule into in the fixedpoint solver. *) - val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit - - (** Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. *) - val get_answer : fixedpoint -> Expr.expr option - - (** Retrieve explanation why fixedpoint engine returned status Unknown. *) - val get_reason_unknown : fixedpoint -> string - - (** Retrieve the number of levels explored for a given predicate. *) - val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int - - (** Retrieve the cover of a predicate. *) - val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option - - (** Add property about the predicate. - The property is added at level. *) - val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit - - (** Retrieve internal string representation of fixedpoint object. *) - val to_string : fixedpoint -> string - - (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit - - (** Convert benchmark given as set of axioms, rules and queries to a string. *) - val to_string_q : fixedpoint -> Boolean.bool_expr list -> string - - (** Retrieve set of rules added to fixedpoint context. *) - val get_rules : fixedpoint -> Boolean.bool_expr list - - (** Retrieve set of assertions added to fixedpoint context. *) - val get_assertions : fixedpoint -> Boolean.bool_expr list - - (** Create a Fixedpoint context. *) - val mk_fixedpoint : context -> fixedpoint -end - -(** Global and context options - - Note: This module contains functions that set parameters/options for context - objects as well as functions that set options that are used globally, across - contexts.*) -module Options : -sig - (** Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - {!get_param_value} *) - val update_param_value : context -> string -> string -> unit - - (** Get a configuration parameter. - - Returns None if the parameter value does not exist. - {!update_param_value} *) - val get_param_value : context -> string -> string option - - (** Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - {!AST.to_string} - {!Quantifier.Pattern.to_string} - {!FuncDecl.to_string} - {!Sort.to_string} *) - val set_print_mode : context -> Z3enums.ast_print_mode -> unit - - (** Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. *) - val toggle_warning_messages : bool -> unit -end - -(** Functions for handling SMT and SMT2 expressions and files *) -module SMT : -sig - (** Convert a benchmark into an SMT-LIB formatted string. - - @return A string representation of the benchmark. *) - val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr list -> Boolean.bool_expr -> string - - (** Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays in the third and fifth argument - don't need to match the names of the sorts and declarations in the arrays in the fourth - and sixth argument. This is a useful feature since we can use arbitrary names to - reference sorts and declarations. *) - val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - - (** Parse the given file using the SMT-LIB parser. - {!parse_smtlib_string} *) - val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - - (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_formulas : context -> int - - (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_formulas : context -> Boolean.bool_expr list - - (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_assumptions : context -> int - - (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_assumptions : context -> Boolean.bool_expr list - - (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_decls : context -> int - - (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_decls : context -> FuncDecl.func_decl list - - (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_sorts : context -> int - - (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_sorts : context -> Sort.sort list - - (** Parse the given string using the SMT-LIB2 parser. - - {!parse_smtlib_string} - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr - - (** Parse the given file using the SMT-LIB2 parser. - {!parse_smtlib2_string} *) - val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr -end - -(** Set a global (or module) parameter, which is shared by all Z3 contexts. - - When a Z3 module is initialized it will use the value of these parameters - when Z3_params objects are not provided. - The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. - The character '.' is a delimiter (more later). - The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. - Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". - This function can be used to set parameters for a specific Z3 module. - This can be done by using .. - For example: - (set_global_param "pp.decimal" "true") - will set the parameter "decimal" in the module "pp" to true. -*) -val set_global_param : string -> string -> unit - -(** Get a global (or module) parameter. - - Returns None if the parameter does not exist. - The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. - This function cannot be invoked simultaneously from different threads without synchronization. - The result string stored in param_value is stored in a shared location. -*) -val get_global_param : string -> string option - -(** Restore the value of all global (and module) parameters. - - This command will not affect already created objects (such as tactics and solvers) - {!set_global_param} -*) -val global_param_reset_all : unit From 3e336592a290c07b2937c84ce415776b3563240d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 4 Jun 2013 18:00:48 +0100 Subject: [PATCH 293/507] ML API: bug and build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 28 ++++++++++++++++------------ scripts/update_api.py | 5 ++++- src/api/ml/z3.ml | 27 +++++++++++++++++---------- src/api/ml/z3.mli | 6 +++--- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index a30e074b0..f46339f5c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1340,26 +1340,30 @@ class MLComponent(Component): mk_dir(os.path.join(BUILD_DIR, sub_dir)) api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): - out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) - if IS_WINDOWS: str = str.replace('/','\\') + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) + out.write(str) + for f in filter(lambda f: f.endswith('.mli'), os.listdir(self.src_dir)): + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): - out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) - if IS_WINDOWS: str = str.replace('/','\\') + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: - out.write('%s/%s.mli: %s/%s.ml %s\n' % (sub_dir,m,sub_dir,m,prev)) - out.write('\t%s -I %s -i -c %s/%s.ml > %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m,sub_dir,m)) - prev = prev + ' ' + sub_dir + '/' + m + '.mli' + fn = os.path.join(self.src_dir, ('%s.mli' % m)) + if not os.path.exists(fn): + out.write('%s.mli: %s.ml %s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) + out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) + prev = prev + ' ' + os.path.join(sub_dir, m) + '.mli' cmis = '' for m in modules: - out.write('%s/%s.cmi: %s/%s.mli\n' % (sub_dir,m,sub_dir,m)) - out.write('\t%s -I %s -c %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m)) - cmis = cmis + ' ' + sub_dir + '/' + m + '.cmi' + out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) + out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) + cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') diff --git a/scripts/update_api.py b/scripts/update_api.py index 44d871348..77a5bf7f2 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1185,7 +1185,8 @@ def mk_ml(): ip = inparams(params) op = outparams(params) if len(ip) == 0: - ml_native.write(' unit -> ') + ml_native.write(' unit -> ') + ml_i.write(' unit -> ') for p in ip: ml_native.write('%s -> ' % param2ml(p)) ml_i.write('%s -> ' % param2ml(p)) @@ -1233,6 +1234,8 @@ def mk_ml(): ml_native.write(' ') ml_native.write('a%d' % i) i = i + 1 + if len(ip) == 0: + ml_native.write('()') ml_native.write(' = \n') ml_native.write(' ') if result == VOID and len(op) == 0: diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 081433f1f..8b783d25d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -34,7 +34,7 @@ struct ) let create_context settings = - let cfg = Z3native.mk_config in + let cfg = Z3native.mk_config () in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = Z3native.mk_context_rc cfg in @@ -101,12 +101,12 @@ end module Version = struct - let major = let (x, _, _, _) = Z3native.get_version in x - let minor = let (_, x, _, _) = Z3native.get_version in x - let build = let (_, _, x, _) = Z3native.get_version in x - let revision = let (_, _, _, x) = Z3native.get_version in x + let major = let (x, _, _, _) = Z3native.get_version () in x + let minor = let (_, x, _, _) = Z3native.get_version () in x + let build = let (_, _, x, _) = Z3native.get_version () in x + let revision = let (_, _, _, x) = Z3native.get_version () in x let to_string = - let (mj, mn, bld, rev) = Z3native.get_version in + let (mj, mn, bld, rev) = Z3native.get_version () in string_of_int mj ^ "." ^ string_of_int mn ^ "." ^ string_of_int bld ^ "." ^ @@ -609,6 +609,10 @@ sig val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit val mk_params : context -> params val to_string : params -> string + + val update_param_value : context -> string -> string -> unit + val get_param_value : context -> string -> string option + val set_print_mode : context -> Z3enums.ast_print_mode -> unit end = struct type params = z3_native_object @@ -1099,7 +1103,7 @@ struct end -module Array = +module Z3Array = struct let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) @@ -1382,7 +1386,7 @@ struct end -module List = +module Z3List = struct let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in @@ -2038,7 +2042,7 @@ struct if not r then None else - expr_of_ptr (z3obj_gc x) v + Some(expr_of_ptr (z3obj_gc x) v) let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = eval x t completion @@ -2331,7 +2335,7 @@ struct if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - (Entry.create_sd k (Z3native.stats_get_float_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in mk_list f n @@ -2667,3 +2671,6 @@ let global_param_reset_all = let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled + +module Array = Z3Array +module List = Z3List diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 570ff8717..3f83ef6b2 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -8,7 +8,7 @@ (** General Z3 exceptions Many functions in this API may throw an exception; if they do, it is this one.*) -exception Error +exception Error of string (** Context objects. @@ -55,11 +55,11 @@ module Log : sig (** Open an interaction log file. @return True if opening the log file succeeds, false otherwise. *) - (* CMW: "open" seems to be a reserved keyword? *) + (* CMW: "open" is a reserved keyword. *) val open_ : string -> bool (** Closes the interaction log. *) - val close : unit + val close : unit -> unit (** Appends a user-provided string to the interaction log. *) val append : string -> unit From 2ee3ff518fcd1e305f4d58cccc52e69af5d21294 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 21 Oct 2013 11:22:42 +0100 Subject: [PATCH 294/507] ML bindings: list/array are now called z3array/z3list to avoid confusion. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 4 ---- src/api/ml/z3.mli | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8b783d25d..ed815d720 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -2670,7 +2670,3 @@ let global_param_reset_all = let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled - - -module Array = Z3Array -module List = Z3List diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 3f83ef6b2..ff1898185 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -761,7 +761,7 @@ sig end (** Functions to manipulate Array expressions *) -module Array : +module Z3Array : sig (** Create a new array sort. *) val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort @@ -1093,7 +1093,7 @@ sig end (** Functions to manipulate List expressions *) -module List : +module Z3List : sig (** Create a new list sort. *) val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort From f7c371ac4d2228669c457ce8e9a27dc622bb3df6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 28 Oct 2013 12:17:58 +0000 Subject: [PATCH 295/507] ML API: bugfix for native function with more than 5 parameters. Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 77a5bf7f2..dd1e46c4f 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1211,9 +1211,11 @@ def mk_ml(): ml_i.write(')') ml_native.write('\n') ml_i.write('\n') - ml_native.write(' = "n_%s"\n' % ml_method_name(name)) if len(ip) > 5: - ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) + ml_native.write(' = "n_%s_bytecode"\n' % ml_method_name(name)) + ml_native.write(' "n_%s"\n' % ml_method_name(name)) + else: + ml_native.write(' = "n_%s"\n' % ml_method_name(name)) ml_native.write('\n') ml_native.write(' end\n\n') ml_i.write('\n(**/**)\n'); From 832e119b9858c60ec4538fbfb21275da1120d953 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 2 Apr 2014 19:08:59 +0100 Subject: [PATCH 296/507] ML API bugfix (Codeplex issue 102) Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 43 ++++++ src/api/ml/z3.ml | 289 +++++++++++++++++++------------------- src/api/ml/z3.mli | 3 + 3 files changed, 192 insertions(+), 143 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index c9ed1d948..0dd227784 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -196,6 +196,48 @@ let basic_tests ( ctx : context ) = Printf.printf "Exception caught, OK.\n" ) +(** + A basic example of how to use quantifiers. +**) +let quantifierExample1 ( ctx : context ) = + Printf.printf "QuantifierExample\n" ; + let is = (Integer.mk_sort ctx) in + let types = [ is; is; is ] in + let names = [ (Symbol.mk_string ctx "x_0"); + (Symbol.mk_string ctx "x_1"); + (Symbol.mk_string ctx "x_2") ] in + let vars = [ (Quantifier.mk_bound ctx 2 (List.nth types 0)); + (Quantifier.mk_bound ctx 2 (List.nth types 1)); + (Quantifier.mk_bound ctx 2 (List.nth types 2)) ] in + let xs = [ (Integer.mk_const ctx (List.nth names 0)); + (Integer.mk_const ctx (List.nth names 1)); + (Integer.mk_const ctx (List.nth names 2)) ] in + + let body_vars = (Boolean.mk_and ctx + [ (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth vars 0) ; (Integer.mk_numeral_i ctx 1)]) + (Integer.mk_numeral_i ctx 2)) ; + (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth vars 1); (Integer.mk_numeral_i ctx 2)]) + (Arithmetic.mk_add ctx [ (List.nth vars 2); (Integer.mk_numeral_i ctx 3)])) ]) in + let body_const = (Boolean.mk_and ctx + [ (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth xs 0); (Integer.mk_numeral_i ctx 1)]) + (Integer.mk_numeral_i ctx 2)) ; + (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth xs 1); (Integer.mk_numeral_i ctx 2)]) + (Arithmetic.mk_add ctx [ (List.nth xs 2); (Integer.mk_numeral_i ctx 3)])) ]) in + + let x = (Quantifier.mk_forall ctx types names body_vars (Some 1) [] [] (Some (Symbol.mk_string ctx "Q1")) (Some (Symbol.mk_string ctx "skid1"))) in + Printf.printf "Quantifier X: %s\n" (Quantifier.to_string x) ; + let y = (Quantifier.mk_forall_const ctx xs body_const (Some 1) [] [] (Some (Symbol.mk_string ctx "Q2")) (Some (Symbol.mk_string ctx "skid2"))) in + Printf.printf "Quantifier Y: %s\n" (Quantifier.to_string y) ; + if (is_true (Quantifier.expr_of_quantifier x)) then + raise (TestFailedException "") (* unreachable *) + else if (is_false (Quantifier.expr_of_quantifier x)) then + raise (TestFailedException "") (* unreachable *) + else if (is_const (Quantifier.expr_of_quantifier x)) then + raise (TestFailedException "") (* unreachable *) let _ = try ( @@ -217,6 +259,7 @@ let _ = Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); basic_tests ctx ; + quantifierExample1 ctx ; Printf.printf "Disposing...\n"; Gc.full_major () ); diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index ed815d720..d91d3ca8d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -297,6 +297,7 @@ struct | VAR_AST -> true | _ -> false + let is_app ( x : ast ) = (get_ast_kind x) == APP_AST let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST @@ -828,22 +829,22 @@ end = struct (Z3native.mk_bool_sort (gnc x)) (Z3native.get_sort (gnc x) (gno x))) - let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) + let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -1100,6 +1101,8 @@ struct mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id + + let to_string ( x : quantifier ) = (Expr.to_string (expr_of_quantifier x)) end @@ -1108,12 +1111,12 @@ struct let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_store ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_select ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_constant_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_default_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_array_map ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_as_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) let is_array ( x : expr ) = (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) @@ -1150,11 +1153,11 @@ struct let mk_sort ( ctx : context ) ( ty : sort ) = sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + let is_union ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_intersect ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_difference ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_complement ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_subset ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) let mk_empty ( ctx : context ) ( domain : sort ) = @@ -1203,7 +1206,7 @@ struct (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) let get_size ( x : sort ) = let (r, v) = (Z3native.get_finite_domain_sort_size (Sort.gnc x) (Sort.gno x)) in @@ -1219,19 +1222,19 @@ struct ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + let is_store ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_empty ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_is_empty ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_join ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_union ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_widen ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_project ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_filter ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_negation_filter ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_rename ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_complement ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_select ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_clone ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) let get_arity ( x : sort ) = Z3native.get_relation_arity (Sort.gnc x) (Sort.gno x) @@ -1534,37 +1537,37 @@ struct (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) let is_real ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) @@ -1616,57 +1619,57 @@ struct sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) let is_bv ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let is_bv_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_bit1 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_sdiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_udiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_SRem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_urem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_smod ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_sdiv0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_udiv0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_srem0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_urem0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_smod0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_ule ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_sle ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_uge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_sge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_ult ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_slt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_ugt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_sgt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_nand ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_xnor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_concat ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_signextension ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_zeroextension ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_extract ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_repeat ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_reduceor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceand ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_comp ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_shiftleft ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftrightlogical ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_rotateleft ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateright ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateleftextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotaterightextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_int_to_bv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_bv_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_carry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_xor3 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) let get_size (x : sort ) = Z3native.get_bv_sort_size (Sort.gnc x) (Sort.gno x) let get_int ( x : expr ) = let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in @@ -1778,44 +1781,44 @@ end module Proof = struct - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) + let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_asserted ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_goal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_modus_ponens ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_reflexivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_symmetry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_transitivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_Transitivity_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_monotonicity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_quant_intro ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_distributivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_and_elimination ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_or_elimination ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_rewrite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_pull_quant ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_push_quant ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_elim_unused_vars ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_der ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_quant_inst ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_hypothesis ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_lemma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_unit_resolution ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_iff_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_commutativity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_def_axiom ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_intro ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_apply_def ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_iff_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_nnf_pos ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_neg ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_cnf_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_skolemize ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_modus_ponens_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_theory_lemma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index ff1898185..5c9c56dbf 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -758,6 +758,9 @@ sig (** Create a Quantifier. *) val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** A string representation of the quantifier. *) + val to_string : quantifier -> string end (** Functions to manipulate Array expressions *) From 0da912e5578cfa56c5cc4a8d804d505794bc3fe3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 2 Apr 2014 19:18:43 +0100 Subject: [PATCH 297/507] ML API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index d91d3ca8d..5f8d96d2a 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -793,7 +793,7 @@ end = struct mk_list f n let update ( x : expr ) ( args : expr list ) = - if (List.length args <> (get_num_args x)) then + if ((AST.is_app (ast_of_expr x)) && (List.length args <> (get_num_args x))) then raise (Z3native.Exception "Number of arguments does not match") else expr_of_ptr (Expr.gc x) (Z3native.update_term (gnc x) (gno x) (List.length args) (expr_lton args)) From 20be39006ec2b86ebb02e46be0cc7c4dec951f18 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:32:06 +0100 Subject: [PATCH 298/507] ML API `or' is deprecated, changed to `||' Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 5f8d96d2a..c037a9263 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -748,7 +748,7 @@ end = struct Expr(z3_native_object_of_ast_ptr ctx no) else if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + if (sk == INT_SORT || sk == REAL_SORT || sk == BV_SORT) then Expr(z3_native_object_of_ast_ptr ctx no) else raise (Z3native.Exception "Unsupported numeral object") From a028f200af844393bf8c9e0a35107303b325fd5c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:33:52 +0100 Subject: [PATCH 299/507] ML example; `or' is deprecated, changed to `||' Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 0dd227784..25862b2d7 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -168,7 +168,7 @@ let basic_tests ( ctx : context ) = let inum = (get_numerator rn) in let iden = get_denominator rn in Printf.printf "Numerator: %s Denominator: %s\n" (Real.to_string inum) (Real.to_string iden) ; - if ((Real.to_string inum) <> "42" or (Real.to_string iden) <> "43") then + if ((Real.to_string inum) <> "42" || (Real.to_string iden) <> "43") then raise (TestFailedException "") else Printf.printf "Test passed.\n" From a3d17a0e24f288b3a3fd1b0572bb5488750aa128 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:38:29 +0100 Subject: [PATCH 300/507] ML API build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index f46339f5c..8017c8c61 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1385,6 +1385,15 @@ class MLComponent(Component): out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') + # Generate META file and package installation commands + self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') + out.write('\tocamlfind remove Z3\n') + out.write('\tocamlfind install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)') + if IS_WINDOWS: + out.write(' libz3$(LIB_EXT)') + out.write('\n') + out.write('\n') def main_component(self): return is_ml_enabled() From d0588c0565b3d96fae32e3d9967092167925c8ab Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:39:53 +0100 Subject: [PATCH 301/507] ML API build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8017c8c61..41efe90f1 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1821,6 +1821,8 @@ def mk_install(out): for c in get_components(): c.mk_install_deps(out) out.write(' ') + if is_ml_enabled(): + out.write('ocamlfind_install') out.write('\n') out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'bin')) out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'include')) From 3228c3ff5ca5784e948b5ceea873ea013d3e80d0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:49:05 +0100 Subject: [PATCH 302/507] ML API build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 41efe90f1..c74836a27 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -35,6 +35,7 @@ JNI_HOME=getenv("JNI_HOME", None) OCAMLC=getenv("OCAMLC", "ocamlc") OCAMLOPT=getenv("OCAMLOPT", "ocamlopt") OCAML_LIB=getenv("OCAML_LIB", None) +OCAMLFIND=getenv("OCAMLFIND", "ocamlfind") CXX_COMPILERS=['g++', 'clang++'] C_COMPILERS=['gcc', 'clang'] @@ -357,6 +358,15 @@ def check_ml(): rmf('hello.cmx') rmf('a.out') find_ml_lib() + find_ocaml_find() + +def find_ocaml_find(): + global OCAMLFIND + if is_verbose(): + print "Testing %s..." % OCAMLFIND + r = exec_cmd([OCAMLFIND, 'printconf']) + if r != 0: + OCAMLFIND='' def find_ml_lib(): global OCAML_LIB @@ -1387,13 +1397,14 @@ class MLComponent(Component): out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') - out.write('\tocamlfind remove Z3\n') - out.write('\tocamlfind install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)') - if IS_WINDOWS: - out.write(' libz3$(LIB_EXT)') - out.write('\n') - out.write('\n') + if OCAMLFIND != '': + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') + out.write('\t%s remove Z3\n' % (OCAMLFIND)) + out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + if IS_WINDOWS: + out.write(' libz3$(LIB_EXT)') + out.write('\n') + out.write('\n') def main_component(self): return is_ml_enabled() @@ -1821,7 +1832,7 @@ def mk_install(out): for c in get_components(): c.mk_install_deps(out) out.write(' ') - if is_ml_enabled(): + if is_ml_enabled() and OCAMLFIND != '': out.write('ocamlfind_install') out.write('\n') out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'bin')) From 10fe6b7759f2b117a71d4129dbe18cfdfa1397ff Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 12:55:23 +0100 Subject: [PATCH 303/507] ML API refactoring Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 72 ++++++++----------- src/api/ml/z3.mli | 180 +++++++++++++++++++++++----------------------- 2 files changed, 119 insertions(+), 133 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c037a9263..051a54696 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,5 +1,5 @@ (** - The Z3 ML/Ocaml Interface. + The Z3 ML/OCaml Interface. Copyright (C) 2012 Microsoft Corporation @author CM Wintersteiger (cwinter) 2012-12-17 @@ -698,7 +698,6 @@ sig val get_simplify_help : context -> string val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs val get_func_decl : expr -> FuncDecl.func_decl - val get_bool_value : expr -> Z3enums.lbool val get_num_args : expr -> int val get_args : expr -> expr list val update : expr -> expr list -> expr @@ -710,20 +709,7 @@ sig val is_numeral : expr -> bool val is_well_sorted : expr -> bool val get_sort : expr -> Sort.sort - val is_bool : expr -> bool val is_const : expr -> bool - val is_true : expr -> bool - val is_false : expr -> bool - val is_eq : expr -> bool - val is_distinct : expr -> bool - val is_ite : expr -> bool - val is_and : expr -> bool - val is_or : expr -> bool - val is_iff : expr -> bool - val is_xor : expr -> bool - val is_not : expr -> bool - val is_implies : expr -> bool - val is_oeq : expr -> bool val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val mk_const_s : context -> string -> Sort.sort -> expr val mk_const_f : context -> FuncDecl.func_decl -> expr @@ -782,9 +768,7 @@ end = struct let get_simplify_parameter_descrs ( ctx : context ) = Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) - - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) @@ -823,29 +807,11 @@ end = struct let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) - - let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (gnc x) - (Z3native.mk_bool_sort (gnc x)) - (Z3native.get_sort (gnc x) (gno x))) - + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -888,12 +854,6 @@ struct let mk_val ( ctx : context ) ( value : bool ) = if value then mk_true ctx else mk_false ctx - - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) - - let mk_distinct ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) let mk_not ( ctx : context ) ( a : expr ) = expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) @@ -917,6 +877,31 @@ struct let mk_or ( ctx : context ) ( args : expr list ) = let f x = (Expr.gno (x)) in expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) + + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + + let mk_distinct ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) + + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) + + let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (Z3native.is_eq_sort (gnc x) + (Z3native.mk_bool_sort (gnc x)) + (Z3native.get_sort (gnc x) (gno x))) + + let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) end @@ -1784,6 +1769,7 @@ struct let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) let is_asserted ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) let is_goal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_OEQ) let is_modus_ponens ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) let is_reflexivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) let is_symmetry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 5c9c56dbf..c554d7564 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1,5 +1,5 @@ (** - The Z3 ML/Ocaml Interface. + The Z3 ML/OCaml Interface. Copyright (C) 2012 Microsoft Corporation @author CM Wintersteiger (cwinter) 2012-12-17 @@ -488,10 +488,6 @@ sig (** The function declaration of the function that is applied in this expression. *) val get_func_decl : Expr.expr -> FuncDecl.func_decl - (** Indicates whether the expression is the true or false expression - or something else (L_UNDEF). *) - val get_bool_value : Expr.expr -> Z3enums.lbool - (** The number of arguments of the expression. *) val get_num_args : Expr.expr -> int @@ -535,11 +531,88 @@ sig (** The Sort of the term. *) val get_sort : Expr.expr -> Sort.sort - (** Indicates whether the term has Boolean sort. *) - val is_bool : Expr.expr -> bool - (** Indicates whether the term represents a constant. *) val is_const : Expr.expr -> bool + + (** Creates a new constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + + (** Creates a new constant. *) + val mk_const_s : context -> string -> Sort.sort -> expr + + (** Creates a constant from the func_decl. *) + val mk_const_f : context -> FuncDecl.func_decl -> expr + + (** Creates a fresh constant with a name prefixed with a string. *) + val mk_fresh_const : context -> string -> Sort.sort -> expr + + (** Create a new function application. *) + val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr + + (** Create a numeral of a given sort. + @return A Term with the given value and sort *) + val mk_numeral_string : context -> string -> Sort.sort -> expr + + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @return A Term with the given value and sort *) + val mk_numeral_int : context -> int -> Sort.sort -> expr +end + +(** Boolean expressions; Propositional logic and equality *) +module Boolean : +sig + (** Create a Boolean sort *) + val mk_sort : context -> Sort.sort + + (** Create a Boolean constant. *) + val mk_const : context -> Symbol.symbol -> Expr.expr + + (** Create a Boolean constant. *) + val mk_const_s : context -> string -> Expr.expr + + (** The true Term. *) + val mk_true : context -> Expr.expr + + (** The false Term. *) + val mk_false : context -> Expr.expr + + (** Creates a Boolean value. *) + val mk_val : context -> bool -> Expr.expr + + (** Mk an expression representing not(a). *) + val mk_not : context -> Expr.expr -> Expr.expr + + (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 iff t2. *) + val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 -> t2. *) + val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 xor t2. *) + val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing the AND of args *) + val mk_and : context -> Expr.expr list -> Expr.expr + + (** Create an expression representing the OR of args *) + val mk_or : context -> Expr.expr list -> Expr.expr + + (** Creates the equality between two expr's. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Creates a distinct term. *) + val mk_distinct : context -> Expr.expr list -> Expr.expr + + (** Indicates whether the expression is the true or false expression + or something else (L_UNDEF). *) + val get_bool_value : Expr.expr -> Z3enums.lbool + + (** Indicates whether the term has Boolean sort. *) + val is_bool : Expr.expr -> bool (** Indicates whether the term is the constant true. *) val is_true : Expr.expr -> bool @@ -573,84 +646,6 @@ sig (** Indicates whether the term is an implication *) val is_implies : Expr.expr -> bool - - (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) - val is_oeq : Expr.expr -> bool - - (** Creates a new constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - - (** Creates a new constant. *) - val mk_const_s : context -> string -> Sort.sort -> expr - - (** Creates a constant from the func_decl. *) - val mk_const_f : context -> FuncDecl.func_decl -> expr - - (** Creates a fresh constant with a name prefixed with a string. *) - val mk_fresh_const : context -> string -> Sort.sort -> expr - - (** Create a new function application. *) - val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - - (** Create a numeral of a given sort. - @return A Term with the goven value and sort *) - val mk_numeral_string : context -> string -> Sort.sort -> expr - - (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. - @return A Term with the given value and sort *) - val mk_numeral_int : context -> int -> Sort.sort -> expr -end - -(** Boolean expressions *) -module Boolean : -sig - (** Create a Boolean sort *) - val mk_sort : context -> Sort.sort - - (** Create a Boolean constant. *) - val mk_const : context -> Symbol.symbol -> Expr.expr - - (** Create a Boolean constant. *) - val mk_const_s : context -> string -> Expr.expr - - (** The true Term. *) - val mk_true : context -> Expr.expr - - (** The false Term. *) - val mk_false : context -> Expr.expr - - (** Creates a Boolean value. *) - val mk_val : context -> bool -> Expr.expr - - (** Creates the equality between two expr's. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Creates a distinct term. *) - val mk_distinct : context -> Expr.expr list -> Expr.expr - - (** Mk an expression representing not(a). *) - val mk_not : context -> Expr.expr -> Expr.expr - - (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) - val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing t1 iff t2. *) - val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing t1 -> t2. *) - val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing t1 xor t2. *) - val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing the AND of args *) - val mk_and : context -> Expr.expr list -> Expr.expr - - (** Create an expression representing the OR of args *) - val mk_or : context -> Expr.expr list -> Expr.expr end (** Quantifier expressions *) @@ -817,7 +812,7 @@ sig The node a must have an array sort [domain -> range], and i must have the sort domain. The sort of the result is range. - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -833,7 +828,7 @@ sig on all indices except for i, where it maps to v (and the select of a with respect to i may be a different value). - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr @@ -841,7 +836,7 @@ sig The resulting term is an array, such that a selecton an arbitrary index produces the value v. - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr @@ -850,7 +845,7 @@ sig Eeach element of args must be of an array sort [domain_i -> range_i]. The function declaration f must have type range_1 .. range_n -> range. v must have sort range. The sort of the result is [domain_i -> range]. - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_select} {!mk_store} *) val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr @@ -1837,6 +1832,11 @@ sig (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) val is_goal : Expr.expr -> bool + (** Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) + val is_oeq : Expr.expr -> bool + (** Indicates whether the term is proof via modus ponens Given a proof for p and a proof for (implies p q), produces a proof for q. From 2f00968b4febd0b2128b50511340e558e026cf98 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 13:05:22 +0100 Subject: [PATCH 304/507] ML example doc fix Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/ml/README b/examples/ml/README index 3e1eb0d1c..7d33df743 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -12,3 +12,13 @@ or LD_LIBRARY_PATH=. ./ml_example.byte for the byte-code version. +If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), +then we can compile this example as follows: + +ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg +ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg + +Note that the resulting binaries depend on the shared z3 library, which needs to be +in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was +installed into ocamlfind, the path that should be added is +`ocamlfind printconf destdir`/Z3 From e5932efc44d5dd3e379e7f77321113909ee06a31 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 13:05:50 +0100 Subject: [PATCH 305/507] ML API refactoring (z3native.c -> z3native_stubs.c) Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 8 ++++---- scripts/update_api.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c74836a27..8aa582d12 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1374,10 +1374,10 @@ class MLComponent(Component): out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') - out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') + out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') diff --git a/scripts/update_api.py b/scripts/update_api.py index dd1e46c4f..0ed9b29ca 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1148,7 +1148,7 @@ def mk_ml(): ml_dir = get_component('ml').src_dir ml_nativef = os.path.join(ml_dir, 'z3native.ml') ml_nativefi = os.path.join(ml_dir, 'z3native.mli') - ml_wrapperf = os.path.join(ml_dir, 'z3native.c') + ml_wrapperf = os.path.join(ml_dir, 'z3native_stubs.c') ml_native = open(ml_nativef, 'w') ml_i = open(ml_nativefi, 'w') ml_native.write('(* Automatically generated file *)\n\n') From 4f0e8a1057069ffb3c34926faad1fe2b582052c0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 13:06:29 +0100 Subject: [PATCH 306/507] ML API refactoring (z3native.c -> z3native_stubs.c) Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fccf9424d..9c9707c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ src/api/ml/native.c src/api/ml/z3.ml src/api/ml/enumerations.ml src/api/ml/z3native.c +src/api/ml/z3native_stubs.c src/api/ml/z3native.ml src/api/ml/z3enums.ml src/api/ml/z3.mllib From e2f0dc31f471af42edce1703719e5da32476c38a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 14:18:46 +0100 Subject: [PATCH 307/507] ML API: Added get_bit_int and get_ratio Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 4 +- src/api/ml/META | 7 ++++ src/api/ml/z3.ml | 101 +++++++++++++++++++++++++-------------------- src/api/ml/z3.mli | 12 ++++-- 4 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 src/api/ml/META diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8aa582d12..b19e95cee 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1534,7 +1534,7 @@ class MLExampleComponent(ExampleComponent): out.write('\t%s ' % OCAMLC) if DEBUG_MODE: out.write('-g ') - out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" z3.cma') + out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3.cma') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -1545,7 +1545,7 @@ class MLExampleComponent(ExampleComponent): out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: out.write('-g ') - out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" z3.cmxa') + out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3.cmxa') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') diff --git a/src/api/ml/META b/src/api/ml/META new file mode 100644 index 000000000..d275d98be --- /dev/null +++ b/src/api/ml/META @@ -0,0 +1,7 @@ +# META file for the "z3" package: +version = "VERSION" +description = "Z3 Theorem Prover (OCaml API)" +requires = "num" +archive(byte) = "z3.cma" +archive(native) = "z3.cmxa" +linkopts = "-cclib -lz3" \ No newline at end of file diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 051a54696..dda8807c9 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1425,6 +1425,50 @@ end module Arithmetic = struct + let is_int ( x : expr ) = + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) + + let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + + let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + + let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + + let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + + let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + + let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + + let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + + let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + + let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + + let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + + let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + + let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + + let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + + let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + + let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + + let is_rat_numeral ( x : expr ) = (Expr.is_numeral x) && (is_real x) + + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) module Integer = struct @@ -1435,6 +1479,12 @@ struct let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") + + let get_big_int ( x : expr ) = + if (is_int_numeral x) then + let s = to_string(x) in + (Big_int.big_int_of_string s) + else raise (Z3native.Exception "Conversion failed.") let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) @@ -1474,6 +1524,12 @@ struct let get_denominator ( x : expr ) = expr_of_ptr (Expr.gc x) (Z3native.get_denominator (Expr.gnc x) (Expr.gno x)) + let get_ratio ( x : expr ) = + if (is_rat_numeral x) then + let s = to_string(x) in + (Ratio.ratio_of_string s) + else raise (Z3native.Exception "Conversion failed.") + let to_decimal_string ( x : expr ) ( precision : int ) = Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision @@ -1518,51 +1574,6 @@ struct end end - let is_int ( x : expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - - let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - - let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - - let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - - let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - - let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - - let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - - let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - - let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - - let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - - let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - - let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - - let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - - let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - - let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - - let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - - let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) - - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - - let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - let mk_add ( ctx : context ) ( t : expr list ) = let f x = (Expr.gno x) in (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index c554d7564..4122f40f2 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1149,6 +1149,9 @@ sig (** Retrieve the int value. *) val get_int : Expr.expr -> int + (** Get a big_int from an integer numeral *) + val get_big_int : Expr.expr -> Big_int.big_int + (** Returns a string representation of the numeral. *) val to_string : Expr.expr -> string @@ -1201,10 +1204,13 @@ sig val mk_sort : context -> Sort.sort (** The numerator of a rational numeral. *) - val get_numerator : Expr.expr-> Expr.expr + val get_numerator : Expr.expr -> Expr.expr (** The denominator of a rational numeral. *) - val get_denominator : Expr.expr-> Expr.expr + val get_denominator : Expr.expr -> Expr.expr + + (** Get a ratio from a real numeral *) + val get_ratio : Expr.expr -> Ratio.ratio (** Returns a string representation in decimal notation. The result has at most as many decimal places as indicated by the int argument.*) @@ -1323,7 +1329,7 @@ sig val is_int_numeral : Expr.expr -> bool (** Indicates whether the term is a real numeral. *) - val is_rat_num : Expr.expr -> bool + val is_rat_numeral : Expr.expr -> bool (** Indicates whether the term is an algebraic number *) val is_algebraic_number : Expr.expr -> bool From 6394dde85d18b350a5c52916c109582343952340 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 15:33:07 +0100 Subject: [PATCH 308/507] ML API: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b19e95cee..84621e396 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1375,7 +1375,7 @@ class MLComponent(Component): out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): From 1e4b14af675c30f38c950672d112b8c463a3d8cb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:10:18 +0100 Subject: [PATCH 309/507] ML API: ocamlfind installation fixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 4 ++-- scripts/mk_util.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/ml/README b/examples/ml/README index 7d33df743..844638552 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -15,8 +15,8 @@ for the byte-code version. If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), then we can compile this example as follows: -ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg -ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg +ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg ml_example.ml +ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg ml_example.ml Note that the resulting binaries depend on the shared z3 library, which needs to be in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 84621e396..8577479b7 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1401,6 +1401,9 @@ class MLComponent(Component): out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + for m in modules: + out.write(' %s.cmi' % (os.path.join(sub_dir, m))) + out.write(' %s.cmx' % (os.path.join(sub_dir, m))) if IS_WINDOWS: out.write(' libz3$(LIB_EXT)') out.write('\n') From f72ac1afb69ea38b77333b11e2cd10d2b108eb68 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:10:29 +0100 Subject: [PATCH 310/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 0ed9b29ca..8ce652ed5 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1254,7 +1254,7 @@ def mk_ml(): ml_native.write(' a%d' % i) i = i + 1 ml_native.write(') in\n') - if len(params) > 0 and param_type(params[0]) == CONTEXT: + if name not in Unwrapped and len(params) > 0 and param_type(params[0]) == CONTEXT: ml_native.write(' let err = (error_code_of_int (ML2C.n_get_error_code a0)) in \n') ml_native.write(' if err <> OK then\n') ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (int_of_error_code err)))\n') From d8a84c9f8990470736c7b3f62e2a6b27aa846f0f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:12:55 +0100 Subject: [PATCH 311/507] ML API doc fix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 4122f40f2..8a88a91bb 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -2404,7 +2404,7 @@ sig (** The finite set of distinct values that represent the interpretation of a sort. {!get_sorts} - @returns A list of expressions, where each is an element of the universe of the sort *) + @return A list of expressions, where each is an element of the universe of the sort *) val sort_universe : model -> Sort.sort -> AST.ast list (** Conversion of models to strings. From 47997e175f10ddfbb20dd103c92261064852bfd1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:16:40 +0100 Subject: [PATCH 312/507] ML API doc fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.mli | 220 +++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 8a88a91bb..ff45fb0f2 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -241,7 +241,7 @@ sig AST objects are reference counted and unwrapping an AST disables automatic reference counting, i.e., all references to the IntPtr that is returned must be handled externally and through native calls (see e.g., - Z3native.inc_ref). + [Z3native.inc_ref]). {!wrap_ast} *) val unwrap_ast : ast -> Z3native.ptr @@ -251,7 +251,7 @@ sig managed objects. Note that the native ast that is passed must be a native object obtained from Z3 (e.g., through {!unwrap_ast}) and that it must have a correct reference count (see e.g., - Z3native.inc_ref). *) + [Z3native.inc_ref]). *) val wrap_ast : context -> Z3native.z3_ast -> ast end @@ -439,7 +439,7 @@ sig (** Update a mutable configuration parameter. The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -p + [z3.exe -p] Only a few configuration parameters are mutable once the context is created. An exception is thrown when trying to modify an immutable parameter. {!get_param_value} *) @@ -479,7 +479,7 @@ sig {!get_simplify_help} *) val simplify : Expr.expr -> Params.params option -> expr - (** A string describing all available parameters to Expr.Simplify. *) + (** A string describing all available parameters to [Expr.Simplify]. *) val get_simplify_help : context -> string (** Retrieves parameter descriptions for simplifier. *) @@ -498,20 +498,20 @@ sig The number of new arguments should coincide with the current number of arguments. *) val update : Expr.expr -> Expr.expr list -> expr - (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + (** Substitute every occurrence of [from[i]] in the expression with [to[i]], for [i] smaller than [num_exprs]. - The result is the new expression. The arrays from and to must have size num_exprs. - For every i smaller than num_exprs, we must have that - sort of from[i] must be equal to sort of to[i]. *) + The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. + For every [i] smaller than [num_exprs], we must have that + sort of [from[i]] must be equal to sort of [to[i]]. *) val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr - (** Substitute every occurrence of from in the expression with to. + (** Substitute every occurrence of [from] in the expression with [to]. {!substitute} *) val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr (** Substitute the free variables in the expression with the expressions in the expr array - For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) + For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) val substitute_vars : Expr.expr -> Expr.expr list -> expr (** Translates (copies) the term to another context. @@ -554,7 +554,7 @@ sig val mk_numeral_string : context -> string -> Sort.sort -> expr (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. @return A Term with the given value and sort *) val mk_numeral_int : context -> int -> Sort.sort -> expr end @@ -580,19 +580,19 @@ sig (** Creates a Boolean value. *) val mk_val : context -> bool -> Expr.expr - (** Mk an expression representing not(a). *) + (** Mk an expression representing [not(a)]. *) val mk_not : context -> Expr.expr -> Expr.expr - (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + (** Create an expression representing an if-then-else: [ite(t1, t2, t3)]. *) val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 iff t2. *) + (** Create an expression representing [t1 iff t2]. *) val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 -> t2. *) + (** Create an expression representing [t1 -> t2]. *) val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 xor t2. *) + (** Create an expression representing [t1 xor t2]. *) val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing the AND of args *) @@ -604,7 +604,7 @@ sig (** Creates the equality between two expr's. *) val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Creates a distinct term. *) + (** Creates a [distinct] term. *) val mk_distinct : context -> Expr.expr list -> Expr.expr (** Indicates whether the expression is the true or false expression @@ -806,45 +806,45 @@ sig (** Array read. - The argument a is the array and i is the index + The argument [a] is the array and [i] is the index of the array that gets read. - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. + The node [a] must have an array sort [[domain -> range]], + and [i] must have the sort [domain]. + The sort of the result is [range]. {!Z3Array.mk_sort} {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr (** Array update. - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. + The node [a] must have an array sort [[domain -> range]], + [i] must have sort [domain], + [v] must have sort range. The sort of the result is [[domain -> range]]. The semantics of this function is given by the theory of arrays described in the SMT-LIB standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). + The result of this function is an array that is equal to [a] + (with respect to [select]) + on all indices except for [i], where it maps to [v] + (and the [select] of [a] with + respect to [i] may be a different value). {!Z3Array.mk_sort} {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr (** Create a constant array. - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. + The resulting term is an array, such that a [select]on an arbitrary index + produces the value [v]. {!Z3Array.mk_sort} {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr (** Maps f on the argument arrays. - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. + Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. + The function declaration [f] must have type [ range_1 .. range_n -> range]. + [v] must have sort range. The sort of the result is [[domain_i -> range]]. {!Z3Array.mk_sort} {!mk_select} {!mk_store} *) @@ -938,8 +938,8 @@ sig (** Indicates whether the term is an relation store Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. *) + The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements + correspond to the [n] columns of the relation. *) val is_store : Expr.expr -> bool (** Indicates whether the term is an empty relation *) @@ -997,8 +997,8 @@ sig (** Indicates whether the term is a relational select Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. *) + The function takes [n+1] arguments, where the first argument is a relation, + and the remaining [n] arguments correspond to a record. *) val is_select : Expr.expr -> bool (** Indicates whether the term is a relational clone (copy) @@ -1161,11 +1161,11 @@ sig (** Creates an integer constant. *) val mk_const_s : context -> string -> Expr.expr - (** Create an expression representing t1 mod t2. + (** Create an expression representing [t1 mod t2]. The arguments must have int type. *) val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 rem t2. + (** Create an expression representing [t1 rem t2]. The arguments must have int type. *) val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1181,8 +1181,8 @@ sig There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + You can take the floor of a real by creating an auxiliary integer Term [k] and + and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. The argument must be of integer sort. *) val mk_int2real : context -> Expr.expr -> Expr.expr @@ -1334,34 +1334,34 @@ sig (** Indicates whether the term is an algebraic number *) val is_algebraic_number : Expr.expr -> bool - (** Create an expression representing t[0] + t[1] + .... *) + (** Create an expression representing [t[0] + t[1] + ...]. *) val mk_add : context -> Expr.expr list -> Expr.expr - (** Create an expression representing t[0] * t[1] * .... *) + (** Create an expression representing [t[0] * t[1] * ...]. *) val mk_mul : context -> Expr.expr list -> Expr.expr - (** Create an expression representing t[0] - t[1] - .... *) + (** Create an expression representing [t[0] - t[1] - ...]. *) val mk_sub : context -> Expr.expr list -> Expr.expr - (** Create an expression representing -t. *) + (** Create an expression representing [-t]. *) val mk_unary_minus : context -> Expr.expr -> Expr.expr - (** Create an expression representing t1 / t2. *) + (** Create an expression representing [t1 / t2]. *) val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 ^ t2. *) + (** Create an expression representing [t1 ^ t2]. *) val mk_power : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 < t2 *) + (** Create an expression representing [t1 < t2] *) val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 <= t2 *) + (** Create an expression representing [t1 <= t2] *) val mk_le : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 > t2 *) + (** Create an expression representing [t1 > t2] *) val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 >= t2 *) + (** Create an expression representing [t1 >= t2] *) val mk_ge : context -> Expr.expr -> Expr.expr -> Expr.expr end @@ -1610,8 +1610,8 @@ sig (** Unsigned division. - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result + It is defined as the floor of [t1/t2] if \c t2 is + different from zero. If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1620,33 +1620,33 @@ sig It is defined in the following way: - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. - If t2 is zero, then the result is undefined. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned remainder. - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. + It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed remainder. - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - If t2 is zero, then the result is undefined. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed remainder (sign follows divisor). - If t2 is zero, then the result is undefined. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1694,27 +1694,27 @@ sig The arguments must have a bit-vector sort. @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). *) + The result is a bit-vector of size [n1+n2], where [n1] ([n2]) + is the size of [t1] ([t2]). *) val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector extraction. Extract the bits between two limits from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. *) + size [m] to yield a new bitvector of size [n], where + [n = high - low + 1]. *) val mk_extract : context -> int -> int -> Expr.expr -> Expr.expr (** Bit-vector sign extension. Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. *) + size [m+i], where \c m is the size of the given bit-vector. *) val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr (** Bit-vector zero extension. Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the + bitvector of size [m+i], where \c m is the size of the given bit-vector. *) val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr @@ -1723,7 +1723,7 @@ sig (** Shift left. - It is equivalent to multiplication by 2^x where \c x is the value of third argument. + It is equivalent to multiplication by [2^x] where \c x is the value of third argument. NB. The semantics of shift operations varies between environments. This definition does not necessarily capture directly the semantics of the @@ -1732,7 +1732,7 @@ sig (** Logical shift right - It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. + It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. NB. The semantics of shift operations varies between environments. This definition does not necessarily capture directly the semantics of the @@ -1773,7 +1773,7 @@ sig (** Create an integer from the bit-vector argument If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where + So the result is non-negative and in the range [[0..2^N-1]], where N are the number of bits in the argument. If \c is_signed is true, \c t1 is treated as a signed bit-vector. @@ -2353,15 +2353,15 @@ sig end (** Retrieves the interpretation (the assignment) of a func_decl in the model. - An expression if the function has an interpretation in the model, null otherwise. *) + @return An expression if the function has an interpretation in the model, null otherwise. *) val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option (** Retrieves the interpretation (the assignment) of an expression in the model. - An expression if the constant has an interpretation in the model, null otherwise. *) + @return An expression if the constant has an interpretation in the model, null otherwise. *) val get_const_interp_e : model -> Expr.expr -> Expr.expr option (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + @return A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option (** The number of constant interpretations in the model. *) @@ -2383,11 +2383,11 @@ sig This function may fail if the argument contains quantifiers, is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. + In this case a [ModelEvaluationFailedException] is thrown. *) val eval : model -> Expr.expr -> bool -> Expr.expr option - (** Alias for eval. *) + (** Alias for [eval]. *) val evaluate : model -> Expr.expr -> bool -> Expr.expr option (** The number of uninterpreted sorts that the model has an interpretation for. *) @@ -2408,7 +2408,7 @@ sig val sort_universe : model -> Sort.sort -> AST.ast list (** Conversion of models to strings. - A string representation of the model. *) + @return A string representation of the model. *) val to_string : model -> string end @@ -2416,17 +2416,17 @@ end Probes are used to inspect a goal (aka problem) and collect information that may be used to decide which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + The complete list of probes may be obtained using the procedures [Context.NumProbes] + and [Context.ProbeNames]. + It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. *) module Probe : sig type probe (** Execute the probe over the goal. - A probe always produce a float value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + @return A probe always produce a float value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) val apply : probe -> Goal.goal -> float (** The number of supported Probes. *) @@ -2478,9 +2478,9 @@ end (** Tactics Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using Context.get_num_tactics - and Context.get_tactic_names. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + The complete list of tactics may be obtained using [Context.get_num_tactics] + and [Context.get_tactic_names]. + It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. *) module Tactic : sig @@ -2504,8 +2504,8 @@ sig val get_subgoal : apply_result -> int -> Goal.goal (** Convert a model for a subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g *) + goal [g], that the ApplyResult was obtained from. + #return A model for [g] *) val convert_model : apply_result -> int -> Model.model -> Model.model (** A string representation of the ApplyResult. *) @@ -2549,7 +2549,7 @@ sig (** Create a tactic that applies one tactic to a given goal if the probe evaluates to true. - If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) + If the probe evaluates to false, then the new tactic behaves like the [skip] tactic. *) val when_ : context -> Probe.probe -> tactic -> tactic (** Create a tactic that applies a tactic to a given goal if the probe @@ -2577,7 +2577,7 @@ sig val using_params : context -> tactic -> Params.params -> tactic (** Create a tactic that applies a tactic using the given set of parameters. - Alias for UsingParams*) + Alias for [UsingParams]*) val with_ : context -> tactic -> Params.params -> tactic (** Create a tactic that applies the given tactics in parallel. *) @@ -2718,26 +2718,26 @@ sig {!Proof} *) val check : solver -> Expr.expr list -> status - (** The model of the last Check. + (** The model of the last [Check]. - The result is None if Check was not invoked before, - if its results was not SATISFIABLE, or if model production is not enabled. *) + The result is [None] if [Check] was not invoked before, + if its results was not [SATISFIABLE], or if model production is not enabled. *) val get_model : solver -> Model.model option - (** The proof of the last Check. + (** The proof of the last [Check]. - The result is null if Check was not invoked before, - if its results was not UNSATISFIABLE, or if proof production is disabled. *) + The result is [null] if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if proof production is disabled. *) val get_proof : solver -> Expr.expr option - (** The unsat core of the last Check. + (** The unsat core of the last [Check]. - The unsat core is a subset of Assertions - The result is empty if Check was not invoked before, - if its results was not UNSATISFIABLE, or if core production is disabled. *) + The unsat core is a subset of [Assertions] + The result is empty if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if core production is disabled. *) val get_unsat_core : solver -> AST.ast list - (** A brief justification of why the last call to Check returned UNKNOWN. *) + (** A brief justification of why the last call to [Check] returned [UNKNOWN]. *) val get_reason_unknown : solver -> string (** Solver statistics. *) @@ -2759,7 +2759,7 @@ sig (** Creates a solver that is implemented using the given tactic. - The solver supports the commands Push and Pop, but it + The solver supports the commands [Push] and [Pop], but it will always solve each check from scratch. *) val mk_solver_t : context -> Tactic.tactic -> solver @@ -2811,7 +2811,7 @@ sig (** Backtrack one backtracking point. - Note that an exception is thrown if Pop is called without a corresponding Push + Note that an exception is thrown if Pop is called without a corresponding [Push] {!push} *) val pop : fixedpoint -> unit @@ -2875,28 +2875,28 @@ sig {!parse_smtlib_string} *) val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_formulas : context -> int - (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_formulas : context -> Expr.expr list - (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_assumptions : context -> int - (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_assumptions : context -> Expr.expr list - (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_decls : context -> int - (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_decls : context -> FuncDecl.func_decl list - (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB sorts parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_sorts : context -> int - (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The sort declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_sorts : context -> Sort.sort list (** Parse the given string using the SMT-LIB2 parser. From 2a67301c50033dd3a9e2a02bcf1ad6bbf153f7a0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Apr 2014 15:06:32 +0100 Subject: [PATCH 313/507] ML API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index dda8807c9..e2fa01478 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1482,7 +1482,7 @@ struct let get_big_int ( x : expr ) = if (is_int_numeral x) then - let s = to_string(x) in + let s = (Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x)) in (Big_int.big_int_of_string s) else raise (Z3native.Exception "Conversion failed.") @@ -1526,7 +1526,7 @@ struct let get_ratio ( x : expr ) = if (is_rat_numeral x) then - let s = to_string(x) in + let s = (Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x)) in (Ratio.ratio_of_string s) else raise (Z3native.Exception "Conversion failed.") From 4c54b6816a1e2669398172391d4c5c93612fcb3d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 22 Apr 2014 11:49:47 +0100 Subject: [PATCH 314/507] ML API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index e2fa01478..dafd255f8 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -119,7 +119,7 @@ let mk_list ( f : int -> 'a ) ( n : int ) = if (i >= n) then tail else - (mk_list' f (i+1) n ((f i) :: tail)) + (f i) :: (mk_list' f (i+1) n tail) in mk_list' f 0 n [] From 1c34842ca6839a3833638e58d18b5e9c1f8f8ff6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Apr 2014 15:15:59 +0100 Subject: [PATCH 315/507] ML API: added Expr.equal and Expr.compare Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 6 ++++++ src/api/ml/z3.mli | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index dafd255f8..3f40b288c 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -717,6 +717,8 @@ sig val mk_app : context -> FuncDecl.func_decl -> expr list -> expr val mk_numeral_string : context -> string -> Sort.sort -> expr val mk_numeral_int : context -> int -> Sort.sort -> expr + val equal : expr -> expr -> bool + val compare : expr -> expr -> int end = struct type expr = Expr of AST.ast @@ -830,6 +832,10 @@ end = struct let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) + + let equal ( a : expr ) ( b : expr ) = AST.equal (ast_of_expr a) (ast_of_expr b) + + let compare a b = AST.compare (ast_of_expr a) (ast_of_expr b) end open FuncDecl diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index ff45fb0f2..84f230d95 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -554,9 +554,17 @@ sig val mk_numeral_string : context -> string -> Sort.sort -> expr (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. - @return A Term with the given value and sort *) + It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. + @return A Term with the given value and sort *) val mk_numeral_int : context -> int -> Sort.sort -> expr + + (** Comparison operator. + @return True if the two expr's are equal; false otherwise. *) + val equal : expr -> expr -> bool + + (** Object Comparison. + @return Negative if the first expr should be sorted before the second, positive if after, else zero. *) + val compare : expr -> expr -> int end (** Boolean expressions; Propositional logic and equality *) From ce94a8b2e0f5f56b2b8c469aeeaef3d4854f0aa5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Apr 2014 15:25:08 +0100 Subject: [PATCH 316/507] ML API: added constructors for ast_map and ast_vector Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 31 ++++++++++++++++++++++--------- src/api/ml/z3.mli | 20 ++++++++++++-------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 3f40b288c..b48681b87 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -214,7 +214,7 @@ struct struct type ast_vector = z3_native_object - let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_vector_inc_ref ; @@ -223,6 +223,8 @@ struct (z3obj_create res) ; res + let mk_ast_vector ( ctx : context ) = (create ctx (Z3native.mk_ast_vector (context_gno ctx))) + let get_size ( x : ast_vector ) = Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) @@ -239,7 +241,7 @@ struct Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) let translate ( x : ast_vector ) ( to_ctx : context ) = - ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) let to_string ( x : ast_vector ) = Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) @@ -248,7 +250,18 @@ struct module ASTMap = struct type ast_map = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_map = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_map_inc_ref ; + dec_ref = Z3native.ast_map_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + let mk_ast_map ( ctx : context ) = (create ctx (Z3native.mk_ast_map (context_gno ctx))) + let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; @@ -277,7 +290,7 @@ struct Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) let get_keys ( x : ast_map ) = - let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in + let av = ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in let f i = (ASTVector.get av i) in mk_list f (ASTVector.get_size av) @@ -2061,7 +2074,7 @@ struct mk_list f n let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in mk_list f n @@ -2386,11 +2399,11 @@ struct Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno c) (Expr.gno p) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) let get_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in mk_list f n @@ -2423,7 +2436,7 @@ struct Some (expr_of_ptr (z3obj_gc x) q) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in mk_list f n @@ -2545,13 +2558,13 @@ struct Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 84f230d95..4347c7431 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -107,10 +107,9 @@ sig (** A string representation of the symbol. *) val to_string : symbol -> string - (** Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. *) + (** Creates a new symbol using an integer. + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. *) val mk_int : context -> int -> symbol (** Creates a new symbol using a string. *) @@ -132,12 +131,14 @@ sig module ASTVector : sig type ast_vector + + (** Create an empty AST vector *) + val mk_ast_vector : context -> ast_vector (** The size of the vector *) val get_size : ast_vector -> int - (** - Retrieves the i-th object in the vector. + (** Retrieves the i-th object in the vector. @return An AST *) val get : ast_vector -> int -> ast @@ -162,7 +163,10 @@ sig (** Map from AST to AST *) module ASTMap : sig - type ast_map + type ast_map + + (** Create an empty mapping from AST to AST *) + val mk_ast_map : context -> ast_map (** Checks whether the map contains a key. @return True if the key in the map, false otherwise. *) @@ -2297,7 +2301,7 @@ sig (** Creates a new Goal. - Note that the Context must have been created with proof generation support if + Note that the Context must have been created with proof generation support if the fourth argument is set to true here. *) val mk_goal : context -> bool -> bool -> bool -> goal From bcbfaad3cc9d0ead2118432a7f04ae7d1c2e0e07 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 18:50:11 +0100 Subject: [PATCH 317/507] ML API bugfix. Thanks to Martin Neuhaeusser for reporting this one! Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b48681b87..bdcf1a26b 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -2045,7 +2045,7 @@ struct let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) let get_func_decls ( x : model ) = - let n = (get_num_consts x) in + let n = (get_num_funcs x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in mk_list f n From 8bd4ea293e9f427fc118fcc90cf2d10ec4a7f8b5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 18:59:03 +0100 Subject: [PATCH 318/507] ML API fix for datatype construction (Issue #121). Thanks to Elarnon for reporting this one! Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 12 ++++++++---- src/api/ml/z3.mli | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index bdcf1a26b..f34ce0ca7 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -374,6 +374,10 @@ struct let sort_lton ( a : sort list ) = let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in Array.of_list (List.map f a) + + let sort_option_lton ( a : sort option list ) = + let f ( e : sort option ) = match e with None -> null | Some(Sort(a)) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) let equal : sort -> sort -> bool = fun a b -> (a == b) || @@ -1257,7 +1261,7 @@ struct let _sizes = Hashtbl.create 0 - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = let n = (List.length field_names) in if n != (List.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -1269,7 +1273,7 @@ struct (Symbol.gno recognizer) n (Symbol.symbol_lton field_names) - (sort_lton sorts) + (sort_option_lton sorts) (Array.of_list sort_refs)) in let no : constructor = { m_ctx = ctx ; m_n_obj = null ; @@ -1316,11 +1320,11 @@ struct res end - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = Constructor.create ctx name recognizer field_names sorts sort_refs - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 4347c7431..1342bb4bc 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1053,12 +1053,12 @@ sig (** Create a datatype constructor. if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a datatype constructor. if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a new datatype sort. *) val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> Sort.sort From 662039938c7999a5cf4925943c7d8b90d825cb27 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 19:16:16 +0100 Subject: [PATCH 319/507] ML API bugfix (Issue #119). Thanks to user Elarnon for reporting this! Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 8ce652ed5..fba194bac 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1464,7 +1464,7 @@ def mk_ml(): for p in params: if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) - ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) + ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s_val, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) elif is_out_param(p): ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) i = i + 1 From d84e728f7ae460a9860d2c16b19ab26eac62a344 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 19:29:06 +0100 Subject: [PATCH 320/507] ML API bugfix for datatype module (Issue #120). Thanks to user Elarnon for reporting this! Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index f34ce0ca7..013101398 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -277,7 +277,7 @@ struct let find ( x : ast_map ) ( key : ast ) = ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - let insert ( x : ast_map ) ( key : ast ) ( value : ast) = + let insert ( x : ast_map ) ( key : ast ) ( value : ast ) = Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) let erase ( x : ast_map ) ( key : ast ) = @@ -1259,7 +1259,13 @@ struct struct type constructor = z3_native_object - let _sizes = Hashtbl.create 0 + module FieldNumTable = Hashtbl.Make(struct + type t = AST.ast + let equal x y = AST.compare x y = 0 + let hash = AST.hash + end) + + let _field_nums = FieldNumTable.create 0 let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = let n = (List.length field_names) in @@ -1283,10 +1289,10 @@ struct (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; - Hashtbl.add _sizes no n ; + FieldNumTable.add _field_nums no n ; no - let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x + let get_num_fields ( x : constructor ) = FieldNumTable.find _field_nums x let get_constructor_decl ( x : constructor ) = let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in From 2a67befe9d7195708614c2603e11cf8e6a2099bc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 14 Aug 2014 18:58:52 +0100 Subject: [PATCH 321/507] ML API: added .cmxs to the distribution. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 17 +++++++++++------ src/api/ml/META | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8577479b7..b3c21b552 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1384,23 +1384,28 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('\t%s ' % (OCAMLOPT)) + if DEBUG_MODE: + out.write('-g ') + out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) - out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) for m in modules: out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) diff --git a/src/api/ml/META b/src/api/ml/META index d275d98be..6238403a3 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -4,4 +4,6 @@ description = "Z3 Theorem Prover (OCaml API)" requires = "num" archive(byte) = "z3.cma" archive(native) = "z3.cmxa" +archive(byte, plugin) = "z3.cma" +archive(native, plugin) = "z3.cmxs" linkopts = "-cclib -lz3" \ No newline at end of file From 45ec0c1b991f98645f2df834e6b22f32d5e8d3a4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:02:00 +0100 Subject: [PATCH 322/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++--- src/api/ml/META | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b3c21b552..16286d62e 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1384,12 +1384,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('-shared -o %s %s -linkall\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1397,7 +1397,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands diff --git a/src/api/ml/META b/src/api/ml/META index 6238403a3..f1d34ba3d 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -6,4 +6,4 @@ archive(byte) = "z3.cma" archive(native) = "z3.cmxa" archive(byte, plugin) = "z3.cma" archive(native, plugin) = "z3.cmxs" -linkopts = "-cclib -lz3" \ No newline at end of file +linkopts = "-cclib -lz3 -lz3ml" \ No newline at end of file From bd9c863e6bf820e918436547fc7caebe3d423f41 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:09:01 +0100 Subject: [PATCH 323/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 16286d62e..da3dd8692 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1384,7 +1384,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: @@ -1397,7 +1397,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From 4109d19cecd016a134baab74261336081362e958 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:18:40 +0100 Subject: [PATCH 324/507] ML API: bugfixes --- scripts/mk_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index da3dd8692..362c74834 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1384,12 +1384,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-shared -o %s %s -linkall\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('-shared -cclib "-L%s -lz3ml" -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir,'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1397,7 +1397,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From 30a30e8dd033395bee17de5e88ac435f292ac338 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:22:40 +0100 Subject: [PATCH 325/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/META | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/META b/src/api/ml/META index f1d34ba3d..6238403a3 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -6,4 +6,4 @@ archive(byte) = "z3.cma" archive(native) = "z3.cmxa" archive(byte, plugin) = "z3.cma" archive(native, plugin) = "z3.cmxs" -linkopts = "-cclib -lz3 -lz3ml" \ No newline at end of file +linkopts = "-cclib -lz3" \ No newline at end of file From fc32a2e4735daa6a290b30767ca9fecf3ef940ef Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:32:33 +0100 Subject: [PATCH 326/507] ML API: Undoing earlier changes. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 362c74834..b3c21b552 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1384,12 +1384,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-shared -cclib "-L%s -lz3ml" -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir,'z3.cmxa'))) + out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1397,7 +1397,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From 16ba29e991729c05c71e424178f71a46345a70e4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 19:39:13 +0000 Subject: [PATCH 327/507] ML API: added interpolation, bugfixes. Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 10 +- src/api/ml/z3.ml | 121 ++-- src/api/ml/z3.mli | 1386 +++++++++++++++++++++-------------------- 3 files changed, 806 insertions(+), 711 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index fba194bac..4669b78fc 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -334,6 +334,8 @@ def param2ml(p): return "ptr" elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: return "%s array" % type2ml(param_type(p)) + elif k == OUT_MANAGED_ARRAY: + return "%s array" % type2ml(param_type(p)); else: return type2ml(param_type(p)) @@ -1067,7 +1069,7 @@ def ml_method_name(name): return name[3:] # Remove Z3_ def is_out_param(p): - if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: + if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_MANAGED_ARRAY: return True else: return False @@ -1411,6 +1413,8 @@ def mk_ml(): type2str(param_type(param)), type2str(param_type(param)), param_array_capacity_pos(param))) + elif k == OUT_MANAGED_ARRAY: + ml_wrapper.write(' %s * _a%s = 0;\n' % (type2str(param_type(param)), i)) elif k == IN_ARRAY or k == INOUT_ARRAY: t = param_type(param) ts = type2str(t) @@ -1449,7 +1453,7 @@ def mk_ml(): else: ml_wrapper.write(', ') k = param_kind(param) - if k == OUT or k == INOUT: + if k == OUT or k == INOUT or k == OUT_MANAGED_ARRAY: ml_wrapper.write('&_a%s' % i) else: ml_wrapper.write('_a%i' % i) @@ -1465,6 +1469,8 @@ def mk_ml(): if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s_val, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) + elif param_kind(p) == OUT_MANAGED_ARRAY: + ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) elif is_out_param(p): ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) i = i + 1 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 013101398..2b54a1113 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -165,7 +165,7 @@ struct let symbol_lton ( a : symbol list ) = let f ( e : symbol ) = (gno e) in Array.of_list (List.map f a) - + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL @@ -213,7 +213,7 @@ struct module ASTVector = struct type ast_vector = z3_native_object - + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; @@ -224,7 +224,7 @@ struct res let mk_ast_vector ( ctx : context ) = (create ctx (Z3native.mk_ast_vector (context_gno ctx))) - + let get_size ( x : ast_vector ) = Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) @@ -259,7 +259,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + let mk_ast_map ( ctx : context ) = (create ctx (Z3native.mk_ast_map (context_gno ctx))) let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = @@ -330,7 +330,7 @@ struct if (get_id a) < (get_id b) then -1 else if (get_id a) > (get_id b) then 1 else 0 - + let translate ( x : ast ) ( to_ctx : context ) = if (z3obj_gnc x) == (context_gno to_ctx) then x @@ -366,7 +366,7 @@ struct | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") let ast_of_sort s = match s with Sort(x) -> x - + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) @@ -378,7 +378,7 @@ struct let sort_option_lton ( a : sort option list ) = let f ( e : sort option ) = match e with None -> null | Some(Sort(a)) -> (AST.ptr_of_ast a) in Array.of_list (List.map f a) - + let equal : sort -> sort -> bool = fun a b -> (a == b) || if (gnc a) != (gnc b) then @@ -629,7 +629,6 @@ sig val to_string : params -> string val update_param_value : context -> string -> string -> unit - val get_param_value : context -> string -> string option val set_print_mode : context -> Z3enums.ast_print_mode -> unit end = struct type params = z3_native_object @@ -688,13 +687,6 @@ end = struct let update_param_value ( ctx : context ) ( id : string) ( value : string )= Z3native.update_param_value (context_gno ctx) id value - let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in - if not r then - None - else - Some v - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) end @@ -826,11 +818,11 @@ end = struct let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) - + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -851,7 +843,7 @@ end = struct expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) let equal ( a : expr ) ( b : expr ) = AST.equal (ast_of_expr a) (ast_of_expr b) - + let compare a b = AST.compare (ast_of_expr a) (ast_of_expr b) end @@ -941,7 +933,7 @@ struct raise (Z3native.Exception "Invalid coercion") else Quantifier(e) - + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) @@ -949,13 +941,13 @@ struct module Pattern = struct type pattern = Pattern of ast - + let ast_of_pattern e = match e with Pattern(x) -> x let pattern_of_ast a = - (* CMW: Unchecked ok? *) + (* CMW: Unchecked ok? *) Pattern(a) - + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) @@ -1258,11 +1250,11 @@ struct module Constructor = struct type constructor = z3_native_object - + module FieldNumTable = Hashtbl.Make(struct - type t = AST.ast - let equal x y = AST.compare x y = 0 - let hash = AST.hash + type t = AST.ast + let equal x y = AST.compare x y = 0 + let hash = AST.hash end) let _field_nums = FieldNumTable.create 0 @@ -1291,7 +1283,7 @@ struct Gc.finalise f no ; FieldNumTable.add _field_nums no n ; no - + let get_num_fields ( x : constructor ) = FieldNumTable.find _field_nums x let get_constructor_decl ( x : constructor ) = @@ -1613,16 +1605,16 @@ struct let mk_sub ( ctx : context ) ( t : expr list ) = let f x = (Expr.gno x) in - (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) let mk_unary_minus ( ctx : context ) ( t : expr ) = - (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) + (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) let mk_div ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) let mk_power ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) let mk_lt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) @@ -1893,7 +1885,7 @@ struct let get_formulas ( x : goal ) = let n = get_size x in let f i = ((expr_of_ptr (z3obj_gc x) - (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in + (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in mk_list f n let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) @@ -2065,7 +2057,7 @@ struct let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in (mk_list f n_funcs) @ (mk_list g n_consts) - + let eval ( x : model ) ( t : expr ) ( completion : bool ) = let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then @@ -2316,7 +2308,7 @@ struct mutable m_is_float : bool ; mutable m_int : int ; mutable m_float : float } - + let create_si k v = let res : statistics_entry = { m_key = k ; @@ -2644,7 +2636,7 @@ struct mk_list f n let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - + let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in @@ -2683,6 +2675,65 @@ struct (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) end +module Interpolation = +struct + let mk_interpolant ( ctx : context ) ( a : expr ) = + (expr_of_ptr ctx (Z3native.mk_interpolant (context_gno ctx) (Expr.gno a))) + + let mk_interpolation_context ( settings : ( string * string ) list ) = + let cfg = Z3native.mk_config () in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_interpolation_context cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + Z3native.set_internal_error_handler v ; + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> dispose_context o in + Gc.finalise f res; + res + + let get_interpolant ( ctx : context ) ( pf : expr ) ( pat: expr ) ( p : Params.params ) = + (ASTVector.create ctx (Z3native.get_interpolant (context_gno ctx) (Expr.gno pf) (Expr.gno pat) (z3obj_gno p))) + + let compute_interpolant ( ctx : context ) ( pat : expr ) ( p : Params.params ) = + let (r, interp, model) = (Z3native.compute_interpolant (context_gno ctx) (Expr.gno pat) (z3obj_gno p)) in + match (lbool_of_int r) with + | L_TRUE -> ((ASTVector.create ctx interp), (Model.create ctx model)) + | _ -> raise (Z3native.Exception "Error computing interpolant.") + + let get_interpolation_profile ( ctx : context ) = + (Z3native.interpolation_profile (context_gno ctx)) + + let read_interpolation_problem ( ctx : context ) ( filename : string ) = + let (r, num, cnsts, parents, error, num_theory, theory) = (Z3native.read_interpolation_problem (context_gno ctx) filename) in + match r with + | 0 -> raise (Z3native.Exception "Interpolation problem could not be read.") + | _ -> + let f1 i = (expr_of_ptr ctx (Array.get cnsts i)) in + let f2 i = (Array.get parents i) in + let f3 i = (expr_of_ptr ctx (Array.get theory i)) in + ((mk_list f1 num), + (mk_list f2 num), + (mk_list f3 num_theory)) + + let check_interpolant ( ctx : context ) ( num : int ) ( cnsts : Expr.expr list ) ( parents : int list ) ( interps : Expr.expr list ) ( num_theory : int ) ( theory : Expr.expr list ) = + let (r, str) = (Z3native.check_interpolant (context_gno ctx) + num + (let f x = Expr.gno x in (Array.of_list (List.map f cnsts))) + (Array.of_list parents) + (let f x = Expr.gno x in (Array.of_list (List.map f interps))) + num_theory + (let f x = Expr.gno x in (Array.of_list (List.map f theory)))) in + match (lbool_of_int r) with + | L_UNDEF -> raise (Z3native.Exception "Interpolant could not be verified.") + | L_FALSE -> raise (Z3native.Exception "Interpolant could not be verified.") + | _ -> () + + let write_interpolation_problem ( ctx : context ) ( num : int ) ( cnsts : Expr.expr list ) ( parents : int list ) ( filename : string ) ( num_theory : int ) ( theory : Expr.expr list ) = + (Z3native.write_interpolation_problem (context_gno ctx) num (expr_lton cnsts) (Array.of_list parents) filename num_theory (expr_lton theory)) ; + () +end let set_global_param ( id : string ) ( value : string ) = (Z3native.global_param_set id value) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 1342bb4bc..b2f0939d0 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -149,11 +149,11 @@ sig val resize : ast_vector -> int -> unit (** Add an ast to the back of the vector. The size - is increased by 1. *) + is increased by 1. *) val push : ast_vector -> ast -> unit (** Translates all ASTs in the vector to another context. - @return A new ASTVector *) + @return A new ASTVector *) val translate : ast_vector -> context -> ast_vector (** Retrieves a string representation of the vector. *) @@ -196,7 +196,7 @@ sig end (** The AST's hash code. - @return A hash code *) + @return A hash code *) val hash : ast -> int (** A unique identifier for the AST (unique among all ASTs). *) @@ -227,34 +227,34 @@ sig val to_sexpr : ast -> string (** Comparison operator. - @return True if the two ast's are from the same context - and represent the same sort; false otherwise. *) + @return True if the two ast's are from the same context + and represent the same sort; false otherwise. *) val equal : ast -> ast -> bool (** Object Comparison. - @return Negative if the first ast should be sorted before the second, positive if after else zero. *) + @return Negative if the first ast should be sorted before the second, positive if after else zero. *) val compare : ast -> ast -> int (** Translates (copies) the AST to another context. - @return A copy of the AST which is associated with the other context. *) + @return A copy of the AST which is associated with the other context. *) val translate : ast -> context -> ast (** Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - [Z3native.inc_ref]). - {!wrap_ast} *) + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + [Z3native.inc_ref]). + {!wrap_ast} *) val unwrap_ast : ast -> Z3native.ptr (** Wraps an AST. - This function is used for transitions between native and - managed objects. Note that the native ast that is passed must be a - native object obtained from Z3 (e.g., through {!unwrap_ast}) - and that it must have a correct reference count (see e.g., + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) + and that it must have a correct reference count (see e.g., [Z3native.inc_ref]). *) val wrap_ast : context -> Z3native.z3_ast -> ast end @@ -267,8 +267,8 @@ sig val ast_of_sort : sort -> AST.ast (** Comparison operator. - @return True if the two sorts are from the same context - and represent the same sort; false otherwise. *) + @return True if the two sorts are from the same context + and represent the same sort; false otherwise. *) val equal : sort -> sort -> bool (** Returns a unique identifier for the sort. *) @@ -441,33 +441,26 @@ sig val to_string : params -> string (** Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - [z3.exe -p] - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - {!get_param_value} *) + + The list of all configuration parameters can be obtained using the Z3 executable: + [z3.exe -p] + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. *) val update_param_value : context -> string -> string -> unit - - (** Get a configuration parameter. - - Returns None if the parameter value does not exist. - {!update_param_value} *) - val get_param_value : context -> string -> string option - + (** Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - {!AST.to_string} - {!Quantifier.Pattern.to_string} - {!FuncDecl.to_string} - {!Sort.to_string} *) + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) val set_print_mode : context -> Z3enums.ast_print_mode -> unit end @@ -480,7 +473,7 @@ sig val expr_of_ast : AST.ast -> Expr.expr (** Returns a simplified version of the expression. - {!get_simplify_help} *) + {!get_simplify_help} *) val simplify : Expr.expr -> Params.params option -> expr (** A string describing all available parameters to [Expr.Simplify]. *) @@ -503,23 +496,23 @@ sig val update : Expr.expr -> Expr.expr list -> expr (** Substitute every occurrence of [from[i]] in the expression with [to[i]], for [i] smaller than [num_exprs]. - - The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. - For every [i] smaller than [num_exprs], we must have that - sort of [from[i]] must be equal to sort of [to[i]]. *) + + The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. + For every [i] smaller than [num_exprs], we must have that + sort of [from[i]] must be equal to sort of [to[i]]. *) val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr (** Substitute every occurrence of [from] in the expression with [to]. - {!substitute} *) + {!substitute} *) val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr (** Substitute the free variables in the expression with the expressions in the expr array - For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) + For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) val substitute_vars : Expr.expr -> Expr.expr list -> expr (** Translates (copies) the term to another context. - @return A copy of the term which is associated with the other context *) + @return A copy of the term which is associated with the other context *) val translate : Expr.expr -> context -> expr (** Returns a string representation of the expression. *) @@ -529,7 +522,7 @@ sig val is_numeral : Expr.expr -> bool (** Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. *) + @return True if the term is well-sorted, false otherwise. *) val is_well_sorted : Expr.expr -> bool (** The Sort of the term. *) @@ -537,26 +530,26 @@ sig (** Indicates whether the term represents a constant. *) val is_const : Expr.expr -> bool - + (** Creates a new constant. *) val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - + (** Creates a new constant. *) val mk_const_s : context -> string -> Sort.sort -> expr - + (** Creates a constant from the func_decl. *) val mk_const_f : context -> FuncDecl.func_decl -> expr - + (** Creates a fresh constant with a name prefixed with a string. *) val mk_fresh_const : context -> string -> Sort.sort -> expr - + (** Create a new function application. *) val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - + (** Create a numeral of a given sort. - @return A Term with the given value and sort *) + @return A Term with the given value and sort *) val mk_numeral_string : context -> string -> Sort.sort -> expr - + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. @return A Term with the given value and sort *) @@ -692,21 +685,21 @@ sig (** The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. *) + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. *) val get_index : Expr.expr -> int (** Indicates whether the quantifier is universal. *) @@ -723,19 +716,19 @@ sig (** The patterns. *) val get_patterns : quantifier -> Pattern.pattern list - - (** The number of no-patterns. *) + + (** The number of no-patterns. *) val get_num_no_patterns : quantifier -> int (** The no-patterns. *) val get_no_patterns : quantifier -> Pattern.pattern list - (** The number of bound variables. *) - val get_num_bound : quantifier -> int - - (** The symbols for the bound variables. *) + (** The number of bound variables. *) + val get_num_bound : quantifier -> int + + (** The symbols for the bound variables. *) val get_bound_variable_names : quantifier -> Symbol.symbol list - + (** The sorts of the bound variables. *) val get_bound_variable_sorts : quantifier -> Sort.sort list @@ -767,7 +760,7 @@ sig val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** A string representation of the quantifier. *) - val to_string : quantifier -> string + val to_string : quantifier -> string end (** Functions to manipulate Array expressions *) @@ -777,28 +770,28 @@ sig val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort (** Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. *) + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. *) val is_store : Expr.expr -> bool (** Indicates whether the term is an array select. *) val is_select : Expr.expr -> bool (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. *) + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) val is_constant_array : Expr.expr -> bool (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. *) + For example default(const(v)) = v. The function is unary. *) val is_default_array : Expr.expr -> bool (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) val is_array_map : Expr.expr -> bool (** Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. *) + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. *) val is_as_array : Expr.expr -> bool (** Indicates whether the term is of an array sort. *) @@ -806,66 +799,66 @@ sig (** The domain of the array sort. *) val get_domain : Sort.sort -> Sort.sort - + (** The range of the array sort. *) val get_range : Sort.sort -> Sort.sort - + (** Create an array constant. *) val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> Expr.expr - + (** Create an array constant. *) val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> Expr.expr - + (** Array read. - - The argument [a] is the array and [i] is the index - of the array that gets read. - - The node [a] must have an array sort [[domain -> range]], - and [i] must have the sort [domain]. - The sort of the result is [range]. - {!Z3Array.mk_sort} - {!mk_store} *) + + The argument [a] is the array and [i] is the index + of the array that gets read. + + The node [a] must have an array sort [[domain -> range]], + and [i] must have the sort [domain]. + The sort of the result is [range]. + {!Z3Array.mk_sort} + {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr (** Array update. - - The node [a] must have an array sort [[domain -> range]], - [i] must have sort [domain], - [v] must have sort range. The sort of the result is [[domain -> range]]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to [a] - (with respect to [select]) - on all indices except for [i], where it maps to [v] - (and the [select] of [a] with - respect to [i] may be a different value). - {!Z3Array.mk_sort} - {!mk_select} *) + + The node [a] must have an array sort [[domain -> range]], + [i] must have sort [domain], + [v] must have sort range. The sort of the result is [[domain -> range]]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to [a] + (with respect to [select]) + on all indices except for [i], where it maps to [v] + (and the [select] of [a] with + respect to [i] may be a different value). + {!Z3Array.mk_sort} + {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr (** Create a constant array. - - The resulting term is an array, such that a [select]on an arbitrary index - produces the value [v]. - {!Z3Array.mk_sort} - {!mk_select} *) + + The resulting term is an array, such that a [select]on an arbitrary index + produces the value [v]. + {!Z3Array.mk_sort} + {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr (** Maps f on the argument arrays. - - Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. - The function declaration [f] must have type [ range_1 .. range_n -> range]. - [v] must have sort range. The sort of the result is [[domain_i -> range]]. - {!Z3Array.mk_sort} - {!mk_select} - {!mk_store} *) + + Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. + The function declaration [f] must have type [ range_1 .. range_n -> range]. + [v] must have sort range. The sort of the result is [[domain_i -> range]]. + {!Z3Array.mk_sort} + {!mk_select} + {!mk_store} *) val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr (** Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. *) + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. *) val mk_term_array : context -> Expr.expr -> Expr.expr end @@ -948,10 +941,10 @@ sig val is_relation : Expr.expr -> bool (** Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements - correspond to the [n] columns of the relation. *) + + Insert a record into a relation. + The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements + correspond to the [n] columns of the relation. *) val is_store : Expr.expr -> bool (** Indicates whether the term is an empty relation *) @@ -964,62 +957,62 @@ sig val is_join : Expr.expr -> bool (** Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. *) + The function takes two arguments. *) val is_union : Expr.expr -> bool (** Indicates whether the term is the widening of two relations - The function takes two arguments. *) + The function takes two arguments. *) val is_widen : Expr.expr -> bool (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. *) + The function takes one argument. *) val is_project : Expr.expr -> bool (** Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. *) + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. *) val is_filter : Expr.expr -> bool (** Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. *) + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. *) val is_negation_filter : Expr.expr -> bool (** Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. *) + + The function takes one argument. + The parameters contain the renaming as a cycle. *) val is_rename : Expr.expr -> bool (** Indicates whether the term is the complement of a relation *) val is_complement : Expr.expr -> bool (** Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes [n+1] arguments, where the first argument is a relation, - and the remaining [n] arguments correspond to a record. *) + + Check if a record is an element of the relation. + The function takes [n+1] arguments, where the first argument is a relation, + and the remaining [n] arguments correspond to a record. *) val is_select : Expr.expr -> bool (** Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind {!is_union} - to perform destructive updates to the first argument. *) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind {!is_union} + to perform destructive updates to the first argument. *) val is_clone : Expr.expr -> bool (** The arity of the relation sort. *) @@ -1039,25 +1032,25 @@ sig (** The number of fields of the constructor. *) val get_num_fields : constructor -> int - + (** The function declaration of the constructor. *) val get_constructor_decl : constructor -> FuncDecl.func_decl (** The function declaration of the tester. *) val get_tester_decl : constructor -> FuncDecl.func_decl - + (** The function declarations of the accessors *) val get_accessor_decls : constructor -> FuncDecl.func_decl list end (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a new datatype sort. *) @@ -1078,7 +1071,7 @@ sig (** The constructors. *) val get_constructors : Sort.sort -> FuncDecl.func_decl list - + (** The recognizers. *) val get_recognizers : Sort.sort -> FuncDecl.func_decl list @@ -1174,38 +1167,38 @@ sig val mk_const_s : context -> string -> Expr.expr (** Create an expression representing [t1 mod t2]. - The arguments must have int type. *) + The arguments must have int type. *) val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing [t1 rem t2]. - The arguments must have int type. *) + The arguments must have int type. *) val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer numeral. *) val mk_numeral_s : context -> string -> Expr.expr (** Create an integer numeral. - @return A Term with the given value and sort Integer *) + @return A Term with the given value and sort Integer *) val mk_numeral_i : context -> int -> Expr.expr (** Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term [k] and - and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. - The argument must be of integer sort. *) + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term [k] and + and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. + The argument must be of integer sort. *) val mk_int2real : context -> Expr.expr -> Expr.expr (** Create an n-bit bit-vector from an integer argument. - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. *) + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. *) val mk_int2bv : context -> int -> Expr.expr -> Expr.expr end @@ -1238,16 +1231,16 @@ sig val mk_const_s : context -> string -> Expr.expr (** Create a real numeral from a fraction. - @return A Term with rational value and sort Real - {!mk_numeral_s} *) + @return A Term with rational value and sort Real + {!mk_numeral_s} *) val mk_numeral_nd : context -> int -> int -> Expr.expr (** Create a real numeral. - @return A Term with the given value and sort Real *) + @return A Term with the given value and sort Real *) val mk_numeral_s : context -> string -> Expr.expr (** Create a real numeral. - @return A Term with the given value and sort Real *) + @return A Term with the given value and sort Real *) val mk_numeral_i : context -> int -> Expr.expr (** Creates an expression that checks whether a real number is an integer. *) @@ -1255,8 +1248,8 @@ sig (** Coerce a real to an integer. - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. *) + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) val mk_real2int : context -> Expr.expr -> Expr.expr (** Algebraic Numbers *) @@ -1522,34 +1515,34 @@ sig val is_bv_rotateright : Expr.expr -> bool (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) val is_bv_rotateleftextended : Expr.expr -> bool (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) val is_bv_rotaterightextended : Expr.expr -> bool - + (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) (** Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) val is_int_to_bv : Expr.expr -> bool (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) val is_bv_to_int : Expr.expr -> bool (** Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) val is_bv_carry : Expr.expr -> bool - + (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) val is_bv_xor3 : Expr.expr -> bool (** The size of a bit-vector sort. *) @@ -1557,7 +1550,7 @@ sig (** Retrieve the int value. *) val get_int : Expr.expr -> int - + (** Returns a string representation of the numeral. *) val to_string : Expr.expr -> string @@ -1568,146 +1561,145 @@ sig val mk_const_s : context -> string -> int -> Expr.expr (** Bitwise negation. - The argument must have a bit-vector sort. *) + The argument must have a bit-vector sort. *) val mk_not : context -> Expr.expr -> Expr.expr (** Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) + The argument must have a bit-vector sort. *) val mk_redand : context -> Expr.expr -> Expr.expr (** Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) + The argument must have a bit-vector sort. *) val mk_redor : context -> Expr.expr -> Expr.expr (** Bitwise conjunction. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_and : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise disjunction. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_or : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise XOR. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise NAND. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_nand : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise NOR. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_nor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise XNOR. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_xnor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Standard two's complement unary minus. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_neg : context -> Expr.expr -> Expr.expr (** Two's complement addition. - The arguments must have the same bit-vector sort. *) + The arguments must have the same bit-vector sort. *) val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement subtraction. - The arguments must have the same bit-vector sort. *) + The arguments must have the same bit-vector sort. *) val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement multiplication. - The arguments must have the same bit-vector sort. *) + The arguments must have the same bit-vector sort. *) val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned division. - - - It is defined as the floor of [t1/t2] if \c t2 is - different from zero. If [t2] is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. *) + + It is defined as the floor of [t1/t2] if \c t2 is + different from zero. If [t2] is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. *) val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed division. - - It is defined in the following way: + + It is defined in the following way: - - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. + - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. - - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. + - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned remainder. - - It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + + It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed remainder. - - It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed remainder (sign follows divisor). - - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned less-than - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_ult : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed less-than - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_slt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_ule : context -> Expr.expr -> Expr.expr -> Expr.expr - + (** Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_sle : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_uge : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_sge : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned greater-than. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_ugt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_sgt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size [n1+n2], where [n1] ([n2]) - is the size of [t1] ([t2]). *) + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size [n1+n2], where [n1] ([n2]) + is the size of [t1] ([t2]). *) val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector extraction. @@ -1719,17 +1711,17 @@ sig (** Bit-vector sign extension. - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size [m+i], where \c m is the size of the given bit-vector. *) + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size [m+i], where \c m is the size of the given bit-vector. *) val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr (** Bit-vector zero extension. - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size [m+i], where \c m is the size of the - given bit-vector. *) + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size [m+i], where \c m is the size of the + given bit-vector. *) val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr - + (** Bit-vector repetition. *) val mk_repeat : context -> int -> Expr.expr -> Expr.expr @@ -1743,27 +1735,27 @@ sig val mk_shl : context -> Expr.expr -> Expr.expr -> Expr.expr (** Logical shift right - - It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. + + It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_lshr : context -> Expr.expr -> Expr.expr -> Expr.expr (** Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_ashr : context -> Expr.expr -> Expr.expr -> Expr.expr (** Rotate Left. @@ -1783,7 +1775,7 @@ sig val mk_ext_rotate_right : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer from the bit-vector argument - + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. So the result is non-negative and in the range [[0..2^N-1]], where N are the number of bits in the argument. @@ -1795,45 +1787,45 @@ sig val mk_bv2int : context -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_add_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_add_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_sub_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_sub_no_underflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_sdiv_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_neg_no_overflow : context -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_mul_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr + The arguments must be of bit-vector sort. *) + val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr + (** Create a bit-vector numeral. *) val mk_numeral : context -> string -> int -> Expr.expr end @@ -1851,389 +1843,389 @@ sig val is_goal : Expr.expr -> bool (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) val is_oeq : Expr.expr -> bool (** Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). *) + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). *) val is_modus_ponens : Expr.expr -> bool (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. *) + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. *) val is_reflexivity : Expr.expr -> bool (** Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. *) + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. *) val is_symmetry : Expr.expr -> bool (** Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) *) + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) *) val is_transitivity : Expr.expr -> bool (** Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. *) + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. *) val is_Transitivity_star : Expr.expr -> bool (** Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. *) + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. *) val is_monotonicity : Expr.expr -> bool (** Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) val is_quant_intro : Expr.expr -> bool (** Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. *) + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. *) val is_distributivity : Expr.expr -> bool (** Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i *) + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i *) val is_and_elimination : Expr.expr -> bool (** Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) *) + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) *) val is_or_elimination : Expr.expr -> bool (** Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) *) + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) val is_rewrite : Expr.expr -> bool (** Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) val is_rewrite_star : Expr.expr -> bool (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) val is_pull_quant : Expr.expr -> bool (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents *) + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents *) val is_pull_quant_star : Expr.expr -> bool (** Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents *) + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents *) val is_push_quant : Expr.expr -> bool (** Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. *) + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. *) val is_elim_unused_vars : Expr.expr -> bool (** Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. *) + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. *) val is_der : Expr.expr -> bool - + (** Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) *) + + A proof of (or (not (forall (x) (P x))) (P a)) *) val is_quant_inst : Expr.expr -> bool (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. *) + Mark a hypothesis in a natural deduction style proof. *) val is_hypothesis : Expr.expr -> bool (** Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. *) + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. *) val is_lemma : Expr.expr -> bool (** Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) val is_unit_resolution : Expr.expr -> bool (** Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) *) + + T1: p + [iff-true T1]: (iff p true) *) val is_iff_true : Expr.expr -> bool (** Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) *) + + T1: (not p) + [iff-false T1]: (iff p false) *) val is_iff_false : Expr.expr -> bool (** Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. *) + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. *) val is_commutativity : Expr.expr -> bool (** Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). *) + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). *) val is_def_axiom : Expr.expr -> bool (** Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) *) + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) *) val is_def_intro : Expr.expr -> bool (** Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. *) + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. *) val is_apply_def : Expr.expr -> bool (** Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) *) + + T1: (iff p q) + [iff~ T1]: (~ p q) *) val is_iff_oeq : Expr.expr -> bool (** Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. *) + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. *) val is_nnf_pos : Expr.expr -> bool (** Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) *) + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) *) val is_nnf_neg : Expr.expr -> bool (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) val is_nnf_star : Expr.expr -> bool (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) val is_cnf_star : Expr.expr -> bool (** Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. *) + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. *) val is_skolemize : Expr.expr -> bool (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q *) + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q *) val is_modus_ponens_oeq : Expr.expr -> bool (** Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) val is_theory_lemma : Expr.expr -> bool end @@ -2265,12 +2257,12 @@ sig (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) val is_garbage : goal -> bool - (** Adds the constraints to the given goal. *) + (** Adds the constraints to the given goal. *) val add : goal -> Expr.expr list -> unit - + (** Indicates whether the goal contains `false'. *) val is_inconsistent : goal -> bool - + (** The depth of the goal. This tracks how many transformations were applied to it. *) val get_depth : goal -> int @@ -2300,7 +2292,7 @@ sig val simplify : goal -> Params.params option -> goal (** Creates a new Goal. - + Note that the Context must have been created with proof generation support if the fourth argument is set to true here. *) val mk_goal : context -> bool -> bool -> bool -> goal @@ -2323,7 +2315,7 @@ sig module FuncInterp : sig type func_interp - + (** Function interpretations entries An Entry object represents an element in the finite map used to a function interpretation. *) @@ -2418,7 +2410,7 @@ sig {!get_sorts} @return A list of expressions, where each is an element of the universe of the sort *) val sort_universe : model -> Sort.sort -> AST.ast list - + (** Conversion of models to strings. @return A string representation of the model. *) val to_string : model -> string @@ -2437,8 +2429,8 @@ sig type probe (** Execute the probe over the goal. - @return A probe always produce a float value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + @return A probe always produce a float value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) val apply : probe -> Goal.goal -> float (** The number of supported Probes. *) @@ -2546,21 +2538,21 @@ sig val mk_tactic : context -> string -> tactic (** Create a tactic that applies one tactic to a Goal and - then another one to every subgoal produced by the first one. *) + then another one to every subgoal produced by the first one. *) val and_then : context -> tactic -> tactic -> tactic list -> tactic (** Create a tactic that first applies one tactic to a Goal and - if it fails then returns the result of another tactic applied to the Goal. *) + if it fails then returns the result of another tactic applied to the Goal. *) val or_else : context -> tactic -> tactic -> tactic (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). - - If the tactic does not terminate within the timeout, then it fails. *) + + If the tactic does not terminate within the timeout, then it fails. *) val try_for : context -> tactic -> int -> tactic (** Create a tactic that applies one tactic to a given goal if the probe evaluates to true. - + If the probe evaluates to false, then the new tactic behaves like the [skip] tactic. *) val when_ : context -> Probe.probe -> tactic -> tactic @@ -2569,7 +2561,7 @@ sig val cond : context -> Probe.probe -> tactic -> tactic -> tactic (** Create a tactic that keeps applying one tactic until the goal is not - modified anymore or the maximum number of iterations is reached. *) + modified anymore or the maximum number of iterations is reached. *) val repeat : context -> tactic -> int -> tactic (** Create a tactic that just returns the given goal. *) @@ -2582,14 +2574,14 @@ sig val fail_if : context -> Probe.probe -> tactic (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). *) + or trivially unsatisfiable (i.e., contains `false'). *) val fail_if_not_decided : context -> tactic (** Create a tactic that applies a tactic using the given set of parameters. *) val using_params : context -> tactic -> Params.params -> tactic (** Create a tactic that applies a tactic using the given set of parameters. - Alias for [UsingParams]*) + Alias for [UsingParams]*) val with_ : context -> tactic -> Params.params -> tactic (** Create a tactic that applies the given tactics in parallel. *) @@ -2600,7 +2592,7 @@ sig val par_and_then : context -> tactic -> tactic -> tactic (** Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. *) + This procedure can be used to interrupt: solvers, simplifiers and tactics. *) val interrupt : context -> unit end @@ -2618,8 +2610,8 @@ sig type statistics (** Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - *) + Entry is either a floating point or integer value. + *) module Entry : sig type statistics_entry @@ -2641,7 +2633,7 @@ sig (** The string representation of the the entry's value. *) val to_string_value : statistics_entry -> string - + (** The string representation of the entry (key and value) *) val to_string : statistics_entry -> string end @@ -2672,49 +2664,49 @@ sig val get_param_descrs : solver -> Params.ParamDescrs.param_descrs (** The current number of backtracking points (scopes). - {!pop} - {!push} *) + {!pop} + {!push} *) val get_num_scopes : solver -> int (** Creates a backtracking point. - {!pop} *) + {!pop} *) val push : solver -> unit (** Backtracks a number of backtracking points. - Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} - {!push} *) + Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} + {!push} *) val pop : solver -> int -> unit (** Resets the Solver. - This removes all assertions from the solver. *) + This removes all assertions from the solver. *) val reset : solver -> unit (** Assert a constraint (or multiple) into the solver. *) val add : solver -> Expr.expr list -> unit (** * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) val assert_and_track_l : solver -> Expr.expr list -> Expr.expr list -> unit (** * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) + * using the Boolean constant p. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) val assert_and_track : solver -> Expr.expr -> Expr.expr -> unit (** The number of assertions in the solver. *) @@ -2724,29 +2716,29 @@ sig val get_assertions : solver -> Expr.expr list (** Checks whether the assertions in the solver are consistent or not. - - {!Model} - {!get_unsat_core} - {!Proof} *) + + {!Model} + {!get_unsat_core} + {!Proof} *) val check : solver -> Expr.expr list -> status (** The model of the last [Check]. - - The result is [None] if [Check] was not invoked before, - if its results was not [SATISFIABLE], or if model production is not enabled. *) + + The result is [None] if [Check] was not invoked before, + if its results was not [SATISFIABLE], or if model production is not enabled. *) val get_model : solver -> Model.model option (** The proof of the last [Check]. - - The result is [null] if [Check] was not invoked before, - if its results was not [UNSATISFIABLE], or if proof production is disabled. *) + + The result is [null] if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if proof production is disabled. *) val get_proof : solver -> Expr.expr option (** The unsat core of the last [Check]. - - The unsat core is a subset of [Assertions] - The result is empty if [Check] was not invoked before, - if its results was not [UNSATISFIABLE], or if core production is disabled. *) + + The unsat core is a subset of [Assertions] + The result is empty if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if core production is disabled. *) val get_unsat_core : solver -> AST.ast list (** A brief justification of why the last call to [Check] returned [UNKNOWN]. *) @@ -2756,23 +2748,23 @@ sig val get_statistics : solver -> Statistics.statistics (** Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. *) + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) val mk_solver : context -> Symbol.symbol option -> solver (** Creates a new (incremental) solver. - {!mk_solver} *) + {!mk_solver} *) val mk_solver_s : context -> string -> solver (** Creates a new (incremental) solver. *) val mk_simple_solver : context -> solver (** Creates a solver that is implemented using the given tactic. - - The solver supports the commands [Push] and [Pop], but it - will always solve each check from scratch. *) + + The solver supports the commands [Push] and [Pop], but it + will always solve each check from scratch. *) val mk_solver_t : context -> Tactic.tactic -> solver (** A string representation of the solver. *) @@ -2806,32 +2798,32 @@ sig val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit (** Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. *) + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. *) val query : fixedpoint -> Expr.expr -> Solver.status (** Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. *) + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. *) val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status (** Creates a backtracking point. - {!pop} *) + {!pop} *) val push : fixedpoint -> unit (** Backtrack one backtracking point. - Note that an exception is thrown if Pop is called without a corresponding [Push] - {!push} *) + Note that an exception is thrown if Pop is called without a corresponding [Push] + {!push} *) val pop : fixedpoint -> unit (** Update named rule into in the fixedpoint solver. *) val update_rule : fixedpoint -> Expr.expr -> Symbol.symbol -> unit (** Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. *) + or definitions for the recursive predicates that show unsatisfiability. *) val get_answer : fixedpoint -> Expr.expr option (** Retrieve explanation why fixedpoint engine returned status Unknown. *) @@ -2844,7 +2836,7 @@ sig val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option (** Add property about the predicate. - The property is added at level. *) + The property is added at level. *) val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit (** Retrieve internal string representation of fixedpoint object. *) @@ -2871,7 +2863,7 @@ module SMT : sig (** Convert a benchmark into an SMT-LIB formatted string. - @return A string representation of the benchmark. *) + @return A string representation of the benchmark. *) val benchmark_to_smtstring : context -> string -> string -> string -> string -> Expr.expr list -> Expr.expr -> string (** Parse the given string using the SMT-LIB parser. @@ -2884,7 +2876,7 @@ sig val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit (** Parse the given file using the SMT-LIB parser. - {!parse_smtlib_string} *) + {!parse_smtlib_string} *) val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit (** The number of SMTLIB formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) @@ -2913,15 +2905,61 @@ sig (** Parse the given string using the SMT-LIB2 parser. - {!parse_smtlib_string} - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) + {!parse_smtlib_string} + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr (** Parse the given file using the SMT-LIB2 parser. - {!parse_smtlib2_string} *) + {!parse_smtlib2_string} *) val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr end +(** Interpolation *) +module Interpolation : +sig + + (** Create an AST node marking a formula position for interpolation. + The expression must have Boolean sort. *) + val mk_interpolant : context -> Expr.expr -> Expr.expr + + (** The interpolation context is suitable for generation of interpolants. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val mk_interpolation_context : (string * string) list -> context + + (** Gets an interpolant. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> AST.ASTVector.ast_vector + + (** Computes an interpolant. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val compute_interpolant : context -> Expr.expr -> Params.params -> (AST.ASTVector.ast_vector * Model.model) + + (** Retrieves an interpolation profile. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val get_interpolation_profile : context -> string + + (** Read an interpolation problem from file. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val read_interpolation_problem : context -> string -> (Expr.expr list * int list * Expr.expr list) + + (** Check the correctness of an interpolant. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val check_interpolant : context -> int -> Expr.expr list -> int list -> Expr.expr list -> int -> Expr.expr list -> unit + + (** Write an interpolation problem to file suitable for reading with + Z3_read_interpolation_problem. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val write_interpolation_problem : context -> int -> Expr.expr list -> int list -> string -> int -> Expr.expr list -> unit + +end + (** Set a global (or module) parameter, which is shared by all Z3 contexts. When a Z3 module is initialized it will use the value of these parameters @@ -2939,9 +2977,9 @@ end val set_global_param : string -> string -> unit (** Get a global (or module) parameter. - + Returns None if the parameter does not exist. - The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + The caller must invoke #Z3_global_param_del_value to delete the value returned at param_value. This function cannot be invoked simultaneously from different threads without synchronization. The result string stored in param_value is stored in a shared location. *) From 8b266cff529fd4412f3a879a1bf2aafadfee0fc9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 20:21:30 +0000 Subject: [PATCH 328/507] ML API: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b3c21b552..1f8bf9fd6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1361,6 +1361,10 @@ class MLComponent(Component): out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) + for f in filter(lambda f: f=='META', os.listdir(self.src_dir)): + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) + out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: @@ -1403,7 +1407,7 @@ class MLComponent(Component): # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs\n') + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/META\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) for m in modules: From 5f9d1af04ad9eda20b05c1e8d69adb1ad6482753 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 20:31:16 +0000 Subject: [PATCH 329/507] ML API build fix --- scripts/mk_util.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 1f8bf9fd6..6ef3df13c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1361,10 +1361,6 @@ class MLComponent(Component): out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) - for f in filter(lambda f: f=='META', os.listdir(self.src_dir)): - out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) - str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) - out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: From fcee69af4b6ea775d4acc5f2b61f5de853a99380 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 22:00:58 +0000 Subject: [PATCH 330/507] ML API build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 6ef3df13c..62078cf84 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1374,9 +1374,14 @@ class MLComponent(Component): out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/z3native_stubs$(OBJ_EXT): %s/z3native_stubs.c\n' % (sub_dir)); out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') + out.write('api/ml/libz3mldyn$(SO_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) + out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) From e11cc5a1f1a0f4be80ffe5b9c7e8886b2dc63837 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 13:45:49 +0000 Subject: [PATCH 331/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 98 ++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 62078cf84..90618edc3 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1366,58 +1366,80 @@ class MLComponent(Component): for m in modules: fn = os.path.join(self.src_dir, ('%s.mli' % m)) if not os.path.exists(fn): - out.write('%s.mli: %s.ml %s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) + out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) prev = prev + ' ' + os.path.join(sub_dir, m) + '.mli' cmis = '' for m in modules: - out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) + out.write('%s.cmi: %s.mli%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m), cmis)) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - out.write('api/ml/z3native_stubs$(OBJ_EXT): %s/z3native_stubs.c\n' % (sub_dir)); - out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) - out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') - out.write('api/ml/libz3mldyn$(SO_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) + + out.write('%s: %s %s\n' % + (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), + os.path.join(sub_dir, 'z3native_stubs.c'), + get_component(Z3_DLL_COMPONENT).dll_name+'$(SO_EXT)')); + out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % + (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) - out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(sub_dir, mlfile)) - out.write('\n') - out.write('\t%s ' % (OCAMLOPT)) - if DEBUG_MODE: - out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - out.write('\t%s ' % (OCAMLOPT)) - if DEBUG_MODE: - out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(sub_dir, mlfile)) - out.write('\n') - out.write('\t%s ' % (OCAMLC)) - if DEBUG_MODE: - out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) - out.write('\n') + # out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + # out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') + + # out.write('api/ml/libz3ml$(SO_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + # out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) + + + # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + + # for mlfile in get_ml_files(self.src_dir): + # out.write(' %s' % os.path.join(sub_dir, mlfile)) + # out.write('\n') + # out.write('\t%s ' % (OCAMLOPT)) + # if DEBUG_MODE: + # out.write('-g ') + # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + + # out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + # out.write('\t%s ' % (OCAMLOPT)) + # if DEBUG_MODE: + # out.write('-g ') + # out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + # for mlfile in get_ml_files(self.src_dir): + # out.write(' %s' % os.path.join(sub_dir, mlfile)) + # out.write('\n') + # out.write('\t%s ' % (OCAMLC)) + # if DEBUG_MODE: + # out.write('-g ') + # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + + out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) + for m in modules: + out.write(' %s.cmi' % (os.path.join(sub_dir, m))) + out.write(' %s.cmx' % (os.path.join(sub_dir, m))) + out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + out.write('%s/z3native_stubs.o\n' % (sub_dir)) + out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) + for m in modules: + out.write(' ' + m) + out.write('z3native_stubs$(OBJ_EXT) ; cd -' ) + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) + #out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/META\n') + out.write('\nocamlfind_install: api/ml/z3.cmxa api/ml/META\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) - out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) for m in modules: + out.write(' %s.cma' % (os.path.join(sub_dir, m))) + out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) + out.write(' %s.cmxx' % (os.path.join(sub_dir, m))) out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - if IS_WINDOWS: - out.write(' libz3$(LIB_EXT)') - out.write('\n') - out.write('\n') + out.write(' %s' % ((os.path.join(sub_dir, 'libz3$(LIB_EXT)')))) + out.write(' %s' % ((os.path.join(sub_dir, 'dllz3$(SO_EXT)')))) + out.write('\n\n') def main_component(self): return is_ml_enabled() From 7d577eeb71e26b488ef7437a36b80e46e370034e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 13:51:17 +0000 Subject: [PATCH 332/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 90618edc3..c4f780358 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1422,8 +1422,9 @@ class MLComponent(Component): out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: out.write(' ' + m) - out.write('z3native_stubs$(OBJ_EXT) ; cd -' ) - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) + out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) + # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) #out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) From 6e1e28dd58fbf0d60aa3b2c53c0c909c968deea6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 14:11:19 +0000 Subject: [PATCH 333/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c4f780358..6803e97e4 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1416,8 +1416,8 @@ class MLComponent(Component): out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) for m in modules: out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) + # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) out.write('%s/z3native_stubs.o\n' % (sub_dir)) out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: @@ -1435,11 +1435,15 @@ class MLComponent(Component): for m in modules: out.write(' %s.cma' % (os.path.join(sub_dir, m))) out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) - out.write(' %s.cmxx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) + out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) + out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s' % ((os.path.join(sub_dir, 'libz3$(LIB_EXT)')))) - out.write(' %s' % ((os.path.join(sub_dir, 'dllz3$(SO_EXT)')))) + out.write(' %s' % ((os.path.join(sub_dir, 'dllz3')))) + if IS_WINDOWS: + out.write('.lib') + else: + out.write('.so') # .so also on OSX! out.write('\n\n') def main_component(self): From b95ada16f32436b140da15853e8e2fc75a2e54e1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 14:14:14 +0000 Subject: [PATCH 334/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 6803e97e4..3d10468c0 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1418,7 +1418,7 @@ class MLComponent(Component): out.write(' %s.cmi' % (os.path.join(sub_dir, m))) # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) - out.write('%s/z3native_stubs.o\n' % (sub_dir)) + out.write(' %s/z3native_stubs.o\n' % (sub_dir)) out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: out.write(' ' + m) From c7b73c98a5cac51880ed224e8b42fcf7838a9e31 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 14:18:03 +0000 Subject: [PATCH 335/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 3d10468c0..6fdbdd2a3 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1421,7 +1421,7 @@ class MLComponent(Component): out.write(' %s/z3native_stubs.o\n' % (sub_dir)) out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: - out.write(' ' + m) + out.write(' %s.ml' % m) out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) From 5de8f880116c555cbfaef76917fac7710907ffa1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 15:03:10 +0000 Subject: [PATCH 336/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 6fdbdd2a3..c8bcd6e12 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1418,28 +1418,28 @@ class MLComponent(Component): out.write(' %s.cmi' % (os.path.join(sub_dir, m))) # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) - out.write(' %s/z3native_stubs.o\n' % (sub_dir)) - out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) + out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) + out.write('\tcd %s ; ocamlmklib -o z3ml' % (sub_dir)) for m in modules: out.write(' %s.ml' % m) out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) #out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('\nocamlfind_install: api/ml/z3.cmxa api/ml/META\n') + out.write('\nocamlfind_install: %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'META'))) out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) for m in modules: out.write(' %s.cma' % (os.path.join(sub_dir, m))) out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) + #out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - out.write(' %s' % ((os.path.join(sub_dir, 'libz3$(LIB_EXT)')))) - out.write(' %s' % ((os.path.join(sub_dir, 'dllz3')))) + out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) + out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) if IS_WINDOWS: out.write('.lib') else: From 1ce0cd3209131ee01e6ba8462f8aa21b12592905 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 15:38:15 +0000 Subject: [PATCH 337/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c8bcd6e12..c169a21f7 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1404,14 +1404,19 @@ class MLComponent(Component): # if DEBUG_MODE: # out.write('-g ') # out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - # for mlfile in get_ml_files(self.src_dir): - # out.write(' %s' % os.path.join(sub_dir, mlfile)) - # out.write('\n') - # out.write('\t%s ' % (OCAMLC)) - # if DEBUG_MODE: - # out.write('-g ') - # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('%s: %s %s$(SO_EXT) %s' % ( + os.path.join(sub_dir, 'z3.cma'), + os.path.join(sub_dir, 'libz3ml$(LIB_EXT)'), + get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + for mlfile in get_ml_files(self.src_dir): + out.write(' %s' % os.path.join(sub_dir, mlfile)) + out.write('\n') + out.write('\t%s ' % (OCAMLC)) + if DEBUG_MODE: + out.write('-g ') + out.write('-I %s -a -o %s -linkall' % (sub_dir, os.path.join(sub_dir, 'z3.cma'))) + for m in modules: + out.write(' %s.ml' % (os.path.join(sub_dir, m))) out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) for m in modules: From f0d66388d4af4c29531978473885d7296ea49ab9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 19:22:23 +0000 Subject: [PATCH 338/507] ML API: build fixes --- scripts/mk_util.py | 96 ++++++++++++++++++---------------------------- src/api/ml/META | 10 ++--- src/api/ml/z3.ml | 2 +- 3 files changed, 43 insertions(+), 65 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c169a21f7..caad10555 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1362,19 +1362,25 @@ class MLComponent(Component): str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! - prev = '' + mls = '' + mlis = '' + cmis = '' + archives = '' + for m in modules: fn = os.path.join(self.src_dir, ('%s.mli' % m)) if not os.path.exists(fn): - out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) + out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),mlis)) out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) - prev = prev + ' ' + os.path.join(sub_dir, m) + '.mli' - cmis = '' - for m in modules: out.write('%s.cmi: %s.mli%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m), cmis)) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) + out.write('%s.cma: %s.ml %s.cmi%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),os.path.join(sub_dir,m), archives)) + out.write('\t%s -a -o %s.ml -o %s.cma\n' % (OCAMLC,os.path.join(sub_dir,m), os.path.join(sub_dir,m))) + mlis = mlis + ' ' + os.path.join(sub_dir, m) + '.mli' cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - + archives = archives + ' ' + os.path.join(sub_dir,m) + '.cma' + mls = mls + ' ' + os.path.join(sub_dir, m) + '.ml' + out.write('%s: %s %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), os.path.join(sub_dir, 'z3native_stubs.c'), @@ -1382,73 +1388,43 @@ class MLComponent(Component): out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) - # out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - # out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') - - # out.write('api/ml/libz3ml$(SO_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - # out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) - - - # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - - # for mlfile in get_ml_files(self.src_dir): - # out.write(' %s' % os.path.join(sub_dir, mlfile)) - # out.write('\n') - # out.write('\t%s ' % (OCAMLOPT)) - # if DEBUG_MODE: - # out.write('-g ') - # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) - - # out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - # out.write('\t%s ' % (OCAMLOPT)) - # if DEBUG_MODE: - # out.write('-g ') - # out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - out.write('%s: %s %s$(SO_EXT) %s' % ( - os.path.join(sub_dir, 'z3.cma'), - os.path.join(sub_dir, 'libz3ml$(LIB_EXT)'), - get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(sub_dir, mlfile)) - out.write('\n') - out.write('\t%s ' % (OCAMLC)) - if DEBUG_MODE: - out.write('-g ') - out.write('-I %s -a -o %s -linkall' % (sub_dir, os.path.join(sub_dir, 'z3.cma'))) - for m in modules: - out.write(' %s.ml' % (os.path.join(sub_dir, m))) - - out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) - for m in modules: - out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + out.write('%s: %s %s %s$(SO_EXT)' % ( + os.path.join(sub_dir, "z3ml.cmxa"), + cmis, + archives, + get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tcd %s ; ocamlmklib -o z3ml' % (sub_dir)) + out.write('\tcd %s ; ocamlmklib -o z3ml -ldopt \'-L../.. -lz3\' ' % (sub_dir)) for m in modules: out.write(' %s.ml' % m) out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) - # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) - #out.write('\n') - # Generate META file and package installation commands + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('\nocamlfind_install: %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'META'))) + out.write('\nocamlfind_install: %s %s %s\n' % ( + get_component(Z3_DLL_COMPONENT).dll_name)+'$(SO_EXT)', + os.path.join(sub_dir, 'z3ml.cmxa'), + os.path.join(sub_dir, 'META'))) out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) for m in modules: out.write(' %s.cma' % (os.path.join(sub_dir, m))) - out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - #out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) out.write(' %s.cmi' % (os.path.join(sub_dir, m))) + out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + out.write(' %s.ml' % (os.path.join(sub_dir, m))) + out.write(' %s.mli' % (os.path.join(sub_dir, m))) + out.write(' %s$(OBJ_EXT)' % (os.path.join(sub_dir, m))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.a')))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cma')))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cmxa')))) out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) if IS_WINDOWS: out.write('.lib') else: out.write('.so') # .so also on OSX! + out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name) + '$(SO_EXT)')))) out.write('\n\n') def main_component(self): @@ -1572,25 +1548,25 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: api/ml/z3.cma ') + out.write('ml_example.byte: api/ml/z3ml.cma ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLC) if DEBUG_MODE: out.write('-g ') - out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3.cma') + out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3ml.cma') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example$(EXE_EXT): api/ml/z3.cmxa ml_example.byte') + out.write('ml_example$(EXE_EXT): api/ml/z3ml.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: out.write('-g ') - out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3.cmxa') + out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3ml.cmxa') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -3035,3 +3011,5 @@ def mk_unix_dist(build_path, dist_path): if __name__ == '__main__': import doctest doctest.testmod() + + diff --git a/src/api/ml/META b/src/api/ml/META index 6238403a3..8634b53b1 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -2,8 +2,8 @@ version = "VERSION" description = "Z3 Theorem Prover (OCaml API)" requires = "num" -archive(byte) = "z3.cma" -archive(native) = "z3.cmxa" -archive(byte, plugin) = "z3.cma" -archive(native, plugin) = "z3.cmxs" -linkopts = "-cclib -lz3" \ No newline at end of file +archive(byte) = "z3ml.cma" +archive(native) = "z3ml.cmxa" +archive(byte, plugin) = "z3ml.cma" +archive(native, plugin) = "z3ml.cmxs" +linkopts = "-cclib -lz3" diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 2b54a1113..350457525 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -110,7 +110,7 @@ struct string_of_int mj ^ "." ^ string_of_int mn ^ "." ^ string_of_int bld ^ "." ^ - string_of_int rev ^ "." + string_of_int rev end From 6022ae68737122ab1142f851c2328946e30e43d4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 19:42:03 +0000 Subject: [PATCH 339/507] ML API: build fixes? --- scripts/mk_util.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index caad10555..99f413090 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1394,16 +1394,18 @@ class MLComponent(Component): archives, get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tcd %s ; ocamlmklib -o z3ml -ldopt \'-L../.. -lz3\' ' % (sub_dir)) + out.write('\tocamlmklib -o %s -I %s -ldopt \'-L. -lz3\' ' % ( + os.path.join(sub_dir, 'z3ml'), + sub_dir)) for m in modules: - out.write(' %s.ml' % m) - out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') + out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) + out.write(' z3native_stubs$(OBJ_EXT)\n') out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': out.write('\nocamlfind_install: %s %s %s\n' % ( - get_component(Z3_DLL_COMPONENT).dll_name)+'$(SO_EXT)', - os.path.join(sub_dir, 'z3ml.cmxa'), + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)', + os.path.join(sub_dir, 'z3ml.cmxa'), os.path.join(sub_dir, 'META'))) out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) @@ -1424,7 +1426,7 @@ class MLComponent(Component): out.write('.lib') else: out.write('.so') # .so also on OSX! - out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name) + '$(SO_EXT)')))) + out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') out.write('\n\n') def main_component(self): From 0fee9659ab7e7df991778995baeb3bd7fbf9a8a5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 5 Dec 2014 16:40:40 +0000 Subject: [PATCH 340/507] ML API: Windows build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 99f413090..d2d9dd983 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1394,12 +1394,10 @@ class MLComponent(Component): archives, get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tocamlmklib -o %s -I %s -ldopt \'-L. -lz3\' ' % ( - os.path.join(sub_dir, 'z3ml'), - sub_dir)) + out.write('\tocamlmklib -o %s -I %s -ldopt \"-L. -lz3\" ' % (os.path.join(sub_dir, 'z3ml'), sub_dir)) for m in modules: out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) - out.write(' z3native_stubs$(OBJ_EXT)\n') + out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': @@ -1417,13 +1415,13 @@ class MLComponent(Component): out.write(' %s.ml' % (os.path.join(sub_dir, m))) out.write(' %s.mli' % (os.path.join(sub_dir, m))) out.write(' %s$(OBJ_EXT)' % (os.path.join(sub_dir, m))) - out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.a')))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml$(LIB_EXT)')))) out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cma')))) out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cmxa')))) out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) if IS_WINDOWS: - out.write('.lib') + out.write('.dll') else: out.write('.so') # .so also on OSX! out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') @@ -1550,7 +1548,7 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: api/ml/z3ml.cma ') + out.write('ml_example.byte: api/ml/z3ml.cmxa ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') From ae2c4d738c850cb9617179eaa567bac27ca1bd13 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 6 Dec 2014 18:14:26 +0000 Subject: [PATCH 341/507] ML API: build fix --- src/api/ml/META | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/api/ml/META b/src/api/ml/META index 8634b53b1..635de613c 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -4,6 +4,8 @@ description = "Z3 Theorem Prover (OCaml API)" requires = "num" archive(byte) = "z3ml.cma" archive(native) = "z3ml.cmxa" -archive(byte, plugin) = "z3ml.cma" -archive(native, plugin) = "z3ml.cmxs" +archive(byte,plugin) = "z3ml.cma" +archive(native,plugin) = "z3ml.cmxa" +archive(byte,toploop) = "z3ml.cma" +archive(native,toploop) = "z3ml.cmxa" linkopts = "-cclib -lz3" From ccffea2bc997e955e605da6fb7c4d43497e9fcf1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 6 Dec 2014 18:21:27 +0000 Subject: [PATCH 342/507] ML API: build fix --- examples/ml/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ml/README b/examples/ml/README index 844638552..c61716b65 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -15,7 +15,7 @@ for the byte-code version. If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), then we can compile this example as follows: -ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg ml_example.ml +ocamlfind ocamlc -o ml_example.byte -package Z3 -linkpkg ml_example.ml ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg ml_example.ml Note that the resulting binaries depend on the shared z3 library, which needs to be From decb09bb9ecc95c1e59c2381131f10e207d779e9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 6 Dec 2014 18:37:09 +0000 Subject: [PATCH 343/507] ML API: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d2d9dd983..5cfcbb4d3 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1425,6 +1425,8 @@ class MLComponent(Component): else: out.write('.so') # .so also on OSX! out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') + if IS_WINDOWS: + out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write('\n\n') def main_component(self): From 90cb04668447edc5414f218ab6ca42733de17c34 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 13:37:02 +0000 Subject: [PATCH 344/507] Beginnings of a new ML API Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 11 + scripts/update_api.py | 576 +++++++++++------------------------------- src/api/ml/README | 5 +- 3 files changed, 166 insertions(+), 426 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5cfcbb4d3..7a054256d 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1428,6 +1428,13 @@ class MLComponent(Component): if IS_WINDOWS: out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write('\n\n') + mk_dir(os.path.join(BUILD_DIR, 'api', 'ml')) + libfile = '%s$(LIB_EXT)' % self.lib_name + out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'z3_native.c'))) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) %s/z3_native.c\n' % self.to_src_dir) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'z3_native')) + out.write('ml: %s\n' % libfile) + out.write('\n') def main_component(self): return is_ml_enabled() @@ -1841,7 +1848,11 @@ def mk_config(): if GPROF: print('gprof: enabled') print('Python version: %s' % distutils.sysconfig.get_python_version()) +<<<<<<< HEAD print('ML API: %s' % is_ml_enabled()) +======= + print 'ML API: %s' % is_ml_enabled() +>>>>>>> Beginnings of a new ML API if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) diff --git a/scripts/update_api.py b/scripts/update_api.py index 4669b78fc..945496781 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -213,7 +213,10 @@ def type2javaw(ty): def type2ml(ty): global Type2ML - return Type2ML[ty] + if (ty >= FIRST_OBJ_ID): + return 'long' + else: + return Type2ML[ty] def _in(ty): return (IN, ty); @@ -1066,216 +1069,76 @@ def mk_bindings(): exe_c.write("}\n") def ml_method_name(name): - return name[3:] # Remove Z3_ - -def is_out_param(p): - if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_MANAGED_ARRAY: - return True - else: - return False - -def outparams(params): - op = [] - for param in params: - if is_out_param(param): - op.append(param) - return op - -def is_in_param(p): - if param_kind(p) == IN or param_kind(p) == INOUT or param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY: - return True - else: - return False - -def inparams(params): - ip = [] - for param in params: - if is_in_param(param): - ip.append(param) - return ip - -def is_array_param(p): - if param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_ARRAY: - return True - else: - return False - -def arrayparams(params): - op = [] - for param in params: - if is_array_param(param): - op.append(param) - return op - - -def ml_unwrap(t, ts, s): - if t == STRING: - return '(' + ts + ') String_val(' + s + ')' - elif t == BOOL: - return '(' + ts + ') Bool_val(' + s + ')' - elif t == INT or t == PRINT_MODE or t == ERROR_CODE: - return '(' + ts + ') Int_val(' + s + ')' - elif t == UINT: - return '(' + ts + ') Unsigned_int_val(' + s + ')' - elif t == INT64: - return '(' + ts + ') Long_val(' + s + ')' - elif t == UINT64: - return '(' + ts + ') Unsigned_long_val(' + s + ')' - elif t == DOUBLE: - return '(' + ts + ') Double_val(' + s + ')' - else: - return '* (' + ts + '*) Data_custom_val(' + s + ')' - -def ml_set_wrap(t, d, n): - if t == VOID: - return d + ' = Val_unit;' - elif t == BOOL: - return d + ' = Val_bool(' + n + ');' - elif t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: - return d + ' = Val_int(' + n + ');' - elif t == INT64 or t == UINT64: - return d + ' = Val_long(' + n + ');' - elif t == DOUBLE: - return 'Store_double_val(' + d + ', ' + n + ');' - elif t == STRING: - return d + ' = caml_copy_string((const char*) ' + n + ');' - else: - ts = type2str(t) - return d + ' = caml_alloc_custom(&default_custom_ops, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' + result = '' + name = name[3:] # Remove Z3_ + return result def mk_ml(): - global Type2Str if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'z3native.ml') - ml_nativefi = os.path.join(ml_dir, 'z3native.mli') - ml_wrapperf = os.path.join(ml_dir, 'z3native_stubs.c') + ml_nativef = os.path.join(ml_dir, 'z3_native.ml') + ml_wrapperf = os.path.join(ml_dir, 'z3_native.c') ml_native = open(ml_nativef, 'w') - ml_i = open(ml_nativefi, 'w') - ml_native.write('(* Automatically generated file *)\n\n') - ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') - ml_i.write('(* Automatically generated file *)\n\n') - ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') - ml_i.write('(**/**)\n\n'); - ml_native.write('open Z3enums\n\n') - ml_native.write('(**/**)\n') - ml_native.write('type ptr\n') - ml_i.write('type ptr\n') - ml_native.write('and z3_symbol = ptr\n') - ml_i.write('and z3_symbol = ptr\n') - for k, v in Type2Str.iteritems(): - if is_obj(k): - ml_native.write('and %s = ptr\n' % v.lower()) - ml_i.write('and %s = ptr\n' % v.lower()) + ml_native.write('// Automatically generated file\n') ml_native.write('\n') - ml_i.write('\n') - ml_native.write('external is_null : ptr -> bool\n = "n_is_null"\n\n') - ml_native.write('external mk_null : unit -> ptr\n = "n_mk_null"\n\n') - ml_native.write('external set_internal_error_handler : ptr -> unit\n = "n_set_internal_error_handler"\n\n') - ml_native.write('exception Exception of string\n\n') - ml_i.write('val is_null : ptr -> bool\n') - ml_i.write('val mk_null : unit -> ptr\n') - ml_i.write('val set_internal_error_handler : ptr -> unit\n\n') - ml_i.write('exception Exception of string\n\n') - - # ML declarations - ml_native.write('module ML2C = struct\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external n_%s : ' % ml_method_name(name)) - ml_i.write('val %s : ' % ml_method_name(name)) - ip = inparams(params) - op = outparams(params) - if len(ip) == 0: - ml_native.write(' unit -> ') - ml_i.write(' unit -> ') - for p in ip: - ml_native.write('%s -> ' % param2ml(p)) - ml_i.write('%s -> ' % param2ml(p)) - if len(op) > 0: - ml_native.write('(') - ml_i.write('(') + ml_native.write(' external %s : (' % ml_method_name(name)) first = True - if result != VOID or len(op) == 0: - ml_native.write('%s' % type2ml(result)) - ml_i.write('%s' % type2ml(result)) - first = False - for p in op: + i = 0; + for param in params: if first: first = False else: - ml_native.write(' * ') - ml_i.write(' * ') - ml_native.write('%s' % param2ml(p)) - ml_i.write('%s' % param2ml(p)) - if len(op) > 0: - ml_native.write(')') - ml_i.write(')') - ml_native.write('\n') - ml_i.write('\n') - if len(ip) > 5: - ml_native.write(' = "n_%s_bytecode"\n' % ml_method_name(name)) - ml_native.write(' "n_%s"\n' % ml_method_name(name)) - else: - ml_native.write(' = "n_%s"\n' % ml_method_name(name)) - ml_native.write('\n') - ml_native.write(' end\n\n') - ml_i.write('\n(**/**)\n'); - - # Exception wrappers - for name, result, params in _dotnet_decls: - ip = inparams(params) - op = outparams(params) - ml_native.write(' let %s ' % ml_method_name(name)) - - first = True - i = 0; - for p in params: - if is_in_param(p): - if first: - first = False; - else: - ml_native.write(' ') - ml_native.write('a%d' % i) + ml_native.write(', ') + ml_native.write('%s a%d' % (param2ml(param), i)) i = i + 1 - if len(ip) == 0: - ml_native.write('()') - ml_native.write(' = \n') - ml_native.write(' ') - if result == VOID and len(op) == 0: - ml_native.write('let _ = ') - else: - ml_native.write('let res = ') - ml_native.write('(ML2C.n_%s' % (ml_method_name(name))) - if len(ip) == 0: - ml_native.write(' ()') - first = True - i = 0; - for p in params: - if is_in_param(p): - ml_native.write(' a%d' % i) - i = i + 1 - ml_native.write(') in\n') - if name not in Unwrapped and len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (error_code_of_int (ML2C.n_get_error_code a0)) in \n') - ml_native.write(' if err <> OK then\n') - ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (int_of_error_code err)))\n') - ml_native.write(' else\n') - if result == VOID and len(op) == 0: - ml_native.write(' ()\n') - else: - ml_native.write(' res\n') - ml_native.write('\n') - ml_native.write('(**/**)\n') - - # C interface + ml_native.write('%s)\n' % (type2ml(result))) + # ml_native.write(' = "NATIVE_%s"' % ml_method_name(name)) + # ml_native.write('\n\n') + # # Exception wrappers + # for name, result, params in _dotnet_decls: + # java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) + # first = True + # i = 0; + # for param in params: + # if first: + # first = False + # else: + # java_native.write(', ') + # java_native.write('%s a%d' % (param2java(param), i)) + # i = i + 1 + # java_native.write(')') + # if len(params) > 0 and param_type(params[0]) == CONTEXT: + # java_native.write(' throws Z3Exception') + # java_native.write('\n') + # java_native.write(' {\n') + # java_native.write(' ') + # if result != VOID: + # java_native.write('%s res = ' % type2java(result)) + # java_native.write('INTERNAL%s(' % (java_method_name(name))) + # first = True + # i = 0; + # for param in params: + # if first: + # first = False + # else: + # java_native.write(', ') + # java_native.write('a%d' % i) + # i = i + 1 + # java_native.write(');\n') + # if len(params) > 0 and param_type(params[0]) == CONTEXT: + # java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') + # java_native.write(' if (err != Z3_error_code.Z3_OK)\n') + # java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') + # if result != VOID: + # java_native.write(' return res;\n') + # java_native.write(' }\n\n') + # java_native.write('}\n') ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') ml_wrapper.write('#include \n') - ml_wrapper.write('#include \n\n') - ml_wrapper.write('#ifdef __cplusplus\n') - ml_wrapper.write('extern "C" {\n') - ml_wrapper.write('#endif\n') + ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') @@ -1285,237 +1148,100 @@ def mk_ml(): ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') ml_wrapper.write('#endif\n') - ml_wrapper.write('#ifdef __cplusplus\n') - ml_wrapper.write('}\n') - ml_wrapper.write('#endif\n\n') - ml_wrapper.write('#include \n\n') - ml_wrapper.write('#define CAMLlocal6(X1,X2,X3,X4,X5,X6) \\\n') - ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal1(X6) \n') - ml_wrapper.write('#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \\\n') - ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal2(X6,X7) \n') - ml_wrapper.write('#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') - ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal3(X6,X7,X8) \n') - ml_wrapper.write('\n') - ml_wrapper.write('#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \\\n') - ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam2(X6,X7) \n') - ml_wrapper.write('#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') - ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam3(X6,X7,X8) \n') - ml_wrapper.write('#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \\\n') - ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9) \n') - ml_wrapper.write('#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \\\n') - ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') - ml_wrapper.write(' CAMLxparam2(X11,X12) \n') - ml_wrapper.write('#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \\\n') - ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') - ml_wrapper.write(' CAMLxparam3(X11,X12,X13) \n') - ml_wrapper.write('\n\n') - ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') - ml_wrapper.write(' (char*) "default handling",\n') - ml_wrapper.write(' custom_finalize_default,\n') - ml_wrapper.write(' custom_compare_default,\n') - ml_wrapper.write(' custom_hash_default,\n') - ml_wrapper.write(' custom_serialize_default,\n') - ml_wrapper.write(' custom_deserialize_default\n') - ml_wrapper.write('};\n\n') - ml_wrapper.write('#ifdef __cplusplus\n') - ml_wrapper.write('extern "C" {\n') - ml_wrapper.write('#endif\n\n') - ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') - ml_wrapper.write(' void * t = * (void**) Data_custom_val(p);\n') - ml_wrapper.write(' return Val_bool(t == 0);\n') - ml_wrapper.write('}\n\n') - ml_wrapper.write('CAMLprim value n_mk_null( void ) {\n') - ml_wrapper.write(' CAMLparam0();\n') - ml_wrapper.write(' CAMLlocal1(result);\n') - ml_wrapper.write(' void * z3_result = 0;\n') - ml_wrapper.write(' result = caml_alloc_custom(&default_custom_ops, sizeof(void*), 0, 1);\n') - ml_wrapper.write(' memcpy( Data_custom_val(result), &z3_result, sizeof(void*));\n') - ml_wrapper.write(' CAMLreturn (result);\n') - ml_wrapper.write('}\n\n') - ml_wrapper.write('void MLErrorHandler(Z3_context c, Z3_error_code e)\n') - ml_wrapper.write('{\n') - ml_wrapper.write(' // Internal do-nothing error handler. This is required to avoid that Z3 calls exit()\n') - ml_wrapper.write(' // upon errors, but the actual error handling is done by throwing exceptions in the\n') - ml_wrapper.write(' // wrappers below.\n') - ml_wrapper.write('}\n\n') - ml_wrapper.write('void n_set_internal_error_handler(value a0)\n') - ml_wrapper.write('{\n') - ml_wrapper.write(' Z3_context _a0 = * (Z3_context*) Data_custom_val(a0);\n') - ml_wrapper.write(' Z3_set_error_handler(_a0, MLErrorHandler);\n') - ml_wrapper.write('}\n\n') - for name, result, params in _dotnet_decls: - ip = inparams(params) - op = outparams(params) - ap = arrayparams(params) - ret_size = len(op) - if result != VOID: - ret_size = ret_size + 1 - - # Setup frame - ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) - first = True - i = 0 - for p in params: - if is_in_param(p): - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('value a%d' % i) - i = i + 1 - ml_wrapper.write(') {\n') - ml_wrapper.write(' CAMLparam%d(' % len(ip)) - i = 0 - first = True - for p in params: - if is_in_param(p): - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('a%d' % i) - i = i + 1 - ml_wrapper.write(');\n') - i = 0 - if len(op) + len(ap) == 0: - ml_wrapper.write(' CAMLlocal1(result);\n') - else: - c = 0 - for p in params: - if is_out_param(p) or is_array_param(p): - c = c + 1 - ml_wrapper.write(' CAMLlocal%s(result, res_val' % (c+2)) - for p in params: - if is_out_param(p) or is_array_param(p): - ml_wrapper.write(', _a%s_val' % i) - i = i + 1 - ml_wrapper.write(');\n') + # for name, result, params in _dotnet_decls: + # java_wrapper.write('JNIEXPORT %s JNICALL Java_%s_Native_INTERNAL%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), pkg_str, java_method_name(name))) + # i = 0; + # for param in params: + # java_wrapper.write(', ') + # java_wrapper.write('%s a%d' % (param2javaw(param), i)) + # i = i + 1 + # java_wrapper.write(') {\n') + # # preprocess arrays, strings, in/out arguments + # i = 0 + # for param in params: + # k = param_kind(param) + # if k == OUT or k == INOUT: + # java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) + # elif k == IN_ARRAY or k == INOUT_ARRAY: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) + # else: + # java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) + # elif k == OUT_ARRAY: + # java_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), + # i, + # type2str(param_type(param)), + # param_array_capacity_pos(param), + # type2str(param_type(param)))) + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + # else: + # java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) + # elif k == IN and param_type(param) == STRING: + # java_wrapper.write(' Z3_string _a%s = (Z3_string) jenv->GetStringUTFChars(a%s, NULL);\n' % (i, i)) + # i = i + 1 + # # invoke procedure + # java_wrapper.write(' ') + # if result != VOID: + # java_wrapper.write('%s result = ' % type2str(result)) + # java_wrapper.write('%s(' % name) + # i = 0 + # first = True + # for param in params: + # if first: + # first = False + # else: + # java_wrapper.write(', ') + # k = param_kind(param) + # if k == OUT or k == INOUT: + # java_wrapper.write('&_a%s' % i) + # elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: + # java_wrapper.write('_a%s' % i) + # elif k == IN and param_type(param) == STRING: + # java_wrapper.write('_a%s' % i) + # else: + # java_wrapper.write('(%s)a%i' % (param2str(param), i)) + # i = i + 1 + # java_wrapper.write(');\n') + # # cleanup + # i = 0 + # for param in params: + # k = param_kind(param) + # if k == OUT_ARRAY: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + # else: + # java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) + # java_wrapper.write(' free(_a%s);\n' % i) + # elif k == IN_ARRAY or k == OUT_ARRAY: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) + # else: + # java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) - if len(ap) != 0: - ml_wrapper.write(' unsigned _i;\n') - - # declare locals, preprocess arrays, strings, in/out arguments - i = 0 - for param in params: - k = param_kind(param) - if k == OUT_ARRAY: - ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * (_a%s));\n' % ( - type2str(param_type(param)), - i, - type2str(param_type(param)), - type2str(param_type(param)), - param_array_capacity_pos(param))) - elif k == OUT_MANAGED_ARRAY: - ml_wrapper.write(' %s * _a%s = 0;\n' % (type2str(param_type(param)), i)) - elif k == IN_ARRAY or k == INOUT_ARRAY: - t = param_type(param) - ts = type2str(t) - ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * _a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) - elif k == IN: - t = param_type(param) - ml_wrapper.write(' %s _a%s = %s;\n' % (type2str(t), i, ml_unwrap(t, type2str(t), 'a' + str(i)))) - elif k == OUT: - ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) - elif k == INOUT: - ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) - i = i + 1 - - if result != VOID: - ml_wrapper.write(' %s z3_result;\n' % type2str(result)) - - i = 0 - for param in params: - k = param_kind(param) - if k == IN_ARRAY or k == INOUT_ARRAY: - t = param_type(param) - ts = type2str(t) - ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { _a%s[_i] = %s; }\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', _i)'))) - i = i + 1 - - # invoke procedure - ml_wrapper.write(' ') - if result != VOID: - ml_wrapper.write('z3_result = ') - ml_wrapper.write('%s(' % name) - i = 0 - first = True - for param in params: - if first: - first = False - else: - ml_wrapper.write(', ') - k = param_kind(param) - if k == OUT or k == INOUT or k == OUT_MANAGED_ARRAY: - ml_wrapper.write('&_a%s' % i) - else: - ml_wrapper.write('_a%i' % i) - i = i + 1 - ml_wrapper.write(');\n') - - # convert output params - if len(op) > 0: - if result != VOID: - ml_wrapper.write(' %s\n' % ml_set_wrap(result, "res_val", "z3_result")) - i = 0; - for p in params: - if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: - ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) - ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s_val, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) - elif param_kind(p) == OUT_MANAGED_ARRAY: - ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) - elif is_out_param(p): - ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) - i = i + 1 - - # return tuples - if len(op) == 0: - ml_wrapper.write(' %s\n' % ml_set_wrap(result, "result", "z3_result")) - else: - ml_wrapper.write(' result = caml_alloc(%s, 0);\n' % ret_size) - i = j = 0 - if result != VOID: - ml_wrapper.write(' Store_field(result, 0, res_val);\n') - j = j + 1 - for p in params: - if is_out_param(p): - ml_wrapper.write(' Store_field(result, %s, _a%s_val);\n' % (j, i)) - j = j + 1; - i = i + 1 - - # local array cleanup - i = 0 - for p in params: - k = param_kind(p) - if k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: - ml_wrapper.write(' free(_a%s);\n' % i) - i = i + 1 - - # return - ml_wrapper.write(' CAMLreturn(result);\n') - ml_wrapper.write('}\n\n') - if len(ip) > 5: - ml_wrapper.write('CAMLprim value n_%s_bytecode(value * argv, int argn) {\n' % ml_method_name(name)) - ml_wrapper.write(' return n_%s(' % ml_method_name(name)) - i = 0 - while i < len(ip): - if i == 0: - ml_wrapper.write('argv[0]') - else: - ml_wrapper.write(', argv[%s]' % i) - i = i + 1 - ml_wrapper.write(');\n}\n') - ml_wrapper.write('\n\n') - ml_wrapper.write('#ifdef __cplusplus\n') - ml_wrapper.write('}\n') - ml_wrapper.write('#endif\n') + # elif k == OUT or k == INOUT: + # if param_type(param) == INT or param_type(param) == UINT: + # java_wrapper.write(' {\n') + # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') + # java_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) + # java_wrapper.write(' }\n') + # else: + # java_wrapper.write(' {\n') + # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') + # java_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) + # java_wrapper.write(' }\n') + # i = i + 1 + # # return + # if result == STRING: + # java_wrapper.write(' return jenv->NewStringUTF(result);\n') + # elif result != VOID: + # java_wrapper.write(' return (%s) result;\n' % type2javaw(result)) + # java_wrapper.write('}\n') + # java_wrapper.write('#ifdef __cplusplus\n') + # java_wrapper.write('}\n') + # java_wrapper.write('#endif\n') if is_verbose(): print "Generated '%s'" % ml_nativef diff --git a/src/api/ml/README b/src/api/ml/README index beee7d864..f8984c79e 100644 --- a/src/api/ml/README +++ b/src/api/ml/README @@ -1,8 +1,11 @@ This directory is work in progress. We are currently working on a brand new ML API. +<<<<<<< HEAD On Windows, there are no less than four different ports of OCaml. The Z3 build system assumes that either the win32 or the win64 port is installed. This means that OCaml will use `cl' as the underlying C compiler and not the cygwin or -mingw compilers. \ No newline at end of file +mingw compilers. +======= +>>>>>>> Beginnings of a new ML API From 1579da02b0e49c079afe95df9fb7b36f32b9dc2a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 15:07:33 +0000 Subject: [PATCH 345/507] More new ML API Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 9 ++-- scripts/mk_util.py | 25 +++++++++ scripts/update_api.py | 121 ++++++++++++++++++++++++------------------ 3 files changed, 99 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 9c9707c4b..2ae719b85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,5 @@ *~ *.pyc -*.pyo -# Ignore callgrind files -callgrind.out.* # .hpp files are automatically generated *.hpp .z3-trace @@ -45,6 +42,7 @@ bld_rel_x64/* # Auto generated files. config.log config.status +configure install_tactic.cpp mem_initializer.cpp gparams_register_modules.cpp @@ -56,8 +54,6 @@ src/api/api_log_macros.cpp src/api/dll/api_dll.def src/api/dotnet/Enumerations.cs src/api/dotnet/Native.cs -src/api/dotnet/Properties/AssemblyInfo.cs -src/api/dotnet/Microsoft.Z3.xml src/api/python/z3consts.py src/api/python/z3core.py src/ast/pattern/database.h @@ -78,3 +74,6 @@ src/api/ml/z3native_stubs.c src/api/ml/z3native.ml src/api/ml/z3enums.ml src/api/ml/z3.mllib +src/api/ml/z3_native.c +src/api/ml/z3_native.ml +src/api/ml/z3_enums.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 7a054256d..d019e24e9 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2431,6 +2431,8 @@ def mk_bindings(api_files): mk_z3consts_ml(api_files) _execfile(os.path.join('scripts', 'update_api.py'), g) # HACK cp_z3py_to_build() + if is_ml_enabled(): + mk_z3consts_ml(api_files) # Extract enumeration types from API files, and add python definitions. def mk_z3consts_py(api_files): @@ -2718,6 +2720,7 @@ def mk_z3consts_ml(api_files): if not os.path.exists(gendir): os.mkdir(gendir) +<<<<<<< HEAD efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') efile.write('(** The enumeration types of Z3. *)\n\n') @@ -2799,6 +2802,13 @@ def mk_z3consts_ml(api_files): efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') efile.write('(** The enumeration types of Z3. *)\n\n') +======= + efile = open('%s.ml' % os.path.join(gendir, "z3_enums"), 'w') + efile.write('(* Automatically generated file *)\n\n') + # efile.write('module z3_enums = struct\n\n'); + + +>>>>>>> More new ML API for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) @@ -2844,6 +2854,7 @@ def mk_z3consts_ml(api_files): if m: name = words[1] if name not in DeprecatedEnums: +<<<<<<< HEAD efile.write('(** %s *)\n' % name[3:]) efile.write('type %s =\n' % name[3:]) # strip Z3_ for k, i in decls.iteritems(): @@ -2854,6 +2865,13 @@ def mk_z3consts_ml(api_files): efile.write('(** Convert int to %s*)\n' % name[3:]) efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_ efile.write('\n') +======= + efile.write('\n(* %s *)\n' % name) + efile.write('type %s =\n' % name[3:]) # strip Z3_ + efile.write + for k, i in decls.iteritems(): + efile.write(' | %s \n' % k[3:]) # strip Z3_ +>>>>>>> More new ML API mode = SEARCHING else: if words[2] != '': @@ -2864,8 +2882,15 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 +<<<<<<< HEAD if VERBOSE: print "Generated '%s/z3enums.mli'" % ('%s' % gendir) +======= + efile.write('\n') + # efile.write'end\n'); + if VERBOSE: + print "Generated '%s/z3_enums.ml'" % ('%s' % gendir) +>>>>>>> More new ML API def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 945496781..c1bb22a44 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -157,9 +157,9 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint'} # Mapping to ML types -Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', - STRING : 'string', STRING_PTR : 'char**', - BOOL : 'bool', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } +Type2ML = { VOID : 'unit', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', + STRING : 'string', STRING_PTR : 'char**', + BOOL : 'lbool', SYMBOL : 'symbol', PRINT_MODE : 'ast_print_mode', ERROR_CODE : 'error_code' } next_type_id = FIRST_OBJ_ID @@ -1069,9 +1069,7 @@ def mk_bindings(): exe_c.write("}\n") def ml_method_name(name): - result = '' - name = name[3:] # Remove Z3_ - return result + return name[3:] # Remove Z3_ def mk_ml(): if not is_ml_enabled(): @@ -1080,10 +1078,57 @@ def mk_ml(): ml_nativef = os.path.join(ml_dir, 'z3_native.ml') ml_wrapperf = os.path.join(ml_dir, 'z3_native.c') ml_native = open(ml_nativef, 'w') - ml_native.write('// Automatically generated file\n') + ml_native.write('(* Automatically generated file *)\n') ml_native.write('\n') + ml_native.write('module Z3 = struct\n\n') + ml_native.write('type context\n') + ml_native.write('and symbol\n') + ml_native.write('and ast\n') + ml_native.write('and sort = private ast\n') + ml_native.write('and func_decl = private ast\n') + ml_native.write('and app = private ast\n') + ml_native.write('and pattern = private ast\n') + ml_native.write('and params\n') + ml_native.write('and param_descrs\n') + ml_native.write('and model\n') + ml_native.write('and func_interp\n') + ml_native.write('and func_entry\n') + ml_native.write('and fixedpoint\n') + ml_native.write('and ast_vector\n') + ml_native.write('and ast_map\n') + ml_native.write('and goal\n') + ml_native.write('and tactic\n') + ml_native.write('and probe\n') + ml_native.write('and apply_result\n') + ml_native.write('and solver\n') + ml_native.write('and stats\n') + ml_native.write('\n') + ml_native.write(' exception Z3Exception of string\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external %s : (' % ml_method_name(name)) + ml_native.write(' external native_%s : ' % ml_method_name(name)) + i = 0; + for param in params: + ml_native.write('%s -> ' % param2ml(param)) + i = i + 1 + ml_native.write('%s\n' % (type2ml(result))) + ml_native.write(' = "Native_Z3_%s"\n\n' % ml_method_name(name)) + # Exception wrappers + for name, result, params in _dotnet_decls: + ml_native.write(' let %s ' % ml_method_name(name)) + first = True + i = 0; + for param in params: + if first: + first = False; + else: + ml_native.write(' ') + ml_native.write('a%d' % i) + i = i + 1 + ml_native.write(' = \n') + ml_native.write(' ') + if result != VOID: + ml_native.write('let res = ') + ml_native.write('n_%s(' % (ml_method_name(name))) first = True i = 0; for param in params: @@ -1091,50 +1136,24 @@ def mk_ml(): first = False else: ml_native.write(', ') - ml_native.write('%s a%d' % (param2ml(param), i)) + ml_native.write('a%d' % i) i = i + 1 - ml_native.write('%s)\n' % (type2ml(result))) - # ml_native.write(' = "NATIVE_%s"' % ml_method_name(name)) - # ml_native.write('\n\n') - # # Exception wrappers - # for name, result, params in _dotnet_decls: - # java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) - # first = True - # i = 0; - # for param in params: - # if first: - # first = False - # else: - # java_native.write(', ') - # java_native.write('%s a%d' % (param2java(param), i)) - # i = i + 1 - # java_native.write(')') - # if len(params) > 0 and param_type(params[0]) == CONTEXT: - # java_native.write(' throws Z3Exception') - # java_native.write('\n') - # java_native.write(' {\n') - # java_native.write(' ') - # if result != VOID: - # java_native.write('%s res = ' % type2java(result)) - # java_native.write('INTERNAL%s(' % (java_method_name(name))) - # first = True - # i = 0; - # for param in params: - # if first: - # first = False - # else: - # java_native.write(', ') - # java_native.write('a%d' % i) - # i = i + 1 - # java_native.write(');\n') - # if len(params) > 0 and param_type(params[0]) == CONTEXT: - # java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') - # java_native.write(' if (err != Z3_error_code.Z3_OK)\n') - # java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') - # if result != VOID: - # java_native.write(' return res;\n') - # java_native.write(' }\n\n') - # java_native.write('}\n') + ml_native.write(')') + if result != VOID: + ml_native.write(' in\n') + else: + ml_native.write(';\n') + if len(params) > 0 and param_type(params[0]) == CONTEXT: + ml_native.write(' let err = error_code.fromInt(n_get_error_code(a0)) in \n') + ml_native.write(' if err <> Z3_enums.OK then\n') + ml_native.write(' raise (z3_exception n_get_error_msg_ex(a0, err.toInt()))\n') + ml_native.write(' else\n') + if result == VOID: + ml_native.write(' ()\n') + else: + ml_native.write(' res\n') + ml_native.write('\n') + ml_native.write('\nend\n') ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') ml_wrapper.write('#include \n') From a40433aae85d0b181c355c9861cf95b163c9d422 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 16:35:39 +0000 Subject: [PATCH 346/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 3 + scripts/mk_util.py | 6 +- scripts/update_api.py | 211 +++++++++++++++++++++++------------------- src/api/ml/Makefile | 10 -- 4 files changed, 120 insertions(+), 110 deletions(-) delete mode 100644 src/api/ml/Makefile diff --git a/.gitignore b/.gitignore index 2ae719b85..a3fa5e919 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,7 @@ src/util/version.h src/api/java/Native.cpp src/api/java/Native.java src/api/java/enumerations/*.java + *.bak doc/api doc/code @@ -76,4 +77,6 @@ src/api/ml/z3enums.ml src/api/ml/z3.mllib src/api/ml/z3_native.c src/api/ml/z3_native.ml +src/api/ml/native.c +src/api/ml/Z3.ml src/api/ml/z3_enums.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d019e24e9..d324e5206 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1430,9 +1430,9 @@ class MLComponent(Component): out.write('\n\n') mk_dir(os.path.join(BUILD_DIR, 'api', 'ml')) libfile = '%s$(LIB_EXT)' % self.lib_name - out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'z3_native.c'))) - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) %s/z3_native.c\n' % self.to_src_dir) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'z3_native')) + out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) -I%s %s/native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'native')) out.write('ml: %s\n' % libfile) out.write('\n') diff --git a/scripts/update_api.py b/scripts/update_api.py index c1bb22a44..72fd32702 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1075,12 +1075,12 @@ def mk_ml(): if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'z3_native.ml') - ml_wrapperf = os.path.join(ml_dir, 'z3_native.c') + ml_nativef = os.path.join(ml_dir, 'Z3.ml') + ml_wrapperf = os.path.join(ml_dir, 'native.c') ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n') ml_native.write('\n') - ml_native.write('module Z3 = struct\n\n') + ml_native.write('module Z3Native = struct\n\n') ml_native.write('type context\n') ml_native.write('and symbol\n') ml_native.write('and ast\n') @@ -1166,101 +1166,118 @@ def mk_ml(): ml_wrapper.write('#ifdef Custom_tag\n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') - ml_wrapper.write('#endif\n') - # for name, result, params in _dotnet_decls: - # java_wrapper.write('JNIEXPORT %s JNICALL Java_%s_Native_INTERNAL%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), pkg_str, java_method_name(name))) - # i = 0; - # for param in params: - # java_wrapper.write(', ') - # java_wrapper.write('%s a%d' % (param2javaw(param), i)) - # i = i + 1 - # java_wrapper.write(') {\n') - # # preprocess arrays, strings, in/out arguments - # i = 0 - # for param in params: - # k = param_kind(param) - # if k == OUT or k == INOUT: - # java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) - # elif k == IN_ARRAY or k == INOUT_ARRAY: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) - # else: - # java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) - # elif k == OUT_ARRAY: - # java_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), - # i, - # type2str(param_type(param)), - # param_array_capacity_pos(param), - # type2str(param_type(param)))) - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - # else: - # java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) - # elif k == IN and param_type(param) == STRING: - # java_wrapper.write(' Z3_string _a%s = (Z3_string) jenv->GetStringUTFChars(a%s, NULL);\n' % (i, i)) - # i = i + 1 - # # invoke procedure - # java_wrapper.write(' ') - # if result != VOID: - # java_wrapper.write('%s result = ' % type2str(result)) - # java_wrapper.write('%s(' % name) - # i = 0 - # first = True - # for param in params: - # if first: - # first = False - # else: - # java_wrapper.write(', ') - # k = param_kind(param) - # if k == OUT or k == INOUT: - # java_wrapper.write('&_a%s' % i) - # elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: - # java_wrapper.write('_a%s' % i) - # elif k == IN and param_type(param) == STRING: - # java_wrapper.write('_a%s' % i) - # else: - # java_wrapper.write('(%s)a%i' % (param2str(param), i)) - # i = i + 1 - # java_wrapper.write(');\n') - # # cleanup - # i = 0 - # for param in params: - # k = param_kind(param) - # if k == OUT_ARRAY: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - # else: - # java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) - # java_wrapper.write(' free(_a%s);\n' % i) - # elif k == IN_ARRAY or k == OUT_ARRAY: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) - # else: - # java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) + ml_wrapper.write('#endif\n\n') + ml_wrapper.write('#include \n\n') + for name, result, params in _dotnet_decls: + #return type = type2ml(result) + ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) + first = True + i = 0 + for param in params: + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('value a%d' % i) + # param type = param2ml(param) + i = i + 1 + ml_wrapper.write(') {\n') + ml_wrapper.write(' CAMLparam%d(' % len(params)) + i = 0 + first = True + for param in params: + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('a%d' % i) + i = i + 1 + ml_wrapper.write(');\n') + # preprocess arrays, strings, in/out arguments + i = 0 + for param in params: + k = param_kind(param) + if k == OUT or k == INOUT: + ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) + elif k == IN_ARRAY or k == INOUT_ARRAY: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) + else: + ml_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) + elif k == OUT_ARRAY: + ml_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), + i, + type2str(param_type(param)), + param_array_capacity_pos(param), + type2str(param_type(param)))) + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + else: + ml_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) + elif k == IN and param_type(param) == STRING: + ml_wrapper.write(' Z3_string _a%s = (Z3_string) String_val(a%s);\n' % (i, i)) + i = i + 1 + # invoke procedure + ml_wrapper.write(' ') + if result != VOID: + ml_wrapper.write('%s result = ' % type2str(result)) + ml_wrapper.write('%s(' % name) + i = 0 + first = True + for param in params: + if first: + first = False + else: + ml_wrapper.write(', ') + k = param_kind(param) + if k == OUT or k == INOUT: + ml_wrapper.write('&_a%s' % i) + elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: + ml_wrapper.write('_a%s' % i) + elif k == IN and param_type(param) == STRING: + ml_wrapper.write('_a%s' % i) + else: + ml_wrapper.write('(%s)a%i' % (param2str(param), i)) + i = i + 1 + ml_wrapper.write(');\n') + # cleanup + i = 0 + for param in params: + k = param_kind(param) + if k == OUT_ARRAY: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + else: + ml_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) + ml_wrapper.write(' free(_a%s);\n' % i) + elif k == IN_ARRAY or k == OUT_ARRAY: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) + else: + ml_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) - # elif k == OUT or k == INOUT: - # if param_type(param) == INT or param_type(param) == UINT: - # java_wrapper.write(' {\n') - # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') - # java_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) - # java_wrapper.write(' }\n') - # else: - # java_wrapper.write(' {\n') - # java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - # java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') - # java_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) - # java_wrapper.write(' }\n') - # i = i + 1 - # # return - # if result == STRING: - # java_wrapper.write(' return jenv->NewStringUTF(result);\n') - # elif result != VOID: - # java_wrapper.write(' return (%s) result;\n' % type2javaw(result)) - # java_wrapper.write('}\n') - # java_wrapper.write('#ifdef __cplusplus\n') - # java_wrapper.write('}\n') - # java_wrapper.write('#endif\n') + elif k == OUT or k == INOUT: + if param_type(param) == INT or param_type(param) == UINT: + ml_wrapper.write(' {\n') + ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') + ml_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) + ml_wrapper.write(' }\n') + else: + ml_wrapper.write(' {\n') + ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) + ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') + ml_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) + ml_wrapper.write(' }\n') + i = i + 1 + # return + if result == STRING: + ml_wrapper.write(' return caml_copy_string(result);\n') + elif result == VOID: + ml_wrapper.write(' CAMLreturn(Val_unit);\n') + elif result != VOID: + ml_wrapper.write(' return (value) result;\n') + ml_wrapper.write('}\n\n') if is_verbose(): print "Generated '%s'" % ml_nativef diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile deleted file mode 100644 index 96fd0a55d..000000000 --- a/src/api/ml/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# This is a temporary support file for emacs annotations. -# It does not compile the Z3 ML API; this will be built -# in the top-level build directory. - -all: - ocamlbuild -cflag -annot z3.cmxa - -doc: *.ml - mkdir -p doc - ocamldoc -html -d doc -I _build -sort *.mli -hide Z3 From dcd6f1f69736ace570ead5e544b670dfa0a1b42c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 11 Dec 2012 21:39:52 +0000 Subject: [PATCH 347/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 4 +-- scripts/mk_util.py | 44 ++++++++++++++++++++++++++++++--- scripts/update_api.py | 57 ++++++++++++++++++++++++------------------- 3 files changed, 75 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index a3fa5e919..a1a8b7f6b 100644 --- a/.gitignore +++ b/.gitignore @@ -78,5 +78,5 @@ src/api/ml/z3.mllib src/api/ml/z3_native.c src/api/ml/z3_native.ml src/api/ml/native.c -src/api/ml/Z3.ml -src/api/ml/z3_enums.ml +src/api/ml/z3.ml +src/api/ml/enumerations.ml diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d324e5206..bd6495d1b 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1428,9 +1428,17 @@ class MLComponent(Component): if IS_WINDOWS: out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write('\n\n') - mk_dir(os.path.join(BUILD_DIR, 'api', 'ml')) + bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') + mk_dir(bld_dir) libfile = '%s$(LIB_EXT)' % self.lib_name - out.write('%s: libz3$(SO_EXT) %s\n' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) + for mlfile in get_ml_files(self.src_dir): + out.write('%si: %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) + out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) + out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) + out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) + for mlfile in get_ml_files(self.src_dir): + out.write(' %si' % os.path.join('api','ml', mlfile)) + out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) -I%s %s/native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'native')) out.write('ml: %s\n' % libfile) @@ -2720,6 +2728,7 @@ def mk_z3consts_ml(api_files): if not os.path.exists(gendir): os.mkdir(gendir) +<<<<<<< HEAD <<<<<<< HEAD efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') @@ -2809,6 +2818,11 @@ def mk_z3consts_ml(api_files): >>>>>>> More new ML API +======= + efile = open('%s.ml' % os.path.join(gendir, "enumerations"), 'w') + efile.write('(* Automatically generated file *)\n\n') + efile.write('module Enumerations = struct\n') +>>>>>>> More ML API for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) @@ -2854,6 +2868,7 @@ def mk_z3consts_ml(api_files): if m: name = words[1] if name not in DeprecatedEnums: +<<<<<<< HEAD <<<<<<< HEAD efile.write('(** %s *)\n' % name[3:]) efile.write('type %s =\n' % name[3:]) # strip Z3_ @@ -2867,11 +2882,28 @@ def mk_z3consts_ml(api_files): efile.write('\n') ======= efile.write('\n(* %s *)\n' % name) +======= +>>>>>>> More ML API efile.write('type %s =\n' % name[3:]) # strip Z3_ - efile.write for k, i in decls.iteritems(): +<<<<<<< HEAD efile.write(' | %s \n' % k[3:]) # strip Z3_ >>>>>>> More new ML API +======= + efile.write(' | %s \n' % k[3:]) # strip Z3_ + efile.write('\n') + efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ + efile.write(' match x with\n') + for k, i in decls.iteritems(): + efile.write(' | %s -> %d\n' % (k[3:], i)) + efile.write('\n') + efile.write('let int2%s x : %s =\n' % (name[3:],name[3:])) # strip Z3_ + efile.write(' match x with\n') + for k, i in decls.iteritems(): + efile.write(' | %d -> %s\n' % (i, k[3:])) + # use Z3.Exception? + efile.write(' | _ -> raise (Failure "undefined enum value")\n\n') +>>>>>>> More ML API mode = SEARCHING else: if words[2] != '': @@ -2882,6 +2914,7 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 +<<<<<<< HEAD <<<<<<< HEAD if VERBOSE: print "Generated '%s/z3enums.mli'" % ('%s' % gendir) @@ -2891,6 +2924,11 @@ def mk_z3consts_ml(api_files): if VERBOSE: print "Generated '%s/z3_enums.ml'" % ('%s' % gendir) >>>>>>> More new ML API +======= + efile.write('end\n') + if VERBOSE: + print "Generated '%s/enumerations.ml'" % ('%s' % gendir) +>>>>>>> More ML API def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 72fd32702..971e6eab1 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -157,9 +157,9 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint'} # Mapping to ML types -Type2ML = { VOID : 'unit', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double', - STRING : 'string', STRING_PTR : 'char**', - BOOL : 'lbool', SYMBOL : 'symbol', PRINT_MODE : 'ast_print_mode', ERROR_CODE : 'error_code' } +Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', + STRING : 'string', STRING_PTR : 'char**', + BOOL : 'int', SYMBOL : 'symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -214,7 +214,7 @@ def type2javaw(ty): def type2ml(ty): global Type2ML if (ty >= FIRST_OBJ_ID): - return 'long' + return 'int' else: return Type2ML[ty] @@ -331,6 +331,8 @@ def param2ml(p): if k == OUT: if param_type(p) == INT or param_type(p) == UINT or param_type(p) == INT64 or param_type(p) == UINT64: return "int" + elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: + return "int" elif param_type(p) == STRING: return "string" else: @@ -1075,12 +1077,12 @@ def mk_ml(): if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'Z3.ml') + ml_nativef = os.path.join(ml_dir, 'z3.ml') ml_wrapperf = os.path.join(ml_dir, 'native.c') ml_native = open(ml_nativef, 'w') - ml_native.write('(* Automatically generated file *)\n') - ml_native.write('\n') - ml_native.write('module Z3Native = struct\n\n') + ml_native.write('(* Automatically generated file *)\n\n') + ml_native.write('open Enumerations\n\n') + ml_native.write('module Z3 = struct\n\n') ml_native.write('type context\n') ml_native.write('and symbol\n') ml_native.write('and ast\n') @@ -1103,15 +1105,17 @@ def mk_ml(): ml_native.write('and solver\n') ml_native.write('and stats\n') ml_native.write('\n') - ml_native.write(' exception Z3Exception of string\n\n') + ml_native.write(' exception Exception of string\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external native_%s : ' % ml_method_name(name)) + ml_native.write(' external n_%s : ' % ml_method_name(name)) i = 0; for param in params: ml_native.write('%s -> ' % param2ml(param)) i = i + 1 + if len(params) == 0: + ml_native.write(' unit -> ') ml_native.write('%s\n' % (type2ml(result))) - ml_native.write(' = "Native_Z3_%s"\n\n' % ml_method_name(name)) + ml_native.write(' = "n_%s"\n\n' % ml_method_name(name)) # Exception wrappers for name, result, params in _dotnet_decls: ml_native.write(' let %s ' % ml_method_name(name)) @@ -1128,25 +1132,28 @@ def mk_ml(): ml_native.write(' ') if result != VOID: ml_native.write('let res = ') - ml_native.write('n_%s(' % (ml_method_name(name))) - first = True - i = 0; - for param in params: - if first: - first = False - else: - ml_native.write(', ') - ml_native.write('a%d' % i) - i = i + 1 - ml_native.write(')') + if len(params) == 0: + ml_native.write('n_%s()' % (ml_method_name(name))) + else: + ml_native.write('(n_%s ' % (ml_method_name(name))) + first = True + i = 0; + for param in params: + if first: + first = False + else: + ml_native.write(' ') + ml_native.write('a%d' % i) + i = i + 1 + ml_native.write(')') if result != VOID: ml_native.write(' in\n') else: ml_native.write(';\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = error_code.fromInt(n_get_error_code(a0)) in \n') - ml_native.write(' if err <> Z3_enums.OK then\n') - ml_native.write(' raise (z3_exception n_get_error_msg_ex(a0, err.toInt()))\n') + ml_native.write(' let err = (Enumerations.int2error_code (n_get_error_code a0)) in \n') + ml_native.write(' if err <> Enumerations.OK then\n') + ml_native.write(' raise (Exception (n_get_error_msg_ex a0 (error_code2int err)))\n') ml_native.write(' else\n') if result == VOID: ml_native.write(' ()\n') From c4f07c7fd179313ff57b73b7336e64bc39854aa3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 04:34:36 +0000 Subject: [PATCH 348/507] New native ML API layer. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 36 ++-- scripts/update_api.py | 400 +++++++++++++++++++++++++++--------------- 2 files changed, 289 insertions(+), 147 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index bd6495d1b..33129f555 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1428,20 +1428,30 @@ class MLComponent(Component): if IS_WINDOWS: out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write('\n\n') + deffile = open('%s.mllib' % os.path.join(self.src_dir, "z3"), 'w') + for mlfile in get_ml_files(self.src_dir): + deffile.write('%s\n' % (string.upper(mlfile[0]) + mlfile[1:-3])) + deffile.close() bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') mk_dir(bld_dir) - libfile = '%s$(LIB_EXT)' % self.lib_name + libfile = '%s$(SO_EXT)' % self.lib_name + # for mlfile in get_ml_files(self.src_dir): + # out.write('%si: libz3$(SO_EXT) %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) + # out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) + # out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) + out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) for mlfile in get_ml_files(self.src_dir): - out.write('%si: %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) - out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) - out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) - out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'native.c'))) - for mlfile in get_ml_files(self.src_dir): - out.write(' %si' % os.path.join('api','ml', mlfile)) + out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3_native$(OBJ_EXT) -I%s %s/native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3ml$(LIB_EXT) $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % os.path.join('api', 'ml', 'native')) - out.write('ml: %s\n' % libfile) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + out.write('z3.cmxa: %s\n' % libfile) + out.write('\tcd %s && ocamlbuild -lflags -cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cmxa && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) + out.write('\tcp api/ml/z3.cmxa .\n') + out.write('z3.cma: %s\n' % libfile) + out.write('\tcd %s && ocamlbuild -lflags -custom,-cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) + out.write('\tcp api/ml/z3.cma .\n') + out.write('ml: z3.cmxa z3.cma\n') out.write('\n') def main_component(self): @@ -2728,6 +2738,7 @@ def mk_z3consts_ml(api_files): if not os.path.exists(gendir): os.mkdir(gendir) +<<<<<<< HEAD <<<<<<< HEAD <<<<<<< HEAD efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') @@ -2823,6 +2834,11 @@ def mk_z3consts_ml(api_files): efile.write('(* Automatically generated file *)\n\n') efile.write('module Enumerations = struct\n') >>>>>>> More ML API +======= + efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') + efile.write('(* Automatically generated file *)\n\n') + efile.write('module Z3enums = struct\n') +>>>>>>> New native ML API layer. for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) diff --git a/scripts/update_api.py b/scripts/update_api.py index 971e6eab1..f142c8ec1 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1073,98 +1073,145 @@ def mk_bindings(): def ml_method_name(name): return name[3:] # Remove Z3_ +def is_out_param(p): + if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: + return True + else: + return False + +def outparams(params): + op = [] + for param in params: + if is_out_param(param): + op.append(param) + return op + +def is_in_param(p): + if param_kind(p) == IN or param_kind(p) == INOUT or param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY: + return True + else: + return False + +def inparams(params): + ip = [] + for param in params: + if is_in_param(param): + ip.append(param) + return ip + +def is_array_param(p): + if param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_ARRAY: + return True + else: + return False + def mk_ml(): if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir - ml_nativef = os.path.join(ml_dir, 'z3.ml') - ml_wrapperf = os.path.join(ml_dir, 'native.c') + ml_nativef = os.path.join(ml_dir, 'z3native.ml') + ml_wrapperf = os.path.join(ml_dir, 'z3native.c') ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n\n') - ml_native.write('open Enumerations\n\n') - ml_native.write('module Z3 = struct\n\n') - ml_native.write('type context\n') - ml_native.write('and symbol\n') - ml_native.write('and ast\n') - ml_native.write('and sort = private ast\n') - ml_native.write('and func_decl = private ast\n') - ml_native.write('and app = private ast\n') - ml_native.write('and pattern = private ast\n') - ml_native.write('and params\n') - ml_native.write('and param_descrs\n') - ml_native.write('and model\n') - ml_native.write('and func_interp\n') - ml_native.write('and func_entry\n') - ml_native.write('and fixedpoint\n') - ml_native.write('and ast_vector\n') - ml_native.write('and ast_map\n') - ml_native.write('and goal\n') - ml_native.write('and tactic\n') - ml_native.write('and probe\n') - ml_native.write('and apply_result\n') - ml_native.write('and solver\n') - ml_native.write('and stats\n') - ml_native.write('\n') + ml_native.write('open Z3enums\n\n') + ml_native.write('module Z3native = struct\n\n') + ml_native.write(' type context\n') + ml_native.write(' and symbol\n') + ml_native.write(' and ast\n') + ml_native.write(' and sort = private ast\n') + ml_native.write(' and func_decl = private ast\n') + ml_native.write(' and app = private ast\n') + ml_native.write(' and pattern = private ast\n') + ml_native.write(' and params\n') + ml_native.write(' and param_descrs\n') + ml_native.write(' and model\n') + ml_native.write(' and func_interp\n') + ml_native.write(' and func_entry\n') + ml_native.write(' and fixedpoint\n') + ml_native.write(' and ast_vector\n') + ml_native.write(' and ast_map\n') + ml_native.write(' and goal\n') + ml_native.write(' and tactic\n') + ml_native.write(' and probe\n') + ml_native.write(' and apply_result\n') + ml_native.write(' and solver\n') + ml_native.write(' and stats\n\n') ml_native.write(' exception Exception of string\n\n') + + # ML declarations + ml_native.write(' module ML2C = struct\n\n') for name, result, params in _dotnet_decls: - ml_native.write(' external n_%s : ' % ml_method_name(name)) - i = 0; - for param in params: - ml_native.write('%s -> ' % param2ml(param)) - i = i + 1 - if len(params) == 0: + ml_native.write(' external n_%s : ' % ml_method_name(name)) + ip = inparams(params) + op = outparams(params) + if len(ip) == 0: ml_native.write(' unit -> ') - ml_native.write('%s\n' % (type2ml(result))) - ml_native.write(' = "n_%s"\n\n' % ml_method_name(name)) + for p in ip: + ml_native.write('%s -> ' % param2ml(p)) + if len(op) > 0: + ml_native.write('(') + ml_native.write('%s' % type2ml(result)) + for p in op: + ml_native.write(' * %s' % param2ml(p)) + if len(op) > 0: + ml_native.write(')') + ml_native.write('\n') + ml_native.write(' = "n_%s"\n' % ml_method_name(name)) + if len(ip) > 5: + ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) + ml_native.write('\n') + ml_native.write(' end\n\n') + # Exception wrappers for name, result, params in _dotnet_decls: - ml_native.write(' let %s ' % ml_method_name(name)) + ip = inparams(params) + op = outparams(params) + ml_native.write(' let %s ' % ml_method_name(name)) first = True i = 0; - for param in params: - if first: - first = False; - else: - ml_native.write(' ') - ml_native.write('a%d' % i) - i = i + 1 - ml_native.write(' = \n') - ml_native.write(' ') - if result != VOID: - ml_native.write('let res = ') - if len(params) == 0: - ml_native.write('n_%s()' % (ml_method_name(name))) - else: - ml_native.write('(n_%s ' % (ml_method_name(name))) - first = True - i = 0; - for param in params: + for p in params: + if is_in_param(p): if first: - first = False + first = False; else: ml_native.write(' ') ml_native.write('a%d' % i) - i = i + 1 - ml_native.write(')') - if result != VOID: - ml_native.write(' in\n') + i = i + 1 + ml_native.write(' = \n') + ml_native.write(' ') + if result == VOID: + ml_native.write('let _ = ') else: - ml_native.write(';\n') + ml_native.write('let res = ') + ml_native.write('(ML2C.n_%s' % (ml_method_name(name))) + first = True + i = 0; + for p in params: + if is_in_param(p): + ml_native.write(' a%d' % i) + i = i + 1 + ml_native.write(') in\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (Enumerations.int2error_code (n_get_error_code a0)) in \n') - ml_native.write(' if err <> Enumerations.OK then\n') - ml_native.write(' raise (Exception (n_get_error_msg_ex a0 (error_code2int err)))\n') + ml_native.write(' let err = (Z3enums.int2error_code (ML2C.n_get_error_code a0)) in \n') + ml_native.write(' if err <> Z3enums.OK then\n') + ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (Z3enums.error_code2int err)))\n') ml_native.write(' else\n') if result == VOID: ml_native.write(' ()\n') else: ml_native.write(' res\n') ml_native.write('\n') - ml_native.write('\nend\n') + + ml_native.write('end\n') + + # C interface ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') ml_wrapper.write('#include \n') - ml_wrapper.write('#include \n') + ml_wrapper.write('#include \n\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('extern "C" {\n') + ml_wrapper.write('#endif\n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') @@ -1173,61 +1220,119 @@ def mk_ml(): ml_wrapper.write('#ifdef Custom_tag\n') ml_wrapper.write('#include \n') ml_wrapper.write('#include \n') + ml_wrapper.write('#endif\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('}\n') ml_wrapper.write('#endif\n\n') ml_wrapper.write('#include \n\n') + ml_wrapper.write('#define CAMLlocal6(X1,X2,X3,X4,X5,X6) \\\n') + ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLlocal1(X6); \n') + ml_wrapper.write('#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \\\n') + ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLlocal2(X6,X7); \n') + ml_wrapper.write('#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') + ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLlocal3(X6,X7,X8); \n') + ml_wrapper.write('\n') + ml_wrapper.write('#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam2(X6,X7); \n') + ml_wrapper.write('#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam3(X6,X7,X8); \n') + ml_wrapper.write('#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9); \n') + ml_wrapper.write('#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') + ml_wrapper.write(' CAMLxparam2(X11,X12); \n') + ml_wrapper.write('#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \\\n') + ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') + ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') + ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') + ml_wrapper.write('\n\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('extern "C" {\n') + ml_wrapper.write('#endif\n\n') for name, result, params in _dotnet_decls: - #return type = type2ml(result) + ip = inparams(params) + op = outparams(params) + ret_size = len(op) + if result != VOID: + ret_size = ret_size + 1 + + # Setup frame + n_locals = 0 + for p in params: + if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): + n_locals = n_locals + 1 ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) first = True i = 0 - for param in params: - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('value a%d' % i) - # param type = param2ml(param) + for p in params: + if is_in_param(p): + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('value a%d' % i) i = i + 1 ml_wrapper.write(') {\n') - ml_wrapper.write(' CAMLparam%d(' % len(params)) + ml_wrapper.write(' CAMLparam%d(' % len(ip)) i = 0 first = True - for param in params: - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('a%d' % i) + for p in params: + if is_in_param(p): + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('a%d' % i) i = i + 1 ml_wrapper.write(');\n') + i = 0 + first = True + if result != VOID: + n_locals = n_locals + 1 + if ret_size > 1: + n_locals = n_locals + 1 + if n_locals > 0: + ml_wrapper.write(' CAMLlocal%s(' % (n_locals)) + if ret_size > 1: + if result != VOID: + ml_wrapper.write('result, ') + ml_wrapper.write('result_tuple') + first = False + elif result != VOID: + ml_wrapper.write('result') + first = False + for p in params: + if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): + if first: + first = False + else: + ml_wrapper.write(', ') + ml_wrapper.write('_a%s' % i) + i = i + 1 + ml_wrapper.write(');\n') + # preprocess arrays, strings, in/out arguments i = 0 for param in params: - k = param_kind(param) - if k == OUT or k == INOUT: - ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) - elif k == IN_ARRAY or k == INOUT_ARRAY: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) - else: - ml_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) - elif k == OUT_ARRAY: - ml_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), - i, - type2str(param_type(param)), - param_array_capacity_pos(param), - type2str(param_type(param)))) - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - else: - ml_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) - elif k == IN and param_type(param) == STRING: - ml_wrapper.write(' Z3_string _a%s = (Z3_string) String_val(a%s);\n' % (i, i)) + if param_kind(param) == OUT_ARRAY: + ml_wrapper.write(' _a%s = (long) malloc(sizeof(%s) * ((long)a%s));\n' % (i, + type2str(param_type(param)), + param_array_capacity_pos(param))) + elif param_kind(param) == IN and param_type(param) == STRING: + ml_wrapper.write(' _a%s = (value) String_val(a%s);\n' % (i, i)) i = i + 1 + # invoke procedure ml_wrapper.write(' ') if result != VOID: - ml_wrapper.write('%s result = ' % type2str(result)) + ml_wrapper.write('result = (value) ') ml_wrapper.write('%s(' % name) i = 0 first = True @@ -1238,53 +1343,74 @@ def mk_ml(): ml_wrapper.write(', ') k = param_kind(param) if k == OUT or k == INOUT: - ml_wrapper.write('&_a%s' % i) - elif k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: - ml_wrapper.write('_a%s' % i) + ml_wrapper.write('(%s)&_a%s' % (param2str(param), i)) + elif k == INOUT_ARRAY or k == IN_ARRAY: + ml_wrapper.write('(%s*)a%s' % (type2str(param_type(param)), i)) + elif k == OUT_ARRAY: + ml_wrapper.write('(%s*)_a%s' % (type2str(param_type(param)), i)) elif k == IN and param_type(param) == STRING: - ml_wrapper.write('_a%s' % i) + ml_wrapper.write('(Z3_string) _a%s' % i) else: ml_wrapper.write('(%s)a%i' % (param2str(param), i)) i = i + 1 ml_wrapper.write(');\n') - # cleanup - i = 0 - for param in params: - k = param_kind(param) - if k == OUT_ARRAY: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) - else: - ml_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) - ml_wrapper.write(' free(_a%s);\n' % i) - elif k == IN_ARRAY or k == OUT_ARRAY: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) - else: - ml_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) - elif k == OUT or k == INOUT: - if param_type(param) == INT or param_type(param) == UINT: - ml_wrapper.write(' {\n') - ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n') - ml_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i)) - ml_wrapper.write(' }\n') + # return tuples + if len(op) > 0: + ml_wrapper.write(' result_tuple = caml_alloc(%s, 0);\n' % ret_size) + i = j = 0 + if result != VOID: + if result == STRING: + ml_wrapper.write(' Store_field(result_tuple, 0, caml_copy_string(result));\n') else: - ml_wrapper.write(' {\n') - ml_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i) - ml_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "J");\n') - ml_wrapper.write(' jenv->SetLongField(a%s, fid, (jlong) _a%s);\n' % (i, i)) - ml_wrapper.write(' }\n') + ml_wrapper.write(' Store_field(result_tuple, 0, result);\n') + j = j + 1 + for p in params: + if param_kind(p) == OUT_ARRAY or param_kind(p) == OUT: + ml_wrapper.write(' Store_field(result_tuple, %s, _a%s);\n' % (j, i)) + j = j + 1; + elif is_out_param(p): + if param_type(p) == STRING: + ml_wrapper.write(' Store_field(result_tuple, %s, caml_copy_string((const char *)_a%s));\n' % (j, i)) + else: + ml_wrapper.write(' Store_field(result_tuple, %s, a%s);\n' % (j, i)) + j = j + 1; + i = i + 1 + + # local array cleanup + i = 0 + for p in params: + if param_kind(p) == OUT_ARRAY: + ml_wrapper.write(' free((long*)_a%s);\n' % i) i = i + 1 + # return - if result == STRING: - ml_wrapper.write(' return caml_copy_string(result);\n') - elif result == VOID: - ml_wrapper.write(' CAMLreturn(Val_unit);\n') - elif result != VOID: - ml_wrapper.write(' return (value) result;\n') + if len(op) > 0: + ml_wrapper.write(' CAMLreturn(result_tuple);\n') + else: + if result == STRING: + ml_wrapper.write(' CAMLreturn(caml_copy_string((const char*) result));\n') + elif result == VOID: + ml_wrapper.write(' CAMLreturn(Val_unit);\n') + elif result != VOID: + ml_wrapper.write(' CAMLreturn(result);\n') + ml_wrapper.write('}\n\n') + if len(ip) > 5: + ml_wrapper.write('CAMLprim value n_%s_bytecode(value * argv, int argn) {\n' % ml_method_name(name)) + ml_wrapper.write(' return n_%s(' % ml_method_name(name)) + i = 0 + while i < len(ip): + if i == 0: + ml_wrapper.write('argv[0]') + else: + ml_wrapper.write(', argv[%s]' % i) + i = i + 1 + ml_wrapper.write(');\n}\n') + ml_wrapper.write('\n\n') + ml_wrapper.write('#ifdef __cplusplus\n') + ml_wrapper.write('}\n') + ml_wrapper.write('#endif\n') if is_verbose(): print "Generated '%s'" % ml_nativef From 1ef9013c8ed4020847bdbccdf17828c3b4338d85 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 04:37:32 +0000 Subject: [PATCH 349/507] More new ML API. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2751 +--------------------------------------------- 1 file changed, 5 insertions(+), 2746 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 350457525..5251a8767 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,2752 +1,11 @@ -(** - The Z3 ML/OCaml Interface. - - Copyright (C) 2012 Microsoft Corporation - @author CM Wintersteiger (cwinter) 2012-12-17 +(* + Author: CM Wintersteiger + (C) Microsoft Research, 2012 *) open Z3enums +open Z3native -exception Error = Z3native.Exception - -(* Some helpers. *) -let null = Z3native.mk_null() -let is_null o = (Z3native.is_null o) - -(* Internal types *) -type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } -type context = z3_native_context - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - -(** Internal stuff *) -module Internal = -struct - let dispose_context ctx = - if ctx.m_n_obj_cnt == 0 then ( - (Z3native.del_context ctx.m_n_ctx) - ) else ( - Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; - ) - - let create_context settings = - let cfg = Z3native.mk_config () in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - Z3native.set_internal_error_handler v ; - let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in - let f = fun o -> dispose_context o in - Gc.finalise f res; - res - - let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) - let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) - let context_gno ctx = ctx.m_n_ctx - - - let z3obj_gc o = o.m_ctx - let z3obj_gnc o = (context_gno o.m_ctx) - - let z3obj_gno o = o.m_n_obj - let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - - let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - - let z3obj_create o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - - let z3obj_nil_ref x y = () - - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> - let res : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res -end - -open Internal - -module Log = -struct - let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - let close = Z3native.close_log - let append s = Z3native.append_log s -end - - -module Version = -struct - let major = let (x, _, _, _) = Z3native.get_version () in x - let minor = let (_, x, _, _) = Z3native.get_version () in x - let build = let (_, _, x, _) = Z3native.get_version () in x - let revision = let (_, _, _, x) = Z3native.get_version () in x - let to_string = - let (mj, mn, bld, rev) = Z3native.get_version () in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev -end - - -let mk_list ( f : int -> 'a ) ( n : int ) = - let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = - if (i >= n) then - tail - else - (f i) :: (mk_list' f (i+1) n tail) - in - mk_list' f 0 n [] - -let list_of_array ( x : _ array ) = - let f i = (Array.get x i) in - mk_list f (Array.length x) - -let mk_context ( cfg : ( string * string ) list ) = - create_context cfg - - -module Symbol = -struct - type symbol = z3_native_object - - let create_i ( ctx : context ) ( no : Z3native.ptr ) = - let res : symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let create_s ( ctx : context ) ( no : Z3native.ptr ) = - let res : symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> (create_i ctx no) - | STRING_SYMBOL -> (create_s ctx no) - - let gc ( x : symbol ) = (z3obj_gc x) - let gnc ( x : symbol ) = (z3obj_gnc x) - let gno ( x : symbol ) = (z3obj_gno x) - - let symbol_lton ( a : symbol list ) = - let f ( e : symbol ) = (gno e) in - Array.of_list (List.map f a) - - let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) - let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL - let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - let get_int (o : symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - let get_string (o : symbol ) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) - let to_string ( o : symbol ) = - match (kind o) with - | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) - | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) - - let mk_int ( ctx : context ) ( i : int ) = - (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) - - let mk_string ( ctx : context ) ( s : string ) = - (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - - let mk_ints ( ctx : context ) ( names : int list ) = - let f elem = mk_int ( ctx : context ) elem in - (List.map f names) - - let mk_strings ( ctx : context ) ( names : string list ) = - let f elem = mk_string ( ctx : context ) elem in - (List.map f names) -end - - -module AST = -struct - type ast = z3_native_object - - let context_of_ast ( x : ast ) = (z3obj_gc x) - let nc_of_ast ( x : ast ) = (z3obj_gnc x) - let ptr_of_ast ( x : ast ) = (z3obj_gno x) - - let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST - | SORT_AST - | QUANTIFIER_AST - | APP_AST - | NUMERAL_AST - | VAR_AST -> z3_native_object_of_ast_ptr ctx no - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") - - module ASTVector = - struct - type ast_vector = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_vector = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_vector_inc_ref ; - dec_ref = Z3native.ast_vector_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let mk_ast_vector ( ctx : context ) = (create ctx (Z3native.mk_ast_vector (context_gno ctx))) - - let get_size ( x : ast_vector ) = - Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) - - let get ( x : ast_vector ) ( i : int ) = - ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) - - let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) - - let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size - - let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) - - let translate ( x : ast_vector ) ( to_ctx : context ) = - create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) - end - - module ASTMap = - struct - type ast_map = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_map = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_map_inc_ref ; - dec_ref = Z3native.ast_map_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let mk_ast_map ( ctx : context ) = (create ctx (Z3native.mk_ast_map (context_gno ctx))) - - let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_map = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_map_inc_ref ; - dec_ref = Z3native.ast_map_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let contains ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - - let find ( x : ast_map ) ( key : ast ) = - ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - - let insert ( x : ast_map ) ( key : ast ) ( value : ast ) = - Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) - - let erase ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - - let reset ( x : ast_map ) = - Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : ast_map ) = - Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) - - let get_keys ( x : ast_map ) = - let av = ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in - let f i = (ASTVector.get av i) in - mk_list f (ASTVector.get_size av) - - let to_string ( x : ast_map ) = - Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let hash ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) - let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) - let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) - - let is_expr ( x : ast ) = - match get_ast_kind ( x : ast ) with - | APP_AST - | NUMERAL_AST - | QUANTIFIER_AST - | VAR_AST -> true - | _ -> false - - let is_app ( x : ast ) = (get_ast_kind x) == APP_AST - let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST - let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST - let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST - let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST - - let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - - - let equal ( a : ast ) ( b : ast ) = (a == b) || - if (z3obj_gnc a) != (z3obj_gnc b) then - false - else - Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) - - let compare a b = - if (get_id a) < (get_id b) then -1 else - if (get_id a) > (get_id b) then 1 else - 0 - - let translate ( x : ast ) ( to_ctx : context ) = - if (z3obj_gnc x) == (context_gno to_ctx) then - x - else - ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let unwrap_ast ( x : ast ) = (z3obj_gno x) - let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr -end - -open AST - - -module Sort = -struct - type sort = Sort of AST.ast - - let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> - let q = (z3_native_object_of_ast_ptr ctx no) in - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then - raise (Z3native.Exception "Invalid coercion") - else - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - - let ast_of_sort s = match s with Sort(x) -> x - - let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) - let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) - let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - - let sort_lton ( a : sort list ) = - let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let sort_option_lton ( a : sort option list ) = - let f ( e : sort option ) = match e with None -> null | Some(Sort(a)) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let equal : sort -> sort -> bool = fun a b -> - (a == b) || - if (gnc a) != (gnc b) then - false - else - (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) - - - let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) - let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) - let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) - let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) - - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; - (z3obj_create res) ; - Sort(res) - - let mk_uninterpreted_s ( ctx : context ) ( s : string ) = - mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) -end - -open Sort - - -module rec FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - val ast_of_func_decl : FuncDecl.func_decl -> AST.ast - val func_decl_of_ptr : context -> Z3native.ptr -> func_decl - val gc : func_decl -> context - val gnc : func_decl -> Z3native.ptr - val gno : func_decl -> Z3native.ptr - module Parameter : - sig - type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - val get_kind : parameter -> Z3enums.parameter_kind - val get_int : parameter -> int - val get_float : parameter -> float - val get_symbol : parameter -> Symbol.symbol - val get_sort : parameter -> Sort.sort - val get_ast : parameter -> AST.ast - val get_func_decl : parameter -> func_decl - val get_rational : parameter -> string - end - val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl - val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl - val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl - val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl - val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - val equal : func_decl -> func_decl -> bool - val to_string : func_decl -> string - val get_id : func_decl -> int - val get_arity : func_decl -> int - val get_domain_size : func_decl -> int - val get_domain : func_decl -> Sort.sort list - val get_range : func_decl -> Sort.sort - val get_decl_kind : func_decl -> Z3enums.decl_kind - val get_name : func_decl -> Symbol.symbol - val get_num_parameters : func_decl -> int - val get_parameters : func_decl -> Parameter.parameter list - val apply : func_decl -> Expr.expr list -> Expr.expr -end = struct - type func_decl = FuncDecl of AST.ast - - let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - FuncDecl(z3_native_object_of_ast_ptr ctx no) - - let ast_of_func_decl f = match f with FuncDecl(x) -> x - - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; - (z3obj_create res) ; - FuncDecl(res) - - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; - (z3obj_create res) ; - FuncDecl(res) - - let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) - let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) - let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - - module Parameter = - struct - type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - let get_kind ( x : parameter ) = - (match x with - | P_Int(_) -> PARAMETER_INT - | P_Dbl(_) -> PARAMETER_DOUBLE - | P_Sym(_) -> PARAMETER_SYMBOL - | P_Srt(_) -> PARAMETER_SORT - | P_Ast(_) -> PARAMETER_AST - | P_Fdl(_) -> PARAMETER_FUNC_DECL - | P_Rat(_) -> PARAMETER_RATIONAL) - - let get_int ( x : parameter ) = - match x with - | P_Int(x) -> x - | _ -> raise (Z3native.Exception "parameter is not an int") - - let get_float ( x : parameter ) = - match x with - | P_Dbl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a float") - - let get_symbol ( x : parameter ) = - match x with - | P_Sym(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a symbol") - - let get_sort ( x : parameter ) = - match x with - | P_Srt(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a sort") - - let get_ast ( x : parameter ) = - match x with - | P_Ast(x) -> x - | _ -> raise (Z3native.Exception "parameter is not an ast") - - let get_func_decl ( x : parameter ) = - match x with - | P_Fdl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a func_decl") - - let get_rational ( x : parameter ) = - match x with - | P_Rat(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a rational string") - end - - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = - create_ndr ctx name domain range - - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = - mk_func_decl ctx (Symbol.mk_string ctx name) domain range - - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = - create_pdr ctx prefix domain range - - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_ndr ctx name [] range - - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = - create_ndr ctx (Symbol.mk_string ctx name) [] range - - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = - create_pdr ctx prefix [] range - - - let equal ( a : func_decl ) ( b : func_decl ) = (a == b) || - if (gnc a) != (gnc b) then - false - else - (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) - - let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) - - let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) - - let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) - - let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) - - let get_domain ( x : func_decl ) = - let n = (get_domain_size x) in - let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in - mk_list f n - - let get_range ( x : func_decl ) = - sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) - - let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) - - let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) - - let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) - - let get_parameters ( x : func_decl ) = - let n = (get_num_parameters x) in - let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) - ) in - mk_list f n - - let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args -end - - -and Params : -sig - type params = z3_native_object - module ParamDescrs : - sig - type param_descrs - val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - val get_names : param_descrs -> Symbol.symbol list - val get_size : param_descrs -> int - val to_string : param_descrs -> string - end - val add_bool : params -> Symbol.symbol -> bool -> unit - val add_int : params -> Symbol.symbol -> int -> unit - val add_float : params -> Symbol.symbol -> float -> unit - val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - val mk_params : context -> params - val to_string : params -> string - - val update_param_value : context -> string -> string -> unit - val set_print_mode : context -> Z3enums.ast_print_mode -> unit -end = struct - type params = z3_native_object - - module ParamDescrs = - struct - type param_descrs = z3_native_object - - let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : param_descrs = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.param_descrs_inc_ref ; - dec_ref = Z3native.param_descrs_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let validate ( x : param_descrs ) ( p : params ) = - Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) - - let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) - - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in - let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = - Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = - Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_float ( x : params ) ( name : Symbol.symbol ) ( value : float ) = - Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = - Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - - let mk_params ( ctx : context ) = - let res : params = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.params_inc_ref ; - dec_ref = Z3native.params_dec_ref } in - (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; - (z3obj_create res) ; - res - - let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) - - let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value (context_gno ctx) id value - - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) -end - -(** General expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - val expr_of_ptr : context -> Z3native.ptr -> expr - val gc : expr -> context - val gnc : expr -> Z3native.ptr - val gno : expr -> Z3native.ptr - val expr_lton : expr list -> Z3native.ptr array - val ast_of_expr : expr -> AST.ast - val expr_of_ast : AST.ast -> expr - val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr - val simplify : expr -> Params.params option -> expr - val get_simplify_help : context -> string - val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs - val get_func_decl : expr -> FuncDecl.func_decl - val get_num_args : expr -> int - val get_args : expr -> expr list - val update : expr -> expr list -> expr - val substitute : expr -> expr list -> expr list -> expr - val substitute_one : expr -> expr -> expr -> expr - val substitute_vars : expr -> expr list -> expr - val translate : expr -> context -> expr - val to_string : expr -> string - val is_numeral : expr -> bool - val is_well_sorted : expr -> bool - val get_sort : expr -> Sort.sort - val is_const : expr -> bool - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - val mk_const_s : context -> string -> Sort.sort -> expr - val mk_const_f : context -> FuncDecl.func_decl -> expr - val mk_fresh_const : context -> string -> Sort.sort -> expr - val mk_app : context -> FuncDecl.func_decl -> expr list -> expr - val mk_numeral_string : context -> string -> Sort.sort -> expr - val mk_numeral_int : context -> int -> Sort.sort -> expr - val equal : expr -> expr -> bool - val compare : expr -> expr -> int -end = struct - type expr = Expr of AST.ast - - let gc e = match e with Expr(a) -> (z3obj_gc a) - let gnc e = match e with Expr(a) -> (z3obj_gnc a) - let gno e = match e with Expr(a) -> (z3obj_gno a) - - let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then - Expr(z3_native_object_of_ast_ptr ctx no) - else - let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) no) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT || sk == REAL_SORT || sk == BV_SORT) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - raise (Z3native.Exception "Unsupported numeral object") - else - Expr(z3_native_object_of_ast_ptr ctx no) - - let expr_of_ast a = - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Expr(a) - - let ast_of_expr e = match e with Expr(a) -> a - - let expr_lton ( a : expr list ) = - let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> - match f with FuncDecl.FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in - expr_of_ptr ctx o - - let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (gnc x) (gno x)) - | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) - - let get_simplify_help ( ctx : context ) = - Z3native.simplify_get_help (context_gno ctx) - - let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) - - let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) - - let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in - mk_list f n - - let update ( x : expr ) ( args : expr list ) = - if ((AST.is_app (ast_of_expr x)) && (List.length args <> (get_num_args x))) then - raise (Z3native.Exception "Number of arguments does not match") - else - expr_of_ptr (Expr.gc x) (Z3native.update_term (gnc x) (gno x) (List.length args) (expr_lton args)) - - let substitute ( x : expr ) from to_ = - if (List.length from) <> (List.length to_) then - raise (Z3native.Exception "Argument sizes do not match") - else - expr_of_ptr (Expr.gc x) (Z3native.substitute (gnc x) (gno x) (List.length from) (expr_lton from) (expr_lton to_)) - - let substitute_one ( x : expr ) from to_ = - substitute ( x : expr ) [ from ] [ to_ ] - - let substitute_vars ( x : expr ) to_ = - expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (gnc x) (gno x) (List.length to_) (expr_lton to_)) - - let translate ( x : expr ) to_ctx = - if (Expr.gc x) == to_ctx then - x - else - expr_of_ptr to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) - - let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) - - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) - - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) - - let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) - - let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && - (get_num_args x) == 0 && - (FuncDecl.get_domain_size (get_func_decl x)) == 0 - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) - - let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name) range - - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] - - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = - expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args - - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) - - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) - - let equal ( a : expr ) ( b : expr ) = AST.equal (ast_of_expr a) (ast_of_expr b) - - let compare a b = AST.compare (ast_of_expr a) (ast_of_expr b) -end - -open FuncDecl -open Expr - -module Boolean = -struct - let mk_sort ( ctx : context ) = - (sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - (Expr.mk_const ctx name (mk_sort ctx)) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_true ( ctx : context ) = - expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) - - let mk_false ( ctx : context ) = - expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) - - let mk_val ( ctx : context ) ( value : bool ) = - if value then mk_true ctx else mk_false ctx - - let mk_not ( ctx : context ) ( a : expr ) = - expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - - let mk_ite ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( t3 : expr ) = - expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - - let mk_iff ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - - let mk_implies ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - - let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - - let mk_and ( ctx : context ) ( args : expr list ) = - let f x = (Expr.gno (x)) in - expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - - let mk_or ( ctx : context ) ( args : expr list ) = - let f x = (Expr.gno (x)) in - expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) - - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) - - let mk_distinct ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) - - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) - - let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (gnc x) - (Z3native.mk_bool_sort (gnc x)) - (Z3native.get_sort (gnc x) (gno x))) - - let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) -end - - -module Quantifier = -struct - type quantifier = Quantifier of expr - - let expr_of_quantifier e = match e with Quantifier(x) -> x - - let quantifier_of_expr e = - match e with Expr.Expr(a) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.QUANTIFIER_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Quantifier(e) - - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - - module Pattern = - struct - type pattern = Pattern of ast - - let ast_of_pattern e = match e with Pattern(x) -> x - - let pattern_of_ast a = - (* CMW: Unchecked ok? *) - Pattern(a) - - let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) - let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) - let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - mk_list f n - - let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) - end - - let get_index ( x : expr ) = - if not (AST.is_var (match x with Expr.Expr(a) -> a)) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value (Expr.gnc x) (Expr.gno x) - - let is_universal ( x : quantifier ) = - Z3native.is_quantifier_forall (gnc x) (gno x) - - let is_existential ( x : quantifier ) = not (is_universal x) - - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) - - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) - - let get_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in - mk_list f n - - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) - - let get_no_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in - mk_list f n - - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) - - let get_bound_variable_names ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in - mk_list f n - - let get_bound_variable_sorts ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in - mk_list f n - - let get_body ( x : quantifier ) = - expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) - - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - - let mk_pattern ( ctx : context ) ( terms : expr list ) = - if (List.length terms) == 0 then - raise (Z3native.Exception "Cannot create a pattern from zero terms") - else - Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) - - let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (List.length sorts) != (List.length names) then - raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - - let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (Expr.gno body))) - - let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (List.length sorts) != (List.length names) then - raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - - let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (Expr.gno body))) - - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (universal) then - (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - else - (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (universal) then - mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id - else - mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id - - let to_string ( x : quantifier ) = (Expr.to_string (expr_of_quantifier x)) -end - - -module Z3Array = -struct - let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - - let is_store ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - let is_select ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - let is_constant_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - let is_default_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - let is_array_map ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - let is_as_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) - let is_array ( x : expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) - - let get_domain ( x : sort ) = Sort.sort_of_ptr (Sort.gc x) (Z3native.get_array_sort_domain (Sort.gnc x) (Sort.gno x)) - let get_range ( x : sort ) = Sort.sort_of_ptr (Sort.gc x) (Z3native.get_array_sort_range (Sort.gnc x) (Sort.gno x)) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - (Expr.mk_const ctx name (mk_sort ctx domain range)) - - let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name) domain range - - let mk_select ( ctx : context ) ( a : expr ) ( i : expr ) = - expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (Expr.gno a) (Expr.gno i)) - - let mk_store ( ctx : context ) ( a : expr ) ( i : expr ) ( v : expr ) = - expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (Expr.gno a) (Expr.gno i) (Expr.gno v)) - - let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) - - let mk_map ( ctx : context ) ( f : func_decl ) ( args : expr list ) = - let m x = (Expr.gno x) in - expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) - - let mk_term_array ( ctx : context ) ( arg : expr ) = - expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (Expr.gno arg)) -end - - -module Set = -struct - let mk_sort ( ctx : context ) ( ty : sort ) = - sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - - let is_union ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - let is_intersect ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - let is_difference ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - let is_complement ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - let is_subset ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) - - - let mk_empty ( ctx : context ) ( domain : sort ) = - (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) - - let mk_full ( ctx : context ) ( domain : sort ) = - expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) - - let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) - - let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) - - let mk_union ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_intersection ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) - - let mk_complement ( ctx : context ) ( arg : expr ) = - expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) - - let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) - - let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) +module Z3 = struct end - - -module FiniteDomain = -struct - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) - - let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_sort ctx (Symbol.mk_string ctx name) size - - let is_finite_domain ( x : expr ) = - let nc = (Expr.gnc x) in - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) - - let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - - let get_size ( x : sort ) = - let (r, v) = (Z3native.get_finite_domain_sort_size (Sort.gnc x) (Sort.gno x)) in - if r then v - else raise (Z3native.Exception "Conversion failed.") -end - - -module Relation = -struct - let is_relation ( x : expr ) = - let nc = (Expr.gnc x) in - ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) - - let is_store ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - let is_empty ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - let is_is_empty ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - let is_join ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - let is_union ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - let is_widen ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - let is_project ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - let is_filter ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - let is_negation_filter ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - let is_rename ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - let is_complement ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - let is_select ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - let is_clone ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - - let get_arity ( x : sort ) = Z3native.get_relation_arity (Sort.gnc x) (Sort.gno x) - - let get_column_sorts ( x : sort ) = - let n = get_arity x in - let f i = (sort_of_ptr (Sort.gc x) (Z3native.get_relation_column (Sort.gnc x) (Sort.gno x) i)) in - mk_list f n -end - - -module Datatype = -struct - module Constructor = - struct - type constructor = z3_native_object - - module FieldNumTable = Hashtbl.Make(struct - type t = AST.ast - let equal x y = AST.compare x y = 0 - let hash = AST.hash - end) - - let _field_nums = FieldNumTable.create 0 - - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = - let n = (List.length field_names) in - if n != (List.length sorts) then - raise (Z3native.Exception "Number of field names does not match number of sorts") - else - if n != (List.length sort_refs) then - raise (Z3native.Exception "Number of field names does not match number of sort refs") - else - let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) - (Symbol.gno recognizer) - n - (Symbol.symbol_lton field_names) - (sort_option_lton sorts) - (Array.of_list sort_refs)) in - let no : constructor = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - (z3obj_sno no ctx ptr) ; - (z3obj_create no) ; - let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in - Gc.finalise f no ; - FieldNumTable.add _field_nums no n ; - no - - let get_num_fields ( x : constructor ) = FieldNumTable.find _field_nums x - - let get_constructor_decl ( x : constructor ) = - let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - func_decl_of_ptr (z3obj_gc x) a - - let get_tester_decl ( x : constructor ) = - let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - func_decl_of_ptr (z3obj_gc x) b - - let get_accessor_decls ( x : constructor ) = - let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in - mk_list f (Array.length c) - - end - - module ConstructorList = - struct - type constructor_list = z3_native_object - - let create ( ctx : context ) ( c : Constructor.constructor list ) = - let res : constructor_list = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - let f x =(z3obj_gno x) in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; - (z3obj_create res) ; - let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in - Gc.finalise f res; - res - end - - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = - Constructor.create ctx name recognizer field_names sorts sort_refs - - - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = - mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = - let f x = (z3obj_gno x) in - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in - sort_of_ptr ctx x - - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = - mk_sort ctx (Symbol.mk_string ctx name) constructors - - let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = - let n = (List.length names) in - let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in - let cla = (Array.of_list (List.map f c)) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in - let g i = (sort_of_ptr ctx (Array.get r i)) in - mk_list g (Array.length r) - - let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = - mk_sorts ctx - ( - let f e = (Symbol.mk_string ctx e) in - List.map f names - ) - c - - let get_num_constructors ( x : sort ) = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) - - let get_constructors ( x : sort ) = - let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i) in - mk_list f n - - let get_recognizers ( x : sort ) = - let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) i) in - mk_list f n - - let get_accessors ( x : sort ) = - let n = (get_num_constructors x) in - let f i = ( - let fd = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i) in - let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) i j) in - mk_list g ds - ) in - mk_list f n -end - - -module Enumeration = -struct - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = - let (a, _, _) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in - sort_of_ptr ctx a - - let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = - mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - - let get_const_decls ( x : sort ) = - let n = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) in - let f i = (func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i)) in - mk_list f n - - let get_tester_decls ( x : sort ) = - let n = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) in - let f i = (func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) i)) in - mk_list f n - -end - - -module Z3List = -struct - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = - let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - sort_of_ptr ctx r - - let mk_list_s ( ctx : context ) (name : string) elem_sort = - mk_sort ctx (Symbol.mk_string ctx name) elem_sort - - let get_nil_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) 0) - - let get_is_nil_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) 0) - - let get_cons_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) 1) - - let get_is_cons_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) 1) - - let get_head_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) 1 0) - - let get_tail_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) 1 1) - - let nil ( x : sort ) = expr_of_func_app (Sort.gc x) (get_nil_decl x) [] -end - - -module Tuple = -struct - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = - let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in - sort_of_ptr ctx r - - let get_mk_decl ( x : sort ) = - func_decl_of_ptr (Sort.gc x) (Z3native.get_tuple_sort_mk_decl (Sort.gnc x) (Sort.gno x)) - - let get_num_fields ( x : sort ) = Z3native.get_tuple_sort_num_fields (Sort.gnc x) (Sort.gno x) - - let get_field_decls ( x : sort ) = - let n = get_num_fields x in - let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_tuple_sort_field_decl (Sort.gnc x) (Sort.gno x) i) in - mk_list f n -end - - -module Arithmetic = -struct - let is_int ( x : expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - - let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - - let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - - let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - - let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - - let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - - let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - - let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - - let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - - let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - - let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - - let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - - let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - - let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - - let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - - let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - - let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) - - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - - let is_rat_numeral ( x : expr ) = (Expr.is_numeral x) && (is_real x) - - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - - module Integer = - struct - let mk_sort ( ctx : context ) = - sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - - let get_int ( x : expr ) = - let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in - if r then v - else raise (Z3native.Exception "Conversion failed.") - - let get_big_int ( x : expr ) = - if (is_int_numeral x) then - let s = (Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x)) in - (Big_int.big_int_of_string s) - else raise (Z3native.Exception "Conversion failed.") - - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - Expr.mk_const ctx name (mk_sort ctx) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_mod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - - let mk_rem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - - let mk_numeral_s ( ctx : context ) ( v : string ) = - expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) - - let mk_numeral_i ( ctx : context ) ( v : int ) = - expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) - - let mk_int2real ( ctx : context ) ( t : expr ) = - (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (Expr.gno t))) - - let mk_int2bv ( ctx : context ) ( n : int ) ( t : expr ) = - (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (Expr.gno t))) - end - - module Real = - struct - let mk_sort ( ctx : context ) = - sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - - let get_numerator ( x : expr ) = - expr_of_ptr (Expr.gc x) (Z3native.get_numerator (Expr.gnc x) (Expr.gno x)) - - let get_denominator ( x : expr ) = - expr_of_ptr (Expr.gc x) (Z3native.get_denominator (Expr.gnc x) (Expr.gno x)) - - let get_ratio ( x : expr ) = - if (is_rat_numeral x) then - let s = (Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x)) in - (Ratio.ratio_of_string s) - else raise (Z3native.Exception "Conversion failed.") - - let to_decimal_string ( x : expr ) ( precision : int ) = - Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - Expr.mk_const ctx name (mk_sort ctx) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = - if (den == 0) then - raise (Z3native.Exception "Denominator is zero") - else - expr_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) - - let mk_numeral_s ( ctx : context ) ( v : string ) = - expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) - - let mk_numeral_i ( ctx : context ) ( v : int ) = - expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) - - let mk_is_integer ( ctx : context ) ( t : expr ) = - (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (Expr.gno t))) - - let mk_real2int ( ctx : context ) ( t : expr ) = - (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (Expr.gno t))) - - module AlgebraicNumber = - struct - let to_upper ( x : expr ) ( precision : int ) = - expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) - - let to_lower ( x : expr ) precision = - expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) - - let to_decimal_string ( x : expr ) ( precision : int ) = - Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - end - end - - let mk_add ( ctx : context ) ( t : expr list ) = - let f x = (Expr.gno x) in - (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_mul ( ctx : context ) ( t : expr list ) = - let f x = (Expr.gno x) in - (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_sub ( ctx : context ) ( t : expr list ) = - let f x = (Expr.gno x) in - (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_unary_minus ( ctx : context ) ( t : expr ) = - (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) - - let mk_div ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - - let mk_power ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - - let mk_lt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - - let mk_le ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - - let mk_gt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - - let mk_ge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) -end - - -module BitVector = -struct - let mk_sort ( ctx : context ) size = - sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) - let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) - let is_bv_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - let is_bv_bit1 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - let is_bv_bit0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - let is_bv_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - let is_bv_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - let is_bv_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - let is_bv_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - let is_bv_sdiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - let is_bv_udiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - let is_bv_SRem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - let is_bv_urem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - let is_bv_smod ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - let is_bv_sdiv0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - let is_bv_udiv0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - let is_bv_srem0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - let is_bv_urem0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - let is_bv_smod0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - let is_bv_ule ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - let is_bv_sle ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - let is_bv_uge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - let is_bv_sge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - let is_bv_ult ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - let is_bv_slt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - let is_bv_ugt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - let is_bv_sgt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - let is_bv_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - let is_bv_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - let is_bv_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - let is_bv_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - let is_bv_nand ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - let is_bv_nor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - let is_bv_xnor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - let is_bv_concat ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - let is_bv_signextension ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - let is_bv_zeroextension ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - let is_bv_extract ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - let is_bv_repeat ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - let is_bv_reduceor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - let is_bv_reduceand ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - let is_bv_comp ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - let is_bv_shiftleft ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - let is_bv_shiftrightlogical ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - let is_bv_shiftrightarithmetic ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - let is_bv_rotateleft ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - let is_bv_rotateright ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - let is_bv_rotateleftextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - let is_bv_rotaterightextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - let is_int_to_bv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - let is_bv_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - let is_bv_carry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - let is_bv_xor3 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - let get_size (x : sort ) = Z3native.get_bv_sort_size (Sort.gnc x) (Sort.gno x) - let get_int ( x : expr ) = - let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in - if r then v - else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - Expr.mk_const ctx name (mk_sort ctx size) - let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_const ctx (Symbol.mk_string ctx name) size - let mk_not ( ctx : context ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (Expr.gno t)) - let mk_redand ( ctx : context ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (Expr.gno t)) - let mk_redor ( ctx : context ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (Expr.gno t)) - let mk_and ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_or ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_nand ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_nor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_xnor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_neg ( ctx : context ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (Expr.gno t)) - let mk_add ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_sub ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_mul ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_udiv ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_sdiv ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_urem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_srem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_smod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_ult ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_slt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_ule ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_sle ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_uge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_sge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_ugt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_sgt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_concat ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (Expr.gno t)) - let mk_sign_ext ( ctx : context ) ( i : int ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (Expr.gno t)) - let mk_zero_ext ( ctx : context ) ( i : int ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (Expr.gno t)) - let mk_repeat ( ctx : context ) ( i : int ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (Expr.gno t)) - let mk_shl ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_lshr ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_ashr ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_rotate_left ( ctx : context ) ( i : int ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (Expr.gno t)) - let mk_rotate_right ( ctx : context ) ( i : int ) ( t : expr ) = - expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (Expr.gno t)) - let mk_ext_rotate_left ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_ext_rotate_right ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_bv2int ( ctx : context ) ( t : expr ) ( signed : bool ) = - expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (Expr.gno t) signed) - let mk_add_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = - (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) - let mk_add_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_sub_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_sub_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = - (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) - let mk_sdiv_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_neg_no_overflow ( ctx : context ) ( t : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (Expr.gno t))) - let mk_mul_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = - (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) - let mk_mul_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx size))) -end - - -module Proof = -struct - let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - let is_asserted ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - let is_goal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_OEQ) - let is_modus_ponens ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - let is_reflexivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - let is_symmetry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - let is_transitivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - let is_Transitivity_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - let is_monotonicity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - let is_quant_intro ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - let is_distributivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - let is_and_elimination ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - let is_or_elimination ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - let is_rewrite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - let is_rewrite_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - let is_pull_quant ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - let is_pull_quant_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - let is_push_quant ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - let is_elim_unused_vars ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - let is_der ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - let is_quant_inst ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - let is_hypothesis ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - let is_lemma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - let is_unit_resolution ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - let is_iff_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - let is_iff_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - let is_commutativity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - let is_def_axiom ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - let is_def_intro ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - let is_apply_def ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - let is_iff_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - let is_nnf_pos ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - let is_nnf_neg ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - let is_nnf_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - let is_cnf_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - let is_skolemize ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - let is_modus_ponens_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - let is_theory_lemma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) -end - - -module Goal = -struct - type goal = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : goal = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.goal_inc_ref ; - dec_ref = Z3native.goal_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_precision ( x : goal ) = - goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) - - let is_precise ( x : goal ) = - (get_precision x) == GOAL_PRECISE - - let is_underapproximation ( x : goal ) = - (get_precision x) == GOAL_UNDER - - let is_overapproximation ( x : goal ) = - (get_precision x) == GOAL_OVER - - let is_garbage ( x : goal ) = - (get_precision x) == GOAL_UNDER_OVER - - let add ( x : goal ) ( constraints : expr list ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e) in - ignore (List.map f constraints) ; - () - - let is_inconsistent ( x : goal ) = - Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) - - let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) - - let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) - - let get_formulas ( x : goal ) = - let n = get_size x in - let f i = ((expr_of_ptr (z3obj_gc x) - (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in - mk_list f n - - let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) - - let is_decided_sat ( x : goal ) = - Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) - - let is_decided_unsat ( x : goal ) = - Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) - - let translate ( x : goal ) ( to_ctx : context ) = - create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let simplify ( x : goal ) ( p : Params.params option ) = - let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in - Z3native.tactic_inc_ref (z3obj_gnc x) tn ; - let arn = match p with - | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) - | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) - in - Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; - let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in - let res = if sg == 0 then - raise (Z3native.Exception "No subgoals") - else - Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in - Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; - Z3native.tactic_dec_ref (z3obj_gnc x) tn ; - create (z3obj_gc x) res - - let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) - - let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Model = -struct - type model = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : model = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.model_inc_ref ; - dec_ref = Z3native.model_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module FuncInterp = - struct - type func_interp = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : func_interp = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.func_interp_inc_ref ; - dec_ref = Z3native.func_interp_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module FuncEntry = - struct - type func_entry = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : func_entry = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.func_entry_inc_ref ; - dec_ref = Z3native.func_entry_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_value ( x : func_entry ) = - expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) - - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) - - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) - - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) - - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) - - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (List.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in - if (Z3native.is_null np) then - None - else - Some (expr_of_ptr (z3obj_gc x) np) - - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if not (Z3native.is_as_array (z3obj_gnc x) n) then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in - if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) - - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) - - let get_func_decls ( x : model ) = - let n = (get_num_funcs x) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - (mk_list f n_funcs) @ (mk_list g n_consts) - - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in - if not r then - None - else - Some(expr_of_ptr (z3obj_gc x) v) - - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) - - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - mk_list f n - - let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Probe = -struct - type probe = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : probe = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.probe_inc_ref ; - dec_ref = Z3native.probe_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - - let apply ( x : probe ) ( g : Goal.goal ) = - Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) - - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes (context_gno ctx) - - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name (context_gno ctx) i) in - mk_list f n - - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr (context_gno ctx) name - - let mk_probe ( ctx : context ) ( name : string ) = - (create ctx (Z3native.mk_probe (context_gno ctx) name)) - - let const ( ctx : context ) ( v : float ) = - (create ctx (Z3native.probe_const (context_gno ctx) v)) - - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let not_ ( ctx : context ) ( p : probe ) = - (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) -end - - -module Tactic = -struct - type tactic = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : tactic = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.tactic_inc_ref ; - dec_ref = Z3native.tactic_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module ApplyResult = - struct - type apply_result = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : apply_result = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.apply_result_inc_ref ; - dec_ref = Z3native.apply_result_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) - - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_subgoal ( x : apply_result ) ( i : int ) = - Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) - - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) - - let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) - - let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = - match p with - | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) - | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) - - let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) - - let get_tactic_names ( ctx : context ) = - let n = (get_num_tactics ctx ) in - let f i = (Z3native.get_tactic_name (context_gno ctx) i) in - mk_list f n - - let get_tactic_description ( ctx : context ) ( name : string ) = - Z3native.tactic_get_descr (context_gno ctx) name - - let mk_tactic ( ctx : context ) ( name : string ) = - create ctx (Z3native.mk_tactic (context_gno ctx) name) - - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = - let f p c = (match p with - | None -> (Some (z3obj_gno c)) - | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in - match (List.fold_left f None ts) with - | None -> - create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - | Some(x) -> - let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in - create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) - - let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - - let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) - - let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) - - let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) - - let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) - - let skip ( ctx : context ) = - create ctx (Z3native.tactic_skip (context_gno ctx)) - - let fail ( ctx : context ) = - create ctx (Z3native.tactic_fail (context_gno ctx)) - - let fail_if ( ctx : context ) ( p : Probe.probe ) = - create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) - - let fail_if_not_decided ( ctx : context ) = - create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) - - let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) - - let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - using_params ctx t p - - let par_or ( ctx : context ) ( t : tactic list ) = - let f e = (z3obj_gno e) in - create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) - - let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - - let interrupt ( ctx : context ) = - Z3native.interrupt (context_gno ctx) -end - - -module Solver = -struct - type solver = z3_native_object - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : solver = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.solver_inc_ref ; - dec_ref = Z3native.solver_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let string_of_status ( s : status) = match s with - | UNSATISFIABLE -> "unsatisfiable" - | SATISFIABLE -> "satisfiable" - | _ -> "unknown" - - module Statistics = - struct - type statistics = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : statistics = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.stats_inc_ref ; - dec_ref = Z3native.stats_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - - module Entry = - struct - type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } - - let create_si k v = - let res : statistics_entry = { - m_key = k ; - m_is_int = true ; - m_is_float = false ; - m_int = v ; - m_float = 0.0 - } in - res - - let create_sd k v = - let res : statistics_entry = { - m_key = k ; - m_is_int = false ; - m_is_float = true ; - m_int = 0 ; - m_float = v - } in - res - - - let get_key (x : statistics_entry) = x.m_key - let get_int (x : statistics_entry) = x.m_int - let get_float (x : statistics_entry) = x.m_float - let is_int (x : statistics_entry) = x.m_is_int - let is_float (x : statistics_entry) = x.m_is_float - let to_string_value (x : statistics_entry) = - if (is_int x) then - string_of_int (get_int x) - else if (is_float x) then - string_of_float (get_float x) - else - raise (Z3native.Exception "Unknown statistical entry type") - let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) - end - - let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) - - let get_entries ( x : statistics ) = - let n = (get_size x ) in - let f i = ( - let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in - if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) - else - (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) - ) in - mk_list f n - - let get_keys ( x : statistics ) = - let n = (get_size x) in - let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get ( x : statistics ) ( key : string ) = - let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in - List.fold_left f None (get_entries x) - end - - let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) - - let set_parameters ( x : solver ) ( p : Params.params )= - Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - - let get_param_descrs ( x : solver ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) - - let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) - - let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n - - let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - - let add ( x : solver ) ( constraints : expr list ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in - ignore (List.map f constraints) - - let assert_and_track_l ( x : solver ) ( cs : expr list ) ( ps : expr list ) = - if ((List.length cs) != (List.length ps)) then - raise (Z3native.Exception "Argument size mismatch") - else - let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno a) (Expr.gno b)) in - ignore (List.iter2 f cs ps) - - let assert_and_track ( x : solver ) ( c : expr ) ( p : expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno c) (Expr.gno p) - - let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVector.get_size a) - - let get_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size a) in - let f i = (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in - mk_list f n - - let check ( x : solver ) ( assumptions : expr list ) = - let r = - if ((List.length assumptions) == 0) then - lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) - else - let f x = (Expr.gno x) in - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) - in - match r with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN - - let get_model ( x : solver ) = - let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in - if (Z3native.is_null q) then - None - else - Some (Model.create (z3obj_gc x) q) - - let get_proof ( x : solver ) = - let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size cn) in - let f i = (AST.ASTVector.get cn i) in - mk_list f n - - let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - let get_statistics ( x : solver ) = - (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) - - let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = - match logic with - | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) - - let mk_solver_s ( ctx : context ) ( logic : string ) = - mk_solver ctx (Some (Symbol.mk_string ctx logic)) - - let mk_simple_solver ( ctx : context ) = - (create ctx (Z3native.mk_simple_solver (context_gno ctx))) - - let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = - (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) - - let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Fixedpoint = -struct - type fixedpoint = z3_native_object - - let create ( ctx : context ) = - let res : fixedpoint = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.fixedpoint_inc_ref ; - dec_ref = Z3native.fixedpoint_dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; - (z3obj_create res) ; - res - - - let get_help ( x : fixedpoint ) = - Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) - - let set_params ( x : fixedpoint ) ( p : Params.params )= - Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - - let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let add ( x : fixedpoint ) ( constraints : expr list ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in - ignore (List.map f constraints) ; - () - - let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - - let add_rule ( x : fixedpoint ) ( rule : expr ) ( name : Symbol.symbol option ) = - match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) (Symbol.gno y) - - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) - - let query ( x : fixedpoint ) ( query : expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Expr.gno query))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN - - let query_r ( x : fixedpoint ) ( relations : func_decl list ) = - let f x = ptr_of_ast (ast_of_func_decl x) in - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN - - let push ( x : fixedpoint ) = - Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) - - let pop ( x : fixedpoint ) = - Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - - let update_rule ( x : fixedpoint ) ( rule : expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) (Symbol.gno name) - - let get_answer ( x : fixedpoint ) = - let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let get_reason_unknown ( x : fixedpoint ) = - Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) - - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) - - let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - - let to_string_q ( x : fixedpoint ) ( queries : expr list ) = - let f x = Expr.gno x in - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) - - let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - mk_list f n - - let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - mk_list f n - - let mk_fixedpoint ( ctx : context ) = create ctx -end - - -module SMT = -struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : expr list ) ( formula : expr ) = - Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (List.length assumptions) (let f x = Expr.gno (x) in (Array.of_list (List.map f assumptions))) - (Expr.gno formula) - - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Z3native.parse_smtlib_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Z3native.parse_smtlib_file (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - - let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) - - let get_smtlib_formulas ( ctx : context ) = - let n = (get_num_smtlib_formulas ctx ) in - let f i =(expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in - mk_list f n - - let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) - - let get_smtlib_assumptions ( ctx : context ) = - let n = (get_num_smtlib_assumptions ctx ) in - let f i = (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in - mk_list f n - - let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) - - let get_smtlib_decls ( ctx : context ) = - let n = (get_num_smtlib_decls ctx) in - let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in - mk_list f n - - let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - - let get_smtlib_sorts ( ctx : context ) = - let n = (get_num_smtlib_sorts ctx) in - let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in - mk_list f n - - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) -end - -module Interpolation = -struct - let mk_interpolant ( ctx : context ) ( a : expr ) = - (expr_of_ptr ctx (Z3native.mk_interpolant (context_gno ctx) (Expr.gno a))) - - let mk_interpolation_context ( settings : ( string * string ) list ) = - let cfg = Z3native.mk_config () in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_interpolation_context cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - Z3native.set_internal_error_handler v ; - let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in - let f = fun o -> dispose_context o in - Gc.finalise f res; - res - - let get_interpolant ( ctx : context ) ( pf : expr ) ( pat: expr ) ( p : Params.params ) = - (ASTVector.create ctx (Z3native.get_interpolant (context_gno ctx) (Expr.gno pf) (Expr.gno pat) (z3obj_gno p))) - - let compute_interpolant ( ctx : context ) ( pat : expr ) ( p : Params.params ) = - let (r, interp, model) = (Z3native.compute_interpolant (context_gno ctx) (Expr.gno pat) (z3obj_gno p)) in - match (lbool_of_int r) with - | L_TRUE -> ((ASTVector.create ctx interp), (Model.create ctx model)) - | _ -> raise (Z3native.Exception "Error computing interpolant.") - - let get_interpolation_profile ( ctx : context ) = - (Z3native.interpolation_profile (context_gno ctx)) - - let read_interpolation_problem ( ctx : context ) ( filename : string ) = - let (r, num, cnsts, parents, error, num_theory, theory) = (Z3native.read_interpolation_problem (context_gno ctx) filename) in - match r with - | 0 -> raise (Z3native.Exception "Interpolation problem could not be read.") - | _ -> - let f1 i = (expr_of_ptr ctx (Array.get cnsts i)) in - let f2 i = (Array.get parents i) in - let f3 i = (expr_of_ptr ctx (Array.get theory i)) in - ((mk_list f1 num), - (mk_list f2 num), - (mk_list f3 num_theory)) - - let check_interpolant ( ctx : context ) ( num : int ) ( cnsts : Expr.expr list ) ( parents : int list ) ( interps : Expr.expr list ) ( num_theory : int ) ( theory : Expr.expr list ) = - let (r, str) = (Z3native.check_interpolant (context_gno ctx) - num - (let f x = Expr.gno x in (Array.of_list (List.map f cnsts))) - (Array.of_list parents) - (let f x = Expr.gno x in (Array.of_list (List.map f interps))) - num_theory - (let f x = Expr.gno x in (Array.of_list (List.map f theory)))) in - match (lbool_of_int r) with - | L_UNDEF -> raise (Z3native.Exception "Interpolant could not be verified.") - | L_FALSE -> raise (Z3native.Exception "Interpolant could not be verified.") - | _ -> () - - let write_interpolation_problem ( ctx : context ) ( num : int ) ( cnsts : Expr.expr list ) ( parents : int list ) ( filename : string ) ( num_theory : int ) ( theory : Expr.expr list ) = - (Z3native.write_interpolation_problem (context_gno ctx) num (expr_lton cnsts) (Array.of_list parents) filename num_theory (expr_lton theory)) ; - () -end - -let set_global_param ( id : string ) ( value : string ) = - (Z3native.global_param_set id value) - -let get_global_param ( id : string ) = - let (r, v) = (Z3native.global_param_get id) in - if not r then - None - else - Some v - -let global_param_reset_all = - Z3native.global_param_reset_all - -let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages enabled From e2ac8c73d9ad7ac7fa59f9a15ff70da94c6fc2fb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 04:37:46 +0000 Subject: [PATCH 350/507] ML API temp files added to .gitignore Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index a1a8b7f6b..648013ca1 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,6 @@ src/util/version.h src/api/java/Native.cpp src/api/java/Native.java src/api/java/enumerations/*.java - *.bak doc/api doc/code From d2d4bf7f835c65d58aa5f56b11bb36e0a5b5bee8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 08:06:10 +0000 Subject: [PATCH 351/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 45 ------------------------- scripts/update_api.py | 45 +++++++------------------ src/api/ml/z3.ml | 78 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 87 insertions(+), 81 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 33129f555..2c525861c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1866,11 +1866,7 @@ def mk_config(): if GPROF: print('gprof: enabled') print('Python version: %s' % distutils.sysconfig.get_python_version()) -<<<<<<< HEAD print('ML API: %s' % is_ml_enabled()) -======= - print 'ML API: %s' % is_ml_enabled() ->>>>>>> Beginnings of a new ML API if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) @@ -2738,9 +2734,6 @@ def mk_z3consts_ml(api_files): if not os.path.exists(gendir): os.mkdir(gendir) -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') efile.write('(** The enumeration types of Z3. *)\n\n') @@ -2822,23 +2815,7 @@ def mk_z3consts_ml(api_files): efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') efile.write('(** The enumeration types of Z3. *)\n\n') -======= - efile = open('%s.ml' % os.path.join(gendir, "z3_enums"), 'w') - efile.write('(* Automatically generated file *)\n\n') - # efile.write('module z3_enums = struct\n\n'); - - ->>>>>>> More new ML API -======= - efile = open('%s.ml' % os.path.join(gendir, "enumerations"), 'w') - efile.write('(* Automatically generated file *)\n\n') - efile.write('module Enumerations = struct\n') ->>>>>>> More ML API -======= - efile = open('%s.ml' % os.path.join(gendir, "z3enums"), 'w') - efile.write('(* Automatically generated file *)\n\n') efile.write('module Z3enums = struct\n') ->>>>>>> New native ML API layer. for api_file in api_files: api_file_c = ml.find_file(api_file, ml.name) api_file = os.path.join(api_file_c.src_dir, api_file) @@ -2884,8 +2861,6 @@ def mk_z3consts_ml(api_files): if m: name = words[1] if name not in DeprecatedEnums: -<<<<<<< HEAD -<<<<<<< HEAD efile.write('(** %s *)\n' % name[3:]) efile.write('type %s =\n' % name[3:]) # strip Z3_ for k, i in decls.iteritems(): @@ -2896,17 +2871,10 @@ def mk_z3consts_ml(api_files): efile.write('(** Convert int to %s*)\n' % name[3:]) efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_ efile.write('\n') -======= efile.write('\n(* %s *)\n' % name) -======= ->>>>>>> More ML API efile.write('type %s =\n' % name[3:]) # strip Z3_ for k, i in decls.iteritems(): -<<<<<<< HEAD efile.write(' | %s \n' % k[3:]) # strip Z3_ ->>>>>>> More new ML API -======= - efile.write(' | %s \n' % k[3:]) # strip Z3_ efile.write('\n') efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ efile.write(' match x with\n') @@ -2919,7 +2887,6 @@ def mk_z3consts_ml(api_files): efile.write(' | %d -> %s\n' % (i, k[3:])) # use Z3.Exception? efile.write(' | _ -> raise (Failure "undefined enum value")\n\n') ->>>>>>> More ML API mode = SEARCHING else: if words[2] != '': @@ -2930,21 +2897,9 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 -<<<<<<< HEAD -<<<<<<< HEAD - if VERBOSE: - print "Generated '%s/z3enums.mli'" % ('%s' % gendir) -======= - efile.write('\n') - # efile.write'end\n'); - if VERBOSE: - print "Generated '%s/z3_enums.ml'" % ('%s' % gendir) ->>>>>>> More new ML API -======= efile.write('end\n') if VERBOSE: print "Generated '%s/enumerations.ml'" % ('%s' % gendir) ->>>>>>> More ML API def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index f142c8ec1..a586ad6e3 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -159,7 +159,7 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I # Mapping to ML types Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', STRING : 'string', STRING_PTR : 'char**', - BOOL : 'int', SYMBOL : 'symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } + BOOL : 'int', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -213,10 +213,7 @@ def type2javaw(ty): def type2ml(ty): global Type2ML - if (ty >= FIRST_OBJ_ID): - return 'int' - else: - return Type2ML[ty] + return Type2ML[ty] def _in(ty): return (IN, ty); @@ -1106,6 +1103,7 @@ def is_array_param(p): return False def mk_ml(): + global Type2Str if not is_ml_enabled(): return ml_dir = get_component('ml').src_dir @@ -1114,29 +1112,12 @@ def mk_ml(): ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n\n') ml_native.write('open Z3enums\n\n') - ml_native.write('module Z3native = struct\n\n') - ml_native.write(' type context\n') - ml_native.write(' and symbol\n') - ml_native.write(' and ast\n') - ml_native.write(' and sort = private ast\n') - ml_native.write(' and func_decl = private ast\n') - ml_native.write(' and app = private ast\n') - ml_native.write(' and pattern = private ast\n') - ml_native.write(' and params\n') - ml_native.write(' and param_descrs\n') - ml_native.write(' and model\n') - ml_native.write(' and func_interp\n') - ml_native.write(' and func_entry\n') - ml_native.write(' and fixedpoint\n') - ml_native.write(' and ast_vector\n') - ml_native.write(' and ast_map\n') - ml_native.write(' and goal\n') - ml_native.write(' and tactic\n') - ml_native.write(' and probe\n') - ml_native.write(' and apply_result\n') - ml_native.write(' and solver\n') - ml_native.write(' and stats\n\n') - ml_native.write(' exception Exception of string\n\n') + ml_native.write('type ptr\n') + ml_native.write('and z3_symbol = ptr\n') + for k, v in Type2Str.iteritems(): + if is_obj(k): + ml_native.write('and %s = ptr\n' % v.lower()) + ml_native.write('\nexception Exception of string\n\n') # ML declarations ml_native.write(' module ML2C = struct\n\n') @@ -1192,9 +1173,9 @@ def mk_ml(): i = i + 1 ml_native.write(') in\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (Z3enums.int2error_code (ML2C.n_get_error_code a0)) in \n') - ml_native.write(' if err <> Z3enums.OK then\n') - ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (Z3enums.error_code2int err)))\n') + ml_native.write(' let err = (int2error_code (ML2C.n_get_error_code a0)) in \n') + ml_native.write(' if err <> OK then\n') + ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (error_code2int err)))\n') ml_native.write(' else\n') if result == VOID: ml_native.write(' ()\n') @@ -1202,8 +1183,6 @@ def mk_ml(): ml_native.write(' res\n') ml_native.write('\n') - ml_native.write('end\n') - # C interface ml_wrapper = open(ml_wrapperf, 'w') ml_wrapper.write('// Automatically generated file\n\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 5251a8767..a6a388aa7 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,11 +1,83 @@ (* Author: CM Wintersteiger (C) Microsoft Research, 2012 -*) + *) open Z3enums open Z3native -module Z3 = struct +class context = + object (self) + val m_n_ctx : Z3native.z3_context option = None + val mutable m_refCount : int = 0 + initializer Gc.finalise (fun self -> self#dispose ()) self + method dispose () = + Printf.printf "Disposing %d \n" (Oo.id self) ; + match m_n_ctx with + | Some(x) -> (del_context x) + | None -> () + method sub_one_ctx_obj = m_refCount <- m_refCount - 1 + method add_one_ctx_obj = m_refCount <- m_refCount + 1 + end + +class virtual z3object ctx_init obj_init = + object (self) + val mutable m_ctx : context option = ctx_init + val mutable m_n_obj : Z3native.ptr option = obj_init + + initializer + (match m_n_obj with + | Some (x) -> self#incref x; + (match m_ctx with + | Some(x) -> x#add_one_ctx_obj + | None -> () + ) + | None -> () + ); + Gc.finalise (fun self -> self#dispose ()) self + + method virtual incref : Z3native.ptr -> unit + method virtual decref : Z3native.ptr -> unit + + (* + Disposes of the underlying native Z3 object. + *) + method dispose () = + Printf.printf "Disposing %d \n" (Oo.id self) ; + (match m_n_obj with + | Some (x) -> self#decref x; m_n_obj <- None + | None -> () + ); + (match m_ctx with + | Some (x) -> x#sub_one_ctx_obj + | None -> () + ); + m_ctx <- None + + + method get_native_object = m_n_obj + + method set_native_object x = + (match x with + | Some(x) -> self#incref x + | None -> () + ); + (match m_n_obj with + | Some(x) -> self#decref x + | None -> () + ); + m_n_obj <- x + + method get_context = m_ctx + + method array_to_native a = + let f e = e#get_native_object in + (Array.map f a) + + method array_length a = + match a with + | Some(x) -> (Array.length x) + | None -> 0 + + end -end From f7b3529f0166facc8b94b6becbe97b56e4abc54d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 16:33:51 +0000 Subject: [PATCH 352/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- examples/ml/MLExample.ml | 12 ++++++++ scripts/mk_util.py | 9 +++++- src/api/ml/README | 3 -- src/api/ml/z3.ml | 59 ++++++++++++++++++++++++++++++++-------- 4 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 examples/ml/MLExample.ml diff --git a/examples/ml/MLExample.ml b/examples/ml/MLExample.ml new file mode 100644 index 000000000..8cc248206 --- /dev/null +++ b/examples/ml/MLExample.ml @@ -0,0 +1,12 @@ +(* + Copyright (C) 2012 Microsoft Corporation + Author: CM Wintersteiger (cwinter) 2012-12-17 + *) + + open Z3 + + let _ = ignore(Log.open_ "z3.log") ; +let cfg = Some [("model", "true"); ("proof", "false")] in +let ctx = (new context cfg) in +ctx#dispose +;; diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 2c525861c..40828f8c3 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1597,7 +1597,14 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('_ex_%s: ml_example.byte ml_example$(EXE_EXT)\n\n' % self.name) + out.write('_ex_%s: z3.cmxa' % self.name) + deps = '' + for mlfile in get_ml_files(self.ex_dir): + out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) + if IS_WINDOWS: + deps = deps.replace('/', '\\') + out.write('%s\n' % deps) + out.write('\tcd %s && ocamlbuild -build-dir ../../%s -lib z3 MLExample.native && cd -\n\n' % (self.to_src_dir, BUILD_DIR)) class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): diff --git a/src/api/ml/README b/src/api/ml/README index f8984c79e..36f903925 100644 --- a/src/api/ml/README +++ b/src/api/ml/README @@ -1,11 +1,8 @@ This directory is work in progress. We are currently working on a brand new ML API. -<<<<<<< HEAD On Windows, there are no less than four different ports of OCaml. The Z3 build system assumes that either the win32 or the win64 port is installed. This means that OCaml will use `cl' as the underlying C compiler and not the cygwin or mingw compilers. -======= ->>>>>>> Beginnings of a new ML API diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index a6a388aa7..0329402dd 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,27 +1,60 @@ (* - Author: CM Wintersteiger - (C) Microsoft Research, 2012 + Copyright (C) 2012 Microsoft Corporation + Author: CM Wintersteiger (cwinter) 2012-12-17 *) open Z3enums open Z3native -class context = +module Log = + struct + let m_is_open = false +(* CMW: "open" seems to be an invalid function name*) + let open_ fn = int2lbool(open_log fn) == L_TRUE + let close = (close_log) + let append s = (append_log s) + end + +class virtual idisposable = + object + method virtual dispose : unit + end + +class context settings = object (self) - val m_n_ctx : Z3native.z3_context option = None + inherit idisposable + val mutable m_n_ctx : Z3native.z3_context option = None val mutable m_refCount : int = 0 - initializer Gc.finalise (fun self -> self#dispose ()) self - method dispose () = - Printf.printf "Disposing %d \n" (Oo.id self) ; - match m_n_ctx with - | Some(x) -> (del_context x) - | None -> () + + initializer + let cfg = mk_config() in + (match settings with + | Some(x) -> + let f e = (set_param_value cfg (fst e) (snd e)) in + (List.iter f x) + | _ -> () + ) ; + m_n_ctx <- Some (mk_context_rc cfg) ; + del_config(cfg) ; + Gc.finalise (fun self -> self#dispose) self + + method dispose : unit = + if m_refCount == 0 then ( + Printf.printf "Disposing %d \n" (Oo.id self) ; + match m_n_ctx with + | Some(x) -> (del_context x) + | None -> () + ) else ( + (* re-queue for finalization? *) + ) + method sub_one_ctx_obj = m_refCount <- m_refCount - 1 method add_one_ctx_obj = m_refCount <- m_refCount + 1 end class virtual z3object ctx_init obj_init = object (self) + inherit idisposable val mutable m_ctx : context option = ctx_init val mutable m_n_obj : Z3native.ptr option = obj_init @@ -34,7 +67,7 @@ class virtual z3object ctx_init obj_init = ) | None -> () ); - Gc.finalise (fun self -> self#dispose ()) self + Gc.finalise (fun self -> self#dispose) self method virtual incref : Z3native.ptr -> unit method virtual decref : Z3native.ptr -> unit @@ -42,7 +75,7 @@ class virtual z3object ctx_init obj_init = (* Disposes of the underlying native Z3 object. *) - method dispose () = + method dispose = Printf.printf "Disposing %d \n" (Oo.id self) ; (match m_n_obj with | Some (x) -> self#decref x; m_n_obj <- None @@ -70,6 +103,7 @@ class virtual z3object ctx_init obj_init = method get_context = m_ctx +(* method array_to_native a = let f e = e#get_native_object in (Array.map f a) @@ -78,6 +112,7 @@ class virtual z3object ctx_init obj_init = match a with | Some(x) -> (Array.length x) | None -> 0 +*) end From f614f6824e63948123354c6d93597a069478b7d0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 17:26:28 +0000 Subject: [PATCH 353/507] More ML API Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 158 +++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0329402dd..a7d59de9f 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,118 +1,118 @@ (* Copyright (C) 2012 Microsoft Corporation Author: CM Wintersteiger (cwinter) 2012-12-17 - *) +*) open Z3enums open Z3native module Log = - struct - let m_is_open = false -(* CMW: "open" seems to be an invalid function name*) - let open_ fn = int2lbool(open_log fn) == L_TRUE - let close = (close_log) - let append s = (append_log s) - end - +struct + let m_is_open = false + (* CMW: "open" seems to be an invalid function name*) + let open_ fn = int2lbool(open_log fn) == L_TRUE + let close = (close_log) + let append s = (append_log s) +end + class virtual idisposable = - object - method virtual dispose : unit - end +object + method virtual dispose : unit +end class context settings = - object (self) - inherit idisposable - val mutable m_n_ctx : Z3native.z3_context option = None - val mutable m_refCount : int = 0 - - initializer - let cfg = mk_config() in - (match settings with - | Some(x) -> - let f e = (set_param_value cfg (fst e) (snd e)) in - (List.iter f x) - | _ -> () - ) ; - m_n_ctx <- Some (mk_context_rc cfg) ; - del_config(cfg) ; - Gc.finalise (fun self -> self#dispose) self - - method dispose : unit = - if m_refCount == 0 then ( - Printf.printf "Disposing %d \n" (Oo.id self) ; - match m_n_ctx with +object (self) + inherit idisposable + val mutable m_n_ctx : Z3native.z3_context option = None + val mutable m_refCount : int = 0 + + initializer + let cfg = mk_config() in + (match settings with + | Some(x) -> + let f e = (set_param_value cfg (fst e) (snd e)) in + (List.iter f x) + | _ -> () + ) ; + m_n_ctx <- Some (mk_context_rc cfg) ; + del_config(cfg) ; + Gc.finalise (fun self -> self#dispose) self + + method dispose : unit = + if m_refCount == 0 then ( + Printf.printf "Disposing %d \n" (Oo.id self) ; + match m_n_ctx with | Some(x) -> (del_context x) | None -> () - ) else ( - (* re-queue for finalization? *) - ) + ) else ( + (* re-queue for finalization? *) + ) - method sub_one_ctx_obj = m_refCount <- m_refCount - 1 - method add_one_ctx_obj = m_refCount <- m_refCount + 1 - end + method sub_one_ctx_obj = m_refCount <- m_refCount - 1 + method add_one_ctx_obj = m_refCount <- m_refCount + 1 +end class virtual z3object ctx_init obj_init = - object (self) - inherit idisposable - val mutable m_ctx : context option = ctx_init - val mutable m_n_obj : Z3native.ptr option = obj_init - - initializer - (match m_n_obj with +object (self) + inherit idisposable + val mutable m_ctx : context option = ctx_init + val mutable m_n_obj : Z3native.ptr option = obj_init + + initializer + (match m_n_obj with | Some (x) -> self#incref x; - (match m_ctx with + (match m_ctx with | Some(x) -> x#add_one_ctx_obj | None -> () - ) + ) | None -> () - ); - Gc.finalise (fun self -> self#dispose) self + ); + Gc.finalise (fun self -> self#dispose) self - method virtual incref : Z3native.ptr -> unit - method virtual decref : Z3native.ptr -> unit - - (* - Disposes of the underlying native Z3 object. - *) - method dispose = - Printf.printf "Disposing %d \n" (Oo.id self) ; - (match m_n_obj with + method virtual incref : Z3native.ptr -> unit + method virtual decref : Z3native.ptr -> unit + + (* + Disposes of the underlying native Z3 object. + *) + method dispose = + Printf.printf "Disposing %d \n" (Oo.id self) ; + (match m_n_obj with | Some (x) -> self#decref x; m_n_obj <- None | None -> () - ); - (match m_ctx with + ); + (match m_ctx with | Some (x) -> x#sub_one_ctx_obj | None -> () - ); - m_ctx <- None + ); + m_ctx <- None - method get_native_object = m_n_obj + method get_native_object = m_n_obj - method set_native_object x = - (match x with + method set_native_object x = + (match x with | Some(x) -> self#incref x | None -> () - ); - (match m_n_obj with + ); + (match m_n_obj with | Some(x) -> self#decref x | None -> () - ); - m_n_obj <- x + ); + m_n_obj <- x - method get_context = m_ctx + method get_context = m_ctx -(* + (* method array_to_native a = - let f e = e#get_native_object in - (Array.map f a) + let f e = e#get_native_object in + (Array.map f a) method array_length a = - match a with - | Some(x) -> (Array.length x) - | None -> 0 -*) + match a with + | Some(x) -> (Array.length x) + | None -> 0 + *) - end +end From c9cca119c5d89296da457b80d8c1fd0300e98aa1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 20:18:53 +0000 Subject: [PATCH 354/507] File renamed Signed-off-by: Christoph M. Wintersteiger --- examples/ml/{MLExample.ml => mlexample.ml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/ml/{MLExample.ml => mlexample.ml} (100%) diff --git a/examples/ml/MLExample.ml b/examples/ml/mlexample.ml similarity index 100% rename from examples/ml/MLExample.ml rename to examples/ml/mlexample.ml From 0e98d267219e5ad3459030a772c418e9f762b5d7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 22:25:16 +0000 Subject: [PATCH 355/507] ML API and example compilation. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 10 -- examples/ml/ml_example.ml | 272 +------------------------------------- examples/ml/mlexample.ml | 12 -- scripts/mk_util.py | 33 +---- src/api/ml/z3.ml | 2 +- 5 files changed, 15 insertions(+), 314 deletions(-) delete mode 100644 examples/ml/mlexample.ml diff --git a/examples/ml/README b/examples/ml/README index c61716b65..3e1eb0d1c 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -12,13 +12,3 @@ or LD_LIBRARY_PATH=. ./ml_example.byte for the byte-code version. -If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), -then we can compile this example as follows: - -ocamlfind ocamlc -o ml_example.byte -package Z3 -linkpkg ml_example.ml -ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg ml_example.ml - -Note that the resulting binaries depend on the shared z3 library, which needs to be -in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was -installed into ocamlfind, the path that should be added is -`ocamlfind printconf destdir`/Z3 diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 25862b2d7..9c704e4d0 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,269 +4,11 @@ *) open Z3 -open Z3.Symbol -open Z3.Sort -open Z3.Expr -open Z3.Boolean -open Z3.FuncDecl -open Z3.Goal -open Z3.Tactic -open Z3.Tactic.ApplyResult -open Z3.Probe -open Z3.Solver -open Z3.Arithmetic -open Z3.Arithmetic.Integer -open Z3.Arithmetic.Real -open Z3.BitVector - -exception TestFailedException of string - -(** - Model Converter test -*) -let model_converter_test ( ctx : context ) = - Printf.printf "ModelConverterTest\n"; - let xr = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Real.mk_sort ctx)) in - let yr = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Real.mk_sort ctx)) in - let g4 = (mk_goal ctx true false false ) in - (Goal.add g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; - (Goal.add g4 [ (mk_eq ctx - yr - (Arithmetic.mk_add ctx [ xr; (Real.mk_numeral_nd ctx 1 1) ])) ]) ; - (Goal.add g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; - ( - let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in - if ((get_num_subgoals ar) == 1 && - ((is_decided_sat (get_subgoal ar 0)) || - (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - ( - let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") []) g4 None) in - if ((get_num_subgoals ar) == 1 && - ((is_decided_sat (get_subgoal ar 0)) || - (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ; - let solver = (mk_solver ctx None) in - let f e = (Solver.add solver [ e ]) in - ignore (List.map f (get_formulas (get_subgoal ar 0))) ; - let q = (check solver []) in - if q != SATISFIABLE then - raise (TestFailedException "") - else - let m = (get_model solver) in - match m with - | None -> raise (TestFailedException "") - | Some (m) -> - Printf.printf "Solver says: %s\n" (string_of_status q) ; - Printf.printf "Model: \n%s\n" (Model.to_string m) ; - Printf.printf "Converted Model: \n%s\n" (Model.to_string (convert_model ar 0 m)) - ) - -(** - Some basic tests. -*) -let basic_tests ( ctx : context ) = - Printf.printf "BasicTests\n" ; -(* let qi = (mk_int ctx 1) in *) - let fname = (mk_string ctx "f") in - let x = (mk_string ctx "x") in - let y = (mk_string ctx "y") in - let bs = (Boolean.mk_sort ctx) in - let domain = [ bs; bs ] in - let f = (FuncDecl.mk_func_decl ctx fname domain bs) in - let fapp = (mk_app ctx f - [ (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) ]) in - let fargs2 = [ (mk_fresh_const ctx "cp" bs) ] in - let domain2 = [ bs ] in - let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in - let trivial_eq = (mk_eq ctx fapp fapp) in - let nontrivial_eq = (mk_eq ctx fapp fapp2) in - let g = (mk_goal ctx true false false) in - (Goal.add g [ trivial_eq ]) ; - (Goal.add g [ nontrivial_eq ]) ; - Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; - ( - let solver = (mk_solver ctx None) in - (List.iter (fun a -> (Solver.add solver [ a ])) (get_formulas g)) ; - if (check solver []) != SATISFIABLE then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - ( - let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in - if ((get_num_subgoals ar) == 1 && - ((is_decided_sat (get_subgoal ar 0)) || - (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - ( - let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_sat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - (Goal.add g [ (mk_eq ctx - (mk_numeral_int ctx 1 (BitVector.mk_sort ctx 32)) - (mk_numeral_int ctx 2 (BitVector.mk_sort ctx 32))) ] ) - ; - ( - let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - ( - let g2 = (mk_goal ctx true true false) in - let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_sat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - ( - let g2 = (mk_goal ctx true true false) in - (Goal.add g2 [ (Boolean.mk_false ctx) ]) ; - let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ); - ( - let g3 = (mk_goal ctx true true false) in - let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Integer.mk_sort ctx)) in - let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Integer.mk_sort ctx)) in - (Goal.add g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; - (Goal.add g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; - let constr = (mk_eq ctx xc yc) in - (Goal.add g3 [ constr ] ) ; - let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ) ; - model_converter_test ctx ; - (* Real num/den test. *) - let rn = Real.mk_numeral_nd ctx 42 43 in - let inum = (get_numerator rn) in - let iden = get_denominator rn in - Printf.printf "Numerator: %s Denominator: %s\n" (Real.to_string inum) (Real.to_string iden) ; - if ((Real.to_string inum) <> "42" || (Real.to_string iden) <> "43") then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ; - if ((to_decimal_string rn 3) <> "0.976?") then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" - ; - if (to_decimal_string (Real.mk_numeral_s ctx "-1231231232/234234333") 5 <> "-5.25640?") then - raise (TestFailedException "") - else if (to_decimal_string (Real.mk_numeral_s ctx "-123123234234234234231232/234234333") 5 <> "-525641278361333.28170?") then - raise (TestFailedException "") - else if (to_decimal_string (Real.mk_numeral_s ctx "-234234333") 5 <> "-234234333") then - raise (TestFailedException "") - else if (to_decimal_string (Real.mk_numeral_s ctx "234234333/2") 5 <> "117117166.5") then - raise (TestFailedException "") - ; - (* Error handling test. *) - try ( - let i = Integer.mk_numeral_s ctx "1/2" in - raise (TestFailedException "") (* unreachable *) - ) - with Z3native.Exception(_) -> ( - Printf.printf "Exception caught, OK.\n" - ) - -(** - A basic example of how to use quantifiers. -**) -let quantifierExample1 ( ctx : context ) = - Printf.printf "QuantifierExample\n" ; - let is = (Integer.mk_sort ctx) in - let types = [ is; is; is ] in - let names = [ (Symbol.mk_string ctx "x_0"); - (Symbol.mk_string ctx "x_1"); - (Symbol.mk_string ctx "x_2") ] in - let vars = [ (Quantifier.mk_bound ctx 2 (List.nth types 0)); - (Quantifier.mk_bound ctx 2 (List.nth types 1)); - (Quantifier.mk_bound ctx 2 (List.nth types 2)) ] in - let xs = [ (Integer.mk_const ctx (List.nth names 0)); - (Integer.mk_const ctx (List.nth names 1)); - (Integer.mk_const ctx (List.nth names 2)) ] in - - let body_vars = (Boolean.mk_and ctx - [ (mk_eq ctx - (Arithmetic.mk_add ctx [ (List.nth vars 0) ; (Integer.mk_numeral_i ctx 1)]) - (Integer.mk_numeral_i ctx 2)) ; - (mk_eq ctx - (Arithmetic.mk_add ctx [ (List.nth vars 1); (Integer.mk_numeral_i ctx 2)]) - (Arithmetic.mk_add ctx [ (List.nth vars 2); (Integer.mk_numeral_i ctx 3)])) ]) in - let body_const = (Boolean.mk_and ctx - [ (mk_eq ctx - (Arithmetic.mk_add ctx [ (List.nth xs 0); (Integer.mk_numeral_i ctx 1)]) - (Integer.mk_numeral_i ctx 2)) ; - (mk_eq ctx - (Arithmetic.mk_add ctx [ (List.nth xs 1); (Integer.mk_numeral_i ctx 2)]) - (Arithmetic.mk_add ctx [ (List.nth xs 2); (Integer.mk_numeral_i ctx 3)])) ]) in - - let x = (Quantifier.mk_forall ctx types names body_vars (Some 1) [] [] (Some (Symbol.mk_string ctx "Q1")) (Some (Symbol.mk_string ctx "skid1"))) in - Printf.printf "Quantifier X: %s\n" (Quantifier.to_string x) ; - let y = (Quantifier.mk_forall_const ctx xs body_const (Some 1) [] [] (Some (Symbol.mk_string ctx "Q2")) (Some (Symbol.mk_string ctx "skid2"))) in - Printf.printf "Quantifier Y: %s\n" (Quantifier.to_string y) ; - if (is_true (Quantifier.expr_of_quantifier x)) then - raise (TestFailedException "") (* unreachable *) - else if (is_false (Quantifier.expr_of_quantifier x)) then - raise (TestFailedException "") (* unreachable *) - else if (is_const (Quantifier.expr_of_quantifier x)) then - raise (TestFailedException "") (* unreachable *) - -let _ = - try ( - if not (Log.open_ "z3.log") then - raise (TestFailedException "Log couldn't be opened.") - else - ( - Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = [("model", "true"); ("proof", "false")] in - let ctx = (mk_context cfg) in - let is = (Symbol.mk_int ctx 42) in - let ss = (Symbol.mk_string ctx "mySymbol") in - let bs = (Boolean.mk_sort ctx) in - let ints = (Integer.mk_sort ctx) in - let rs = (Real.mk_sort ctx) in - Printf.printf "int symbol: %s\n" (Symbol.to_string is); - Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string bs); - Printf.printf "int sort: %s\n" (Sort.to_string ints); - Printf.printf "real sort: %s\n" (Sort.to_string rs); - basic_tests ctx ; - quantifierExample1 ctx ; - Printf.printf "Disposing...\n"; - Gc.full_major () - ); - Printf.printf "Exiting.\n" ; - exit 0 - ) with Z3native.Exception(msg) -> ( - Printf.printf "Z3 EXCEPTION: %s\n" msg ; - exit 1 - ) + +let _ = ignore(Log.open_ "z3.log") ; + let cfg = Some [("model", "true"); ("proof", "false")] in + let ctx = (new context cfg) in + Printf.printf "Disposing...\n"; + ctx#dispose ; + Printf.printf "Exiting.\n"; ;; diff --git a/examples/ml/mlexample.ml b/examples/ml/mlexample.ml deleted file mode 100644 index 8cc248206..000000000 --- a/examples/ml/mlexample.ml +++ /dev/null @@ -1,12 +0,0 @@ -(* - Copyright (C) 2012 Microsoft Corporation - Author: CM Wintersteiger (cwinter) 2012-12-17 - *) - - open Z3 - - let _ = ignore(Log.open_ "z3.log") ; -let cfg = Some [("model", "true"); ("proof", "false")] in -let ctx = (new context cfg) in -ctx#dispose -;; diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 40828f8c3..38af3893f 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1435,10 +1435,6 @@ class MLComponent(Component): bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') mk_dir(bld_dir) libfile = '%s$(SO_EXT)' % self.lib_name - # for mlfile in get_ml_files(self.src_dir): - # out.write('%si: libz3$(SO_EXT) %s\n' % (os.path.join('api', 'ml', mlfile),os.path.join(self.to_src_dir, mlfile))) - # out.write('\tocamlopt -I %s -i %s > %si\n' % (os.path.join('api', 'ml'), os.path.join(self.to_src_dir, mlfile), os.path.join('api', 'ml', mlfile))) - # out.write('\tocamlopt -I %s -c %si \n' % (os.path.join('api', 'ml'), os.path.join('api','ml', mlfile))) out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) @@ -1446,11 +1442,9 @@ class MLComponent(Component): out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) out.write('z3.cmxa: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -lflags -cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cmxa && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) - out.write('\tcp api/ml/z3.cmxa .\n') + out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('z3.cma: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -lflags -custom,-cclib,../../../%s/libz3ml.so,-cclib,../../../%s/libz3.so -build-dir ../../../%s/api/ml z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR,BUILD_DIR,BUILD_DIR)) - out.write('\tcp api/ml/z3.cma .\n') + out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -custom,-cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3native$(OBJ_EXT) z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('ml: z3.cmxa z3.cma\n') out.write('\n') @@ -1575,36 +1569,23 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: api/ml/z3ml.cmxa ') + out.write('ml_example.byte: z3.cma ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') - out.write('\t%s ' % OCAMLC) - if DEBUG_MODE: - out.write('-g ') - out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3ml.cma') + out.write('\tocamlc -g -o ml_example.byte -I . z3.cma -I api/ml') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example$(EXE_EXT): api/ml/z3ml.cmxa ml_example.byte') + out.write('ml_example($EXE_EXT): z3.cmxa ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') - out.write('\t%s ' % OCAMLOPT) - if DEBUG_MODE: - out.write('-g ') - out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3ml.cmxa') + out.write('\tocamlopt -g -o ml_example -I . z3.cmxa -I api/ml') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('_ex_%s: z3.cmxa' % self.name) - deps = '' - for mlfile in get_ml_files(self.ex_dir): - out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) - if IS_WINDOWS: - deps = deps.replace('/', '\\') - out.write('%s\n' % deps) - out.write('\tcd %s && ocamlbuild -build-dir ../../%s -lib z3 MLExample.native && cd -\n\n' % (self.to_src_dir, BUILD_DIR)) + out.write('_ex_%s: ml_example.byte ml_example($EXE_EXT)\n\n' % self.name) class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index a7d59de9f..68edd9b42 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -76,7 +76,7 @@ object (self) Disposes of the underlying native Z3 object. *) method dispose = - Printf.printf "Disposing %d \n" (Oo.id self) ; + Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with | Some (x) -> self#decref x; m_n_obj <- None | None -> () From 50560ba791c23f89ad40178e4930f7fec24155d8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 19 Dec 2012 23:31:42 +0000 Subject: [PATCH 356/507] more ML API Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 94 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 68edd9b42..9812bd790 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -23,48 +23,42 @@ end class context settings = object (self) inherit idisposable - val mutable m_n_ctx : Z3native.z3_context option = None + + val mutable m_n_ctx : Z3native.z3_context = + let cfg = mk_config() in + let f e = (set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = mk_context_rc cfg in + del_config(cfg) ; + v + val mutable m_refCount : int = 0 - initializer - let cfg = mk_config() in - (match settings with - | Some(x) -> - let f e = (set_param_value cfg (fst e) (snd e)) in - (List.iter f x) - | _ -> () - ) ; - m_n_ctx <- Some (mk_context_rc cfg) ; - del_config(cfg) ; - Gc.finalise (fun self -> self#dispose) self + initializer Gc.finalise (fun self -> self#dispose) self method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing %d \n" (Oo.id self) ; - match m_n_ctx with - | Some(x) -> (del_context x) - | None -> () + (del_context m_n_ctx) ) else ( (* re-queue for finalization? *) ) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 method add_one_ctx_obj = m_refCount <- m_refCount + 1 + method get_native = m_n_ctx end class virtual z3object ctx_init obj_init = object (self) inherit idisposable - val mutable m_ctx : context option = ctx_init + val mutable m_ctx : context = ctx_init val mutable m_n_obj : Z3native.ptr option = obj_init initializer (match m_n_obj with | Some (x) -> self#incref x; - (match m_ctx with - | Some(x) -> x#add_one_ctx_obj - | None -> () - ) + m_ctx#add_one_ctx_obj | None -> () ); Gc.finalise (fun self -> self#dispose) self @@ -78,15 +72,9 @@ object (self) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with - | Some (x) -> self#decref x; m_n_obj <- None + | Some (x) -> self#decref x; m_n_obj <- None; m_ctx#sub_one_ctx_obj | None -> () ); - (match m_ctx with - | Some (x) -> x#sub_one_ctx_obj - | None -> () - ); - m_ctx <- None - method get_native_object = m_n_obj @@ -102,6 +90,7 @@ object (self) m_n_obj <- x method get_context = m_ctx + method get_native_context = m_ctx#get_native (* method array_to_native a = @@ -113,6 +102,57 @@ object (self) | Some(x) -> (Array.length x) | None -> 0 *) +end + +class symbol ctx_init obj_init = +object (self) + inherit z3object ctx_init obj_init + + method incref o = () + method decref o = () + + method kind = match m_n_obj with + | Some(x) -> (int2symbol_kind (get_symbol_kind self#get_native_context x)) + | _ -> raise (Exception "Underlying object lost") + + method is_int_symbol = match m_n_obj with + | Some(x) -> self#kind == INT_SYMBOL + | _ -> false + + method is_string_symbol = match m_n_obj with + | Some(x) -> self#kind == STRING_SYMBOL + | _ -> false + + method to_string = match m_n_obj with + | Some(x) -> + ( + match self#kind with + | INT_SYMBOL -> (string_of_int (get_symbol_int self#get_native_context x)) + | STRING_SYMBOL -> (get_symbol_string self#get_native_context x) + ) + | None -> "" + + method create ctx obj = + match obj with + | Some(x) -> ( + match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with + | INT_SYMBOL -> (new intsymbol ctx obj :> symbol) + | STRING_SYMBOL -> (new stringsymbol ctx obj :> symbol) + ) + | None -> raise (Exception "Can't create null objects") end +and intsymbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init + + method get_int = match m_n_obj with + | Some(x) -> (get_symbol_int m_ctx#get_native x) + | None -> 0 +end + +and stringsymbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end From 1685e3dd6fbf3341aadc1d6b9bfa72722b65e061 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 04:10:38 +0000 Subject: [PATCH 357/507] ML API bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 20 +++++-- scripts/update_api.py | 22 ++++--- src/api/ml/z3.ml | 121 +++++++++++++++++++++++--------------- 3 files changed, 99 insertions(+), 64 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 9c704e4d0..c79b3cdaa 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,11 +4,19 @@ *) open Z3 - -let _ = ignore(Log.open_ "z3.log") ; - let cfg = Some [("model", "true"); ("proof", "false")] in - let ctx = (new context cfg) in - Printf.printf "Disposing...\n"; - ctx#dispose ; + +exception ExampleException of string + +let _ = + if not (Log.open_ "z3.log") then + raise (ExampleException "Log couldn't be opened.") + else + ( + Printf.printf "Running Z3 version %s\n" Version.to_string ; + let cfg = [("model", "true"); ("proof", "false")] in + let ctx = (new context cfg) in + Printf.printf "Disposing...\n"; + ctx#dispose (* can do, but we'd rather let it go out of scope *) ; + ); Printf.printf "Exiting.\n"; ;; diff --git a/scripts/update_api.py b/scripts/update_api.py index a586ad6e3..25adce2af 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1,4 +1,3 @@ - ############################################ # Copyright (c) 2012 Microsoft Corporation # @@ -328,16 +327,12 @@ def param2ml(p): if k == OUT: if param_type(p) == INT or param_type(p) == UINT or param_type(p) == INT64 or param_type(p) == UINT64: return "int" - elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: - return "int" elif param_type(p) == STRING: return "string" else: return "ptr" elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: return "%s array" % type2ml(param_type(p)) - elif k == OUT_MANAGED_ARRAY: - return "%s array" % type2ml(param_type(p)); else: return type2ml(param_type(p)) @@ -1131,9 +1126,16 @@ def mk_ml(): ml_native.write('%s -> ' % param2ml(p)) if len(op) > 0: ml_native.write('(') - ml_native.write('%s' % type2ml(result)) + first = True + if result != VOID or len(op) == 0: + ml_native.write('%s' % type2ml(result)) + first = False for p in op: - ml_native.write(' * %s' % param2ml(p)) + if first: + first = False + else: + ml_native.write(' * ') + ml_native.write('%s' % param2ml(p)) if len(op) > 0: ml_native.write(')') ml_native.write('\n') @@ -1160,11 +1162,13 @@ def mk_ml(): i = i + 1 ml_native.write(' = \n') ml_native.write(' ') - if result == VOID: + if result == VOID and len(op) == 0: ml_native.write('let _ = ') else: ml_native.write('let res = ') ml_native.write('(ML2C.n_%s' % (ml_method_name(name))) + if len(ip) == 0: + ml_native.write(' ()') first = True i = 0; for p in params: @@ -1177,7 +1181,7 @@ def mk_ml(): ml_native.write(' if err <> OK then\n') ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (error_code2int err)))\n') ml_native.write(' else\n') - if result == VOID: + if result == VOID and len(op) == 0: ml_native.write(' ()\n') else: ml_native.write(' res\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 9812bd790..31bb7e5fc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -9,12 +9,27 @@ open Z3native module Log = struct let m_is_open = false - (* CMW: "open" seems to be an invalid function name*) - let open_ fn = int2lbool(open_log fn) == L_TRUE - let close = (close_log) - let append s = (append_log s) + (* CMW: "open" seems to be an invalid function name*) + let open_ fn = let rv = (open_log fn) in + Printf.printf "ol returned %d\n" rv ; + ((int2lbool rv) == L_TRUE) + let close = close_log + let append s = append_log s end - + +module Version = +struct + let major = let (x, _, _, _) = get_version in x + let minor = let (_, x, _, _) = get_version in x + let build = let (_, _, x, _) = get_version in x + let revision = let (_, _, _, x) = get_version in x + let to_string = + string_of_int major ^ "." ^ + string_of_int minor ^ "." ^ + string_of_int build ^ "." ^ + string_of_int revision ^ "." +end + class virtual idisposable = object method virtual dispose : unit @@ -25,7 +40,7 @@ object (self) inherit idisposable val mutable m_n_ctx : Z3native.z3_context = - let cfg = mk_config() in + let cfg = mk_config in let f e = (set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = mk_context_rc cfg in @@ -34,14 +49,15 @@ object (self) val mutable m_refCount : int = 0 - initializer Gc.finalise (fun self -> self#dispose) self + initializer + Gc.finalise (fun self -> self#dispose) self method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing %d \n" (Oo.id self) ; (del_context m_n_ctx) ) else ( - (* re-queue for finalization? *) + (* re-queue for finalization? *) ) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 @@ -66,9 +82,9 @@ object (self) method virtual incref : Z3native.ptr -> unit method virtual decref : Z3native.ptr -> unit - (* - Disposes of the underlying native Z3 object. - *) + (* + Disposes of the underlying native Z3 object. + *) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with @@ -92,16 +108,17 @@ object (self) method get_context = m_ctx method get_native_context = m_ctx#get_native - (* - method array_to_native a = +(* + method array_to_native a = let f e = e#get_native_object in (Array.map f a) - method array_length a = + method array_length a = match a with - | Some(x) -> (Array.length x) - | None -> 0 - *) + | Some(x) -> (Array.length x) + | None -> 0 +*) + end class symbol ctx_init obj_init = @@ -110,49 +127,55 @@ object (self) method incref o = () method decref o = () +end - method kind = match m_n_obj with - | Some(x) -> (int2symbol_kind (get_symbol_kind self#get_native_context x)) - | _ -> raise (Exception "Underlying object lost") +class int_symbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end - method is_int_symbol = match m_n_obj with - | Some(x) -> self#kind == INT_SYMBOL - | _ -> false +class string_symbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end - method is_string_symbol = match m_n_obj with - | Some(x) -> self#kind == STRING_SYMBOL - | _ -> false - - method to_string = match m_n_obj with - | Some(x) -> - ( - match self#kind with - | INT_SYMBOL -> (string_of_int (get_symbol_int self#get_native_context x)) - | STRING_SYMBOL -> (get_symbol_string self#get_native_context x) - ) - | None -> "" - - method create ctx obj = +module Symbol = +struct + let create ctx obj = match obj with | Some(x) -> ( match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with - | INT_SYMBOL -> (new intsymbol ctx obj :> symbol) - | STRING_SYMBOL -> (new stringsymbol ctx obj :> symbol) + | INT_SYMBOL -> (new int_symbol ctx obj :> symbol) + | STRING_SYMBOL -> (new string_symbol ctx obj :> symbol) ) | None -> raise (Exception "Can't create null objects") -end + let kind o = match o#m_n_obj with + | Some(x) -> (int2symbol_kind (get_symbol_kind o#get_native_context x)) + | _ -> raise (Exception "Underlying object lost") -and intsymbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init + let is_int_symbol o = match o#m_n_obj with + | Some(x) -> x#kind == INT_SYMBOL + | _ -> false - method get_int = match m_n_obj with - | Some(x) -> (get_symbol_int m_ctx#get_native x) + let is_string_symbol o = match o#m_n_obj with + | Some(x) -> x#kind == STRING_SYMBOL + | _ -> false + + let get_int o = match o#m_n_obj with + | Some(x) -> (get_symbol_int o#get_native_context x) | None -> 0 -end -and stringsymbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init + let get_string o = match o#m_n_obj with + | Some(x) -> (get_symbol_string o#get_native_context x) + | None -> "" + + let to_string o = match o#m_n_obj with + | Some(x) -> + ( + match (kind o) with + | INT_SYMBOL -> (string_of_int (get_symbol_int o#get_native_context x)) + | STRING_SYMBOL -> (get_symbol_string o#get_native_context x) + ) + | None -> "" end From 18a57267d1cf13d59dabcff027db7c4801ec4012 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 04:12:41 +0000 Subject: [PATCH 358/507] added temporary Makefile for ML annotations. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/api/ml/Makefile diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile new file mode 100644 index 000000000..f97a2dc30 --- /dev/null +++ b/src/api/ml/Makefile @@ -0,0 +1,6 @@ +# This is a temporary support file for emacs annotations. +# It does not compile the Z3 ML API; this will be built +# in the top-level build directory. + +all: + ocamlbuild -cflag -annot z3.cmxa \ No newline at end of file From cfa099007a2c93628ab5fae0acdf32224d1dc483 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 20 Dec 2012 20:51:18 +0000 Subject: [PATCH 359/507] ML build system checks Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 +- src/api/ml/z3.ml | 127 +++++++++++++++++++-------------------------- 2 files changed, 55 insertions(+), 77 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 38af3893f..a0f123609 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1439,7 +1439,7 @@ class MLComponent(Component): for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, self.to_src_dir)) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) out.write('z3.cmxa: %s\n' % libfile) out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) @@ -1577,7 +1577,7 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example($EXE_EXT): z3.cmxa ') + out.write('ml_example($EXE_EXT): z3.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') @@ -2434,6 +2434,7 @@ def mk_bindings(api_files): _execfile(os.path.join('scripts', 'update_api.py'), g) # HACK cp_z3py_to_build() if is_ml_enabled(): + check_ml() mk_z3consts_ml(api_files) # Extract enumeration types from API files, and add python definitions. diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 31bb7e5fc..4f847bc48 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -10,26 +10,11 @@ module Log = struct let m_is_open = false (* CMW: "open" seems to be an invalid function name*) - let open_ fn = let rv = (open_log fn) in - Printf.printf "ol returned %d\n" rv ; - ((int2lbool rv) == L_TRUE) - let close = close_log - let append s = append_log s + let open_ fn = int2lbool(open_log fn) == L_TRUE + let close = (close_log) + let append s = (append_log s) end - -module Version = -struct - let major = let (x, _, _, _) = get_version in x - let minor = let (_, x, _, _) = get_version in x - let build = let (_, _, x, _) = get_version in x - let revision = let (_, _, _, x) = get_version in x - let to_string = - string_of_int major ^ "." ^ - string_of_int minor ^ "." ^ - string_of_int build ^ "." ^ - string_of_int revision ^ "." -end - + class virtual idisposable = object method virtual dispose : unit @@ -40,7 +25,7 @@ object (self) inherit idisposable val mutable m_n_ctx : Z3native.z3_context = - let cfg = mk_config in + let cfg = mk_config() in let f e = (set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = mk_context_rc cfg in @@ -49,15 +34,14 @@ object (self) val mutable m_refCount : int = 0 - initializer - Gc.finalise (fun self -> self#dispose) self + initializer Gc.finalise (fun self -> self#dispose) self method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing %d \n" (Oo.id self) ; (del_context m_n_ctx) ) else ( - (* re-queue for finalization? *) + (* re-queue for finalization? *) ) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 @@ -82,9 +66,9 @@ object (self) method virtual incref : Z3native.ptr -> unit method virtual decref : Z3native.ptr -> unit - (* - Disposes of the underlying native Z3 object. - *) + (* + Disposes of the underlying native Z3 object. + *) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with @@ -108,17 +92,16 @@ object (self) method get_context = m_ctx method get_native_context = m_ctx#get_native -(* - method array_to_native a = + (* + method array_to_native a = let f e = e#get_native_object in (Array.map f a) - method array_length a = + method array_length a = match a with - | Some(x) -> (Array.length x) - | None -> 0 -*) - + | Some(x) -> (Array.length x) + | None -> 0 + *) end class symbol ctx_init obj_init = @@ -127,55 +110,49 @@ object (self) method incref o = () method decref o = () -end -class int_symbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init -end + method kind = match m_n_obj with + | Some(x) -> (int2symbol_kind (get_symbol_kind self#get_native_context x)) + | _ -> raise (Exception "Underlying object lost") -class string_symbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init -end + method is_int_symbol = match m_n_obj with + | Some(x) -> self#kind == INT_SYMBOL + | _ -> false -module Symbol = -struct - let create ctx obj = + method is_string_symbol = match m_n_obj with + | Some(x) -> self#kind == STRING_SYMBOL + | _ -> false + + method to_string = match m_n_obj with + | Some(x) -> + ( + match self#kind with + | INT_SYMBOL -> (string_of_int (get_symbol_int self#get_native_context x)) + | STRING_SYMBOL -> (get_symbol_string self#get_native_context x) + ) + | None -> "" + + method create ctx obj = match obj with | Some(x) -> ( match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with - | INT_SYMBOL -> (new int_symbol ctx obj :> symbol) - | STRING_SYMBOL -> (new string_symbol ctx obj :> symbol) + | INT_SYMBOL -> (new intsymbol ctx obj :> symbol) + | STRING_SYMBOL -> (new stringsymbol ctx obj :> symbol) ) | None -> raise (Exception "Can't create null objects") - let kind o = match o#m_n_obj with - | Some(x) -> (int2symbol_kind (get_symbol_kind o#get_native_context x)) - | _ -> raise (Exception "Underlying object lost") - - let is_int_symbol o = match o#m_n_obj with - | Some(x) -> x#kind == INT_SYMBOL - | _ -> false - - let is_string_symbol o = match o#m_n_obj with - | Some(x) -> x#kind == STRING_SYMBOL - | _ -> false - - let get_int o = match o#m_n_obj with - | Some(x) -> (get_symbol_int o#get_native_context x) - | None -> 0 - - let get_string o = match o#m_n_obj with - | Some(x) -> (get_symbol_string o#get_native_context x) - | None -> "" - - let to_string o = match o#m_n_obj with - | Some(x) -> - ( - match (kind o) with - | INT_SYMBOL -> (string_of_int (get_symbol_int o#get_native_context x)) - | STRING_SYMBOL -> (get_symbol_string o#get_native_context x) - ) - | None -> "" +end + +and intsymbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init + + method get_int = match m_n_obj with + | Some(x) -> (get_symbol_int m_ctx#get_native x) + | None -> 0 +end + +and stringsymbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init end From d8ed9be98e9224b9abfc37d90b1ea7879b35a3f0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 21 Dec 2012 03:02:12 +0000 Subject: [PATCH 360/507] ML native layer bugfixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- scripts/update_api.py | 165 +++++++++++++++++++++++++----------------- src/api/ml/z3.ml | 120 +++++++++++++++++------------- 3 files changed, 171 insertions(+), 116 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index a0f123609..e44c120cb 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2888,7 +2888,7 @@ def mk_z3consts_ml(api_files): linenum = linenum + 1 efile.write('end\n') if VERBOSE: - print "Generated '%s/enumerations.ml'" % ('%s' % gendir) + print "Generated '%s/z3enums.ml'" % ('%s' % gendir) def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 25adce2af..d0ef2ec86 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1,3 +1,4 @@ + ############################################ # Copyright (c) 2012 Microsoft Corporation # @@ -1097,6 +1098,45 @@ def is_array_param(p): else: return False +def arrayparams(params): + op = [] + for param in params: + if is_array_param(param): + op.append(param) + return op + + +def ml_unwrap(t): + if t == STRING: + return 'String_val' + elif t == BOOL or t == INT or PRINT_MODE or ERROR_CODE: + return 'Int_val' + elif t == UINT: + return 'Unsigned_int_val' + elif t == INT64: + return 'Long_val' + elif t == UINT64: + return 'Unsigned_long_val' + elif t == DOUBLE: + return 'Double_val' + else: + return 'Data_custom_val' + +def ml_set_wrap(t, d, n): + if t == VOID: + return d + ' = Val_unit;' + elif t == BOOL or t == INT or t == UINT or PRINT_MODE or ERROR_CODE: + return d + ' = Val_int(' + n + ');' + elif t == INT64 or t == UINT64: + return d + ' = Val_long(' + n + ');' + elif t == DOUBLE: + return 'Store_double_val(' + d + ', ' + n + ');' + elif t == STRING: + return d + ' = caml_copy_string((const char*) ' + n + ');' + else: + ts = type2str(t) + return d + ' = caml_alloc_custom(0, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' + def mk_ml(): global Type2Str if not is_ml_enabled(): @@ -1242,15 +1282,12 @@ def mk_ml(): for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) + ap = arrayparams(params) ret_size = len(op) if result != VOID: ret_size = ret_size + 1 # Setup frame - n_locals = 0 - for p in params: - if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): - n_locals = n_locals + 1 ml_wrapper.write('CAMLprim value n_%s(' % ml_method_name(name)) first = True i = 0 @@ -1276,46 +1313,50 @@ def mk_ml(): i = i + 1 ml_wrapper.write(');\n') i = 0 - first = True - if result != VOID: - n_locals = n_locals + 1 - if ret_size > 1: - n_locals = n_locals + 1 - if n_locals > 0: - ml_wrapper.write(' CAMLlocal%s(' % (n_locals)) - if ret_size > 1: - if result != VOID: - ml_wrapper.write('result, ') - ml_wrapper.write('result_tuple') - first = False - elif result != VOID: - ml_wrapper.write('result') - first = False + if len(op) + len(ap) == 0: + ml_wrapper.write(' CAMLlocal1(result);\n') + else: + c = 0 for p in params: - if is_out_param(p) or (is_in_param(p) and param_type(p) == STRING): - if first: - first = False - else: - ml_wrapper.write(', ') - ml_wrapper.write('_a%s' % i) + if is_out_param(p) or is_array_param(p): + c = c + 1 + ml_wrapper.write(' CAMLlocal%s(result, res_val' % (c+2)) + for p in params: + if is_out_param(p) or is_array_param(p): + ml_wrapper.write(', _a%s_val' % i) i = i + 1 ml_wrapper.write(');\n') # preprocess arrays, strings, in/out arguments i = 0 for param in params: - if param_kind(param) == OUT_ARRAY: - ml_wrapper.write(' _a%s = (long) malloc(sizeof(%s) * ((long)a%s));\n' % (i, - type2str(param_type(param)), - param_array_capacity_pos(param))) - elif param_kind(param) == IN and param_type(param) == STRING: - ml_wrapper.write(' _a%s = (value) String_val(a%s);\n' % (i, i)) + k = param_kind(param) + if k == OUT_ARRAY: + ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * (_a%s));\n' % ( + type2str(param_type(param)), + i, + type2str(param_type(param)), + type2str(param_type(param)), + param_array_capacity_pos(param))) + elif k == IN_ARRAY or k == INOUT_ARRAY: + t = param_type(param) + ts = type2str(t) + ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) + ml_wrapper.write(' for (unsigned i = 0; i < a%s; i++) _a%s[i] = (%s) %s(Field(a%s, i));\n' % (param_array_capacity_pos(param), i, ts, ml_unwrap(t), i)) + elif k == IN: + t = param_type(param) + ml_wrapper.write(' %s _a%s = (%s) %s(a%s);\n' % (type2str(t), i, type2str(t), ml_unwrap(t), i)) + elif k == OUT: + ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) + elif k == INOUT: + ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) + i = i + 1 # invoke procedure ml_wrapper.write(' ') if result != VOID: - ml_wrapper.write('result = (value) ') + ml_wrapper.write('%s z3_result = ' % type2str(result)) ml_wrapper.write('%s(' % name) i = 0 first = True @@ -1326,58 +1367,50 @@ def mk_ml(): ml_wrapper.write(', ') k = param_kind(param) if k == OUT or k == INOUT: - ml_wrapper.write('(%s)&_a%s' % (param2str(param), i)) - elif k == INOUT_ARRAY or k == IN_ARRAY: - ml_wrapper.write('(%s*)a%s' % (type2str(param_type(param)), i)) - elif k == OUT_ARRAY: - ml_wrapper.write('(%s*)_a%s' % (type2str(param_type(param)), i)) - elif k == IN and param_type(param) == STRING: - ml_wrapper.write('(Z3_string) _a%s' % i) + ml_wrapper.write('&_a%s' % i) else: - ml_wrapper.write('(%s)a%i' % (param2str(param), i)) + ml_wrapper.write('_a%i' % i) i = i + 1 ml_wrapper.write(');\n') - # return tuples + # convert output params if len(op) > 0: - ml_wrapper.write(' result_tuple = caml_alloc(%s, 0);\n' % ret_size) + if result != VOID: + ml_wrapper.write(' %s\n' % ml_set_wrap(result, "res_val", "z3_result")) + i = 0; + for p in params: + if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: + ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) + ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) { value t; %s Store_field(_a%s, i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[i]'), i)) + elif is_out_param(p): + ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) + i = i + 1 + + # return tuples + if len(op) == 0: + ml_wrapper.write(' %s\n' % ml_set_wrap(result, "result", "z3_result")) + else: + ml_wrapper.write(' result = caml_alloc(%s, 0);\n' % ret_size) i = j = 0 if result != VOID: - if result == STRING: - ml_wrapper.write(' Store_field(result_tuple, 0, caml_copy_string(result));\n') - else: - ml_wrapper.write(' Store_field(result_tuple, 0, result);\n') + ml_wrapper.write(' Store_field(result, 0, res_val);\n') j = j + 1 for p in params: - if param_kind(p) == OUT_ARRAY or param_kind(p) == OUT: - ml_wrapper.write(' Store_field(result_tuple, %s, _a%s);\n' % (j, i)) - j = j + 1; - elif is_out_param(p): - if param_type(p) == STRING: - ml_wrapper.write(' Store_field(result_tuple, %s, caml_copy_string((const char *)_a%s));\n' % (j, i)) - else: - ml_wrapper.write(' Store_field(result_tuple, %s, a%s);\n' % (j, i)) + if is_out_param(p): + ml_wrapper.write(' Store_field(result, %s, _a%s_val);\n' % (j, i)) j = j + 1; i = i + 1 # local array cleanup i = 0 for p in params: - if param_kind(p) == OUT_ARRAY: - ml_wrapper.write(' free((long*)_a%s);\n' % i) + k = param_kind(p) + if k == OUT_ARRAY or k == IN_ARRAY or k == INOUT_ARRAY: + ml_wrapper.write(' free(_a%s);\n' % i) i = i + 1 # return - if len(op) > 0: - ml_wrapper.write(' CAMLreturn(result_tuple);\n') - else: - if result == STRING: - ml_wrapper.write(' CAMLreturn(caml_copy_string((const char*) result));\n') - elif result == VOID: - ml_wrapper.write(' CAMLreturn(Val_unit);\n') - elif result != VOID: - ml_wrapper.write(' CAMLreturn(result);\n') - + ml_wrapper.write(' CAMLreturn(result);\n') ml_wrapper.write('}\n\n') if len(ip) > 5: ml_wrapper.write('CAMLprim value n_%s_bytecode(value * argv, int argn) {\n' % ml_method_name(name)) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 4f847bc48..d1ba2b746 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -10,11 +10,25 @@ module Log = struct let m_is_open = false (* CMW: "open" seems to be an invalid function name*) - let open_ fn = int2lbool(open_log fn) == L_TRUE - let close = (close_log) - let append s = (append_log s) + let open_ fn = ((int2lbool (open_log fn)) == L_TRUE) + let close = close_log + let append s = append_log s end - + +module Version = +struct + let major = let (x, _, _, _) = get_version in x + let minor = let (_, x, _, _) = get_version in x + let build = let (_, _, x, _) = get_version in x + let revision = let (_, _, _, x) = get_version in x + let to_string = + let (mj, mn, bld, rev) = get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + class virtual idisposable = object method virtual dispose : unit @@ -25,7 +39,7 @@ object (self) inherit idisposable val mutable m_n_ctx : Z3native.z3_context = - let cfg = mk_config() in + let cfg = mk_config in let f e = (set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = mk_context_rc cfg in @@ -34,14 +48,15 @@ object (self) val mutable m_refCount : int = 0 - initializer Gc.finalise (fun self -> self#dispose) self + initializer + Gc.finalise (fun self -> self#dispose) self method dispose : unit = if m_refCount == 0 then ( - Printf.printf "Disposing %d \n" (Oo.id self) ; + Printf.printf "Disposing context %d \n" (Oo.id self) ; (del_context m_n_ctx) ) else ( - (* re-queue for finalization? *) + (* re-queue for finalization? *) ) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 @@ -66,9 +81,9 @@ object (self) method virtual incref : Z3native.ptr -> unit method virtual decref : Z3native.ptr -> unit - (* - Disposes of the underlying native Z3 object. - *) + (* + Disposes of the underlying native Z3 object. + *) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with @@ -92,16 +107,17 @@ object (self) method get_context = m_ctx method get_native_context = m_ctx#get_native - (* - method array_to_native a = +(* + method array_to_native a = let f e = e#get_native_object in (Array.map f a) - method array_length a = + method array_length a = match a with - | Some(x) -> (Array.length x) - | None -> 0 - *) + | Some(x) -> (Array.length x) + | None -> 0 +*) + end class symbol ctx_init obj_init = @@ -110,49 +126,55 @@ object (self) method incref o = () method decref o = () +end - method kind = match m_n_obj with - | Some(x) -> (int2symbol_kind (get_symbol_kind self#get_native_context x)) - | _ -> raise (Exception "Underlying object lost") +class int_symbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end - method is_int_symbol = match m_n_obj with - | Some(x) -> self#kind == INT_SYMBOL - | _ -> false +class string_symbol ctx_init obj_init = +object(self) + inherit symbol ctx_init obj_init +end - method is_string_symbol = match m_n_obj with - | Some(x) -> self#kind == STRING_SYMBOL - | _ -> false - - method to_string = match m_n_obj with - | Some(x) -> - ( - match self#kind with - | INT_SYMBOL -> (string_of_int (get_symbol_int self#get_native_context x)) - | STRING_SYMBOL -> (get_symbol_string self#get_native_context x) - ) - | None -> "" - - method create ctx obj = +module Symbol = +struct + let create ctx obj = match obj with | Some(x) -> ( match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with - | INT_SYMBOL -> (new intsymbol ctx obj :> symbol) - | STRING_SYMBOL -> (new stringsymbol ctx obj :> symbol) + | INT_SYMBOL -> (new int_symbol ctx obj :> symbol) + | STRING_SYMBOL -> (new string_symbol ctx obj :> symbol) ) | None -> raise (Exception "Can't create null objects") -end + let kind o = match o#m_n_obj with + | Some(x) -> (int2symbol_kind (get_symbol_kind o#get_native_context x)) + | _ -> raise (Exception "Underlying object lost") -and intsymbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init + let is_int_symbol o = match o#m_n_obj with + | Some(x) -> x#kind == INT_SYMBOL + | _ -> false - method get_int = match m_n_obj with - | Some(x) -> (get_symbol_int m_ctx#get_native x) + let is_string_symbol o = match o#m_n_obj with + | Some(x) -> x#kind == STRING_SYMBOL + | _ -> false + + let get_int o = match o#m_n_obj with + | Some(x) -> (get_symbol_int o#get_native_context x) | None -> 0 -end -and stringsymbol ctx_init obj_init = -object(self) - inherit symbol ctx_init obj_init + let get_string o = match o#m_n_obj with + | Some(x) -> (get_symbol_string o#get_native_context x) + | None -> "" + + let to_string o = match o#m_n_obj with + | Some(x) -> + ( + match (kind o) with + | INT_SYMBOL -> (string_of_int (get_symbol_int o#get_native_context x)) + | STRING_SYMBOL -> (get_symbol_string o#get_native_context x) + ) + | None -> "" end From 7ae90f0b20ef3dc24e0f220f9f30db1ca870dd0c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 21 Dec 2012 07:18:46 +0000 Subject: [PATCH 361/507] More ML API: Fixes in native layer. Added symbols. Prepared code for automatic documentation. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 5 ++ scripts/mk_util.py | 89 +------------------- scripts/update_api.py | 37 ++++++--- src/api/ml/z3.ml | 168 ++++++++++++++++++++++++++------------ 4 files changed, 148 insertions(+), 151 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index c79b3cdaa..7046a92b0 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,6 +4,7 @@ *) open Z3 +open Z3.Context exception ExampleException of string @@ -15,6 +16,10 @@ let _ = Printf.printf "Running Z3 version %s\n" Version.to_string ; let cfg = [("model", "true"); ("proof", "false")] in let ctx = (new context cfg) in + let is = (mk_symbol_int ctx 42) in + let ss = (mk_symbol_string ctx "mySymbol") in + Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); + Printf.printf "string symbol: %s\n" (Symbol.to_string (ss :> symbol)); Printf.printf "Disposing...\n"; ctx#dispose (* can do, but we'd rather let it go out of scope *) ; ); diff --git a/scripts/mk_util.py b/scripts/mk_util.py index e44c120cb..5ca0d2299 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2777,99 +2777,12 @@ def mk_z3consts_ml(api_files): efile.write(' | %s \n' % k[3:]) # strip Z3_ efile.write('\n') efile.write('(** Convert %s to int*)\n' % name[3:]) - efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_ - efile.write(' match x with\n') - for k, i in decls.iteritems(): - efile.write(' | %s -> %d\n' % (k[3:], i)) - efile.write('\n') - efile.write('(** Convert int to %s*)\n' % name[3:]) - efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_ - efile.write(' match x with\n') - for k, i in decls.iteritems(): - efile.write(' | %d -> %s\n' % (i, k[3:])) - # use Z3.Exception? - efile.write(' | _ -> raise (Failure "undefined enum value")\n\n') - mode = SEARCHING - else: - if words[2] != '': - if len(words[2]) > 1 and words[2][1] == 'x': - idx = int(words[2], 16) - else: - idx = int(words[2]) - decls[words[1]] = idx - idx = idx + 1 - linenum = linenum + 1 - if VERBOSE: - print "Generated '%s/z3enums.ml'" % ('%s' % gendir) - efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') - efile.write('(* Automatically generated file *)\n\n') - efile.write('(** The enumeration types of Z3. *)\n\n') - efile.write('module Z3enums = struct\n') - for api_file in api_files: - api_file_c = ml.find_file(api_file, ml.name) - api_file = os.path.join(api_file_c.src_dir, api_file) - - api = open(api_file, 'r') - - SEARCHING = 0 - FOUND_ENUM = 1 - IN_ENUM = 2 - - mode = SEARCHING - decls = {} - idx = 0 - - linenum = 1 - for line in api: - m1 = blank_pat.match(line) - m2 = comment_pat.match(line) - if m1 or m2: - # skip blank lines and comments - linenum = linenum + 1 - elif mode == SEARCHING: - m = typedef_pat.match(line) - if m: - mode = FOUND_ENUM - m = typedef2_pat.match(line) - if m: - mode = IN_ENUM - decls = {} - idx = 0 - elif mode == FOUND_ENUM: - m = openbrace_pat.match(line) - if m: - mode = IN_ENUM - decls = {} - idx = 0 - else: - assert False, "Invalid %s, line: %s" % (api_file, linenum) - else: - assert mode == IN_ENUM - words = re.split('[^\-a-zA-Z0-9_]+', line) - m = closebrace_pat.match(line) - if m: - name = words[1] - if name not in DeprecatedEnums: - efile.write('(** %s *)\n' % name[3:]) - efile.write('type %s =\n' % name[3:]) # strip Z3_ - for k, i in decls.iteritems(): - efile.write(' | %s \n' % k[3:]) # strip Z3_ - efile.write('\n') - efile.write('(** Convert %s to int*)\n' % name[3:]) - efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_ - efile.write('(** Convert int to %s*)\n' % name[3:]) - efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_ - efile.write('\n') - efile.write('\n(* %s *)\n' % name) - efile.write('type %s =\n' % name[3:]) # strip Z3_ - for k, i in decls.iteritems(): - efile.write(' | %s \n' % k[3:]) # strip Z3_ - efile.write('\n') efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): efile.write(' | %s -> %d\n' % (k[3:], i)) efile.write('\n') + efile.write('(** Convert int to %s*)\n' % name[3:]) efile.write('let int2%s x : %s =\n' % (name[3:],name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): diff --git a/scripts/update_api.py b/scripts/update_api.py index d0ef2ec86..c8cd05c7e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1106,26 +1106,26 @@ def arrayparams(params): return op -def ml_unwrap(t): +def ml_unwrap(t, ts, s): if t == STRING: - return 'String_val' - elif t == BOOL or t == INT or PRINT_MODE or ERROR_CODE: - return 'Int_val' + return '(' + ts + ') String_val(' + s + ')' + elif t == BOOL or t == INT or t == PRINT_MODE or t == ERROR_CODE: + return '(' + ts + ') Int_val(' + s + ')' elif t == UINT: - return 'Unsigned_int_val' + return '(' + ts + ') Unsigned_int_val(' + s + ')' elif t == INT64: - return 'Long_val' + return '(' + ts + ') Long_val(' + s + ')' elif t == UINT64: - return 'Unsigned_long_val' + return '(' + ts + ') Unsigned_long_val(' + s + ')' elif t == DOUBLE: - return 'Double_val' + return '(' + ts + ') Double_val(' + s + ')' else: - return 'Data_custom_val' + return '* (' + ts + '*) Data_custom_val(' + s + ')' def ml_set_wrap(t, d, n): if t == VOID: return d + ' = Val_unit;' - elif t == BOOL or t == INT or t == UINT or PRINT_MODE or ERROR_CODE: + elif t == BOOL or t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: return d + ' = Val_int(' + n + ');' elif t == INT64 or t == UINT64: return d + ' = Val_long(' + n + ');' @@ -1135,7 +1135,7 @@ def ml_set_wrap(t, d, n): return d + ' = caml_copy_string((const char*) ' + n + ');' else: ts = type2str(t) - return d + ' = caml_alloc_custom(0, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' + return d + ' = caml_alloc_custom(&default_custom_ops, sizeof(' + ts + '), 0, 1); memcpy( Data_custom_val(' + d + '), &' + n + ', sizeof(' + ts + '));' def mk_ml(): global Type2Str @@ -1146,7 +1146,9 @@ def mk_ml(): ml_wrapperf = os.path.join(ml_dir, 'z3native.c') ml_native = open(ml_nativef, 'w') ml_native.write('(* Automatically generated file *)\n\n') + ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_native.write('open Z3enums\n\n') + ml_native.write('(**/**)\n') ml_native.write('type ptr\n') ml_native.write('and z3_symbol = ptr\n') for k, v in Type2Str.iteritems(): @@ -1226,6 +1228,7 @@ def mk_ml(): else: ml_native.write(' res\n') ml_native.write('\n') + ml_native.write('(**/**)\n') # C interface ml_wrapper = open(ml_wrapperf, 'w') @@ -1276,6 +1279,14 @@ def mk_ml(): ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') ml_wrapper.write('\n\n') + ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') + ml_wrapper.write(' identifier: "default handling",\n') + ml_wrapper.write(' finalize: custom_finalize_default,\n') + ml_wrapper.write(' compare: custom_compare_default,\n') + ml_wrapper.write(' hash: custom_hash_default,\n') + ml_wrapper.write(' serialize: custom_serialize_default,\n') + ml_wrapper.write(' deserialize: custom_deserialize_default\n') + ml_wrapper.write('};\n\n') ml_wrapper.write('#ifdef __cplusplus\n') ml_wrapper.write('extern "C" {\n') ml_wrapper.write('#endif\n\n') @@ -1342,10 +1353,10 @@ def mk_ml(): t = param_type(param) ts = type2str(t) ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) - ml_wrapper.write(' for (unsigned i = 0; i < a%s; i++) _a%s[i] = (%s) %s(Field(a%s, i));\n' % (param_array_capacity_pos(param), i, ts, ml_unwrap(t), i)) + ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) _a%s[i] = %s;\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', i)'))) elif k == IN: t = param_type(param) - ml_wrapper.write(' %s _a%s = (%s) %s(a%s);\n' % (type2str(t), i, type2str(t), ml_unwrap(t), i)) + ml_wrapper.write(' %s _a%s = %s;\n' % (type2str(t), i, ml_unwrap(t, type2str(t), 'a' + str(i)))) elif k == OUT: ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) elif k == INOUT: diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index d1ba2b746..321b17c82 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,33 +1,17 @@ -(* +(** + The Z3 ML/Ocaml Interface. + Copyright (C) 2012 Microsoft Corporation - Author: CM Wintersteiger (cwinter) 2012-12-17 + @author CM Wintersteiger (cwinter) 2012-12-17 *) open Z3enums open Z3native -module Log = -struct - let m_is_open = false - (* CMW: "open" seems to be an invalid function name*) - let open_ fn = ((int2lbool (open_log fn)) == L_TRUE) - let close = close_log - let append s = append_log s -end +(**/**) -module Version = -struct - let major = let (x, _, _, _) = get_version in x - let minor = let (_, x, _, _) = get_version in x - let build = let (_, _, x, _) = get_version in x - let revision = let (_, _, _, x) = get_version in x - let to_string = - let (mj, mn, bld, rev) = get_version in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev ^ "." -end +(* Object definitions. These are internal and should be interacted + with only via the corresponding functions from modules. *) class virtual idisposable = object @@ -61,7 +45,7 @@ object (self) method sub_one_ctx_obj = m_refCount <- m_refCount - 1 method add_one_ctx_obj = m_refCount <- m_refCount + 1 - method get_native = m_n_ctx + method gno = m_n_ctx end class virtual z3object ctx_init obj_init = @@ -91,9 +75,9 @@ object (self) | None -> () ); - method get_native_object = m_n_obj + method gno = m_n_obj - method set_native_object x = + method sno x = (match x with | Some(x) -> self#incref x | None -> () @@ -105,11 +89,11 @@ object (self) m_n_obj <- x method get_context = m_ctx - method get_native_context = m_ctx#get_native + method gnc = m_ctx#gno (* method array_to_native a = - let f e = e#get_native_object in + let f e = e#gno in (Array.map f a) method array_length a = @@ -120,61 +104,145 @@ object (self) end -class symbol ctx_init obj_init = +class symbol ctx obj = object (self) - inherit z3object ctx_init obj_init + inherit z3object ctx obj method incref o = () method decref o = () end -class int_symbol ctx_init obj_init = +class int_symbol ctx = object(self) - inherit symbol ctx_init obj_init + inherit symbol ctx None + method cnstr_obj obj = (self#sno obj) ; self + method cnstr_int i = (self#sno (Some (mk_int_symbol ctx#gno i))) ; self end -class string_symbol ctx_init obj_init = +class string_symbol ctx = object(self) - inherit symbol ctx_init obj_init + inherit symbol ctx None + method cnstr_obj obj = (self#sno obj) ; self + method cnstr_string name = (self#sno (Some (mk_string_symbol ctx#gno name))) ; self end +(**/**) + +(** Interaction logging for Z3. + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log = +struct + (** Open an interaction log file. + @param filename the name of the file to open. + @return True if opening the log file succeeds, false otherwise. + *) + (* CMW: "open" seems to be a reserved keyword? *) + let open_ filename = ((int2lbool (open_log filename)) == L_TRUE) + + (** Closes the interaction log. *) + let close = close_log + + (** Appends a user-provided string to the interaction log. + @param s the string to append*) + let append s = append_log s +end + +(** Version information. *) +module Version = +struct + (** The major version. *) + let major = let (x, _, _, _) = get_version in x + + (** The minor version. *) + let minor = let (_, x, _, _) = get_version in x + + (** The build version. *) + let build = let (_, _, x, _) = get_version in x + + (** The revision. *) + let revision = let (_, _, _, x) = get_version in x + + (** A string representation of the version information. *) + let to_string = + let (mj, mn, bld, rev) = get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + +(** Symbols are used to name several term and type constructors. *) module Symbol = struct +(**/**) let create ctx obj = match obj with | Some(x) -> ( - match (int2symbol_kind (get_symbol_kind ctx#get_native x)) with - | INT_SYMBOL -> (new int_symbol ctx obj :> symbol) - | STRING_SYMBOL -> (new string_symbol ctx obj :> symbol) + match (int2symbol_kind (get_symbol_kind ctx#gno x)) with + | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj obj) :> symbol) + | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj obj) :> symbol) ) | None -> raise (Exception "Can't create null objects") +(**/**) - let kind o = match o#m_n_obj with - | Some(x) -> (int2symbol_kind (get_symbol_kind o#get_native_context x)) + (** The kind of the symbol (int or string) *) + let kind (o : symbol) = match o#gno with + | Some(x) -> (int2symbol_kind (get_symbol_kind o#gnc x)) | _ -> raise (Exception "Underlying object lost") - let is_int_symbol o = match o#m_n_obj with - | Some(x) -> x#kind == INT_SYMBOL + (** Indicates whether the symbol is of Int kind *) + let is_int_symbol (o : symbol) = match o#gno with + | Some(x) -> (kind o) == INT_SYMBOL | _ -> false - let is_string_symbol o = match o#m_n_obj with - | Some(x) -> x#kind == STRING_SYMBOL + (** Indicates whether the symbol is of string kind. *) + let is_string_symbol (o : symbol) = match o#gno with + | Some(x) -> (kind o) == STRING_SYMBOL | _ -> false - let get_int o = match o#m_n_obj with - | Some(x) -> (get_symbol_int o#get_native_context x) + (** The int value of the symbol. *) + let get_int (o : int_symbol) = match o#gno with + | Some(x) -> (get_symbol_int o#gnc x) | None -> 0 - let get_string o = match o#m_n_obj with - | Some(x) -> (get_symbol_string o#get_native_context x) + (** The string value of the symbol. *) + let get_string (o : string_symbol) = match o#gno with + | Some(x) -> (get_symbol_string o#gnc x) | None -> "" - let to_string o = match o#m_n_obj with + (** A string representation of the symbol. *) + let to_string (o : symbol) = match o#gno with | Some(x) -> ( match (kind o) with - | INT_SYMBOL -> (string_of_int (get_symbol_int o#get_native_context x)) - | STRING_SYMBOL -> (get_symbol_string o#get_native_context x) + | INT_SYMBOL -> (string_of_int (get_symbol_int o#gnc x)) + | STRING_SYMBOL -> (get_symbol_string o#gnc x) ) | None -> "" end + +(** The main interaction with Z3 happens via the Context. *) +module Context = +struct + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) + let mk_symbol_int ctx i = + (new int_symbol ctx)#cnstr_int i + + (** Creates a new symbol using a string. *) + let mk_symbol_string ctx s = + (new string_symbol ctx)#cnstr_string s + + (** + Create an array of symbols. + *) + let mk_symbols ctx names = + let f elem = mk_symbol_string ctx elem in + (Array.map f names) + +end From a2ad7d91bc29b8cec52a2fceed1aa5d655966bf4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 00:51:07 +0000 Subject: [PATCH 362/507] New ML API savepoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/Makefile | 6 +- src/api/ml/z3.ml | 5746 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 5659 insertions(+), 93 deletions(-) diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index f97a2dc30..4d4a6c08f 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -3,4 +3,8 @@ # in the top-level build directory. all: - ocamlbuild -cflag -annot z3.cmxa \ No newline at end of file + ocamlbuild -cflag -annot z3.cmxa + +doc: *.ml + mkdir -p doc + ocamldoc -html -d doc -I ../../../bld_dbg/api/ml *.ml -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 321b17c82..2100f371e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -6,7 +6,6 @@ *) open Z3enums -open Z3native (**/**) @@ -18,27 +17,28 @@ object method virtual dispose : unit end +(** Context objects *) class context settings = object (self) inherit idisposable val mutable m_n_ctx : Z3native.z3_context = - let cfg = mk_config in - let f e = (set_param_value cfg (fst e) (snd e)) in + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; - let v = mk_context_rc cfg in - del_config(cfg) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; v val mutable m_refCount : int = 0 initializer Gc.finalise (fun self -> self#dispose) self - + method dispose : unit = if m_refCount == 0 then ( Printf.printf "Disposing context %d \n" (Oo.id self) ; - (del_context m_n_ctx) + (Z3native.del_context m_n_ctx) ) else ( (* re-queue for finalization? *) ) @@ -48,6 +48,8 @@ object (self) method gno = m_n_ctx end + +(** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) inherit idisposable @@ -56,14 +58,14 @@ object (self) initializer (match m_n_obj with - | Some (x) -> self#incref x; + | Some (x) -> self#incref m_ctx#gno x; m_ctx#add_one_ctx_obj | None -> () ); Gc.finalise (fun self -> self#dispose) self - method virtual incref : Z3native.ptr -> unit - method virtual decref : Z3native.ptr -> unit + method virtual incref : Z3native.ptr -> Z3native.ptr -> unit + method virtual decref : Z3native.ptr -> Z3native.ptr -> unit (* Disposes of the underlying native Z3 object. @@ -71,61 +73,415 @@ object (self) method dispose = Printf.printf "Disposing z3object %d \n" (Oo.id self) ; (match m_n_obj with - | Some (x) -> self#decref x; m_n_obj <- None; m_ctx#sub_one_ctx_obj + | Some (x) -> self#decref m_ctx#gno x; m_n_obj <- None; m_ctx#sub_one_ctx_obj | None -> () ); - method gno = m_n_obj + method gno = match m_n_obj with + | Some(x) -> x + | None -> raise (Z3native.Exception "Z3 object lost") - method sno x = - (match x with - | Some(x) -> self#incref x - | None -> () - ); + method sno nc o = + self#incref nc o ; (match m_n_obj with - | Some(x) -> self#decref x + | Some(x) -> self#decref nc x | None -> () ); - m_n_obj <- x + m_n_obj <- Some o - method get_context = m_ctx + method gc = m_ctx method gnc = m_ctx#gno - -(* - method array_to_native a = - let f e = e#gno in - (Array.map f a) - - method array_length a = - match a with - | Some(x) -> (Array.length x) - | None -> 0 -*) - end -class symbol ctx obj = + +(** Parameter set objects *) +class params ctx obj = object (self) - inherit z3object ctx obj - - method incref o = () - method decref o = () + inherit z3object ctx obj as super + method incref ctx o = Z3native.params_inc_ref ctx o + method decref ctx o = Z3native.params_dec_ref ctx o end + +(** Symbol objects *) +class symbol ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method incref ctx o = () + method decref ctx o = () +end + +let symbolaton (a : symbol array) = + let f (e : symbol) = e#gno in + Array.map f a + +(** Int symbol objects *) class int_symbol ctx = object(self) - inherit symbol ctx None - method cnstr_obj obj = (self#sno obj) ; self - method cnstr_int i = (self#sno (Some (mk_int_symbol ctx#gno i))) ; self + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_int i = (self#sno ctx#gno (Z3native.mk_int_symbol ctx#gno i)) ; self end +(** String symbol objects *) class string_symbol ctx = object(self) - inherit symbol ctx None - method cnstr_obj obj = (self#sno obj) ; self - method cnstr_string name = (self#sno (Some (mk_string_symbol ctx#gno name))) ; self + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_string name = (self#sno ctx#gno (Z3native.mk_string_symbol ctx#gno name)) ; self end +let create_symbol ctx no = + match (int2symbol_kind (Z3native.get_symbol_kind ctx#gno no)) with + | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) + | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) + +(** AST objects *) +class ast ctx = +object (self) + inherit z3object ctx None as super (* CMW: derive from icomparable? *) + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + + method incref nc o = Z3native.inc_ref nc o + method decref nc o = Z3native.dec_ref nc o +end + +let astaton (a : ast array) = + let f (e : ast) = e#gno in + Array.map f a + +(** Sort objects *) +class sort ctx = +object (self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Arithmetic sort objects, i.e., Int or Real. *) +class arith_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Array sorts objects *) +class array_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx#gno (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self +end + +(** Bit-vector sort objects *) +class bitvec_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Boolean sort objects *) +class bool_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Datatype sort objects *) +class datatype_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_sc (name : symbol) constructors = (self#sno ctx#gno (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self +end + +(** Enum sort objects *) +class enum_sort ctx = +object (self) + inherit sort ctx as super + val mutable _constdecls = None + val mutable _testerdecls = None + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_ss (name : symbol) (enum_names : symbol array) = + let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in + _constdecls <- Some a ; + _testerdecls <- Some b ; + (self#sno ctx#gno r) ; + self + + method const_decls = match _constdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing const decls") + + method tester_decls = match _testerdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tester decls") +end + +(** Int sort objects *) +class int_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Real sort objects *) +class real_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Uninterpreted sort objects *) +class uninterpreted_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_s (s : symbol) = (self #sno ctx#gno (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self +end + +(** Finite domain sort objects *) +class finite_domain_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx#gno (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self +end + +(** Relation sort objects *) +class relation_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** List sort objects *) +class list_sort ctx = +object (self) + inherit sort ctx as super + val mutable _nildecl = None + val mutable _is_nildecl = None + val mutable _consdecl = None + val mutable _is_consdecl = None + val mutable _headdecl = None + val mutable _taildecl = None + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_ss (name : symbol) (elem_sort : sort) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in + _nildecl <- Some a ; + _is_nildecl <- Some b ; + _consdecl <- Some c ; + _is_consdecl <- Some d ; + _headdecl <- Some e ; + _taildecl <- Some f ; + (self#sno ctx#gno r) ; + self + + method nil_decl = match _nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing nil decl") + + method is_nil_decl = match _is_nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_nil decls") + + method cons_decl = match _consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing cons decls") + + method is_cons_decl = match _is_consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_cons decls") + + method head_decl = match _headdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing head decls") + + method tail_decl = match _taildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tail decls") + +end + +(** Set sort objects *) +class set_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_s (s : sort) = (self#sno ctx#gno s#gno) ; self +end + +(** Tuple sort objects *) +class tuple_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = + let (x,_,_) = (Z3native.mk_tuple_sort ctx#gno name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in + (self#sno ctx#gno x) ; + self +end + +let create_sort ctx obj = + match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with + | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) + | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) + | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) + | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) + | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) + | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) + | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) + | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) + | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + +(** Function declaration objects *) +class func_decl ctx = +object (self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self + + method incref nc o = super#incref nc o + method decref nc o = super#decref nc o +end + +class parameter = +object (self) + val mutable m_kind : parameter_kind = PARAMETER_INT; + val mutable m_i : int = 0 + val mutable m_d : float = 0.0 + val mutable m_sym : symbol option = None + val mutable m_srt : sort option = None + val mutable m_ast : ast option = None + val mutable m_fd : func_decl option = None + val mutable m_r : string = "" + + method cnstr_int i = m_kind <- PARAMETER_INT; m_i <- i + method cnstr_double d = m_kind <- PARAMETER_DOUBLE; m_d <- d + method cnstr_symbol sym = m_kind <- PARAMETER_SYMBOL; m_sym <- sym + method cnstr_sort srt = m_kind <- PARAMETER_SORT; m_srt <- srt + method cnstr_ast ast = m_kind <- PARAMETER_AST; m_ast <- ast + method cnstr_func_decl fd = m_kind <- PARAMETER_FUNC_DECL; m_fd <- fd + method cnstr_rational r = m_kind <- PARAMETER_RATIONAL; m_r <- r + + method kind = m_kind + method int = m_i + method double = m_d + method symbol = match m_sym with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter symbol") + method sort = match m_srt with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter sort") + method ast = match m_ast with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter ast") + method func_decl = match m_fd with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing parameter func_decl") + method rational = m_r +end + +(** Expression objects *) +class expr ctx = +object(self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +let expraton (a : expr array) = + let f (e : expr) = e#gno in + Array.map f a + +(** Boolean expression objects *) +class bool_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Arithmetic expression objects (int/real) *) +class arith_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Int expression objects *) +class int_expr ctx = +object (self) + inherit arith_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Real expression objects *) +class real_expr ctx = +object (self) + inherit arith_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Bit-vector expression objects *) +class bitvec_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Array expression objects *) +class array_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Datatype expression objects *) +class datatype_expr ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Integer numeral expression objects *) +class int_num ctx = +object (self) + inherit int_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Rational numeral expression objects *) +class rat_num ctx = +object (self) + inherit real_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Bit-vector numeral expression objects *) +class bitvec_num ctx = +object (self) + inherit bitvec_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + +(** Algebraic numeral expression objects *) +class algebraic_num ctx = +object (self) + inherit arith_expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + + +(** Quantifier objects *) +class quantifier ctx = +object (self) + inherit expr ctx as super + method cnstr_obj obj = (self#sno ctx#gno obj) ; self +end + + + (**/**) (** Interaction logging for Z3. @@ -138,34 +494,34 @@ struct @return True if opening the log file succeeds, false otherwise. *) (* CMW: "open" seems to be a reserved keyword? *) - let open_ filename = ((int2lbool (open_log filename)) == L_TRUE) + let open_ filename = ((int2lbool (Z3native.open_log filename)) == L_TRUE) (** Closes the interaction log. *) - let close = close_log + let close = Z3native.close_log (** Appends a user-provided string to the interaction log. @param s the string to append*) - let append s = append_log s + let append s = Z3native.append_log s end (** Version information. *) module Version = struct (** The major version. *) - let major = let (x, _, _, _) = get_version in x + let major = let (x, _, _, _) = Z3native.get_version in x (** The minor version. *) - let minor = let (_, x, _, _) = get_version in x + let minor = let (_, x, _, _) = Z3native.get_version in x (** The build version. *) - let build = let (_, _, x, _) = get_version in x + let build = let (_, _, x, _) = Z3native.get_version in x (** The revision. *) - let revision = let (_, _, _, x) = get_version in x + let revision = let (_, _, _, x) = Z3native.get_version in x (** A string representation of the version information. *) let to_string = - let (mj, mn, bld, rev) = get_version in + let (mj, mn, bld, rev) = Z3native.get_version in string_of_int mj ^ "." ^ string_of_int mn ^ "." ^ string_of_int bld ^ "." ^ @@ -174,75 +530,5281 @@ end (** Symbols are used to name several term and type constructors. *) module Symbol = -struct -(**/**) - let create ctx obj = - match obj with - | Some(x) -> ( - match (int2symbol_kind (get_symbol_kind ctx#gno x)) with - | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj obj) :> symbol) - | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj obj) :> symbol) - ) - | None -> raise (Exception "Can't create null objects") -(**/**) - +struct (** The kind of the symbol (int or string) *) - let kind (o : symbol) = match o#gno with - | Some(x) -> (int2symbol_kind (get_symbol_kind o#gnc x)) - | _ -> raise (Exception "Underlying object lost") + let kind (o : symbol) = (int2symbol_kind (Z3native.get_symbol_kind o#gnc o#gno)) (** Indicates whether the symbol is of Int kind *) - let is_int_symbol (o : symbol) = match o#gno with - | Some(x) -> (kind o) == INT_SYMBOL - | _ -> false + let is_int_symbol (o : symbol) = (kind o) == INT_SYMBOL (** Indicates whether the symbol is of string kind. *) - let is_string_symbol (o : symbol) = match o#gno with - | Some(x) -> (kind o) == STRING_SYMBOL - | _ -> false + let is_string_symbol (o : symbol) = (kind o) == STRING_SYMBOL (** The int value of the symbol. *) - let get_int (o : int_symbol) = match o#gno with - | Some(x) -> (get_symbol_int o#gnc x) - | None -> 0 + let get_int (o : int_symbol) = Z3native.get_symbol_int o#gnc o#gno (** The string value of the symbol. *) - let get_string (o : string_symbol) = match o#gno with - | Some(x) -> (get_symbol_string o#gnc x) - | None -> "" + let get_string (o : string_symbol) = Z3native.get_symbol_string o#gnc o#gno (** A string representation of the symbol. *) - let to_string (o : symbol) = match o#gno with - | Some(x) -> - ( - match (kind o) with - | INT_SYMBOL -> (string_of_int (get_symbol_int o#gnc x)) - | STRING_SYMBOL -> (get_symbol_string o#gnc x) - ) - | None -> "" + let to_string (o : symbol) = + match (kind o) with + | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int o#gnc o#gno)) + | STRING_SYMBOL -> (Z3native.get_symbol_string o#gnc o#gno) end -(** The main interaction with Z3 happens via the Context. *) + +(** + The Sort module implements type information for ASTs. +*) +module Sort = +struct + (** + Comparison operator. + @param a A sort + @param b A sort + @return True if and are from the same context + and represent the same sort; false otherwise. + *) + let ( = ) (a : sort) (b : sort) = (a == b) || + if a#gnc != b#gnc then + false + else + ((int2lbool (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) + + (** + Returns a unique identifier for the sort. + *) + let get_id (x : sort) = Z3native.get_sort_id x#gnc x#gno + + (** + The kind of the sort. + *) + let get_sort_kind (x : sort) = (int2sort_kind (Z3native.get_sort_kind x#gnc x#gno)) + + (** + The name of the sort + *) + let get_name (x : sort) = (create_symbol x#gc (Z3native.get_sort_name x#gnc x#gno)) + + (** + A string representation of the sort. + *) + let to_string (x : sort) = Z3native.sort_to_string x#gnc x#gno +end + +(** Array sorts *) +module ArraySort = +struct + (** The domain of the array sort. *) + let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) + + (** The range of the array sort. *) + let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) +end + +(** Bit-vector sorts *) +module BitVectorSort = +struct + (** The size of the bit-vector sort. *) + let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno +end + +(** Finite domain sorts. *) +module FiniteDomainSort = +struct + (** The size of the finite domain sort. *) + let get_size (x : finite_domain_sort) = + let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") +end + +(** Relation sorts. *) +module RelationSort = +struct + (** The arity of the relation sort. *) + let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno + + (** The sorts of the columns of the relation sort. *) + let get_column_sorts (x : relation_sort) = + let n = get_arity x in + let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in + Array.init n f + +end + +(**/**) +let create_expr ctx obj = + if int2ast_kind (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then + (((new quantifier ctx)#cnstr_obj obj) :> expr) + else + let s = Z3native.get_sort ctx#gno obj in + let sk = (int2sort_kind (Z3native.get_sort_kind ctx#gno s)) in + if (int2lbool (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then + (((new algebraic_num ctx)#cnstr_obj obj) :> expr) + else + if ((int2lbool (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && + (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + match sk with + | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) + | REAL_SORT -> (((new rat_num ctx)#cnstr_obj obj) :> expr) + | BV_SORT -> (((new bitvec_num ctx)#cnstr_obj obj) :> expr) + | _ -> raise (Z3native.Exception "Unsupported numeral object") + else + match sk with + | BOOL_SORT -> (((new bool_expr ctx)#cnstr_obj obj) :> expr) + | INT_SORT -> (((new int_expr ctx)#cnstr_obj obj) :> expr) + | REAL_SORT -> (((new real_expr ctx)#cnstr_obj obj) :> expr) + | BV_SORT -> (((new bitvec_expr ctx)#cnstr_obj obj) :> expr) + | ARRAY_SORT -> (((new array_expr ctx)#cnstr_obj obj) :> expr) + | DATATYPE_SORT -> (((new datatype_expr ctx)#cnstr_obj obj) :> expr) + | _ -> (new expr ctx)#cnstr_obj obj + +let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = + let o = Z3native.mk_app ctx#gno f#gno (Array.length args) (astaton args) in + create_expr ctx o + +let create_ast ctx no = + match (int2ast_kind (Z3native.get_ast_kind ctx#gno no)) with + | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) + | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) + | SORT_AST -> ((create_sort ctx no) :> ast) + | APP_AST + | NUMERAL_AST + | VAR_AST -> ((create_expr ctx no) :> ast) + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") +(**/**) + +(** Function declarations. *) +module FuncDecl = +struct +(** Parameters of Func_Decls *) + module Parameter = + struct + (** + The kind of the parameter. + *) + let get_kind (x : parameter) = x#kind + + (**The int value of the parameter.*) + let get_int (x : parameter) = + if (x#kind != PARAMETER_INT) then + raise (Z3native.Exception "parameter is not an int") + else + x#int + + (**The double value of the parameter.*) + let get_double (x : parameter) = + if (x#kind != PARAMETER_DOUBLE) then + raise (Z3native.Exception "parameter is not a double") + else + x#double + + (**The Symbol value of the parameter.*) + let get_symbol (x : parameter) = + if (x#kind != PARAMETER_SYMBOL) then + raise (Z3native.Exception "parameter is not a symbol") + else + x#symbol + + (**The Sort value of the parameter.*) + let get_sort (x : parameter) = + if (x#kind != PARAMETER_SORT) then + raise (Z3native.Exception "parameter is not a sort") + else + x#sort + + (**The AST value of the parameter.*) + let get_ast (x : parameter) = + if (x#kind != PARAMETER_AST) then + raise (Z3native.Exception "parameter is not an ast") + else + x#ast + + (**The FunctionDeclaration value of the parameter.*) + let get_ast (x : parameter) = + if (x#kind != PARAMETER_FUNC_DECL) then + raise (Z3native.Exception "parameter is not an function declaration") + else + x#func_decl + + (**The rational string value of the parameter.*) + let get_rational (x : parameter) = + if (x#kind != PARAMETER_RATIONAL) then + raise (Z3native.Exception "parameter is not a ratinoal string") + else + x#rational + end + + (** + Comparison operator. + @param a A func_decl + @param b A func_decl + @return True if and are from the same context + and represent the same func_decl; false otherwise. + *) + let ( = ) (a : func_decl) (b : func_decl) = (a == b) || + if a#gnc == a#gnc then + false + else + ((int2lbool (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) + (** + A string representations of the function declaration. + *) + let to_string (x : func_decl) = Z3native.func_decl_to_string x#gnc x#gno + + (** + Returns a unique identifier for the function declaration. + *) + let get_id (x : func_decl) = Z3native.get_func_decl_id x#gnc x#gno + + (** + The arity of the function declaration + *) + let get_arity (x : func_decl) = Z3native.get_arity x#gnc x#gno + + (** + The size of the domain of the function declaration + + *) + let get_domain_size (x : func_decl) = Z3native.get_domain_size x#gnc x#gno + + (** + The domain of the function declaration + *) + let get_domain (x : func_decl) = + let n = (get_domain_size x) in + let f i = create_sort x#gc (Z3native.get_domain x#gnc x#gno i) in + Array.init n f + + (** + The range of the function declaration + *) + let get_range (x : func_decl) = + create_sort x#gc (Z3native.get_range x#gnc x#gno) + + (** + The kind of the function declaration. + *) + let get_decl_kind (x : func_decl) = (int2decl_kind (Z3native.get_decl_kind x#gnc x#gno)) + + (** + The name of the function declaration + *) + let get_name (x : func_decl) = (create_symbol x#gc (Z3native.get_decl_name x#gnc x#gno)) + + (** + The number of parameters of the function declaration + *) + let get_num_parameters (x : func_decl) = (Z3native.get_decl_num_parameters x#gnc x#gno) + + (** + The parameters of the function declaration + *) + let get_parameters (x : func_decl) = + let n = (get_num_parameters x) in + let f i = ( + match (int2parameter_kind (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with + | PARAMETER_INT -> (new parameter)#cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) + | PARAMETER_DOUBLE -> (new parameter)#cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) + | PARAMETER_SYMBOL-> (new parameter)#cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) + | PARAMETER_SORT -> (new parameter)#cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) + | PARAMETER_AST -> (new parameter)#cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) + | PARAMETER_FUNC_DECL -> (new parameter)#cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) + | PARAMETER_RATIONAL -> (new parameter)#cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) + ) in + Array.init n f + + (** + Create expression that applies function to arguments. + + *) + let apply (x : func_decl) (args : expr array) = create_expr_fa x#gc x args + +end + +(** Datatype sorts *) +module DatatypeSort = +struct + (** The number of constructors of the datatype sort. *) + let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno + + (** The range of the array sort. *) + let get_constructors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in + Array.init n f + + (** The recognizers. *) + let get_recognizers (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in + Array.init n f + + (** The constructor accessors. *) + let get_accessors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = ( + let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in + let ds = (Z3native.get_domain_size fd#gnc fd#gno) in + let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in + Array.init ds g + ) in + Array.init n f +end + +(** Enumeration sorts. *) +module EnumSort = +struct + (** The function declarations of the constants in the enumeration. *) + let get_const_decls (x : enum_sort) = + let f e = ((new func_decl x#gc)#cnstr_obj e) in + Array.map f x#const_decls + + (** The test predicates for the constants in the enumeration. *) + let get_tester_decls (x : enum_sort) = + let f e = ((new func_decl x#gc)#cnstr_obj e) in + Array.map f x#tester_decls +end + +(** List sorts. *) +module ListSort = +struct + (** The declaration of the nil function of this list sort. *) + let get_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#nil_decl + + (** The declaration of the isNil function of this list sort. *) + let get_is_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_nil_decl + + (** The declaration of the cons function of this list sort. *) + let get_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#cons_decl + + (** The declaration of the isCons function of this list sort. *) + let get_is_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_cons_decl + + (** The declaration of the head function of this list sort.*) + let get_head_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#head_decl + + (** The declaration of the tail function of this list sort. *) + let get_tail_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#tail_decl + + (** The empty list. *) + let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] +end + +module TupleSort = +struct + (** The constructor function of the tuple.*) + let get_mk_decl (x : tuple_sort) = + (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) + + (** The number of fields in the tuple. *) + let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno + + (** The field declarations. *) + let get_field_decls (x : tuple_sort) = + let n = get_num_fields x in + let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in + Array.init n f +end + +(** The abstract syntax tree (AST) module. *) +module AST = +struct + (** + The AST's hash code. + @return A hash code + *) + let get_hash_code ( x : ast) = Z3native.get_ast_hash x#gnc x#gno + + (** + A unique identifier for the AST (unique among all ASTs). + *) + let get_id ( x : ast) = Z3native.get_ast_id x#gnc x#gno + + (** + The kind of the AST. + *) + let get_ast_kind ( x : ast) = (int2ast_kind (Z3native.get_ast_kind x#gnc x#gno)) + + (** + Indicates whether the AST is an Expr + *) + let is_expr ( x : ast) = + match get_ast_kind ( x : ast) with + | APP_AST + | NUMERAL_AST + | QUANTIFIER_AST + | VAR_AST -> true + | _ -> false + + (** + Indicates whether the AST is a BoundVariable + *) + let is_var ( x : ast) = (get_ast_kind x) == VAR_AST + + (** + Indicates whether the AST is a Quantifier + *) + let is_quantifier ( x : ast) = (get_ast_kind x) == QUANTIFIER_AST + + + (** + Indicates whether the AST is a Sort + *) + let is_sort ( x : ast) = (get_ast_kind x) == SORT_AST + + (** + Indicates whether the AST is a FunctionDeclaration + *) + let is_func_decl ( x : ast) = (get_ast_kind x) == FUNC_DECL_AST + + (** + A string representation of the AST. + *) + let to_string ( x : ast) = Z3native.ast_to_string x#gnc x#gno + + (** + A string representation of the AST in s-expression notation. + *) + let to_sexpr ( x : ast) = Z3native.ast_to_string x#gnc x#gno + + (** + Comparison operator. + @param a An AST + @param b An AST + @return True if and are from the same context + and represent the same sort; false otherwise. + *) + let ( = ) (a : expr) (b : expr) = (a == b) || + if a#gnc == b#gnc then + false + else + ((int2lbool (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) + + (** + Object Comparison. + @param other Another ast + @return Negative if the object should be sorted before , positive if after else zero. + *) + let compare a b = + if (get_id a) < (get_id b) then -1 else + if (get_id a) > (get_id b) then 1 else + 0 + + (** Operator < *) + let ( < ) (a : ast) (b : ast) = (compare a b) + + (** + Translates (copies) the AST to the Context . + @param ctx A context + @return A copy of the AST which is associated with + *) + let translate ( x : ast) to_ctx = + if x#gc == to_ctx then + x + else + (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) +end + +(** + Parameter sets + + A Params objects represents a configuration in the form of Symbol/value pairs. +*) +module Params = +struct + (** + Adds a parameter setting. + *) + let add_bool (p : params) (name : symbol) (value : bool) = + Z3native.params_set_bool p#gnc p#gno name#gno (lbool2int (if value then L_TRUE else L_FALSE)) + + (** + Adds a parameter setting. + *) + let add_int (p : params) (name : symbol) (value : int) = + Z3native.params_set_uint p#gnc p#gno name#gno value + + (** + Adds a parameter setting. + *) + let add_double (p : params) (name : symbol) (value : float) = + Z3native.params_set_double p#gnc p#gno name#gno value + + (** + Adds a parameter setting. + *) + let add_symbol (p : params) (name : symbol) (value : symbol) = + Z3native.params_set_symbol p#gnc p#gno name#gno value#gno + + (** + Adds a parameter setting. + *) + let add_s_bool (p : params) (name : string) (value : bool) = + add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_int (p : params) (name : string) (value : int) = + add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_double (p : params) (name : string) (value : float) = + add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_symbol (p : params) (name : string) (value : symbol) = + add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + A string representation of the parameter set. + *) + let to_string (p : params) = Z3native.params_to_string p#gnc p#gno +end + +(** Expressions (terms) *) +module Expr = +struct + (** + Returns a simplified version of the expression. + A set of parameters to configure the simplifier + + *) + let simplify ( x : expr ) ( p : params option ) = match p with + | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) + | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) + + (** + The function declaration of the function that is applied in this expression. + *) + let get_func_decl ( x : expr ) = (new func_decl x#gc)#cnstr_obj (Z3native.get_app_decl x#gnc x#gno) + + (** + Indicates whether the expression is the true or false expression + or something else (Z3_L_UNDEF). + *) + let get_bool_value ( x : expr ) = int2lbool (Z3native.get_bool_value x#gnc x#gno) + + (** + The number of arguments of the expression. + *) + let get_num_args ( x : expr ) = Z3native.get_app_num_args x#gnc x#gno + + (** + The arguments of the expression. + *) + let get_args ( x : expr ) = let n = (get_num_args x) in + let f i = create_expr x#gc (Z3native.get_app_arg x#gnc x#gno i) in + Array.init n f + + (** + Update the arguments of the expression using the arguments + The number of new arguments should coincide with the current number of arguments. + *) + let update ( x : expr ) args = + if (Array.length args <> (get_num_args x)) then + raise (Z3native.Exception "Number of arguments does not match") + else + x#sno x#gnc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) + + (** + Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + + The result is the new expression. The arrays from and to must have size num_exprs. + For every i smaller than num_exprs, we must have that + sort of from[i] must be equal to sort of to[i]. + + *) + let substitute ( x : expr ) from to_ = + if (Array.length from) <> (Array.length to_) then + raise (Z3native.Exception "Argument sizes do not match") + else + create_expr x#gc (Z3native.substitute x#gnc x#gno (Array.length from) (expraton from) (expraton to_)) + + (** + Substitute every occurrence of from in the expression with to. + + *) + let substitute_one ( x : expr ) from to_ = + substitute ( x : expr ) [| from |] [| to_ |] + + (** + Substitute the free variables in the expression with the expressions in + + For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. + + *) + let substitute_vars ( x : expr ) to_ = + create_expr x#gc (Z3native.substitute_vars x#gnc x#gno (Array.length to_) (expraton to_)) + + + (** + Translates (copies) the term to the Context . + A context + A copy of the term which is associated with + *) + let translate ( x : expr ) to_ctx = + if x#gc == to_ctx then + x + else + create_expr to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno) + + (** + Returns a string representation of the expression. + *) + let to_string ( x : expr ) = Z3native.ast_to_string x#gnc x#gno + + (** + Indicates whether the term is a numeral + *) + let is_numeral ( x : expr ) = int2lbool (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE + + (** + Indicates whether the term is well-sorted. + True if the term is well-sorted, false otherwise. + *) + let is_well_sorted ( x : expr ) = int2lbool (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE + + (** + The Sort of the term. + *) + let get_sort ( x : expr ) = create_sort x#gc (Z3native.get_sort x#gnc x#gno) + + (** + Indicates whether the term has Boolean sort. + *) + let is_bool ( x : expr ) = (AST.is_expr x) && + (int2lbool (Z3native.is_eq_sort x#gnc + (Z3native.mk_bool_sort x#gnc) + (Z3native.get_sort x#gnc x#gno))) == L_TRUE + + (** + Indicates whether the term is of integer sort. + *) + let is_int ( x : expr ) = + ((int2lbool (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + + (** + Indicates whether the term is of sort real. + *) + let is_real ( x : expr ) = + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + + (** + Indicates whether the term is of an array sort. + *) + let is_array ( x : expr ) = + ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + + (** + Indicates whether the term represents a constant. + *) + let is_const ( x : expr ) = (AST.is_expr x) && + (get_num_args x) == 0 && + FuncDecl.get_domain_size(get_func_decl x) == 0 + + (** + Indicates whether the term is an integer numeral. + *) + let is_int_numeral ( x : expr ) = (is_numeral x) && (is_int x) + + (** + Indicates whether the term is a real numeral. + *) + let is_rat_num ( x : expr ) = (is_numeral x) && (is_real x) + + (** + Indicates whether the term is an algebraic number + *) + let is_algebraic_number ( x : expr ) = int2lbool(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + + (** + Indicates whether the term is the constant true. + *) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + + (** + Indicates whether the term is the constant false. + *) + let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + + (** + Indicates whether the term is an equality predicate. + *) + let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + + (** + Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). + *) + let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + + (** + Indicates whether the term is a ternary if-then-else term + *) + let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + + (** + Indicates whether the term is an n-ary conjunction + *) + let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + + (** + Indicates whether the term is an n-ary disjunction + *) + let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + + (** + Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) + *) + let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + + (** + Indicates whether the term is an exclusive or + *) + let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + + (** + Indicates whether the term is a negation + *) + let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + + (** + Indicates whether the term is an implication + *) + let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) + + (** + Indicates whether the term is an arithmetic numeral. + *) + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ANUM) + + (** + Indicates whether the term is a less-than-or-equal + *) + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LE) + + (** + Indicates whether the term is a greater-than-or-equal + *) + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GE) + + (** + Indicates whether the term is a less-than + *) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LT) + + (** + Indicates whether the term is a greater-than + *) + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GT) + + (** + Indicates whether the term is addition (binary) + *) + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ADD) + + (** + Indicates whether the term is subtraction (binary) + *) + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SUB) + + (** + Indicates whether the term is a unary minus + *) + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UMINUS) + + (** + Indicates whether the term is multiplication (binary) + *) + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MUL) + + (** + Indicates whether the term is division (binary) + *) + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DIV) + + (** + Indicates whether the term is integer division (binary) + *) + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IDIV) + + (** + Indicates whether the term is remainder (binary) + *) + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REM) + + (** + Indicates whether the term is modulus (binary) + *) + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MOD) + + (** + Indicates whether the term is a coercion of integer to real (unary) + *) + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_REAL) + + (** + Indicates whether the term is a coercion of real to integer (unary) + *) + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_INT) + + (** + Indicates whether the term is a check that tests whether a real is integral (unary) + *) + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IS_INT) + + (** + Indicates whether the term is an array store. + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. + *) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_STORE) + + (** + Indicates whether the term is an array select. + *) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SELECT) + + (** + Indicates whether the term is a constant array. + For example, select(const(v),i) = v holds for every v and i. The function is unary. + *) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONST_ARRAY) + + (** + Indicates whether the term is a default array. + For example default(const(v)) = v. The function is unary. + *) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_DEFAULT) + + (** + Indicates whether the term is an array map. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + *) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_MAP) + + (** + Indicates whether the term is an as-array term. + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. + *) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AS_ARRAY) + + (** + Indicates whether the term is set union + *) + let is_set_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_UNION) + + (** + Indicates whether the term is set intersection + *) + let is_set_intersect ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_INTERSECT) + + (** + Indicates whether the term is set difference + *) + let is_set_difference ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_DIFFERENCE) + + (** + Indicates whether the term is set complement + *) + let is_set_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_COMPLEMENT) + + (** + Indicates whether the term is set subset + *) + let is_set_subset ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_SUBSET) + + (** + Indicates whether the terms is of bit-vector sort. + *) + let is_bv ( x : expr ) = + ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) + + (** + Indicates whether the term is a bit-vector numeral + *) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNUM) + + (** + Indicates whether the term is a one-bit bit-vector with value one + *) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT1) + + (** + Indicates whether the term is a one-bit bit-vector with value zero + *) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT0) + + (** + Indicates whether the term is a bit-vector unary minus + *) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNEG) + + (** + Indicates whether the term is a bit-vector addition (binary) + *) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BADD) + + (** + Indicates whether the term is a bit-vector subtraction (binary) + *) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSUB) + + (** + Indicates whether the term is a bit-vector multiplication (binary) + *) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BMUL) + + (** + Indicates whether the term is a bit-vector signed division (binary) + *) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV) + + (** + Indicates whether the term is a bit-vector unsigned division (binary) + *) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV) + + (** + Indicates whether the term is a bit-vector signed remainder (binary) + *) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM) + + (** + Indicates whether the term is a bit-vector unsigned remainder (binary) + *) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM) + + (** + Indicates whether the term is a bit-vector signed modulus + *) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD) + + (** + Indicates whether the term is a bit-vector signed division by zero + *) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV0) + + (** + Indicates whether the term is a bit-vector unsigned division by zero + *) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV0) + + (** + Indicates whether the term is a bit-vector signed remainder by zero + *) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM0) + + (** + Indicates whether the term is a bit-vector unsigned remainder by zero + *) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM0) + + (** + Indicates whether the term is a bit-vector signed modulus by zero + *) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD0) + + (** + Indicates whether the term is an unsigned bit-vector less-than-or-equal + *) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULEQ) + + (** + Indicates whether the term is a signed bit-vector less-than-or-equal + *) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLEQ) + + (** + Indicates whether the term is an unsigned bit-vector greater-than-or-equal + *) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGEQ) + + (** + Indicates whether the term is a signed bit-vector greater-than-or-equal + *) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGEQ) + + (** + Indicates whether the term is an unsigned bit-vector less-than + *) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULT) + + (** + Indicates whether the term is a signed bit-vector less-than + *) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLT) + + (** + Indicates whether the term is an unsigned bit-vector greater-than + *) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGT) + + (** + Indicates whether the term is a signed bit-vector greater-than + *) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGT) + + (** + Indicates whether the term is a bit-wise AND + *) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BAND) + + (** + Indicates whether the term is a bit-wise OR + *) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BOR) + + (** + Indicates whether the term is a bit-wise NOT + *) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOT) + + (** + Indicates whether the term is a bit-wise XOR + *) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXOR) + + (** + Indicates whether the term is a bit-wise NAND + *) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNAND) + + (** + Indicates whether the term is a bit-wise NOR + *) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOR) + + (** + Indicates whether the term is a bit-wise XNOR + *) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXNOR) + + (** + Indicates whether the term is a bit-vector concatenation (binary) + *) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONCAT) + + (** + Indicates whether the term is a bit-vector sign extension + *) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SIGN_EXT) + + (** + Indicates whether the term is a bit-vector zero extension + *) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ZERO_EXT) + + (** + Indicates whether the term is a bit-vector extraction + *) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXTRACT) + + (** + Indicates whether the term is a bit-vector repetition + *) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REPEAT) + + (** + Indicates whether the term is a bit-vector reduce OR + *) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDOR) + + (** + Indicates whether the term is a bit-vector reduce AND + *) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDAND) + + (** + Indicates whether the term is a bit-vector comparison + *) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BCOMP) + + (** + Indicates whether the term is a bit-vector shift left + *) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSHL) + + (** + Indicates whether the term is a bit-vector logical shift right + *) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BLSHR) + + (** + Indicates whether the term is a bit-vector arithmetic shift left + *) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BASHR) + + (** + Indicates whether the term is a bit-vector rotate left + *) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_LEFT) + + (** + Indicates whether the term is a bit-vector rotate right + *) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_RIGHT) + + (** + Indicates whether the term is a bit-vector rotate left (extended) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. + *) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_LEFT) + + (** + Indicates whether the term is a bit-vector rotate right (extended) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. + *) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_RIGHT) + + (** + Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. + *) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_INT2BV) + + (** + Indicates whether the term is a coercion from bit-vector to integer + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. + *) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BV2INT) + + (** + Indicates whether the term is a bit-vector carry + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + *) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CARRY) + + (** + Indicates whether the term is a bit-vector ternary XOR + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) + *) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR3) + + (** + Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. + *) + let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) + + (** + Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) + *) + + (** + Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. + *) + let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + + (** + Indicates whether the term is a Proof for the expression 'true'. + *) + let is_proof_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRUE) + + (** + Indicates whether the term is a proof for a fact asserted by the user. + *) + let is_proof_asserted ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ASSERTED) + + (** + Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. + *) + let is_proof_goal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_GOAL) + + (** + Indicates whether the term is proof via modus ponens + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). + *) + let is_proof_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS) + + (** + Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. + *) + let is_proof_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REFLEXIVITY) + + (** + Indicates whether the term is proof by symmetricity of a relation + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. + + *) + let is_proof_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SYMMETRY) + + (** + Indicates whether the term is a proof by transitivity of a relation + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) + + *) + let is_proof_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY) + + (** + Indicates whether the term is a proof by condensed transitivity of a relation + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. + + *) + let is_proof_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + + + (** + Indicates whether the term is a monotonicity proof object. + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. + + *) + let is_proof_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MONOTONICITY) + + (** + Indicates whether the term is a quant-intro proof + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) + + *) + let is_proof_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INTRO) + + (** + Indicates whether the term is a distributivity proof object. + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. + + *) + let is_proof_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DISTRIBUTIVITY) + + (** + Indicates whether the term is a proof by elimination of AND + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i + + *) + let is_proof_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_AND_ELIM) + + (** + Indicates whether the term is a proof by eliminiation of not-or + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) + + *) + let is_proof_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NOT_OR_ELIM) + + (** + Indicates whether the term is a proof by rewriting + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) + + *) + let is_proof_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE) + + (** + Indicates whether the term is a proof by rewriting + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) + + *) + let is_proof_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE_STAR) + + (** + Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. + + *) + let is_proof_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT) + + (** + Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents + + *) + let is_proof_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT_STAR) + + (** + Indicates whether the term is a proof for pushing quantifiers in. + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents + + *) + let is_proof_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PUSH_QUANT) + + (** + Indicates whether the term is a proof for elimination of unused variables. + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. + + *) + let is_proof_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + + (** + Indicates whether the term is a proof for destructive equality resolution + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. + + *) + let is_proof_der ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DER) + + (** + Indicates whether the term is a proof for quantifier instantiation + + A proof of (or (not (forall (x) (P x))) (P a)) + + *) + let is_proof_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INST) + + (** + Indicates whether the term is a hypthesis marker. + Mark a hypothesis in a natural deduction style proof. + *) + let is_proof_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_HYPOTHESIS) + + (** + Indicates whether the term is a proof by lemma + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. + + *) + let is_proof_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_LEMMA) + + (** + Indicates whether the term is a proof by unit resolution + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') + + *) + let is_proof_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_UNIT_RESOLUTION) + + (** + Indicates whether the term is a proof by iff-true + + T1: p + [iff-true T1]: (iff p true) + + *) + let is_proof_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_TRUE) + + (** + Indicates whether the term is a proof by iff-false + + T1: (not p) + [iff-false T1]: (iff p false) + + *) + let is_proof_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_FALSE) + + (** + Indicates whether the term is a proof by commutativity + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. + + *) + let is_proof_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + + (** + Indicates whether the term is a proof for Tseitin-like axioms + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). + + *) + let is_proof_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_AXIOM) + + (** + Indicates whether the term is a proof for introduction of a name + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) + + *) + let is_proof_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_INTRO) + + (** + Indicates whether the term is a proof for application of a definition + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. + + *) + let is_proof_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_APPLY_DEF) + + (** + Indicates whether the term is a proof iff-oeq + + T1: (iff p q) + [iff~ T1]: (~ p q) + + *) + let is_proof_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_OEQ) + + (** + Indicates whether the term is a proof for a positive NNF step + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. + + *) + let is_proof_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_POS) + + (** + Indicates whether the term is a proof for a negative NNF step + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) + + *) + let is_proof_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_NEG) + + (** + Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. + + *) + let is_proof_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_STAR) + + (** + Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. + + *) + let is_proof_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_CNF_STAR) + + (** + Indicates whether the term is a proof for a Skolemization step + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. + + *) + let is_proof_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SKOLEMIZE) + + (** + Indicates whether the term is a proof by modus ponens for equi-satisfiability. + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q + + *) + let is_proof_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + + (** + Indicates whether the term is a proof for theory lemma + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. + + *) + let is_proof_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TH_LEMMA) + + (** + Indicates whether the term is of a relation sort. + *) + let is_Relation ( x : expr ) = + ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + + (** + Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. + + *) + let is_relation_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_STORE) + + (** + Indicates whether the term is an empty relation + *) + let is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_EMPTY) + + (** + Indicates whether the term is a test for the emptiness of a relation + *) + let is_is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_IS_EMPTY) + + (** + Indicates whether the term is a relational join + *) + let is_relational_join ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_JOIN) + + (** + Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. + *) + let is_relation_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_UNION) + + (** + Indicates whether the term is the widening of two relations + The function takes two arguments. + *) + let is_relation_widen ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_WIDEN) + + (** + Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. + *) + let is_relation_project ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_PROJECT) + + (** + Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. + + *) + let is_relation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_FILTER) + + (** + Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. + + *) + let is_relation_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_NEGATION_FILTER) + + (** + Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. + + *) + let is_relation_rename ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_RENAME) + + (** + Indicates whether the term is the complement of a relation + *) + let is_relation_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_COMPLEMENT) + + (** + Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. + + *) + let is_relation_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_SELECT) + + (** + Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind + to perform destructive updates to the first argument. + + *) + let is_relation_clone ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_CLONE) + + (** + Indicates whether the term is of an array sort. + *) + let is_finite_domain ( x : expr ) = + ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + + (** + Indicates whether the term is a less than predicate over a finite domain. + *) + let is_finite_domain_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FD_LT) + + (** + The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. + + *) + let get_index ( x : expr ) = + if not (AST.is_var x) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value x#gnc x#gno +end + +(* Integer Numerals *) +module IntNum = +struct + (** Retrieve the int value. *) + let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** Rational Numerals *) +module RatNum = +struct + + (** The numerator of a rational numeral. *) + let get_numerator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) + + (** The denominator of a rational numeral. *) + let get_denominator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : rat_num ) (precision : int) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** Bit-vector numerals *) +module BitVecNum = +struct + (** Retrieve the int value. *) + let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** Algebraic numbers *) +module AlgebraicNum = +struct + (** + Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + + the precision of the result + A numeral Expr of sort Real + *) + let to_upper ( x : algebraic_num ) ( precision : int ) = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) + + (** + Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + + + A numeral Expr of sort Real + *) + let to_lower ( x : algebraic_num ) precision = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno +end + +(** The main interaction with Z3 happens via the Context module. *) module Context = struct + + (* SYMBOLS *) + (** Creates a new symbol using an integer. Not all integers can be passed to this function. The legal range of unsigned integers is 0 to 2^30-1. *) - let mk_symbol_int ctx i = + let mk_symbol_int ( ctx : context ) i = (new int_symbol ctx)#cnstr_int i - + (** Creates a new symbol using a string. *) - let mk_symbol_string ctx s = + let mk_symbol_string ( ctx : context ) s = (new string_symbol ctx)#cnstr_string s (** Create an array of symbols. *) - let mk_symbols ctx names = - let f elem = mk_symbol_string ctx elem in + let mk_symbols_int ( ctx : context ) names = + let f elem = mk_symbol_int ( ctx : context ) elem in + (Array.map f names) + + (** + Create an array of symbols. + *) + let mk_symbols_string ( ctx : context ) names = + let f elem = mk_symbol_string ( ctx : context ) elem in (Array.map f names) + + (* SORTS *) + + (** + Create a new Boolean sort. + *) + let mk_bool_sort ( ctx : context ) = + (new bool_sort ctx) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_sort ( ctx : context ) (s : symbol) = + (new uninterpreted_sort ctx)#cnstr_s s + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_sort_s ( ctx : context ) (s : string) = + mk_uninterpreted_sort ctx ((mk_symbol_string ( ctx : context ) s) :> symbol) + + (** + Create a new integer sort. + *) + let mk_int_sort ( ctx : context ) = + (new int_sort ctx) + + (** + Create a real sort. + *) + let mk_real_sort ( ctx : context ) = + (new real_sort ctx) + + (** + Create a new bit-vector sort. + *) + let mk_bitvec_sort ( ctx : context ) size = + (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) + + (** + Create a new array sort. + *) + let mk_array_sort ( ctx : context ) domain range = + (new array_sort ctx)#cnstr_dr domain range + + (** + Create a new tuple sort. + *) + let mk_tuple_sort ( ctx : context ) name field_names field_sorts = + (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts + + (** + Create a new enumeration sort. + *) + let mk_enum_sort ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss name enum_names + + (** + Create a new enumeration sort. + *) + let mk_enum_sort_s ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss + ((mk_symbol_string ( ctx : context ) name) :> symbol) + (let f e = (e :> symbol) in + (Array.map f (mk_symbols_string ( ctx : context ) enum_names)) + ) + + (** + Create a new list sort. + *) + let mk_list_sort ( ctx : context ) (name : symbol) elem_sort = + (new list_sort ctx)#cnstr_ss name elem_sort + + (** + Create a new list sort. + *) + let mk_list_sort_s ( ctx : context ) (name : string) elem_sort = + mk_list_sort ctx ((mk_symbol_string ctx name) :> symbol) elem_sort + + + (** + Create a new finite domain sort. + *) + let mk_finite_domain_sort ( ctx : context ) ( name : symbol ) size = + (new finite_domain_sort ctx)#cnstr_si name size + + (** + Create a new finite domain sort. + *) + let mk_finite_domain_sort_s ( ctx : context ) ( name : string ) size = + (new finite_domain_sort ctx)#cnstr_si ((mk_symbol_string ctx name) :> symbol) size + +(** + +(* DATATYPES *) +(** + Create a datatype constructor. +*) + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) + { + + + + + return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs); + } + +(** + Create a datatype constructor. +*) + @param name + @param recognizer + @param fieldNames + @param sorts + @param sortRefs + @return + public Constructor MkConstructor(string name, string recognizer, string[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) + { + + + return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); + } + +(** + Create a new datatype sort. +*) + let mk_Datatype_Sort(Symbol name, Constructor[] constructors) + { + + + + + + + CheckContextMatch(name); + CheckContextMatch(constructors); + return new DatatypeSort(this, name, constructors); + } + +(** + Create a new datatype sort. +*) + let mk_Datatype_Sort(string name, Constructor[] constructors) + { + + + + + CheckContextMatch(constructors); + return new DatatypeSort(this, MkSymbol(name), constructors); + } + +(** + Create mutually recursive datatypes. +*) + @param names names of datatype sorts + @param c list of constructors, one list per sort. + let mk_Datatype_Sorts(Symbol[] names, Constructor[][] c) + { + + + + + + + + CheckContextMatch(names); + uint n = (uint)names.Length; + ConstructorList[] cla = new ConstructorList[n]; + IntPtr[] n_constr = new IntPtr[n]; + for (uint i = 0; i < n; i++) + { + Constructor[] constructor = c[i]; + + CheckContextMatch(constructor); + cla[i] = new ConstructorList(this, constructor); + n_constr[i] = cla[i].x#gno; + } + IntPtr[] n_res = new IntPtr[n]; + Z3native.mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr); + DatatypeSort[] res = new DatatypeSort[n]; + for (uint i = 0; i < n; i++) + res[i] = new DatatypeSort(this, n_res[i]); + return res; + } + +(** + Create mutually recursive data-types. +*) + @param names + @param c + @return + let mk_Datatype_Sorts(string[] names, Constructor[][] c) + { + + + + + + + + return MkDatatypeSorts(MkSymbols(names), c); + } + + + + +(* FUNCTION DECLARATIONS *) +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(Symbol name, Sort[] domain, Sort range) + { + + + + + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + return new Func_Decl(this, name, domain, range); + } + +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(Symbol name, Sort domain, Sort range) + { + + + + + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new Func_Decl(this, name, q, range); + } + +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(string name, Sort[] domain, Sort range) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(range); + return new Func_Decl(this, MkSymbol(name), domain, range); + } + +(** + Creates a new function declaration. +*) + public Func_Decl MkFunc_Decl(string name, Sort domain, Sort range) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new Func_Decl(this, MkSymbol(name), q, range); + } + +(** + Creates a fresh function declaration with a name prefixed with . +*) + + + let mk_Fresh_Func_Decl(string prefix, Sort[] domain, Sort range) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(range); + return new Func_Decl(this, prefix, domain, range); + } + +(** + Creates a new constant function declaration. +*) + let mk_Const_Decl(Symbol name, Sort range) + { + + + + + CheckContextMatch(name); + CheckContextMatch(range); + return new Func_Decl(this, name, null, range); + } + +(** + Creates a new constant function declaration. +*) + let mk_Const_Decl(string name, Sort range) + { + + + + CheckContextMatch(range); + return new Func_Decl(this, MkSymbol(name), null, range); + } + +(** + Creates a fresh constant function declaration with a name prefixed with . +*) + + + let mk_Fresh_ConstDecl(string prefix, Sort range) + { + + + + CheckContextMatch(range); + return new Func_Decl(this, prefix, null, range); + } + + +(* BOUND VARIABLES *) +(** + Creates a new bound variable. +*) + @param index The de-Bruijn index of the variable + @param ty The sort of the variable + public Expr MkBound(uint index, Sort ty) + { + + + + return Expr.Create(this, Z3native.mk_bound(nCtx, index, ty.x#gno)); + } + + +(* QUANTIFIER PATTERNS *) +(** + Create a quantifier pattern. +*) + public Pattern MkPattern(params Expr[] terms) + { + + if (terms.Length == 0) + throw new Z3Exception("Cannot create a pattern from zero terms"); + + + + + + IntPtr[] termsNative = AST.ArrayToNative(terms); + return new Pattern(this, Z3native.mk_pattern(nCtx, (uint)terms.Length, termsNative)); + } + + +(* CONSTANTS *) +(** + Creates a new Constant of sort and named . +*) + public Expr MkConst(Symbol name, Sort range) + { + + + + + CheckContextMatch(name); + CheckContextMatch(range); + + return Expr.Create(this, Z3native.mk_const(nCtx, name.x#gno, range.x#gno)); + } + +(** + Creates a new Constant of sort and named . +*) + public Expr MkConst(string name, Sort range) + { + + + + return MkConst(MkSymbol(name), range); + } + +(** + Creates a fresh Constant of sort and a + name prefixed with . +*) + let mk_Fresh_Const(string prefix, Sort range) + { + + + + CheckContextMatch(range); + return Expr.Create(this, Z3native.mk_fresh_const(nCtx, prefix, range.x#gno)); + } + +(** + Creates a fresh constant from the Func_Decl . +*) + @param f A decl of a 0-arity function + public Expr MkConst(Func_Decl f) + { + + + + return MkApp(f); + } + +(** + Create a Boolean constant. +*) + let mk_Bool_Const(Symbol name) + { + + + + return (BoolExpr)MkConst(name, BoolSort); + } + +(** + Create a Boolean constant. +*) + let mk_Bool_Const(string name) + { + + + return (BoolExpr)MkConst(MkSymbol(name), BoolSort); + } + +(** + Creates an integer constant. +*) + let mk_Int_Const(Symbol name) + { + + + + return (IntExpr)MkConst(name, IntSort); + } + +(** + Creates an integer constant. +*) + let mk_Int_Const(string name) + { + + + + return (IntExpr)MkConst(name, IntSort); + } + +(** + Creates a real constant. +*) + let mk_Real_Const(Symbol name) + { + + + + return (RealExpr)MkConst(name, RealSort); + } + +(** + Creates a real constant. +*) + let mk_Real_Const(string name) + { + + + return (RealExpr)MkConst(name, RealSort); + } + +(** + Creates a bit-vector constant. +*) + let mk_B_VConst(Symbol name, uint size) + { + + + + return (BitVecExpr)MkConst(name, MkBitVecSort(size)); + } + +(** + Creates a bit-vector constant. +*) + let mk_B_VConst(string name, uint size) + { + + + return (BitVecExpr)MkConst(name, MkBitVecSort(size)); + } + + +(* TERMS *) +(** + Create a new function application. +*) + public Expr MkApp(Func_Decl f, params Expr[] args) + { + + + + + CheckContextMatch(f); + CheckContextMatch(args); + return Expr.Create(this, f, args); + } + +(* PROPOSITIONAL *) +(** + The true Term. +*) + public BoolExpr MkTrue ( ctx : context ) = + { + + + return new BoolExpr(this, Z3native.mk_true(nCtx)); + } + +(** + The false Term. +*) + public BoolExpr MkFalse ( ctx : context ) = + { + + + return new BoolExpr(this, Z3native.mk_false(nCtx)); + } + +(** + Creates a Boolean value. +*) + public BoolExpr MkBool(bool value) + { + + + return value ? MkTrue ( ctx : context ) = : MkFalse ( ctx : context ) =; + } + +(** + Creates the equality = . +*) + public BoolExpr MkEq(Expr x, Expr y) + { + + + + + CheckContextMatch(x); + CheckContextMatch(y); + return new BoolExpr(this, Z3native.mk_eq(nCtx, x.x#gno, y.x#gno)); + } + +(** + Creates a distinct term. +*) + public BoolExpr MkDistinct(params Expr[] args) + { + + + + + + CheckContextMatch(args); + return new BoolExpr(this, Z3native.mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + +(** + Mk an expression representing not(a). +*) + public BoolExpr MkNot(BoolExpr a) + { + + + + CheckContextMatch(a); + return new BoolExpr(this, Z3native.mk_not(nCtx, a.x#gno)); + } + +(** + Create an expression representing an if-then-else: ite(t1, t2, t3). +*) + @param t1 An expression with Boolean sort + @param t2 An expression + @param t3 An expression with the same sort as + let mk_I_TE(BoolExpr t1, Expr t2, Expr t3) + { + + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(t3); + return Expr.Create(this, Z3native.mk_ite(nCtx, t1.x#gno, t2.x#gno, t3.x#gno)); + } + +(** + Create an expression representing t1 iff t2. +*) + public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_iff(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 -> t2. +*) + public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_implies(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 xor t2. +*) + public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_xor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t[0] and t[1] and .... +*) + public BoolExpr MkAnd(params BoolExpr[] t) + { + + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing t[0] or t[1] or .... +*) + public BoolExpr MkOr(params BoolExpr[] t) + { + + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + + +(* ARITHMETIC *) +(** + Create an expression representing t[0] + t[1] + .... +*) + public ArithExpr MkAdd(params ArithExpr[] t) + { + + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing t[0] * t[1] * .... +*) + public ArithExpr MkMul(params ArithExpr[] t) + { + + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing t[0] - t[1] - .... +*) + public ArithExpr MkSub(params ArithExpr[] t) + { + + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t))); + } + +(** + Create an expression representing -t. +*) + let mk_Unary_Minus(ArithExpr t) + { + + + + CheckContextMatch(t); + return (ArithExpr)Expr.Create(this, Z3native.mk_unary_minus(nCtx, t.x#gno)); + } + +(** + Create an expression representing t1 / t2. +*) + public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr)Expr.Create(this, Z3native.mk_div(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 mod t2. +*) + The arguments must have int type. + public IntExpr MkMod(IntExpr t1, IntExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Z3native.mk_mod(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 rem t2. +*) + The arguments must have int type. + public IntExpr MkRem(IntExpr t1, IntExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Z3native.mk_rem(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 ^ t2. +*) + public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr)Expr.Create(this, Z3native.mk_power(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 < t2 +*) + public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_lt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 <= t2 +*) + public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_le(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 > t2 +*) + public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_gt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an expression representing t1 >= t2 +*) + public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_ge(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Coerce an integer to a real. +*) + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. + + public RealExpr MkInt2Real(IntExpr t) + { + + + + CheckContextMatch(t); + return new RealExpr(this, Z3native.mk_int2real(nCtx, t.x#gno)); + } + +(** + Coerce a real to an integer. +*) + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. + + public IntExpr MkReal2Int(RealExpr t) + { + + + + CheckContextMatch(t); + return new IntExpr(this, Z3native.mk_real2int(nCtx, t.x#gno)); + } + +(** + Creates an expression that checks whether a real number is an integer. +*) + let mk_Is_Integer(RealExpr t) + { + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_is_int(nCtx, t.x#gno)); + } + + +(* BIT-VECTORS *) +(** + Bitwise negation. +*) + The argument must have a bit-vector sort. + let mk_B_VNot(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvnot(nCtx, t.x#gno)); + } + +(** + Take conjunction of bits in a vector, return vector of length 1. +*) + The argument must have a bit-vector sort. + let mk_B_VRedAND(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvredand(nCtx, t.x#gno)); + } + +(** + Take disjunction of bits in a vector, return vector of length 1. +*) + The argument must have a bit-vector sort. + let mk_B_VRedOR(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvredor(nCtx, t.x#gno)); + } + +(** + Bitwise conjunction. +*) + The arguments must have a bit-vector sort. + let mk_B_VAND(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvand(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise disjunction. +*) + The arguments must have a bit-vector sort. + let mk_B_VOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise XOR. +*) + The arguments must have a bit-vector sort. + let mk_B_VXOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvxor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise NAND. +*) + The arguments must have a bit-vector sort. + let mk_B_VNAND(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvnand(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise NOR. +*) + The arguments must have a bit-vector sort. + let mk_B_VNOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvnor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bitwise XNOR. +*) + The arguments must have a bit-vector sort. + let mk_B_VXNOR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvxnor(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Standard two's complement unary minus. +*) + The arguments must have a bit-vector sort. + let mk_B_VNeg(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_bvneg(nCtx, t.x#gno)); + } + +(** + Two's complement addition. +*) + The arguments must have the same bit-vector sort. + let mk_B_VAdd(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvadd(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement subtraction. +*) + The arguments must have the same bit-vector sort. + let mk_B_VSub(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsub(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement multiplication. +*) + The arguments must have the same bit-vector sort. + let mk_B_VMul(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvmul(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned division. +*) + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VUDiv(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvudiv(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Signed division. +*) + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VSDiv(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsdiv(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned remainder. +*) + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VURem(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvurem(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Signed remainder. +*) + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VSRem(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsrem(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed remainder (sign follows divisor). +*) + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + + let mk_B_VSMod(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvsmod(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned less-than +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VULT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvult(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed less-than +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSLT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvslt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned less-than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VULE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvule(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed less-than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSLE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsle(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned greater than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VUGE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvuge(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed greater than or equal to. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSGE(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsge(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Unsigned greater-than. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VUGT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvugt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Two's complement signed greater-than. +*) + + The arguments must have the same bit-vector sort. + + let mk_B_VSGT(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsgt(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bit-vector concatenation. +*) + + The arguments must have a bit-vector sort. + + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). + + public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_concat(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Bit-vector extraction. +*) + + Extract the bits down to from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. + The argument must have a bit-vector sort. + + public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_extract(nCtx, high, low, t.x#gno)); + } + +(** + Bit-vector sign extension. +*) + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. + The argument must have a bit-vector sort. + + let mk_Sign_Ext(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_sign_ext(nCtx, i, t.x#gno)); + } + +(** + Bit-vector zero extension. +*) + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. + The argument must have a bit-vector sort. + + let mk_Zero_Ext(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_zero_ext(nCtx, i, t.x#gno)); + } + +(** + Bit-vector repetition. +*) + + The argument must have a bit-vector sort. + + public BitVecExpr MkRepeat(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_repeat(nCtx, i, t.x#gno)); + } + +(** + Shift left. +*) + + It is equivalent to multiplication by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + + let mk_B_VSHL(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvshl(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Logical shift right +*) + + It is equivalent to unsigned division by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + + let mk_B_VLSHR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvlshr(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Arithmetic shift right +*) + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + + let mk_B_VASHR(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_bvashr(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Rotate Left. +*) + + Rotate bits of \c t to the left \c i times. + The argument must have a bit-vector sort. + + let mk_B_VRotateLeft(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_rotate_left(nCtx, i, t.x#gno)); + } + +(** + Rotate Right. +*) + + Rotate bits of \c t to the right \c i times. + The argument must have a bit-vector sort. + + let mk_B_VRotateRight(uint i, BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_rotate_right(nCtx, i, t.x#gno)); + } + +(** + Rotate Left. +*) + + Rotate bits of to the left times. + The arguments must have the same bit-vector sort. + + let mk_B_VRotateLeft(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_ext_rotate_left(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Rotate Right. +*) + + Rotate bits of to the right times. + The arguments must have the same bit-vector sort. + + let mk_B_VRotateRight(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Z3native.mk_ext_rotate_right(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create an bit bit-vector from the integer argument . +*) + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. + + public BitVecExpr MkInt2BV(uint n, IntExpr t) + { + + + + CheckContextMatch(t); + return new BitVecExpr(this, Z3native.mk_int2bv(nCtx, n, t.x#gno)); + } + +(** + Create an integer from the bit-vector argument . +*) + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in . + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of bit-vector sort. + + let mk_B_V2Int(BitVecExpr t, bool signed) + { + + + + CheckContextMatch(t); + return new IntExpr(this, Z3native.mk_bv2int(nCtx, t.x#gno, (signed) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise addition does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VAddNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvadd_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise addition does not underflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvadd_no_underflow(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise subtraction does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VSubNoOverflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsub_no_overflow(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise subtraction does not underflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsub_no_underflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise signed division does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvsdiv_no_overflow(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise negation does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VNegNoOverflow(BitVecExpr t) + { + + + + CheckContextMatch(t); + return new BoolExpr(this, Z3native.mk_bvneg_no_overflow(nCtx, t.x#gno)); + } + +(** + Create a predicate that checks that the bit-wise multiplication does not overflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VMulNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvmul_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); + } + +(** + Create a predicate that checks that the bit-wise multiplication does not underflow. +*) + + The arguments must be of bit-vector sort. + + let mk_B_VMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Z3native.mk_bvmul_no_underflow(nCtx, t1.x#gno, t2.x#gno)); + } + + +(* ARRAYS *) +(** + Create an array constant. +*) + let mk_Array_Const(Symbol name, Sort domain, Sort range) + { + + + + + + return (ArrayExpr)MkConst(name, MkArraySort(domain, range)); + } + +(** + Create an array constant. +*) + let mk_Array_Const(string name, Sort domain, Sort range) + { + + + + + return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); + } + +(** + Array read. +*) + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + + + + public Expr MkSelect(ArrayExpr a, Expr i) + { + + + + + CheckContextMatch(a); + CheckContextMatch(i); + return Expr.Create(this, Z3native.mk_select(nCtx, a.x#gno, i.x#gno)); + } + +(** + Array update. +*) + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + + + + public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) + { + + + + + + CheckContextMatch(a); + CheckContextMatch(i); + CheckContextMatch(v); + return new ArrayExpr(this, Z3native.mk_store(nCtx, a.x#gno, i.x#gno, v.x#gno)); + } + +(** + Create a constant array. +*) + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + + + + let mk_Const_Array(Sort domain, Expr v) + { + + + + + CheckContextMatch(domain); + CheckContextMatch(v); + return new ArrayExpr(this, Z3native.mk_const_array(nCtx, domain.x#gno, v.x#gno)); + } + +(** + Maps f on the argument arrays. +*) + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + + + + + public ArrayExpr MkMap(Func_Decl f, params ArrayExpr[] args) + { + + + + + CheckContextMatch(f); + CheckContextMatch(args); + return (ArrayExpr)Expr.Create(this, Z3native.mk_map(nCtx, f.x#gno, AST.ArrayLength(args), AST.ArrayToNative(args))); + } + +(** + Access the array default value. +*) + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. + + let mk_Term_Array(ArrayExpr array) + { + + + + CheckContextMatch(array); + return Expr.Create(this, Z3native.mk_array_default(nCtx, array.x#gno)); + } + + +(* SETS *) +(** + Create a set type. +*) + let mk_Set_Sort(Sort ty) + { + + + + CheckContextMatch(ty); + return new SetSort(this, ty); + } + +(** + Create an empty set. +*) + let mk_Empty_Set(Sort domain) + { + + + + CheckContextMatch(domain); + return Expr.Create(this, Z3native.mk_empty_set(nCtx, domain.x#gno)); + } + +(** + Create the full set. +*) + let mk_Full_Set(Sort domain) + { + + + + CheckContextMatch(domain); + return Expr.Create(this, Z3native.mk_full_set(nCtx, domain.x#gno)); + } + +(** + Add an element to the set. +*) + let mk_Set_Add(Expr set, Expr element) + { + + + + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create(this, Z3native.mk_set_add(nCtx, set.x#gno, element.x#gno)); + } + + +(** + Remove an element from a set. +*) + let mk_Set_Del(Expr set, Expr element) + { + + + + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create(this, Z3native.mk_set_del(nCtx, set.x#gno, element.x#gno)); + } + +(** + Take the union of a list of sets. +*) + let mk_Set_Union(params Expr[] args) + { + + + + CheckContextMatch(args); + return Expr.Create(this, Z3native.mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + +(** + Take the intersection of a list of sets. +*) + let mk_Set_Intersection(params Expr[] args) + { + + + + + CheckContextMatch(args); + return Expr.Create(this, Z3native.mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args))); + } + +(** + Take the difference between two sets. +*) + let mk_Set_Difference(Expr arg1, Expr arg2) + { + + + + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create(this, Z3native.mk_set_difference(nCtx, arg1.x#gno, arg2.x#gno)); + } + +(** + Take the complement of a set. +*) + let mk_Set_Complement(Expr arg) + { + + + + CheckContextMatch(arg); + return Expr.Create(this, Z3native.mk_set_complement(nCtx, arg.x#gno)); + } + +(** + Check for set membership. +*) + let mk_Set_Membership(Expr elem, Expr set) + { + + + + + CheckContextMatch(elem); + CheckContextMatch(set); + return Expr.Create(this, Z3native.mk_set_member(nCtx, elem.x#gno, set.x#gno)); + } + +(** + Check for subsetness of sets. +*) + let mk_Set_Subset(Expr arg1, Expr arg2) + { + + + + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create(this, Z3native.mk_set_subset(nCtx, arg1.x#gno, arg2.x#gno)); + } + + +(* NUMERALS *) + +(* GENERAL NUMERALS *) +(** + Create a Term of a given sort. +*) + @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + @return A Term with value and sort + public Expr MkNumeral(string v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_numeral(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(int v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_int(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(uint v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_unsigned_int(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(long v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_int64(nCtx, v, ty.x#gno)); + } + +(** + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. +*) + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(ulong v, Sort ty) + { + + + + CheckContextMatch(ty); + return Expr.Create(this, Z3native.mk_unsigned_int64(nCtx, v, ty.x#gno)); + } + + +(* REALS *) +(** + Create a real from a fraction. +*) + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + public RatNum MkReal(int num, int den) + { + if (den == 0) + throw new Z3Exception("Denominator is zero"); + + + + + return new RatNum(this, Z3native.mk_real(nCtx, num, den)); + } + +(** + Create a real numeral. +*) + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + public RatNum MkReal(string v) + { + + + return new RatNum(this, Z3native.mk_numeral(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(int v) + { + + + return new RatNum(this, Z3native.mk_int(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(uint v) + { + + + return new RatNum(this, Z3native.mk_unsigned_int(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(long v) + { + + + return new RatNum(this, Z3native.mk_int64(nCtx, v, RealSort.x#gno)); + } + +(** + Create a real numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(ulong v) + { + + + return new RatNum(this, Z3native.mk_unsigned_int64(nCtx, v, RealSort.x#gno)); + } + + +(* INTEGERS *) +(** + Create an integer numeral. +*) + @param v A string representing the Term value in decimal notation. + public IntNum MkInt(string v) + { + + + return new IntNum(this, Z3native.mk_numeral(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(int v) + { + + + return new IntNum(this, Z3native.mk_int(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(uint v) + { + + + return new IntNum(this, Z3native.mk_unsigned_int(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(long v) + { + + + return new IntNum(this, Z3native.mk_int64(nCtx, v, IntSort.x#gno)); + } + +(** + Create an integer numeral. +*) + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(ulong v) + { + + + return new IntNum(this, Z3native.mk_unsigned_int64(nCtx, v, IntSort.x#gno)); + } + + +(* BIT-VECTORS *) +(** + Create a bit-vector numeral. +*) + @param v A string representing the value in decimal notation. + @param size the size of the bit-vector + let mk_B_V(string v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(int v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(uint v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(long v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + +(** + Create a bit-vector numeral. +*) + @param v value of the numeral. + @param size the size of the bit-vector + let mk_B_V(ulong v, uint size) + { + + + return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); + } + + + // Numerals + +(* QUANTIFIERS *) +(** + Create a universal Quantifier. +*) + + Creates a forall formula, where is the weight, + is an array of patterns, is an array + with the sorts of the bound variables, is an array with the + 'names' of the bound variables, and is the body of the + quantifier. Quantifiers are associated with weights indicating + the importance of using the quantifier during instantiation. + + @param sorts the sorts of the bound variables. + @param names names of the bound variables + @param body the body of the quantifier. + @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + @param patterns array containing the patterns created using MkPattern. + @param noPatterns array containing the anti-patterns created using MkPattern. + @param quantifierID optional symbol to track quantifier. + @param skolemID optional symbol to track skolem constants. + public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + + + + + return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + +(** + Create a universal Quantifier. +*) + public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + +(** + Create an existential Quantifier. +*) + + public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + + + + return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + +(** + Create an existential Quantifier. +*) + public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + +(** + Create a Quantifier. +*) + public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + + + + + if (universal) + return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + +(** + Create a Quantifier. +*) + public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + { + + + + + + + + if (universal) + return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + } + + + + // Expr + +(* OPTIONS *) + +(** + Selects the format used for pretty-printing expressions. +*) + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the Z3_PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + + + + + + public Z3_ast_print_mode PrintMode + { + set { Z3native.set_ast_print_mode(nCtx, (uint)value); } + } + + +(* SMT Files & Strings *) +(** + Convert a benchmark into an SMT-LIB formatted string. +*) + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) + { + + + + + return Z3native.benchmark_to_smtlib_string(nCtx, name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula.x#gno); + } + +(** + Parse the given string using the SMT-LIB parser. +*) + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. + + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_string(nCtx, str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); + } + +(** + Parse the given file using the SMT-LIB parser. +*) + + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_file(nCtx, fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); + } + +(** + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBFormulas { get { return Z3native.get_smtlib_num_formulas(nCtx)) + +(** + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public BoolExpr[] SMTLIBFormulas + { + get + { + + + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_formula(nCtx, i)); + return res; + } + } + +(** + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBAssumptions { get { return Z3native.get_smtlib_num_assumptions(nCtx)) + +(** + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public BoolExpr[] SMTLIBAssumptions + { + get + { + + + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_assumption(nCtx, i)); + return res; + } + } + +(** + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBDecls { get { return Z3native.get_smtlib_num_decls(nCtx)) + +(** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public Func_Decl[] SMTLIBDecls + { + get + { + + + uint n = NumSMTLIBDecls; + Func_Decl[] res = new Func_Decl[n]; + for (uint i = 0; i < n; i++) + res[i] = new Func_Decl(this, Z3native.get_smtlib_decl(nCtx, i)); + return res; + } + } + +(** + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public uint NumSMTLIBSorts { get { return Z3native.get_smtlib_num_sorts(nCtx)) + +(** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. +*) + public Sort[] SMTLIBSorts + { + get + { + + + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Z3native.get_smtlib_sort(nCtx, i)); + return res; + } + } + +(** + Parse the given string using the SMT-LIB2 parser. +*) + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_string(nCtx, str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + +(** + Parse the given file using the SMT-LIB2 parser. +*) + + public BoolExpr ParseSMTLIB2File(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + { + + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_file(nCtx, fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + + +(* GOALS *) +(** + Creates a new Goal. +*) + + Note that the Context must have been created with proof generation support if + is set to true here. + + @param models Indicates whether model generation should be enabled. + @param unsatCores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) + { + + + return new Goal(this, models, unsatCores, proofs); + } + + +(* PARAMETERSETS *) +(** + Creates a new ParameterSet. +*) + public Params MkParams ( ctx : context ) = + { + + + return new Params(this); + } + + +(* TACTICS *) +(** + The number of supported tactics. +*) + public uint NumTactics + { + get { return Z3native.get_num_tactics(nCtx); } + } + +(** + The names of all supported tactics. +*) + public string[] TacticNames + { + get + { + + + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_tactic_name(nCtx, i); + return res; + } + } + +(** + Returns a string containing a description of the tactic with the given name. +*) + public string TacticDescription(string name) + { + + + return Z3native.tactic_get_descr(nCtx, name); + } + +(** + Creates a new Tactic. +*) + public Tactic MkTactic(string name) + { + + + return new Tactic(this, name); + } + +(** + Create a tactic that applies to a Goal and + then to every subgoal produced by . +*) + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + { + + + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(ts); + + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) + { + last = ts[ts.Length - 1].x#gno; + for (int i = ts.Length - 2; i >= 0; i--) + last = Z3native.tactic_and_then(nCtx, ts[i].x#gno, last); + } + if (last != IntPtr.Zero) + { + last = Z3native.tactic_and_then(nCtx, t2.x#gno, last); + return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, last)); + } + else + return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a tactic that applies to a Goal and + then to every subgoal produced by . +*) + + Shorthand for AndThen. + + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) + { + + + + + + return AndThen(t1, t2, ts); + } + +(** + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. +*) + public Tactic OrElse(Tactic t1, Tactic t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Z3native.tactic_or_else(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Create a tactic that applies to a goal for milliseconds. +*) + + If does not terminate within milliseconds, then it fails. + + public Tactic TryFor(Tactic t, uint ms) + { + + + + CheckContextMatch(t); + return new Tactic(this, Z3native.tactic_try_for(nCtx, t.x#gno, ms)); + } + +(** + Create a tactic that applies to a given goal if the probe + evaluates to true. +*) + + If evaluates to false, then the new tactic behaves like the skip tactic. + + public Tactic When(Probe p, Tactic t) + { + + + + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Z3native.tactic_when(nCtx, p.x#gno, t.x#gno)); + } + +(** + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. +*) + public Tactic Cond(Probe p, Tactic t1, Tactic t2) + { + + + + + + CheckContextMatch(p); + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Z3native.tactic_cond(nCtx, p.x#gno, t1.x#gno, t2.x#gno)); + } + +(** + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. +*) + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) + { + + + + CheckContextMatch(t); + return new Tactic(this, Z3native.tactic_repeat(nCtx, t.x#gno, max)); + } + +(** + Create a tactic that just returns the given goal. +*) + public Tactic Skip ( ctx : context ) = + { + + + return new Tactic(this, Z3native.tactic_skip(nCtx)); + } + +(** + Create a tactic always fails. +*) + public Tactic Fail ( ctx : context ) = + { + + + return new Tactic(this, Z3native.tactic_fail(nCtx)); + } + +(** + Create a tactic that fails if the probe evaluates to false. +*) + public Tactic FailIf(Probe p) + { + + + + CheckContextMatch(p); + return new Tactic(this, Z3native.tactic_fail_if(nCtx, p.x#gno)); + } + +(** + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). +*) + public Tactic FailIfNotDecided ( ctx : context ) = + { + + + return new Tactic(this, Z3native.tactic_fail_if_not_decided(nCtx)); + } + +(** + Create a tactic that applies using the given set of parameters . +*) + public Tactic UsingParams(Tactic t, Params p) + { + + + + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Z3native.tactic_using_params(nCtx, t.x#gno, p.x#gno)); + } + +(** + Create a tactic that applies using the given set of parameters . +*) + Alias for UsingParams + public Tactic With(Tactic t, Params p) + { + + + + + return UsingParams(t, p); + } + +(** + Create a tactic that applies the given tactics in parallel. +*) + public Tactic ParOr(params Tactic[] t) + { + + + + CheckContextMatch(t); + return new Tactic(this, Z3native.tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); + } + +(** + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. +*) + public Tactic ParAndThen(Tactic t1, Tactic t2) + { + + + + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Z3native.tactic_par_and_then(nCtx, t1.x#gno, t2.x#gno)); + } + +(** + Interrupt the execution of a Z3 procedure. +*) + This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt ( ctx : context ) = + { + Z3native.interrupt(nCtx); + } + + +(* PROBES *) +(** + The number of supported Probes. +*) + public uint NumProbes + { + get { return Z3native.get_num_probes(nCtx); } + } + +(** + The names of all supported Probes. +*) + public string[] ProbeNames + { + get + { + + + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_probe_name(nCtx, i); + return res; + } + } + +(** + Returns a string containing a description of the probe with the given name. +*) + public string ProbeDescription(string name) + { + + + return Z3native.probe_get_descr(nCtx, name); + } + +(** + Creates a new Probe. +*) + public Probe MkProbe(string name) + { + + + return new Probe(this, name); + } + +(** + Create a probe that always evaluates to . +*) + public Probe Const(double val) + { + + + return new Probe(this, Z3native.probe_const(nCtx, val)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by +*) + public Probe Lt(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_lt(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by +*) + public Probe Gt(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_gt(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by +*) + public Probe Le(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_le(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by +*) + public Probe Ge(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_ge(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by +*) + public Probe Eq(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_eq(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value + and evaluate to "true". +*) + public Probe And(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_and(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value + or evaluate to "true". +*) + public Probe Or(Probe p1, Probe p2) + { + + + + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Z3native.probe_or(nCtx, p1.x#gno, p2.x#gno)); + } + +(** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". +*) + public Probe Not(Probe p) + { + + + + CheckContextMatch(p); + return new Probe(this, Z3native.probe_not(nCtx, p.x#gno)); + } + + +(* SOLVERS *) +(** + Creates a new (incremental) solver. +*) + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. + + public Solver MkSolver(Symbol logic = null) + { + + + if (logic == null) + return new Solver(this, Z3native.mk_solver(nCtx)); + else + return new Solver(this, Z3native.mk_solver_for_logic(nCtx, logic.x#gno)); + } + +(** + Creates a new (incremental) solver. +*) + + public Solver MkSolver(string logic) + { + + + return MkSolver(MkSymbol(logic)); + } + +(** + Creates a new (incremental) solver. +*) + let mk_Simple_Solver ( ctx : context ) = + { + + + return new Solver(this, Z3native.mk_simple_solver(nCtx)); + } + +(** + Creates a solver that is implemented using the given tactic. +*) + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. + + public Solver MkSolver(Tactic t) + { + + + + return new Solver(this, Z3native.mk_solver_from_tactic(nCtx, t.x#gno)); + } + + +(* FIXEDPOINTS *) +(** + Create a Fixedpoint context. +*) + public Fixedpoint MkFixedpoint ( ctx : context ) = + { + + + return new Fixedpoint(this); + } + + + +(* MISCELLANEOUS *) +(** + Wraps an AST. +*) + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) + { + + return AST.Create(this, nativeObject); + } + +(** + Unwraps an AST. +*) + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + public IntPtr UnwrapAST(AST a) + { + return a.x#gno; + } + +(** + Return a string describing all available parameters to Expr.Simplify. +*) + public string SimplifyHelp ( ctx : context ) = + { + + + return Z3native.simplify_get_help(nCtx); + } + +(** + Retrieves parameter descriptions for simplifier. +*) + public ParamDescrs SimplifyParameterDescriptions + { + get { return new ParamDescrs(this, Z3native.simplify_get_param_descrs(nCtx)); } + } + +(** + Enable/disable printing of warning messages to the console. +*) + Note that this function is static and effects the behaviour of + all contexts globally. + public static void ToggleWarningMessages(bool enabled) + { + Z3native.toggle_warning_messages((enabled) ? 1 : 0); + } + + +(* ERROR HANDLING *) + //(** + //A delegate which is executed when an error is raised. + //*) + // + //Note that it is possible for memory leaks to occur if error handlers + //throw exceptions. + // + //public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); + + //(** + //The OnError event. + //*) + //public event ErrorHandler OnError = null; + + +(* PARAMETERS *) +(** + Update a mutable configuration parameter. +*) + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + + + public void UpdateParamValue(string id, string value) + { + Z3native.update_param_value(nCtx, id, value); + } + +(** + Get a configuration parameter. +*) + + Returns null if the parameter value does not exist. + + + public string GetParamValue(string id) + { + IntPtr res = IntPtr.Zero; + int r = Z3native.get_param_value(nCtx, id, out res); + if (r == (int)Z3_lbool.Z3_L_FALSE) + return null; + else + return Marshal.PtrToStringAnsi(res); + } + + + +(* INTERNAL *) + internal IntPtr m_ctx = IntPtr.Zero; + internal Z3native.error_handler m_n_err_handler = null; + internal IntPtr nCtx { get { return m_ctx) + + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + { + // Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + } + + internal void InitContext ( ctx : context ) = + { + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); // keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); + } +*) end From c28f0e7c8ac61db34bdb96493d3df1913bc2a5d4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 01:45:10 +0000 Subject: [PATCH 363/507] ML API bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 8 ++- scripts/update_api.py | 2 +- src/api/ml/z3.ml | 136 ++++++++++++++++++++------------------ 3 files changed, 80 insertions(+), 66 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 7046a92b0..f414e9d1a 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -18,10 +18,16 @@ let _ = let ctx = (new context cfg) in let is = (mk_symbol_int ctx 42) in let ss = (mk_symbol_string ctx "mySymbol") in + let bs = (mk_bool_sort ctx) in + let ints = (mk_int_sort ctx) in + let rs = (mk_real_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); Printf.printf "string symbol: %s\n" (Symbol.to_string (ss :> symbol)); + Printf.printf "bool sort: %s\n" (Sort.to_string bs); + Printf.printf "int sort: %s\n" (Sort.to_string ints); + Printf.printf "real sort: %s\n" (Sort.to_string rs); Printf.printf "Disposing...\n"; - ctx#dispose (* can do, but we'd rather let it go out of scope *) ; + Gc.full_major () ); Printf.printf "Exiting.\n"; ;; diff --git a/scripts/update_api.py b/scripts/update_api.py index c8cd05c7e..c3f2abce6 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1280,7 +1280,7 @@ def mk_ml(): ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') ml_wrapper.write('\n\n') ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') - ml_wrapper.write(' identifier: "default handling",\n') + ml_wrapper.write(' identifier: (char*) "default handling",\n') ml_wrapper.write(' finalize: custom_finalize_default,\n') ml_wrapper.write(' compare: custom_compare_default,\n') ml_wrapper.write(' hash: custom_hash_default,\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 2100f371e..3a0e9208e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -30,21 +30,25 @@ object (self) Z3native.del_config(cfg) ; v - val mutable m_refCount : int = 0 + val mutable m_obj_cnt : int = 0 initializer - Gc.finalise (fun self -> self#dispose) self + (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) + let f = fun o -> o#dispose in + let v = self in + Gc.finalise f v method dispose : unit = - if m_refCount == 0 then ( - Printf.printf "Disposing context %d \n" (Oo.id self) ; + if m_obj_cnt == 0 then ( + (* Printf.printf "Disposing context %d \n" (Oo.id self) ; *) (Z3native.del_context m_n_ctx) ) else ( + Printf.printf "NOT DISPOSING context %d because it still has %d objects alive\n" (Oo.id self) m_obj_cnt; (* re-queue for finalization? *) ) - method sub_one_ctx_obj = m_refCount <- m_refCount - 1 - method add_one_ctx_obj = m_refCount <- m_refCount + 1 + method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 + method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 method gno = m_n_ctx end @@ -62,18 +66,21 @@ object (self) m_ctx#add_one_ctx_obj | None -> () ); - Gc.finalise (fun self -> self#dispose) self + (* Printf.printf "Installing finalizer on z3object %d \n" (Oo.id self) ; *) + let f = fun o -> o#dispose in + let v = self in + Gc.finalise f v method virtual incref : Z3native.ptr -> Z3native.ptr -> unit method virtual decref : Z3native.ptr -> Z3native.ptr -> unit - (* - Disposes of the underlying native Z3 object. - *) method dispose = - Printf.printf "Disposing z3object %d \n" (Oo.id self) ; + (* Printf.printf "Disposing z3object %d \n" (Oo.id self) ; *) (match m_n_obj with - | Some (x) -> self#decref m_ctx#gno x; m_n_obj <- None; m_ctx#sub_one_ctx_obj + | Some (x) -> + self#decref m_ctx#gno x; + m_ctx#sub_one_ctx_obj ; + m_n_obj <- None; | None -> () ); @@ -81,10 +88,11 @@ object (self) | Some(x) -> x | None -> raise (Z3native.Exception "Z3 object lost") - method sno nc o = - self#incref nc o ; + method sno (ctx : context) o = + m_ctx#add_one_ctx_obj ; + self#incref ctx#gno o ; (match m_n_obj with - | Some(x) -> self#decref nc x + | Some(x) -> self#decref ctx#gno x ; m_ctx#sub_one_ctx_obj | None -> () ); m_n_obj <- Some o @@ -107,7 +115,7 @@ end class symbol ctx = object (self) inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method incref ctx o = () method decref ctx o = () end @@ -120,16 +128,16 @@ let symbolaton (a : symbol array) = class int_symbol ctx = object(self) inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_int i = (self#sno ctx#gno (Z3native.mk_int_symbol ctx#gno i)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol ctx#gno i)) ; self end (** String symbol objects *) class string_symbol ctx = object(self) inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_string name = (self#sno ctx#gno (Z3native.mk_string_symbol ctx#gno name)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol ctx#gno name)) ; self end let create_symbol ctx no = @@ -141,7 +149,7 @@ let create_symbol ctx no = class ast ctx = object (self) inherit z3object ctx None as super (* CMW: derive from icomparable? *) - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method incref nc o = Z3native.inc_ref nc o method decref nc o = Z3native.dec_ref nc o @@ -155,44 +163,44 @@ let astaton (a : ast array) = class sort ctx = object (self) inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Arithmetic sort objects, i.e., Int or Real. *) class arith_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Array sorts objects *) class array_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx#gno (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self end (** Bit-vector sort objects *) class bitvec_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Boolean sort objects *) class bool_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Datatype sort objects *) class datatype_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_sc (name : symbol) constructors = (self#sno ctx#gno (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_sc (name : symbol) constructors = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self end (** Enum sort objects *) @@ -201,12 +209,12 @@ object (self) inherit sort ctx as super val mutable _constdecls = None val mutable _testerdecls = None - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (enum_names : symbol array) = let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in _constdecls <- Some a ; _testerdecls <- Some b ; - (self#sno ctx#gno r) ; + (self#sno ctx r) ; self method const_decls = match _constdecls with @@ -222,37 +230,37 @@ end class int_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Real sort objects *) class real_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Uninterpreted sort objects *) class uninterpreted_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_s (s : symbol) = (self #sno ctx#gno (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self end (** Finite domain sort objects *) class finite_domain_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx#gno (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self end (** Relation sort objects *) class relation_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** List sort objects *) @@ -265,7 +273,7 @@ object (self) val mutable _is_consdecl = None val mutable _headdecl = None val mutable _taildecl = None - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (elem_sort : sort) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in _nildecl <- Some a ; @@ -274,7 +282,7 @@ object (self) _is_consdecl <- Some d ; _headdecl <- Some e ; _taildecl <- Some f ; - (self#sno ctx#gno r) ; + (self#sno ctx r) ; self method nil_decl = match _nildecl with @@ -307,18 +315,18 @@ end class set_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_s (s : sort) = (self#sno ctx#gno s#gno) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_s (s : sort) = (self#sno ctx s#gno) ; self end (** Tuple sort objects *) class tuple_sort ctx = object (self) inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = let (x,_,_) = (Z3native.mk_tuple_sort ctx#gno name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in - (self#sno ctx#gno x) ; + (self#sno ctx x) ; self end @@ -339,9 +347,9 @@ let create_sort ctx obj = class func_decl ctx = object (self) inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self - method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self - method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx#gno (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self method incref nc o = super#incref nc o method decref nc o = super#decref nc o @@ -388,7 +396,7 @@ end class expr ctx = object(self) inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end let expraton (a : expr array) = @@ -399,77 +407,77 @@ let expraton (a : expr array) = class bool_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Arithmetic expression objects (int/real) *) class arith_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Int expression objects *) class int_expr ctx = object (self) inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Real expression objects *) class real_expr ctx = object (self) inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Bit-vector expression objects *) class bitvec_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Array expression objects *) class array_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Datatype expression objects *) class datatype_expr ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Integer numeral expression objects *) class int_num ctx = object (self) inherit int_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Rational numeral expression objects *) class rat_num ctx = object (self) inherit real_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Bit-vector numeral expression objects *) class bitvec_num ctx = object (self) inherit bitvec_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end (** Algebraic numeral expression objects *) class algebraic_num ctx = object (self) inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end @@ -477,7 +485,7 @@ end class quantifier ctx = object (self) inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx#gno obj) ; self + method cnstr_obj obj = (self#sno ctx obj) ; self end @@ -1112,7 +1120,7 @@ struct if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - x#sno x#gnc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) + x#sno x#gc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. @@ -2483,7 +2491,7 @@ struct Create a new Boolean sort. *) let mk_bool_sort ( ctx : context ) = - (new bool_sort ctx) + (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) (** Create a new uninterpreted sort. @@ -2501,13 +2509,13 @@ struct Create a new integer sort. *) let mk_int_sort ( ctx : context ) = - (new int_sort ctx) + (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) (** Create a real sort. *) let mk_real_sort ( ctx : context ) = - (new real_sort ctx) + (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) (** Create a new bit-vector sort. From 2a6c74bc13e57459effcb46c0bcebc88bb7582b3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 03:57:18 +0000 Subject: [PATCH 364/507] New ML API savepoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 572 ++++++++++++++++++++++++++++++----------------- 1 file changed, 364 insertions(+), 208 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 3a0e9208e..116d7a230 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -33,11 +33,11 @@ object (self) val mutable m_obj_cnt : int = 0 initializer - (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) - let f = fun o -> o#dispose in - let v = self in - Gc.finalise f v - + (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) + let f = fun o -> o#dispose in + let v = self in + Gc.finalise f v + method dispose : unit = if m_obj_cnt == 0 then ( (* Printf.printf "Disposing context %d \n" (Oo.id self) ; *) @@ -110,7 +110,6 @@ object (self) method decref ctx o = Z3native.params_dec_ref ctx o end - (** Symbol objects *) class symbol ctx = object (self) @@ -166,6 +165,10 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +let sortaton (a : sort array) = + let f (e : sort) = e#gno in + Array.map f a + (** Arithmetic sort objects, i.e., Int or Real. *) class arith_sort ctx = object (self) @@ -195,20 +198,12 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end -(** Datatype sort objects *) -class datatype_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : symbol) constructors = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (astaton constructors)))) ; self -end - (** Enum sort objects *) class enum_sort ctx = object (self) inherit sort ctx as super - val mutable _constdecls = None - val mutable _testerdecls = None + val mutable _constdecls : Z3native.ptr array option = None + val mutable _testerdecls : Z3native.ptr array option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (enum_names : symbol array) = let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in @@ -267,12 +262,12 @@ end class list_sort ctx = object (self) inherit sort ctx as super - val mutable _nildecl = None - val mutable _is_nildecl = None - val mutable _consdecl = None - val mutable _is_consdecl = None - val mutable _headdecl = None - val mutable _taildecl = None + val mutable _nildecl : Z3native.ptr option = None + val mutable _is_nildecl : Z3native.ptr option = None + val mutable _consdecl : Z3native.ptr option = None + val mutable _is_consdecl : Z3native.ptr option = None + val mutable _headdecl : Z3native.ptr option = None + val mutable _taildecl : Z3native.ptr option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (elem_sort : sort) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in @@ -291,23 +286,23 @@ object (self) method is_nil_decl = match _is_nildecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_nil decls") + | None -> raise (Z3native.Exception "Missing is_nil decl") method cons_decl = match _consdecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing cons decls") + | None -> raise (Z3native.Exception "Missing cons decl") method is_cons_decl = match _is_consdecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_cons decls") + | None -> raise (Z3native.Exception "Missing is_cons decl") method head_decl = match _headdecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing head decls") + | None -> raise (Z3native.Exception "Missing head decl") method tail_decl = match _taildecl with | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tail decls") + | None -> raise (Z3native.Exception "Missing tail decl") end @@ -330,18 +325,6 @@ object (self) self end -let create_sort ctx obj = - match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with - | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) - | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) - | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) - | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) - | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) - | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) - | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) - | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) - | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") (** Function declaration objects *) class func_decl ctx = @@ -392,6 +375,126 @@ object (self) method rational = m_r end + +(** Constructor objects *) +class constructor ctx = +object (self) + inherit z3object ctx None as super + val mutable m_n : int = 0 + val mutable m_tester_decl : func_decl option = None + val mutable m_constructor_decl : func_decl option = None + val mutable m_accessor_decls : func_decl array option = None + method incref ctx o = () + method decref ctx o = () + initializer + let f = fun o -> Z3native.del_constructor o#gnc o#gno in + let v = self in + Gc.finalise f v + + method cnstr_ssssi (name : symbol) (recognizer : symbol) (field_names : symbol array) (sorts : sort array) (sort_refs : int array) = + m_n <- (Array.length field_names) ; + if m_n != (Array.length sorts) then + raise (Z3native.Exception "Number of field names does not match number of sorts") + else + if m_n != (Array.length sort_refs) then + raise (Z3native.Exception "Number of field names does not match number of sort refs") + else + let o = (Z3native.mk_constructor ctx#gno name#gno recognizer#gno m_n (symbolaton field_names) + (sortaton sorts) + sort_refs) in + self#sno ctx o ; + self + + method private init = + match m_tester_decl with + | None -> + let (a, b, c) = (Z3native.query_constructor self#gnc self#gno m_n) in + m_constructor_decl <- Some ((new func_decl ctx)#cnstr_obj a) ; + m_tester_decl <- Some ((new func_decl ctx)#cnstr_obj b) ; + m_accessor_decls <- Some (let f e = ((new func_decl ctx)#cnstr_obj e) in Array.map f c) ; + () + | _ -> () + + method get_n = m_n + + method tester_decl = match m_tester_decl with + | Some(x) -> x + | None -> self#init ; self#tester_decl + + method constructor_decl = match m_constructor_decl with + | Some(x) -> x + | None -> self#init ; self#constructor_decl + + method accessor_decls = match m_accessor_decls with + | Some(x) -> x + | None -> self#init ; self#accessor_decls +end + +let constructoraton (a : constructor array) = + let f (e : constructor) = e#gno in + Array.map f a + +(** Constructor list objects *) +class constructor_list ctx = +object (self) + inherit z3object ctx None + method incref ctx o = () + method decref ctx o = () + initializer + let f = fun o -> Z3native.del_constructor_list o#gnc o#gno in + let v = self in + Gc.finalise f v + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ca ( c : constructor array ) = + self#sno ctx (Z3native.mk_constructor_list ctx#gno (Array.length c) (constructoraton c)) ; + self +end + +let constructor_listaton (a : constructor_list array) = + let f (e : constructor_list) = e#gno in + Array.map f a + +(** Datatype sort objects *) +class datatype_sort ctx = +object (self) + inherit sort ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (constructoraton constructors)))) ; self +end + +let create_sort ctx obj = + match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with + | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) + | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) + | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) + | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) + | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) + | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) + | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) + | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) + | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + +(** AST vector objects *) +class ast_vector ctx = +object (self) + inherit z3object ctx None + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref ctx o = Z3native.ast_vector_inc_ref ctx o + method decref ctx o = Z3native.ast_vector_dec_ref ctx o +end + + +(** AST map objects *) +class ast_map ctx = +object (self) + inherit z3object ctx None + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref ctx o = Z3native.ast_map_inc_ref ctx o + method decref ctx o = Z3native.ast_map_dec_ref ctx o +end + + (** Expression objects *) class expr ctx = object(self) @@ -492,7 +595,8 @@ end (**/**) -(** Interaction logging for Z3. +(** Interaction logging for Z3 + Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) module Log = @@ -512,7 +616,7 @@ struct let append s = Z3native.append_log s end -(** Version information. *) +(** Version information *) module Version = struct (** The major version. *) @@ -536,7 +640,7 @@ struct string_of_int rev ^ "." end -(** Symbols are used to name several term and type constructors. *) +(** Symbols are used to name several term and type constructors *) module Symbol = struct (** The kind of the symbol (int or string) *) @@ -562,9 +666,7 @@ struct end -(** - The Sort module implements type information for ASTs. -*) +(** The Sort module implements type information for ASTs *) module Sort = struct (** @@ -612,13 +714,13 @@ struct end (** Bit-vector sorts *) -module BitVectorSort = +module BitVecSort = struct (** The size of the bit-vector sort. *) let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno end -(** Finite domain sorts. *) +(** Finite domain sorts *) module FiniteDomainSort = struct (** The size of the finite domain sort. *) @@ -628,7 +730,7 @@ struct else raise (Z3native.Exception "Conversion failed.") end -(** Relation sorts. *) +(** Relation sorts *) module RelationSort = struct (** The arity of the relation sort. *) @@ -684,60 +786,60 @@ let create_ast ctx no = | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") (**/**) -(** Function declarations. *) +(** Function declarations *) module FuncDecl = struct -(** Parameters of Func_Decls *) + (** Parameters of Func_Decls *) module Parameter = struct - (** - The kind of the parameter. - *) + (** + The kind of the parameter. + *) let get_kind (x : parameter) = x#kind - (**The int value of the parameter.*) + (**The int value of the parameter.*) let get_int (x : parameter) = if (x#kind != PARAMETER_INT) then raise (Z3native.Exception "parameter is not an int") else x#int - (**The double value of the parameter.*) + (**The double value of the parameter.*) let get_double (x : parameter) = if (x#kind != PARAMETER_DOUBLE) then raise (Z3native.Exception "parameter is not a double") else x#double - (**The Symbol value of the parameter.*) + (**The Symbol value of the parameter.*) let get_symbol (x : parameter) = if (x#kind != PARAMETER_SYMBOL) then raise (Z3native.Exception "parameter is not a symbol") else x#symbol - (**The Sort value of the parameter.*) + (**The Sort value of the parameter.*) let get_sort (x : parameter) = if (x#kind != PARAMETER_SORT) then raise (Z3native.Exception "parameter is not a sort") else x#sort - (**The AST value of the parameter.*) + (**The AST value of the parameter.*) let get_ast (x : parameter) = if (x#kind != PARAMETER_AST) then raise (Z3native.Exception "parameter is not an ast") else x#ast - (**The FunctionDeclaration value of the parameter.*) + (**The FunctionDeclaration value of the parameter.*) let get_ast (x : parameter) = if (x#kind != PARAMETER_FUNC_DECL) then raise (Z3native.Exception "parameter is not an function declaration") else x#func_decl - (**The rational string value of the parameter.*) + (**The rational string value of the parameter.*) let get_rational (x : parameter) = if (x#kind != PARAMETER_RATIONAL) then raise (Z3native.Exception "parameter is not a ratinoal string") @@ -826,7 +928,7 @@ struct (** Create expression that applies function to arguments. - + @param args The arguments *) let apply (x : func_decl) (args : expr array) = create_expr_fa x#gc x args @@ -862,7 +964,7 @@ struct Array.init n f end -(** Enumeration sorts. *) +(** Enumeration sorts *) module EnumSort = struct (** The function declarations of the constants in the enumeration. *) @@ -876,7 +978,7 @@ struct Array.map f x#tester_decls end -(** List sorts. *) +(** List sorts *) module ListSort = struct (** The declaration of the nil function of this list sort. *) @@ -901,6 +1003,7 @@ struct let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] end +(** Tuple sorts *) module TupleSort = struct (** The constructor function of the tuple.*) @@ -917,7 +1020,7 @@ struct Array.init n f end -(** The abstract syntax tree (AST) module. *) +(** The abstract syntax tree (AST) module *) module AST = struct (** @@ -1077,12 +1180,107 @@ struct let to_string (p : params) = Z3native.params_to_string p#gnc p#gno end +(** Vectors of ASTs *) +module ASTVector = +struct + (** The size of the vector *) + let get_size ( x : ast_vector ) = + Z3native.ast_vector_size x#gnc x#gno + + (** + Retrieves the i-th object in the vector. + @param i Index + @return An AST + *) + let get ( x : ast_vector ) ( i : int ) = + create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) + + (** Sets the i-th object in the vector. *) + let set ( x : ast_vector ) ( i : int ) ( value : ast ) = + Z3native.ast_vector_set x#gnc x#gno i value#gno + + (** Resize the vector to . + @param newSize The new size of the vector. *) + let resize ( x : ast_vector ) ( new_size : int ) = + Z3native.ast_vector_resize x#gnc x#gno new_size + + (** + Add the AST to the back of the vector. The size + is increased by 1. + @param a An AST + *) + let push ( x : ast_vector ) ( a : ast ) = + Z3native.ast_vector_push x#gnc x#gno a#gno + + (** + Translates all ASTs in the vector to . + @param to_ctx A context + @return A new ASTVector + *) + let translate ( x : ast_vector ) ( to_ctx : context ) = + (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) + + (** Retrieves a string representation of the vector. *) + let to_string ( x : ast_vector ) = + Z3native.ast_vector_to_string x#gnc x#gno +end + +(** Map from AST to AST *) +module ASTMap = +struct + (** Checks whether the map contains the key . + @param k An AST + @return True if is a key in the map, false otherwise. *) + let contains ( m : ast_map ) ( key : ast ) = + (int2lbool (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + + (** Finds the value associated with the key . + + This function signs an error when is not a key in the map. + + @param k An AST + *) + let find ( m : ast_map ) ( key : ast ) = + create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) + + (** + Stores or replaces a new key/value pair in the map. + @param k The key AST + @param v The value AST + *) + let insert ( m : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert m#gnc m#gno key#gno value#gno + + (** + Erases the key from the map. + @param k An AST + *) + let erase ( m : ast_map ) ( key : ast ) = + Z3native.ast_map_erase m#gnc m#gno key#gno + + (** Removes all keys from the map. *) + let reset ( m : ast_map ) = + Z3native.ast_map_reset m#gnc m#gno + + (** The size of the map *) + let get_size ( m : ast_map ) = + Z3native.ast_map_size m#gnc m#gno + + (** The keys stored in the map. *) + let get_keys ( m : ast_map ) = + (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) + + (** Retrieves a string representation of the map.*) + let to_strnig ( m : ast_map ) = + Z3native.ast_map_to_string m#gnc m#gno +end + (** Expressions (terms) *) module Expr = struct (** Returns a simplified version of the expression. - A set of parameters to configure the simplifier + @param p A set of parameters to configure the simplifier *) let simplify ( x : expr ) ( p : params option ) = match p with @@ -1155,8 +1353,8 @@ struct (** Translates (copies) the term to the Context . - A context - A copy of the term which is associated with + @param ctx A context + @return A copy of the term which is associated with *) let translate ( x : expr ) to_ctx = if x#gc == to_ctx then @@ -1176,7 +1374,7 @@ struct (** Indicates whether the term is well-sorted. - True if the term is well-sorted, false otherwise. + @return True if the term is well-sorted, false otherwise. *) let is_well_sorted ( x : expr ) = int2lbool (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE @@ -2372,13 +2570,13 @@ struct Z3native.get_index_value x#gnc x#gno end -(* Integer Numerals *) +(** Integer Numerals *) module IntNum = struct (** Retrieve the int value. *) let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -2410,9 +2608,9 @@ module BitVecNum = struct (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") - + if int2lbool(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno end @@ -2424,9 +2622,8 @@ struct Return a upper bound for a given real algebraic number. The interval isolating the number is smaller than 1/10^. - - the precision of the result - A numeral Expr of sort Real + @param precision the precision of the result + @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) @@ -2435,9 +2632,8 @@ struct Return a lower bound for the given real algebraic number. The interval isolating the number is smaller than 1/10^. - - - A numeral Expr of sort Real + @param precision the precision of the result + @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) @@ -2450,8 +2646,24 @@ struct (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno end + +(** Constructors are used for datatype sorts *) +module Constructor = +struct + (** The number of fields of the constructor. *) + let get_num_fields ( x : constructor ) = x#get_n + + (** The function declaration of the constructor. *) + let get_constructor_decl ( x : constructor ) = x#constructor_decl + + (** The function declaration of the tester. *) + let get_tester_decl ( x : constructor ) = x#tester_decl + + (** The function declarations of the accessors *) + let get_accessor_decls ( x : constructor ) = x#accessor_decls +end -(** The main interaction with Z3 happens via the Context module. *) +(** The main interaction with Z3 happens via the Context module *) module Context = struct @@ -2551,151 +2763,95 @@ struct (Array.map f (mk_symbols_string ( ctx : context ) enum_names)) ) - (** - Create a new list sort. - *) + (** + Create a new list sort. + *) let mk_list_sort ( ctx : context ) (name : symbol) elem_sort = - (new list_sort ctx)#cnstr_ss name elem_sort + (new list_sort ctx)#cnstr_ss name elem_sort - (** - Create a new list sort. - *) + (** + Create a new list sort. + *) let mk_list_sort_s ( ctx : context ) (name : string) elem_sort = mk_list_sort ctx ((mk_symbol_string ctx name) :> symbol) elem_sort - (** - Create a new finite domain sort. - *) + (** + Create a new finite domain sort. + *) let mk_finite_domain_sort ( ctx : context ) ( name : symbol ) size = (new finite_domain_sort ctx)#cnstr_si name size - (** - Create a new finite domain sort. - *) + (** + Create a new finite domain sort. + *) let mk_finite_domain_sort_s ( ctx : context ) ( name : string ) size = (new finite_domain_sort ctx)#cnstr_si ((mk_symbol_string ctx name) :> symbol) size -(** - -(* DATATYPES *) -(** - Create a datatype constructor. -*) - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) - { + (* DATATYPES *) + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + mk_constructor ctx ((mk_symbol_string ctx name) :> symbol) recognizer field_names sorts sort_refs - return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs); - } + (** + Create a new datatype sort. + *) + let mk_datatype_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + (new datatype_sort ctx)#cnstr_sc name constructors + + (** + Create a new datatype sort. + *) + let mk_datatype_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = + mk_datatype_sort ctx ((mk_symbol_string ctx name) :> symbol) constructors + + (** + Create mutually recursive datatypes. + @param names names of datatype sorts + @param c list of constructors, one list per sort. + *) + let mk_datatype_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let n = (Array.length names) in + let f e = ( (new constructor_list ctx)#cnstr_ca e ) in + let cla = (Array.map f c) in + let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in + let g e = ( (new datatype_sort ctx)#cnstr_obj e) in + (Array.map g r) + + (** Create mutually recursive data-types. *) + let mk_datatype_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + mk_datatype_sorts ctx + ( + let f e = ((mk_symbol_string ctx e) :> symbol) in + Array.map f names + ) + c (** - Create a datatype constructor. -*) - @param name - @param recognizer - @param fieldNames - @param sorts - @param sortRefs - @return - public Constructor MkConstructor(string name, string recognizer, string[] fieldNames = null, Sort[] sorts = null, uint[] sortRefs = null) - { - - - return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); - } - -(** - Create a new datatype sort. -*) - let mk_Datatype_Sort(Symbol name, Constructor[] constructors) - { - - - - - - - CheckContextMatch(name); - CheckContextMatch(constructors); - return new DatatypeSort(this, name, constructors); - } - -(** - Create a new datatype sort. -*) - let mk_Datatype_Sort(string name, Constructor[] constructors) - { - - - - - CheckContextMatch(constructors); - return new DatatypeSort(this, MkSymbol(name), constructors); - } - -(** - Create mutually recursive datatypes. -*) - @param names names of datatype sorts - @param c list of constructors, one list per sort. - let mk_Datatype_Sorts(Symbol[] names, Constructor[][] c) - { - - - - - - - - CheckContextMatch(names); - uint n = (uint)names.Length; - ConstructorList[] cla = new ConstructorList[n]; - IntPtr[] n_constr = new IntPtr[n]; - for (uint i = 0; i < n; i++) - { - Constructor[] constructor = c[i]; - - CheckContextMatch(constructor); - cla[i] = new ConstructorList(this, constructor); - n_constr[i] = cla[i].x#gno; - } - IntPtr[] n_res = new IntPtr[n]; - Z3native.mk_datatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr); - DatatypeSort[] res = new DatatypeSort[n]; - for (uint i = 0; i < n; i++) - res[i] = new DatatypeSort(this, n_res[i]); - return res; - } - -(** - Create mutually recursive data-types. -*) - @param names - @param c - @return - let mk_Datatype_Sorts(string[] names, Constructor[][] c) - { - - - - - - - - return MkDatatypeSorts(MkSymbols(names), c); - } - - (* FUNCTION DECLARATIONS *) From 954d92a5135aa8996ef4db5b02756e8d956aca72 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 22 Dec 2012 21:06:13 +0000 Subject: [PATCH 365/507] More new ML API Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 4 +- scripts/update_api.py | 11 +- src/api/ml/Makefile | 2 +- src/api/ml/z3.ml | 1025 +++++++++++++++++++++++++++++++++++------ 4 files changed, 901 insertions(+), 141 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5ca0d2299..849644a18 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -2777,13 +2777,13 @@ def mk_z3consts_ml(api_files): efile.write(' | %s \n' % k[3:]) # strip Z3_ efile.write('\n') efile.write('(** Convert %s to int*)\n' % name[3:]) - efile.write('let %s2int x : int =\n' % (name[3:])) # strip Z3_ + efile.write('let int_of_%s x : int =\n' % (name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): efile.write(' | %s -> %d\n' % (k[3:], i)) efile.write('\n') efile.write('(** Convert int to %s*)\n' % name[3:]) - efile.write('let int2%s x : %s =\n' % (name[3:],name[3:])) # strip Z3_ + efile.write('let %s_of_int x : %s =\n' % (name[3:],name[3:])) # strip Z3_ efile.write(' match x with\n') for k, i in decls.iteritems(): efile.write(' | %d -> %s\n' % (i, k[3:])) diff --git a/scripts/update_api.py b/scripts/update_api.py index c3f2abce6..27f7dd507 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1154,7 +1154,9 @@ def mk_ml(): for k, v in Type2Str.iteritems(): if is_obj(k): ml_native.write('and %s = ptr\n' % v.lower()) - ml_native.write('\nexception Exception of string\n\n') + ml_native.write('\nexternal is_null : ptr -> bool\n') + ml_native.write(' = "n_is_null"\n\n') + ml_native.write('exception Exception of string\n\n') # ML declarations ml_native.write(' module ML2C = struct\n\n') @@ -1219,9 +1221,9 @@ def mk_ml(): i = i + 1 ml_native.write(') in\n') if len(params) > 0 and param_type(params[0]) == CONTEXT: - ml_native.write(' let err = (int2error_code (ML2C.n_get_error_code a0)) in \n') + ml_native.write(' let err = (error_code_of_int (ML2C.n_get_error_code a0)) in \n') ml_native.write(' if err <> OK then\n') - ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (error_code2int err)))\n') + ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (int_of_error_code err)))\n') ml_native.write(' else\n') if result == VOID and len(op) == 0: ml_native.write(' ()\n') @@ -1290,6 +1292,9 @@ def mk_ml(): ml_wrapper.write('#ifdef __cplusplus\n') ml_wrapper.write('extern "C" {\n') ml_wrapper.write('#endif\n\n') + ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') + ml_wrapper.write(' return Val_bool(Data_custom_val(p) == 0);\n') + ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index 4d4a6c08f..ad5442327 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -7,4 +7,4 @@ all: doc: *.ml mkdir -p doc - ocamldoc -html -d doc -I ../../../bld_dbg/api/ml *.ml -hide Z3 + ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.ml -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 116d7a230..c22ef869b 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -9,9 +9,6 @@ open Z3enums (**/**) -(* Object definitions. These are internal and should be interacted - with only via the corresponding functions from modules. *) - class virtual idisposable = object method virtual dispose : unit @@ -106,8 +103,8 @@ end class params ctx obj = object (self) inherit z3object ctx obj as super - method incref ctx o = Z3native.params_inc_ref ctx o - method decref ctx o = Z3native.params_dec_ref ctx o + method incref nc o = Z3native.params_inc_ref nc o + method decref nc o = Z3native.params_dec_ref nc o end (** Symbol objects *) @@ -115,8 +112,8 @@ class symbol ctx = object (self) inherit z3object ctx None as super method cnstr_obj obj = (self#sno ctx obj) ; self - method incref ctx o = () - method decref ctx o = () + method incref nc o = () + method decref nc o = () end let symbolaton (a : symbol array) = @@ -140,7 +137,7 @@ object(self) end let create_symbol ctx no = - match (int2symbol_kind (Z3native.get_symbol_kind ctx#gno no)) with + match (symbol_kind_of_int (Z3native.get_symbol_kind ctx#gno no)) with | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) @@ -198,29 +195,6 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end -(** Enum sort objects *) -class enum_sort ctx = -object (self) - inherit sort ctx as super - val mutable _constdecls : Z3native.ptr array option = None - val mutable _testerdecls : Z3native.ptr array option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (enum_names : symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in - _constdecls <- Some a ; - _testerdecls <- Some b ; - (self#sno ctx r) ; - self - - method const_decls = match _constdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing const decls") - - method tester_decls = match _testerdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tester decls") -end - (** Int sort objects *) class int_sort ctx = object (self) @@ -258,54 +232,6 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end -(** List sort objects *) -class list_sort ctx = -object (self) - inherit sort ctx as super - val mutable _nildecl : Z3native.ptr option = None - val mutable _is_nildecl : Z3native.ptr option = None - val mutable _consdecl : Z3native.ptr option = None - val mutable _is_consdecl : Z3native.ptr option = None - val mutable _headdecl : Z3native.ptr option = None - val mutable _taildecl : Z3native.ptr option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in - _nildecl <- Some a ; - _is_nildecl <- Some b ; - _consdecl <- Some c ; - _is_consdecl <- Some d ; - _headdecl <- Some e ; - _taildecl <- Some f ; - (self#sno ctx r) ; - self - - method nil_decl = match _nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing nil decl") - - method is_nil_decl = match _is_nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_nil decl") - - method cons_decl = match _consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing cons decl") - - method is_cons_decl = match _is_consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_cons decl") - - method head_decl = match _headdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing head decl") - - method tail_decl = match _taildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tail decl") - -end - (** Set sort objects *) class set_sort ctx = object (self) @@ -376,6 +302,76 @@ object (self) end +(** Enum sort objects *) +class enum_sort ctx = +object (self) + inherit sort ctx as super + val mutable _constdecls : func_decl array option = None + val mutable _testerdecls : func_decl array option = None + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ss (name : symbol) (enum_names : symbol array) = + let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in + _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; + _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; + (self#sno ctx r) ; + self + + method const_decls = match _constdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing const decls") + + method tester_decls = match _testerdecls with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tester decls") +end + +(** List sort objects *) +class list_sort ctx = +object (self) + inherit sort ctx as super + val mutable _nildecl : func_decl option = None + val mutable _is_nildecl : func_decl option = None + val mutable _consdecl : func_decl option = None + val mutable _is_consdecl : func_decl option = None + val mutable _headdecl : func_decl option = None + val mutable _taildecl : func_decl option = None + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_ss (name : symbol) (elem_sort : sort) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in + _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; + _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; + _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; + _is_consdecl <- Some ((new func_decl ctx)#cnstr_obj d) ; + _headdecl <- Some ((new func_decl ctx)#cnstr_obj e) ; + _taildecl <- Some ((new func_decl ctx)#cnstr_obj f) ; + (self#sno ctx r) ; + self + + method nil_decl = match _nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing nil decl") + + method is_nil_decl = match _is_nildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_nil decl") + + method cons_decl = match _consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing cons decl") + + method is_cons_decl = match _is_consdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing is_cons decl") + + method head_decl = match _headdecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing head decl") + + method tail_decl = match _taildecl with + | Some(x) -> x + | None -> raise (Z3native.Exception "Missing tail decl") +end + (** Constructor objects *) class constructor ctx = object (self) @@ -384,8 +380,8 @@ object (self) val mutable m_tester_decl : func_decl option = None val mutable m_constructor_decl : func_decl option = None val mutable m_accessor_decls : func_decl array option = None - method incref ctx o = () - method decref ctx o = () + method incref nc o = () + method decref nc o = () initializer let f = fun o -> Z3native.del_constructor o#gnc o#gno in let v = self in @@ -438,8 +434,8 @@ let constructoraton (a : constructor array) = class constructor_list ctx = object (self) inherit z3object ctx None - method incref ctx o = () - method decref ctx o = () + method incref nc o = () + method decref nc o = () initializer let f = fun o -> Z3native.del_constructor_list o#gnc o#gno in let v = self in @@ -463,7 +459,7 @@ object (self) end let create_sort ctx obj = - match (int2sort_kind (Z3native.get_sort_kind ctx#gno obj)) with + match (sort_kind_of_int (Z3native.get_sort_kind ctx#gno obj)) with | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) @@ -480,8 +476,8 @@ class ast_vector ctx = object (self) inherit z3object ctx None method cnstr_obj obj = (self#sno ctx obj) ; self - method incref ctx o = Z3native.ast_vector_inc_ref ctx o - method decref ctx o = Z3native.ast_vector_dec_ref ctx o + method incref nc o = Z3native.ast_vector_inc_ref nc o + method decref nc o = Z3native.ast_vector_dec_ref nc o end @@ -490,8 +486,8 @@ class ast_map ctx = object (self) inherit z3object ctx None method cnstr_obj obj = (self#sno ctx obj) ; self - method incref ctx o = Z3native.ast_map_inc_ref ctx o - method decref ctx o = Z3native.ast_map_dec_ref ctx o + method incref nc o = Z3native.ast_map_inc_ref nc o + method decref nc o = Z3native.ast_map_dec_ref nc o end @@ -583,7 +579,6 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end - (** Quantifier objects *) class quantifier ctx = object (self) @@ -591,10 +586,127 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +(** Parameter description objects *) +class param_descrs ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.param_descrs_inc_ref nc o + method decref nc o = Z3native.param_descrs_dec_ref nc o +end +(** Goal objects *) +class goal ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.goal_inc_ref nc o + method decref nc o = Z3native.goal_dec_ref nc o +end + +(** Tactic objects *) +class tactic ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.tactic_inc_ref nc o + method decref nc o = Z3native.tactic_dec_ref nc o +end + +(** Function interpretation entry objects *) +class func_entry ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.func_entry_inc_ref nc o + method decref nc o = Z3native.func_entry_dec_ref nc o +end + +(** Function interpretation objects *) +class func_interp ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.func_interp_inc_ref nc o + method decref nc o = Z3native.func_interp_dec_ref nc o +end + +(** Model objects *) +class model ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.model_inc_ref nc o + method decref nc o = Z3native.model_dec_ref nc o +end + +(** Tactic application result objects *) +class apply_result ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.apply_result_inc_ref nc o + method decref nc o = Z3native.apply_result_dec_ref nc o +end + +(** Probe objects *) +class probe ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.probe_inc_ref nc o + method decref nc o = Z3native.probe_dec_ref nc o +end + +(** Statistical value objects *) +class statistics_entry = +object (self) + val mutable m_key : string = "" + val mutable m_is_int = false + val mutable m_is_float = false + val mutable m_int = 0 + val mutable m_float = 0.0 + + method cnstr_si k v = + m_key <- k; + m_is_int <- true; + m_int <- v; + self + + method cnstr_sd k v = + m_key <- k; + m_is_float <- true; + m_float <- v; + self + + method key = m_key + method int = m_int + method float = m_float + method is_int = m_is_int + method is_float = m_is_float +end + +(** Statistics objects *) +class statistics ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.stats_inc_ref nc o + method decref nc o = Z3native.stats_dec_ref nc o +end + +(** Solver objects *) +class solver ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.solver_inc_ref nc o + method decref nc o = Z3native.solver_dec_ref nc o +end (**/**) + (** Interaction logging for Z3 Note that this is a global, static log and if multiple Context @@ -606,7 +718,7 @@ struct @return True if opening the log file succeeds, false otherwise. *) (* CMW: "open" seems to be a reserved keyword? *) - let open_ filename = ((int2lbool (Z3native.open_log filename)) == L_TRUE) + let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) (** Closes the interaction log. *) let close = Z3native.close_log @@ -644,7 +756,7 @@ end module Symbol = struct (** The kind of the symbol (int or string) *) - let kind (o : symbol) = (int2symbol_kind (Z3native.get_symbol_kind o#gnc o#gno)) + let kind (o : symbol) = (symbol_kind_of_int (Z3native.get_symbol_kind o#gnc o#gno)) (** Indicates whether the symbol is of Int kind *) let is_int_symbol (o : symbol) = (kind o) == INT_SYMBOL @@ -680,7 +792,7 @@ struct if a#gnc != b#gnc then false else - ((int2lbool (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) + ((lbool_of_int (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) (** Returns a unique identifier for the sort. @@ -690,7 +802,7 @@ struct (** The kind of the sort. *) - let get_sort_kind (x : sort) = (int2sort_kind (Z3native.get_sort_kind x#gnc x#gno)) + let get_sort_kind (x : sort) = (sort_kind_of_int (Z3native.get_sort_kind x#gnc x#gno)) (** The name of the sort @@ -726,7 +838,7 @@ struct (** The size of the finite domain sort. *) let get_size (x : finite_domain_sort) = let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in - if int2lbool(r) == L_TRUE then v + if lbool_of_int(r) == L_TRUE then v else raise (Z3native.Exception "Conversion failed.") end @@ -746,15 +858,15 @@ end (**/**) let create_expr ctx obj = - if int2ast_kind (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then + if ast_kind_of_int (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then (((new quantifier ctx)#cnstr_obj obj) :> expr) else let s = Z3native.get_sort ctx#gno obj in - let sk = (int2sort_kind (Z3native.get_sort_kind ctx#gno s)) in - if (int2lbool (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then + let sk = (sort_kind_of_int (Z3native.get_sort_kind ctx#gno s)) in + if (lbool_of_int (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then (((new algebraic_num ctx)#cnstr_obj obj) :> expr) else - if ((int2lbool (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && + if ((lbool_of_int (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) @@ -776,7 +888,7 @@ let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = create_expr ctx o let create_ast ctx no = - match (int2ast_kind (Z3native.get_ast_kind ctx#gno no)) with + match (ast_kind_of_int (Z3native.get_ast_kind ctx#gno no)) with | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) | SORT_AST -> ((create_sort ctx no) :> ast) @@ -858,7 +970,7 @@ struct if a#gnc == a#gnc then false else - ((int2lbool (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) + ((lbool_of_int (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) (** A string representations of the function declaration. *) @@ -897,7 +1009,7 @@ struct (** The kind of the function declaration. *) - let get_decl_kind (x : func_decl) = (int2decl_kind (Z3native.get_decl_kind x#gnc x#gno)) + let get_decl_kind (x : func_decl) = (decl_kind_of_int (Z3native.get_decl_kind x#gnc x#gno)) (** The name of the function declaration @@ -915,7 +1027,7 @@ struct let get_parameters (x : func_decl) = let n = (get_num_parameters x) in let f i = ( - match (int2parameter_kind (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with + match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with | PARAMETER_INT -> (new parameter)#cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) | PARAMETER_DOUBLE -> (new parameter)#cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) | PARAMETER_SYMBOL-> (new parameter)#cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) @@ -968,36 +1080,32 @@ end module EnumSort = struct (** The function declarations of the constants in the enumeration. *) - let get_const_decls (x : enum_sort) = - let f e = ((new func_decl x#gc)#cnstr_obj e) in - Array.map f x#const_decls + let get_const_decls (x : enum_sort) = x#const_decls (** The test predicates for the constants in the enumeration. *) - let get_tester_decls (x : enum_sort) = - let f e = ((new func_decl x#gc)#cnstr_obj e) in - Array.map f x#tester_decls + let get_tester_decls (x : enum_sort) = x#tester_decls end (** List sorts *) module ListSort = struct (** The declaration of the nil function of this list sort. *) - let get_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#nil_decl + let get_nil_decl (x : list_sort) = x#nil_decl (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_nil_decl + let get_is_nil_decl (x : list_sort) = x#is_nil_decl (** The declaration of the cons function of this list sort. *) - let get_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#cons_decl + let get_cons_decl (x : list_sort) = x#cons_decl (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#is_cons_decl + let get_is_cons_decl (x : list_sort) = x#is_cons_decl (** The declaration of the head function of this list sort.*) - let get_head_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#head_decl + let get_head_decl (x : list_sort) = x#head_decl (** The declaration of the tail function of this list sort. *) - let get_tail_decl (x : list_sort) = (new func_decl x#gc)#cnstr_obj x#tail_decl + let get_tail_decl (x : list_sort) = x#tail_decl (** The empty list. *) let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] @@ -1037,7 +1145,7 @@ struct (** The kind of the AST. *) - let get_ast_kind ( x : ast) = (int2ast_kind (Z3native.get_ast_kind x#gnc x#gno)) + let get_ast_kind ( x : ast) = (ast_kind_of_int (Z3native.get_ast_kind x#gnc x#gno)) (** Indicates whether the AST is an Expr @@ -1092,7 +1200,7 @@ struct if a#gnc == b#gnc then false else - ((int2lbool (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) + ((lbool_of_int (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) (** Object Comparison. @@ -1130,7 +1238,7 @@ struct Adds a parameter setting. *) let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno (lbool2int (if value then L_TRUE else L_FALSE)) + Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) (** Adds a parameter setting. @@ -1232,7 +1340,7 @@ struct @param k An AST @return True if is a key in the map, false otherwise. *) let contains ( m : ast_map ) ( key : ast ) = - (int2lbool (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE (** Finds the value associated with the key . @@ -1296,7 +1404,7 @@ struct Indicates whether the expression is the true or false expression or something else (Z3_L_UNDEF). *) - let get_bool_value ( x : expr ) = int2lbool (Z3native.get_bool_value x#gnc x#gno) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value x#gnc x#gno) (** The number of arguments of the expression. @@ -1370,13 +1478,13 @@ struct (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = int2lbool (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE + let is_numeral ( x : expr ) = lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = int2lbool (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE + let is_well_sorted ( x : expr ) = lbool_of_int (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE (** The Sort of the term. @@ -1387,7 +1495,7 @@ struct Indicates whether the term has Boolean sort. *) let is_bool ( x : expr ) = (AST.is_expr x) && - (int2lbool (Z3native.is_eq_sort x#gnc + (lbool_of_int (Z3native.is_eq_sort x#gnc (Z3native.mk_bool_sort x#gnc) (Z3native.get_sort x#gnc x#gno))) == L_TRUE @@ -1395,21 +1503,21 @@ struct Indicates whether the term is of integer sort. *) let is_int ( x : expr ) = - ((int2lbool (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) (** Indicates whether the term is of sort real. *) let is_real ( x : expr ) = - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) (** Indicates whether the term is of an array sort. *) let is_array ( x : expr ) = - ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) (** Indicates whether the term represents a constant. @@ -1431,7 +1539,7 @@ struct (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : expr ) = int2lbool(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE (** Indicates whether the term is the constant true. @@ -1634,7 +1742,7 @@ struct Indicates whether the terms is of bit-vector sort. *) let is_bv ( x : expr ) = - ((int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) (** Indicates whether the term is a bit-vector numeral @@ -2422,8 +2530,8 @@ struct Indicates whether the term is of a relation sort. *) let is_Relation ( x : expr ) = - ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) (** Indicates whether the term is an relation store @@ -2536,8 +2644,8 @@ struct Indicates whether the term is of an array sort. *) let is_finite_domain ( x : expr ) = - ((int2lbool (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (int2sort_kind (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) (** Indicates whether the term is a less than predicate over a finite domain. @@ -2575,7 +2683,7 @@ module IntNum = struct (** Retrieve the int value. *) let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v + if lbool_of_int(r) == L_TRUE then v else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) @@ -2608,7 +2716,7 @@ module BitVecNum = struct (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if int2lbool(r) == L_TRUE then v + if lbool_of_int(r) == L_TRUE then v else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) @@ -2662,7 +2770,654 @@ struct (** The function declarations of the accessors *) let get_accessor_decls ( x : constructor ) = x#accessor_decls end + + +(** ParamDescrs describe sets of parameters.*) +module ParamDescrs = +struct + + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno + + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size x#gnc x#gno in + let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno + + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno + +end + +(** Goals + + A goal (aka problem). A goal is essentially a + of formulas, that can be solved and/or transformed using + tactics and solvers. *) +module Goal = +struct + + (** The precision of the goal. + + Goals can be transformed using over and under approximations. + An under approximation is applied when the objective is to find a model for a given goal. + An over approximation is applied when the objective is to find a proof for a given goal. + *) + let get_precision ( x : goal ) = + goal_prec_of_int (Z3native.goal_precision x#gnc x#gno) + + (** Indicates whether the goal is precise. *) + let is_precise ( x : goal ) = + (get_precision x) == GOAL_PRECISE + + (** Indicates whether the goal is an under-approximation. *) + let is_underapproximation ( x : goal ) = + (get_precision x) == GOAL_UNDER + + (** Indicates whether the goal is an over-approximation. *) + let is_overapproximation ( x : goal ) = + (get_precision x) == GOAL_OVER + + (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) + let is_garbage ( x : goal ) = + (get_precision x) == GOAL_UNDER_OVER + + (** Adds the constraints to the given goal. *) + (* CMW: assert seems to be a keyword. *) + let assert_ ( x : goal ) ( constraints : bool_expr array ) = + let f e = Z3native.goal_assert x#gnc x#gno e#gno in + Array.map f constraints + + (** Indicates whether the goal contains `false'. *) + let is_inconsistent ( x : goal ) = + (lbool_of_int (Z3native.goal_inconsistent x#gnc x#gno)) == L_TRUE + + (** The depth of the goal. + This tracks how many transformations were applied to it. *) + let get_depth ( x : goal ) = Z3native.goal_depth x#gnc x#gno + + (** Erases all formulas from the given goal. *) + let reset ( x : goal ) = Z3native.goal_reset x#gnc x#gno + + (** The number of formulas in the goal. *) + let get_size ( x : goal ) = Z3native.goal_size x#gnc x#gno + + (** The formulas in the goal. *) + let get_formulas ( x : goal ) = + let n = get_size x in + let f i = (new bool_expr x#gc)#cnstr_obj (Z3native.goal_formula x#gnc x#gno i) in + Array.init n f + + (** The number of formulas, subformulas and terms in the goal. *) + let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs x#gnc x#gno + + (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) + let is_decided_sat ( x : goal ) = + (lbool_of_int (Z3native.goal_is_decided_sat x#gnc x#gno)) == L_TRUE + + (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) + let is_decided_unsat ( x : goal ) = + (lbool_of_int (Z3native.goal_is_decided_unsat x#gnc x#gno)) == L_TRUE + + (** Translates (copies) the Goal to the target Context . *) + let translate ( x : goal ) ( to_ctx : context ) = + (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno to_ctx#gno) + + (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) + let simplify ( x : goal ) ( p : params option ) = + let tn = Z3native.mk_tactic x#gnc "simplify" in + Z3native.tactic_inc_ref x#gnc tn ; + let arn = match p with + | None -> Z3native.tactic_apply x#gnc tn x#gno + | Some(pn) -> Z3native.tactic_apply_ex x#gnc tn x#gno pn#gno + in + Z3native.apply_result_inc_ref x#gnc arn ; + let sg = Z3native.apply_result_get_num_subgoals x#gnc arn in + let res = if sg == 0 then + raise (Z3native.Exception "No subgoals") + else + Z3native.apply_result_get_subgoal x#gnc arn 0 in + Z3native.apply_result_dec_ref x#gnc arn ; + Z3native.tactic_dec_ref x#gnc tn ; + (new goal x#gc)#cnstr_obj res + + (** A string representation of the Goal. *) + let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno +end + + +(** Tactics + + Tactics are the basic building block for creating custom solvers for specific problem domains. + The complete list of tactics may be obtained using Context.get_num_tactics + and Context.get_tactic_names. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Tactic = +struct + (** A string containing a description of parameters accepted by the tactic. *) + let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno + + + (** Retrieves parameter descriptions for Tactics. *) + let get_param_descrs ( x : tactic ) = + (new param_descrs x#gc)#cnstr_obj (Z3native.tactic_get_param_descrs x#gnc x#gno) + + (** Apply the tactic to the goal. *) + let apply ( x : tactic ) ( g : goal ) ( p : params option ) = + match p with + | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) + | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) + + (** Creates a solver that is implemented using the given tactic. + *) + let get_solver ( x : tactic ) = + (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) + +end + + +(** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. +*) +module FuncInterp = +struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") +end + +(** Models. + + A Model contains interpretations (assignments) of constants and functions. *) +module Model = +struct + (** Retrieves the interpretation (the assignment) of in the model. + A function declaration of zero arity + An expression if the function has an interpretation in the model, null otherwise. *) + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null np) then + None + else + Some (create_expr x#gc np) + + (** Retrieves the interpretation (the assignment) of in the model. + A Constant + An expression if the constant has an interpretation in the model, null otherwise. + *) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + (** Retrieves the interpretation (the assignment) of a non-constant in the model. + A function declaration of non-zero arity + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl x#gnc n in + get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in + if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno + + (** The function declarations of the constants in the model. *) + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.init n f + + + (** The number of function interpretations in the model. *) + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno + + (** The function declarations of the function interpretations in the model. *) + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + Array.init n f + + (** All symbols that have an interpretation in the model. *) + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.append (Array.init n_funcs f) (Array.init n_consts g) + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** + Evaluates the expression in the current model. + + + This function may fail if contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + + An expression + + When this flag is enabled, a model value will be assigned to any constant + or function that does not have an interpretation in the model. + + The evaluation of in the model. + *) + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in + if (lbool_of_int r) == L_FALSE then + raise (ModelEvaluationFailedException "evaluation failed") + else + create_expr x#gc v + + (** Alias for eval. *) + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + + + + *) + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in + Array.init n f + + + (** The finite set of distinct values that represent the interpretation for sort . + + An uninterpreted sort + An array of expressions, where each is an element of the universe of + *) + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in + let n = (ASTVector.get_size n_univ) in + let f i = (ASTVector.get n_univ i) in + Array.init n f + + (** Conversion of models to strings. + A string representation of the model. + *) + let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno +end + +(** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) +module ApplyResult = +struct + (** The number of Subgoals. *) + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals x#gnc x#gno + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in + Array.init n f + + (** Convert a model for the subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g + *) + let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = + (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) + + (** A string representation of the ApplyResult. *) + let to_string ( x : apply_result) = Z3native.apply_result_to_string x#gnc x#gno +end + +(** Objects that track statistical information about solvers. *) +module Statistics = +struct + + (** + Statistical data is organized into pairs of [Key, Entry], where every + Entry is either a DoubleEntry or a UIntEntry + *) + module Entry = + struct + (** The key of the entry. *) + let get_key (x : statistics_entry) = x#key + + (** The int-value of the entry. *) + let get_int (x : statistics_entry) = x#int + + (** The float-value of the entry. *) + let get_float (x : statistics_entry) = x#float + + (** True if the entry is uint-valued. *) + let is_int (x : statistics_entry) = x#is_int + + (** True if the entry is double-valued. *) + let is_float (x : statistics_entry) = x#is_float + + (** The string representation of the the entry's value. *) + let to_string_value (x : statistics_entry) = + if (is_int x) then + string_of_int (get_int x) + else if (is_float x) then + string_of_float (get_float x) + else + raise (Z3native.Exception "Unknown statistical entry type") + + (** The string representation of the entry (key and value) *) + let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) + end + + (** A string representation of the statistical data. *) + let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno + + (** The number of statistical data. *) + let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno + + (** The data entries. *) + let get_entries ( x : statistics ) = + let n = (get_size x ) in + let f i = ( + let k = Z3native.stats_get_key x#gnc x#gno i in + if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then + ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) + else + ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) + ) in + Array.init n f + + (** + The statistical counters. + *) + let get_keys ( x : statistics ) = + let n = (get_size x) in + let f i = (Z3native.stats_get_key x#gnc x#gno i) in + Array.init n f + + (** + The value of a particular statistical counter. + *) + let get ( x : statistics ) ( key : string ) = + let f p c = (if (Entry.get_key c) = key then (Some c) else p) in + Array.fold_left f None (get_entries x) + +end + +(** Solvers *) +module Solver = +struct + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + (** + A string that describes all available solver parameters. + *) + let get_help ( x : solver ) = Z3native.solver_get_help x#gnc x#gno + + (** + Sets the solver parameters. + *) + let set_parameters ( x : solver ) ( value : params )= + Z3native.solver_set_params x#gnc x#gno value#gno + + (** + Retrieves parameter descriptions for solver. + *) + let get_param_descrs ( x : solver ) = + (new param_descrs x#gc)#cnstr_obj (Z3native.solver_get_param_descrs x#gnc x#gno) + + (** + The current number of backtracking points (scopes). + + + *) + let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes x#gnc x#gno + + (** + Creates a backtracking point. + + *) + let push ( x : solver ) = Z3native.solver_push x#gnc x#gno + + (** + Backtracks backtracking points. + Note that an exception is thrown if is not smaller than NumScopes + + *) + let pop ( x : solver ) ( n : int ) = Z3native.solver_pop x#gnc x#gno n + + (** + Resets the Solver. + This removes all assertions from the solver. + *) + let reset ( x : solver ) = Z3native.solver_reset x#gnc x#gno + + (** + Assert a constraint (or multiple) into the solver. + *) + let assert_ ( x : solver ) ( constraints : bool_expr array ) = + let f e = (Z3native.solver_assert x#gnc x#gno e#gno) in + Array.map f constraints + + (** + The number of assertions in the solver. + *) + let get_num_assertions ( x : solver ) = + let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + (ASTVector.get_size a) + + + (** + The set of asserted formulas. + *) + let get_assertions ( x : solver ) = + let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + let n = (ASTVector.get_size a) in + let f i = ((new bool_expr x#gc)#cnstr_obj (ASTVector.get a i)#gno) in + Array.init n f + + (** + Checks whether the assertions in the solver are consistent or not. + + + + + + *) + let check ( x : solver ) ( assumptions : bool_expr array option) = + let r = + match assumptions with + | None -> lbool_of_int (Z3native.solver_check x#gnc x#gno) + | Some (ass) -> lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length ass) (astaton ass)) + in + match r with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN + + (** + The model of the last Check. + + The result is None if Check was not invoked before, + if its results was not SATISFIABLE, or if model production is not enabled. + + *) + let get_model ( x : solver ) = + let q = Z3native.solver_get_model x#gnc x#gno in + if (Z3native.is_null q) then + None + else + Some ((new model x#gc)#cnstr_obj q) + + (** + The proof of the last Check. + + The result is null if Check was not invoked before, + if its results was not UNSATISFIABLE, or if proof production is disabled. + + *) + let get_proof ( x : solver ) = + let q = Z3native.solver_get_proof x#gnc x#gno in + if (Z3native.is_null q) then + None + else + Some (create_expr x#gc q) + + (** + The unsat core of the last Check. + + The unsat core is a subset of Assertions + The result is empty if Check was not invoked before, + if its results was not UNSATISFIABLE, or if core production is disabled. + + *) + let get_unsat_core ( x : solver ) = + let cn = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_unsat_core x#gnc x#gno) in + let n = (ASTVector.get_size cn) in + let f i = (ASTVector.get cn i) in + Array.init n f + + (** + A brief justification of why the last call to Check returned UNKNOWN. + *) + let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown x#gnc x#gno + + + (** + Solver statistics. + *) + let get_statistics ( x : solver ) = + (new statistics x#gc)#cnstr_obj (Z3native.solver_get_statistics x#gnc x#gno) + + (** + A string representation of the solver. + *) + let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno +end + +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe = +struct + (** + Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. + *) + let apply ( x : probe ) (g : goal) = + Z3native.probe_apply x#gnc x#gno g#gno +end + + (** The main interaction with Z3 happens via the Context module *) module Context = struct From f1ecf3ae0bec626e0bc9861ed94beb146f288424 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 23 Dec 2012 02:20:24 +0000 Subject: [PATCH 366/507] New ML API savepoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 6488 +++++++++++++++++++--------------------------- 1 file changed, 2629 insertions(+), 3859 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c22ef869b..5f67e11e2 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -586,6 +586,13 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +(** Quantifier pattern objects *) +class pattern ctx = +object (self) + inherit ast ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self +end + (** Parameter description objects *) class param_descrs ctx = object (self) @@ -775,6 +782,33 @@ struct match (kind o) with | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int o#gnc o#gno)) | STRING_SYMBOL -> (Z3native.get_symbol_string o#gnc o#gno) + + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) + let mk_int ( ctx : context ) i = + (new int_symbol ctx)#cnstr_int i + + (** Creates a new symbol using a string. *) + let mk_string ( ctx : context ) s = + (new string_symbol ctx)#cnstr_string s + + (** + Create an array of symbols. + *) + let mk_ints ( ctx : context ) ( names : int array ) = + let f elem = mk_int ( ctx : context ) elem in + (Array.map f names) + + (** + Create an array of symbols. + *) + let mk_strings ( ctx : context ) ( names : string array ) = + let f elem = mk_string ( ctx : context ) elem in + (Array.map f names) end @@ -813,49 +847,26 @@ struct A string representation of the sort. *) let to_string (x : sort) = Z3native.sort_to_string x#gnc x#gno + + (** + Create a new Boolean sort. + *) + let mk_bool ( ctx : context ) = + (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted ( ctx : context ) (s : symbol) = + (new uninterpreted_sort ctx)#cnstr_s s + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_s ( ctx : context ) (s : string) = + mk_uninterpreted ctx ((Symbol.mk_string ( ctx : context ) s) :> symbol) end -(** Array sorts *) -module ArraySort = -struct - (** The domain of the array sort. *) - let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) - - (** The range of the array sort. *) - let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) -end - -(** Bit-vector sorts *) -module BitVecSort = -struct - (** The size of the bit-vector sort. *) - let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno -end - -(** Finite domain sorts *) -module FiniteDomainSort = -struct - (** The size of the finite domain sort. *) - let get_size (x : finite_domain_sort) = - let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") -end - -(** Relation sorts *) -module RelationSort = -struct - (** The arity of the relation sort. *) - let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno - - (** The sorts of the columns of the relation sort. *) - let get_column_sorts (x : relation_sort) = - let n = get_arity x in - let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in - Array.init n f - -end - (**/**) let create_expr ctx obj = if ast_kind_of_int (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then @@ -957,6 +968,48 @@ struct raise (Z3native.Exception "parameter is not a ratinoal string") else x#rational + + (** + Creates a new function declaration. + *) + let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name domain range + + (** + Creates a new function declaration. + *) + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = + mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range + + (** + Creates a fresh function declaration with a name prefixed with . + + + *) + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix domain range + + (** + Creates a new constant function declaration. + *) + let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name [||] range + + + (** + Creates a new constant function declaration. + *) + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range + + (** + Creates a fresh constant function declaration with a name prefixed with . + + + *) + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix [||] range + end (** @@ -1046,91 +1099,103 @@ struct end -(** Datatype sorts *) -module DatatypeSort = -struct - (** The number of constructors of the datatype sort. *) - let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno - - (** The range of the array sort. *) - let get_constructors (x : datatype_sort) = - let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in - Array.init n f - - (** The recognizers. *) - let get_recognizers (x : datatype_sort) = - let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in - Array.init n f - - (** The constructor accessors. *) - let get_accessors (x : datatype_sort) = - let n = (get_num_constructors x) in - let f i = ( - let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in - let ds = (Z3native.get_domain_size fd#gnc fd#gno) in - let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in - Array.init ds g - ) in - Array.init n f -end - -(** Enumeration sorts *) -module EnumSort = -struct - (** The function declarations of the constants in the enumeration. *) - let get_const_decls (x : enum_sort) = x#const_decls - - (** The test predicates for the constants in the enumeration. *) - let get_tester_decls (x : enum_sort) = x#tester_decls -end - -(** List sorts *) -module ListSort = -struct - (** The declaration of the nil function of this list sort. *) - let get_nil_decl (x : list_sort) = x#nil_decl - - (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl (x : list_sort) = x#is_nil_decl - - (** The declaration of the cons function of this list sort. *) - let get_cons_decl (x : list_sort) = x#cons_decl - - (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl (x : list_sort) = x#is_cons_decl - - (** The declaration of the head function of this list sort.*) - let get_head_decl (x : list_sort) = x#head_decl - - (** The declaration of the tail function of this list sort. *) - let get_tail_decl (x : list_sort) = x#tail_decl - - (** The empty list. *) - let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] -end - -(** Tuple sorts *) -module TupleSort = -struct - (** The constructor function of the tuple.*) - let get_mk_decl (x : tuple_sort) = - (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) - - (** The number of fields in the tuple. *) - let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno - - (** The field declarations. *) - let get_field_decls (x : tuple_sort) = - let n = get_num_fields x in - let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in - Array.init n f -end - (** The abstract syntax tree (AST) module *) module AST = struct + (** Vectors of ASTs *) + module ASTVector = + struct + (** The size of the vector *) + let get_size ( x : ast_vector ) = + Z3native.ast_vector_size x#gnc x#gno + + (** + Retrieves the i-th object in the vector. + @param i Index + @return An AST + *) + let get ( x : ast_vector ) ( i : int ) = + create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) + + (** Sets the i-th object in the vector. *) + let set ( x : ast_vector ) ( i : int ) ( value : ast ) = + Z3native.ast_vector_set x#gnc x#gno i value#gno + + (** Resize the vector to . + @param newSize The new size of the vector. *) + let resize ( x : ast_vector ) ( new_size : int ) = + Z3native.ast_vector_resize x#gnc x#gno new_size + + (** + Add the AST to the back of the vector. The size + is increased by 1. + @param a An AST + *) + let push ( x : ast_vector ) ( a : ast ) = + Z3native.ast_vector_push x#gnc x#gno a#gno + + (** + Translates all ASTs in the vector to . + @param to_ctx A context + @return A new ASTVector + *) + let translate ( x : ast_vector ) ( to_ctx : context ) = + (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) + + (** Retrieves a string representation of the vector. *) + let to_string ( x : ast_vector ) = + Z3native.ast_vector_to_string x#gnc x#gno + end + + (** Map from AST to AST *) + module ASTMap = + struct + (** Checks whether the map contains the key . + @param k An AST + @return True if is a key in the map, false otherwise. *) + let contains ( m : ast_map ) ( key : ast ) = + (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + + (** Finds the value associated with the key . + + This function signs an error when is not a key in the map. + @param k An AST + *) + let find ( m : ast_map ) ( key : ast ) = + create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) + + (** + Stores or replaces a new key/value pair in the map. + @param k The key AST + @param v The value AST + *) + let insert ( m : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert m#gnc m#gno key#gno value#gno + + (** + Erases the key from the map. + @param k An AST + *) + let erase ( m : ast_map ) ( key : ast ) = + Z3native.ast_map_erase m#gnc m#gno key#gno + + (** Removes all keys from the map. *) + let reset ( m : ast_map ) = + Z3native.ast_map_reset m#gnc m#gno + + (** The size of the map *) + let get_size ( m : ast_map ) = + Z3native.ast_map_size m#gnc m#gno + + (** The keys stored in the map. *) + let get_keys ( m : ast_map ) = + (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) + + (** Retrieves a string representation of the map.*) + let to_strnig ( m : ast_map ) = + Z3native.ast_map_to_string m#gnc m#gno + end + (** The AST's hash code. @return A hash code @@ -1159,7 +1224,7 @@ struct | _ -> false (** - Indicates whether the AST is a BoundVariable + Indicates whether the AST is a bound variable *) let is_var ( x : ast) = (get_ast_kind x) == VAR_AST @@ -1227,163 +1292,7 @@ struct (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) end -(** - Parameter sets - - A Params objects represents a configuration in the form of Symbol/value pairs. -*) -module Params = -struct - (** - Adds a parameter setting. - *) - let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) - - (** - Adds a parameter setting. - *) - let add_int (p : params) (name : symbol) (value : int) = - Z3native.params_set_uint p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_double (p : params) (name : symbol) (value : float) = - Z3native.params_set_double p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_symbol (p : params) (name : symbol) (value : symbol) = - Z3native.params_set_symbol p#gnc p#gno name#gno value#gno - - (** - Adds a parameter setting. - *) - let add_s_bool (p : params) (name : string) (value : bool) = - add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_int (p : params) (name : string) (value : int) = - add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_double (p : params) (name : string) (value : float) = - add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_symbol (p : params) (name : string) (value : symbol) = - add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - A string representation of the parameter set. - *) - let to_string (p : params) = Z3native.params_to_string p#gnc p#gno -end - -(** Vectors of ASTs *) -module ASTVector = -struct - (** The size of the vector *) - let get_size ( x : ast_vector ) = - Z3native.ast_vector_size x#gnc x#gno - - (** - Retrieves the i-th object in the vector. - @param i Index - @return An AST - *) - let get ( x : ast_vector ) ( i : int ) = - create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) - - (** Sets the i-th object in the vector. *) - let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set x#gnc x#gno i value#gno - - (** Resize the vector to . - @param newSize The new size of the vector. *) - let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize x#gnc x#gno new_size - - (** - Add the AST to the back of the vector. The size - is increased by 1. - @param a An AST - *) - let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push x#gnc x#gno a#gno - - (** - Translates all ASTs in the vector to . - @param to_ctx A context - @return A new ASTVector - *) - let translate ( x : ast_vector ) ( to_ctx : context ) = - (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) - - (** Retrieves a string representation of the vector. *) - let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string x#gnc x#gno -end - -(** Map from AST to AST *) -module ASTMap = -struct - (** Checks whether the map contains the key . - @param k An AST - @return True if is a key in the map, false otherwise. *) - let contains ( m : ast_map ) ( key : ast ) = - (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE - - (** Finds the value associated with the key . - - This function signs an error when is not a key in the map. - - @param k An AST - *) - let find ( m : ast_map ) ( key : ast ) = - create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) - - (** - Stores or replaces a new key/value pair in the map. - @param k The key AST - @param v The value AST - *) - let insert ( m : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert m#gnc m#gno key#gno value#gno - - (** - Erases the key from the map. - @param k An AST - *) - let erase ( m : ast_map ) ( key : ast ) = - Z3native.ast_map_erase m#gnc m#gno key#gno - - (** Removes all keys from the map. *) - let reset ( m : ast_map ) = - Z3native.ast_map_reset m#gnc m#gno - - (** The size of the map *) - let get_size ( m : ast_map ) = - Z3native.ast_map_size m#gnc m#gno - - (** The keys stored in the map. *) - let get_keys ( m : ast_map ) = - (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) - - (** Retrieves a string representation of the map.*) - let to_strnig ( m : ast_map ) = - Z3native.ast_map_to_string m#gnc m#gno -end - -(** Expressions (terms) *) +(** General expressions (terms), including Boolean logic *) module Expr = struct (** @@ -1402,7 +1311,7 @@ struct (** Indicates whether the expression is the true or false expression - or something else (Z3_L_UNDEF). + or something else (L_UNDEF). *) let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value x#gnc x#gno) @@ -1434,7 +1343,6 @@ struct The result is the new expression. The arrays from and to must have size num_exprs. For every i smaller than num_exprs, we must have that sort of from[i] must be equal to sort of to[i]. - *) let substitute ( x : expr ) from to_ = if (Array.length from) <> (Array.length to_) then @@ -1453,7 +1361,6 @@ struct Substitute the free variables in the expression with the expressions in For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. - *) let substitute_vars ( x : expr ) to_ = create_expr x#gc (Z3native.substitute_vars x#gnc x#gno (Array.length to_) (expraton to_)) @@ -1496,28 +1403,8 @@ struct *) let is_bool ( x : expr ) = (AST.is_expr x) && (lbool_of_int (Z3native.is_eq_sort x#gnc - (Z3native.mk_bool_sort x#gnc) - (Z3native.get_sort x#gnc x#gno))) == L_TRUE - - (** - Indicates whether the term is of integer sort. - *) - let is_int ( x : expr ) = - ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) - - (** - Indicates whether the term is of sort real. - *) - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) - - (** - Indicates whether the term is of an array sort. - *) - let is_array ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + (Z3native.mk_bool_sort x#gnc) + (Z3native.get_sort x#gnc x#gno))) == L_TRUE (** Indicates whether the term represents a constant. @@ -1526,21 +1413,6 @@ struct (get_num_args x) == 0 && FuncDecl.get_domain_size(get_func_decl x) == 0 - (** - Indicates whether the term is an integer numeral. - *) - let is_int_numeral ( x : expr ) = (is_numeral x) && (is_int x) - - (** - Indicates whether the term is a real numeral. - *) - let is_rat_num ( x : expr ) = (is_numeral x) && (is_real x) - - (** - Indicates whether the term is an algebraic number - *) - let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE - (** Indicates whether the term is the constant true. *) @@ -1597,146 +1469,1189 @@ struct let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) (** - Indicates whether the term is an arithmetic numeral. + Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ANUM) + let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) (** - Indicates whether the term is a less-than-or-equal + Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LE) (** - Indicates whether the term is a greater-than-or-equal + Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GE) + let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) (** - Indicates whether the term is a less-than + Creates a new Constant of sort and named . *) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LT) + let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = + create_expr ctx (Z3native.mk_const ctx#gno name#gno range#gno) + (** - Indicates whether the term is a greater-than + Creates a new Constant of sort and named . *) - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_GT) + let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = + mk_const ctx ((Symbol.mk_string ctx name) :> symbol) range + (** - Indicates whether the term is addition (binary) + Creates a constant from the func_decl . + @param f An expression of a 0-arity function *) - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ADD) + let mk_const_f ( ctx : context ) ( f : func_decl ) = + create_expr_fa ctx f [||] (** - Indicates whether the term is subtraction (binary) + Creates a fresh constant of sort and a + name prefixed with . *) - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SUB) + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort) = + create_expr ctx (Z3native.mk_fresh_const ctx#gno prefix range#gno) (** - Indicates whether the term is a unary minus - *) - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UMINUS) + Create a Boolean constant. + *) + let mk_bool_const ( ctx : context ) ( name : symbol ) = + ((mk_const ctx name (Sort.mk_bool ctx)) :> bool_expr) + + (** + Create a Boolean constant. + *) + let mk_bool_const_s ( ctx : context ) ( name : string ) = + mk_bool_const ctx ((Symbol.mk_string ctx name) :> symbol) (** - Indicates whether the term is multiplication (binary) + Create a new function application. *) - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MUL) + let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = + create_expr_fa ctx f args (** - Indicates whether the term is division (binary) - *) - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DIV) + The true Term. + *) + let mk_true ( ctx : context ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_true ctx#gno) (** - Indicates whether the term is integer division (binary) - *) - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IDIV) + The false Term. + *) + let mk_false ( ctx : context ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_false ctx#gno) (** - Indicates whether the term is remainder (binary) - *) - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REM) + Creates a Boolean value. + *) + let mk_bool ( ctx : context ) ( value : bool) = + if value then mk_true ctx else mk_false ctx (** - Indicates whether the term is modulus (binary) + Creates the equality = . *) - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_MOD) + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq ctx#gno x#gno y#gno) (** - Indicates whether the term is a coercion of integer to real (unary) + Creates a distinct term. *) - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_REAL) + let mk_distinct ( ctx : context ) ( args : expr array ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct ctx#gno (Array.length args) (astaton args)) + + (** + Mk an expression representing not(a). + *) + let mk_not ( ctx : context ) ( a : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_not ctx#gno a#gno) + + (** + Create an expression representing an if-then-else: ite(t1, t2, t3). + @param t1 An expression with Boolean sort + @param t2 An expression + @param t3 An expression with the same sort as + *) + let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = + create_expr ctx (Z3native.mk_ite ctx#gno t1#gno t2#gno t3#gno) + + (** + Create an expression representing t1 iff t2. + *) + let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff ctx#gno t1#gno t2#gno) (** - Indicates whether the term is a coercion of real to integer (unary) + Create an expression representing t1 -> t2. *) - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TO_INT) + let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies ctx#gno t1#gno t2#gno) (** - Indicates whether the term is a check that tests whether a real is integral (unary) + Create an expression representing t1 xor t2. *) - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IS_INT) + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor ctx#gno t1#gno t2#gno) + + (** + Create an expression representing the AND of args + *) + let mk_and ( ctx : context ) ( args : bool_expr array ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_and ctx#gno (Array.length args) (astaton args)) + + (** + Create an expression representing the OR of args + *) + let mk_or ( ctx : context ) ( args : bool_expr array ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_or ctx#gno (Array.length args) (astaton args)) +end + +(** Functions to manipulate Array expressions *) +module Arrays = +struct + (** + Create a new array sort. + *) + let mk_sort ( ctx : context ) domain range = + (new array_sort ctx)#cnstr_dr domain range (** Indicates whether the term is an array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. + Array store takes at least 3 arguments. *) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_STORE) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) (** Indicates whether the term is an array select. *) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SELECT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONST_ARRAY) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. + For example default(const(v)) = v. The function is unary. *) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_DEFAULT) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ARRAY_MAP) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) (** Indicates whether the term is an as-array term. An as-array term is n array value that behaves as the function graph of the - function passed as parameter. + function passed as parameter. *) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AS_ARRAY) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + (** + Indicates whether the term is of an array sort. + *) + let is_array ( x : expr ) = + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + + (** The domain of the array sort. *) + let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) + + (** The range of the array sort. *) + let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) + + + (** + Create an array constant. + *) + let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = + ((Expr.mk_const ctx name ((mk_sort ctx domain range) :> sort)) :> array_expr) + + (** + Create an array constant. + *) + let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = + mk_const ctx ((Symbol.mk_string ctx name) :> symbol) domain range + + (** + Array read. + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + + + *) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = + ((create_expr ctx (Z3native.mk_select ctx#gno a#gno i#gno)) :> array_expr) + + (** + Array update. + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + + + *) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr) = + (new array_expr ctx)#cnstr_obj (Z3native.mk_store ctx#gno a#gno i#gno v#gno) + + (** + Create a constant array. + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + + + *) + let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = + (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array ctx#gno domain#gno v#gno) + + (** + Maps f on the argument arrays. + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + + + + *) + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = + ((create_expr ctx (Z3native.mk_map ctx#gno f#gno (Array.length args) (astaton args))) :> array_expr) + + (** + Access the array default value. + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. + *) + let mk_term_array ( ctx : context ) ( arg : array_expr ) = + ((create_expr ctx (Z3native.mk_array_default ctx#gno arg#gno)) :> array_expr) +end + +(** Functions to manipulate Set expressions *) +module Sets = +struct (** Indicates whether the term is set union *) - let is_set_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_UNION) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) (** Indicates whether the term is set intersection *) - let is_set_intersect ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_INTERSECT) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) (** Indicates whether the term is set difference *) - let is_set_difference ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_DIFFERENCE) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) (** Indicates whether the term is set complement *) - let is_set_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_COMPLEMENT) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) (** Indicates whether the term is set subset *) - let is_set_subset ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SET_SUBSET) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + +(** + Create a set type. +*) +let mk_sort ( ctx : context ) ( ty : sort) = + (new set_sort ctx)#cnstr_s ty + +(** + Create an empty set. +*) +let mk_empty ( ctx : context ) ( domain : sort ) = + (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) + + (** + Create the full set. + *) +let mk_full ( ctx : context ) ( domain : sort ) = + create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) + +(** + Add an element to the set. +*) +let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) + + (** + Remove an element from a set. + *) +let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) + + (** + Take the union of a list of sets. + *) +let mk_union ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) + +(** + Take the intersection of a list of sets. +*) +let mk_intersection ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) + +(** + Take the difference between two sets. +*) +let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) + +(** + Take the complement of a set. +*) +let mk_complement ( ctx : context ) ( arg : expr ) = + create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) + +(** + Check for set membership. +*) +let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) + + (** + Check for subsetness of sets. + *) +let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) + +end + +(** Functions to manipulate Finite Domain expressions *) +module FiniteDomains = +struct + (** + Create a new finite domain sort. + *) + let mk_sort ( ctx : context ) ( name : symbol ) size = + (new finite_domain_sort ctx)#cnstr_si name size + + (** + Create a new finite domain sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) size = + (new finite_domain_sort ctx)#cnstr_si ((Symbol.mk_string ctx name) :> symbol) size + + + (** + Indicates whether the term is of an array sort. + *) + let is_finite_domain ( x : expr ) = + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + + (** + Indicates whether the term is a less than predicate over a finite domain. + *) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + + (** The size of the finite domain sort. *) + let get_size (x : finite_domain_sort) = + let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in + if lbool_of_int(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") +end + +(** Functions to manipulate Relation expressions *) +module Relations = +struct + (** + Indicates whether the term is of a relation sort. + *) + let is_relation ( x : expr ) = + ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + + (** + Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. + *) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + + (** + Indicates whether the term is an empty relation + *) + let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + + (** + Indicates whether the term is a test for the emptiness of a relation + *) + let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + + (** + Indicates whether the term is a relational join + *) + let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + + (** + Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. + *) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + + (** + Indicates whether the term is the widening of two relations + The function takes two arguments. + *) + let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + + (** + Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. + *) + let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + + (** + Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. + *) + let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + + (** + Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. + *) + let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + + (** + Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. + *) + let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + + (** + Indicates whether the term is the complement of a relation + *) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + + (** + Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. + *) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + + (** + Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind + to perform destructive updates to the first argument. + *) + let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + + (** The arity of the relation sort. *) + let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno + + (** The sorts of the columns of the relation sort. *) + let get_column_sorts (x : relation_sort) = + let n = get_arity x in + let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in + Array.init n f + +end + +(** Quantifier expressions *) +module Quantifiers = +struct + (** + The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. + *) + let get_index ( x : expr ) = + if not (AST.is_var x) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value x#gnc x#gno + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. + *) + module Pattern = + struct + (** + The number of terms in the pattern. + *) + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms x#gnc x#gno + + (** + The terms in the pattern. + *) + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the pattern. + *) + let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno + end + + (** + Indicates whether the quantifier is universal. + *) + let is_universal ( x : quantifier ) = + lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE + + (** + Indicates whether the quantifier is existential. + *) + let is_existential ( x : quantifier ) = not (is_universal x) + + (** + The weight of the quantifier. + *) + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno + + (** + The number of patterns. + *) + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno + + (** + The patterns. + *) + let get_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of no-patterns. + *) + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno + + (** + The no-patterns. + *) + let get_no_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of bound variables. + *) + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno + + (** + The symbols for the bound variables. + *) + let get_bound_variable_names ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + Array.init n f + + (** + The sorts of the bound variables. + *) + let get_bound_variable_sorts ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in + Array.init n f + + (** + The body of the quantifier. + *) + let get_body ( x : quantifier ) = + (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) + + (** + Creates a new bound variable. + @param index The de-Bruijn index of the variable + @param ty The sort of the variable + *) + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) + + (** + Create a quantifier pattern. + *) + let mk_pattern ( ctx : context ) ( terms : expr array ) = + if (Array.length terms) == 0 then + raise (Z3native.Exception "Cannot create a pattern from zero terms") + else + (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) +end + +(** Functions to manipulate Datatype expressions *) +module Datatypes = +struct + (** Constructors *) + module Constructor = + struct + (** The number of fields of the constructor. *) + let get_num_fields ( x : constructor ) = x#get_n + + (** The function declaration of the constructor. *) + let get_constructor_decl ( x : constructor ) = x#constructor_decl + + (** The function declaration of the tester. *) + let get_tester_decl ( x : constructor ) = x#tester_decl + + (** The function declarations of the accessors *) + let get_accessor_decls ( x : constructor ) = x#accessor_decls + end + + (* DATATYPES *) + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs + + + (** + Create a datatype constructor. + @param name constructor name + @param recognizer name of recognizer function. + @param fieldNames names of the constructor fields. + @param sorts field sorts, 0 if the field sort refers to a recursive sort. + @param sortRefs reference to datatype sort that is an argument to the constructor; + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. + *) + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + mk_constructor ctx ((Symbol.mk_string ctx name) :> symbol) recognizer field_names sorts sort_refs + + + (** + Create a new datatype sort. + *) + let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + (new datatype_sort ctx)#cnstr_sc name constructors + + (** + Create a new datatype sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = + mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) constructors + + (** + Create mutually recursive datatypes. + @param names names of datatype sorts + @param c list of constructors, one list per sort. + *) + let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let n = (Array.length names) in + let f e = ( (new constructor_list ctx)#cnstr_ca e ) in + let cla = (Array.map f c) in + let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in + let g e = ( (new datatype_sort ctx)#cnstr_obj e) in + (Array.map g r) + + (** Create mutually recursive data-types. *) + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + mk_sorts ctx + ( + let f e = ((Symbol.mk_string ctx e) :> symbol) in + Array.map f names + ) + c + + (** The number of constructors of the datatype sort. *) + let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno + + (** The range of the array sort. *) + let get_constructors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in + Array.init n f + + (** The recognizers. *) + let get_recognizers (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in + Array.init n f + + (** The constructor accessors. *) + let get_accessors (x : datatype_sort) = + let n = (get_num_constructors x) in + let f i = ( + let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in + let ds = (Z3native.get_domain_size fd#gnc fd#gno) in + let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in + Array.init ds g + ) in + Array.init n f +end + +(** Functions to manipulate Enumeration expressions *) +module Enumerations = +struct + (** + Create a new enumeration sort. + *) + let mk_sort ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss name enum_names + + (** + Create a new enumeration sort. + *) + let mk_sort_s ( ctx : context ) name enum_names = + (new enum_sort ctx)#cnstr_ss + ((Symbol.mk_string ( ctx : context ) name) :> symbol) + (let f e = (e :> symbol) in + (Array.map f (Symbol.mk_strings ( ctx : context ) enum_names)) + ) + + (** The function declarations of the constants in the enumeration. *) + let get_const_decls (x : enum_sort) = x#const_decls + + (** The test predicates for the constants in the enumeration. *) + let get_tester_decls (x : enum_sort) = x#tester_decls +end + +(** Functions to manipulate List expressions *) +module Lists = +struct + (** + Create a new list sort. + *) + let mk_sort ( ctx : context ) (name : symbol) elem_sort = + (new list_sort ctx)#cnstr_ss name elem_sort + + (** + Create a new list sort. + *) + let mk_list_s ( ctx : context ) (name : string) elem_sort = + mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) elem_sort + + + (** The declaration of the nil function of this list sort. *) + let get_nil_decl (x : list_sort) = x#nil_decl + + (** The declaration of the isNil function of this list sort. *) + let get_is_nil_decl (x : list_sort) = x#is_nil_decl + + (** The declaration of the cons function of this list sort. *) + let get_cons_decl (x : list_sort) = x#cons_decl + + (** The declaration of the isCons function of this list sort. *) + let get_is_cons_decl (x : list_sort) = x#is_cons_decl + + (** The declaration of the head function of this list sort. *) + let get_head_decl (x : list_sort) = x#head_decl + + (** The declaration of the tail function of this list sort. *) + let get_tail_decl (x : list_sort) = x#tail_decl + + (** The empty list. *) + let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] +end + +(** Functions to manipulate Tuple expressions *) +module Tuples = +struct + (** + Create a new tuple sort. + *) + let mk_sort ( ctx : context ) name field_names field_sorts = + (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts + + (** The constructor function of the tuple. *) + let get_mk_decl (x : tuple_sort) = + (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) + + (** The number of fields in the tuple. *) + let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno + + (** The field declarations. *) + let get_field_decls (x : tuple_sort) = + let n = get_num_fields x in + let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in + Array.init n f +end + +(** Functions to manipulate arithmetic expressions *) +module Arithmetic = +struct + (** + Create a new integer sort. + *) + let mk_int_sort ( ctx : context ) = + (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) + + (** + Create a real sort. + *) + let mk_real_sort ( ctx : context ) = + (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) + + (** + Indicates whether the term is of integer sort. + *) + let is_int ( x : expr ) = + ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + + (** + Indicates whether the term is an arithmetic numeral. + *) + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + + (** + Indicates whether the term is a less-than-or-equal + *) + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + + (** + Indicates whether the term is a greater-than-or-equal + *) + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + + (** + Indicates whether the term is a less-than + *) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + + (** + Indicates whether the term is a greater-than + *) + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + + (** + Indicates whether the term is addition (binary) + *) + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + + (** + Indicates whether the term is subtraction (binary) + *) + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + + (** + Indicates whether the term is a unary minus + *) + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + + (** + Indicates whether the term is multiplication (binary) + *) + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + + (** + Indicates whether the term is division (binary) + *) + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + + (** + Indicates whether the term is integer division (binary) + *) + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + + (** + Indicates whether the term is remainder (binary) + *) + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + + (** + Indicates whether the term is modulus (binary) + *) + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + + (** + Indicates whether the term is a coercion of integer to real (unary) + *) + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + + (** + Indicates whether the term is a coercion of real to integer (unary) + *) + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + + (** + Indicates whether the term is a check that tests whether a real is integral (unary) + *) + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + + (** + Indicates whether the term is of sort real. + *) + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + + (** + Indicates whether the term is an integer numeral. + *) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + + (** + Indicates whether the term is a real numeral. + *) + let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) + + (** + Indicates whether the term is an algebraic number + *) + let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + + (** Retrieve the int value. *) + let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if lbool_of_int(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno + + (** The numerator of a rational numeral. *) + let get_numerator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) + + (** The denominator of a rational numeral. *) + let get_denominator ( x : rat_num ) = + (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : rat_num ) (precision : int) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno + + (** + Creates an integer constant. + *) + let mk_int_const ( ctx : context ) ( name : symbol ) = + ((Expr.mk_const ctx name (mk_int_sort ctx)) :> int_expr) + + (** + Creates an integer constant. + *) + let mk_int_const_s ( ctx : context ) ( name : string ) = + mk_int_const ctx ((Symbol.mk_string ctx name) :> symbol) + + (** + Creates a real constant. + *) + let mk_real_const ( ctx : context ) ( name : symbol ) = + ((Expr.mk_const ctx name (mk_real_sort ctx)) :> real_expr) + + (** + Creates a real constant. + *) + let mk_real_const_s ( ctx : context ) ( name : string ) = + mk_real_const ctx ((Symbol.mk_string ctx name) :> symbol) + + (** + Create an expression representing t[0] + t[1] + .... + *) + let mk_add ( ctx : context ) ( t : arith_expr array ) = + (create_expr ctx (Z3native.mk_add ctx#gno (Array.length t) (astaton t)) :> arith_expr) + + (** + Create an expression representing t[0] * t[1] * .... + *) + let mk_mul ( ctx : context ) ( t : arith_expr array ) = + (create_expr ctx (Z3native.mk_mul ctx#gno (Array.length t) (astaton t)) :> arith_expr) + + (** + Create an expression representing t[0] - t[1] - .... + *) + let mk_sub ( ctx : context ) ( t : arith_expr array ) = + (create_expr ctx (Z3native.mk_sub ctx#gno (Array.length t) (astaton t)) :> arith_expr) + + (** + Create an expression representing -t. + *) + let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = + (create_expr ctx (Z3native.mk_unary_minus ctx#gno t#gno) :> arith_expr) + + (** + Create an expression representing t1 / t2. + *) + let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + (create_expr ctx (Z3native.mk_div ctx#gno t1#gno t2#gno) :> arith_expr) + + (** + Create an expression representing t1 mod t2. + The arguments must have int type. + *) + let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_mod ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 rem t2. + The arguments must have int type. + *) + let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_rem ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 ^ t2. + *) + let mk_Power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (create_expr ctx (Z3native.mk_power ctx#gno t1#gno t2#gno) :> arith_expr) + + (** + Create an expression representing t1 < t2 + *) + let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 <= t2 + *) + let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_le ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 > t2 + *) + let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt ctx#gno t1#gno t2#gno) + + (** + Create an expression representing t1 >= t2 + *) + let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge ctx#gno t1#gno t2#gno) + + (** + Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. + *) + let mk_int2real ( ctx : context ) ( t : int_expr ) = + (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real ctx#gno t#gno) + + (** + Coerce a real to an integer. + + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. + *) + let mk_real2int ( ctx : context ) ( t : real_expr ) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int ctx#gno t#gno) + + (** + Creates an expression that checks whether a real number is an integer. + *) + let mk_is_integer ( ctx : context ) ( t : real_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int ctx#gno t#gno) + + (** + Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_upper ( x : algebraic_num ) ( precision : int ) = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) + + (** + Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_lower ( x : algebraic_num ) precision = + (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno +end + + +(** Functions to manipulate bit-vector expressions *) +module BitVectors = +struct + (** + Create a new bit-vector sort. + *) + let mk_sort ( ctx : context ) size = + (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) (** Indicates whether the terms is of bit-vector sort. @@ -1747,300 +2662,750 @@ struct (** Indicates whether the term is a bit-vector numeral *) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNUM) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) (** Indicates whether the term is a one-bit bit-vector with value one *) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT1) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) (** Indicates whether the term is a one-bit bit-vector with value zero *) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BIT0) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) (** Indicates whether the term is a bit-vector unary minus *) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNEG) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) (** Indicates whether the term is a bit-vector addition (binary) *) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BADD) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) (** Indicates whether the term is a bit-vector subtraction (binary) *) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSUB) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) (** Indicates whether the term is a bit-vector multiplication (binary) *) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BMUL) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) (** Indicates whether the term is a bit-vector signed division (binary) *) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) (** Indicates whether the term is a bit-vector unsigned division (binary) *) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) (** Indicates whether the term is a bit-vector signed remainder (binary) *) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) (** Indicates whether the term is a bit-vector signed modulus *) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) (** Indicates whether the term is a bit-vector signed division by zero *) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSDIV0) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) (** Indicates whether the term is a bit-vector unsigned division by zero *) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUDIV0) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) (** Indicates whether the term is a bit-vector signed remainder by zero *) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSREM0) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BUREM0) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) (** Indicates whether the term is a bit-vector signed modulus by zero *) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSMOD0) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULEQ) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLEQ) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGEQ) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGEQ) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) (** Indicates whether the term is an unsigned bit-vector less-than *) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ULT) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) (** Indicates whether the term is a signed bit-vector less-than *) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SLT) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) (** Indicates whether the term is an unsigned bit-vector greater-than *) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_UGT) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) (** Indicates whether the term is a signed bit-vector greater-than *) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SGT) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) (** Indicates whether the term is a bit-wise AND *) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BAND) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) (** Indicates whether the term is a bit-wise OR *) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BOR) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) (** Indicates whether the term is a bit-wise NOT *) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOT) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) (** Indicates whether the term is a bit-wise XOR *) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXOR) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) (** Indicates whether the term is a bit-wise NAND *) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNAND) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) (** Indicates whether the term is a bit-wise NOR *) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BNOR) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) (** Indicates whether the term is a bit-wise XNOR *) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BXNOR) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) (** Indicates whether the term is a bit-vector concatenation (binary) *) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CONCAT) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) (** Indicates whether the term is a bit-vector sign extension *) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_SIGN_EXT) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) (** Indicates whether the term is a bit-vector zero extension *) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ZERO_EXT) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) (** Indicates whether the term is a bit-vector extraction *) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXTRACT) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) (** Indicates whether the term is a bit-vector repetition *) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_REPEAT) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) (** Indicates whether the term is a bit-vector reduce OR *) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDOR) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) (** Indicates whether the term is a bit-vector reduce AND *) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BREDAND) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) (** Indicates whether the term is a bit-vector comparison *) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BCOMP) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) (** Indicates whether the term is a bit-vector shift left *) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BSHL) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) (** Indicates whether the term is a bit-vector logical shift right *) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) (** Indicates whether the term is a bit-vector arithmetic shift left *) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BASHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) (** Indicates whether the term is a bit-vector rotate left *) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right *) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. + rudimentary simplification rules are applied to this function. *) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_INT2BV) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. + rudimentary simplification rules are applied to this function. *) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_BV2INT) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_CARRY) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR3) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + + (** The size of a bit-vector sort. *) + let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno + + (** Retrieve the int value. *) + let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if lbool_of_int(r) == L_TRUE then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno (** - Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. + Creates a bit-vector constant. *) - let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) + let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = + ((Expr.mk_const ctx name (mk_sort ctx size)) :> bitvec_expr) (** - Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) + Creates a bit-vector constant. *) + let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_const ctx ((Symbol.mk_string ctx name) :> symbol) size (** - Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. + Bitwise negation. + The argument must have a bit-vector sort. *) - let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + let mk_not ( ctx : context ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot ctx#gno t#gno) + (** + Take conjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. + *) + let mk_redand ( ctx : context ) ( t : bitvec_expr) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand ctx#gno t#gno) + + (** + Take disjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. + *) + let mk_redor ( ctx : context ) ( t : bitvec_expr) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor ctx#gno t#gno) + + (** + Bitwise conjunction. + The arguments must have a bit-vector sort. + *) + let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand ctx#gno t1#gno t2#gno) + + (** + Bitwise disjunction. + The arguments must have a bit-vector sort. + *) + let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor ctx#gno t1#gno t2#gno) + + (** + Bitwise XOR. + The arguments must have a bit-vector sort. + *) + let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor ctx#gno t1#gno t2#gno) + + (** + Bitwise NAND. + The arguments must have a bit-vector sort. + *) + let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand ctx#gno t1#gno t2#gno) + + (** + Bitwise NOR. + The arguments must have a bit-vector sort. + *) + let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor ctx#gno t1#gno t2#gno) + + (** + Bitwise XNOR. + The arguments must have a bit-vector sort. + *) + let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor ctx#gno t1#gno t2#gno) + + (** + Standard two's complement unary minus. + The arguments must have a bit-vector sort. + *) + let mk_neg ( ctx : context ) ( t : bitvec_expr) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg ctx#gno t#gno) + + (** + Two's complement addition. + The arguments must have the same bit-vector sort. + *) + let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd ctx#gno t1#gno t2#gno) + + (** + Two's complement subtraction. + The arguments must have the same bit-vector sort. + *) + let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub ctx#gno t1#gno t2#gno) + + (** + Two's complement multiplication. + The arguments must have the same bit-vector sort. + *) + let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul ctx#gno t1#gno t2#gno) + + (** + Unsigned division. + + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv ctx#gno t1#gno t2#gno) + + (** + Signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv ctx#gno t1#gno t2#gno) + + (** + Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem ctx#gno t1#gno t2#gno) + + (** + Signed remainder. + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem ctx#gno t1#gno t2#gno) + + (** + Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. + *) + let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod ctx#gno t1#gno t2#gno) + + (** + Unsigned less-than + + The arguments must have the same bit-vector sort. + *) + let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult ctx#gno t1#gno t2#gno) + + (** + Two's complement signed less-than + + The arguments must have the same bit-vector sort. + *) + let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt ctx#gno t1#gno t2#gno) + + (** + Unsigned less-than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule ctx#gno t1#gno t2#gno) + + (** + Two's complement signed less-than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle ctx#gno t1#gno t2#gno) + + (** + Unsigned greater than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge ctx#gno t1#gno t2#gno) + + (** + Two's complement signed greater than or equal to. + + The arguments must have the same bit-vector sort. + *) + let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge ctx#gno t1#gno t2#gno) + + (** + Unsigned greater-than. + + The arguments must have the same bit-vector sort. + *) + let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt ctx#gno t1#gno t2#gno) + + (** + Two's complement signed greater-than. + + The arguments must have the same bit-vector sort. + *) + let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt ctx#gno t1#gno t2#gno) + + (** + Bit-vector concatenation. + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). + *) + let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat ctx#gno t1#gno t2#gno) + + (** + Bit-vector extraction. + + Extract the bits down to from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. + The argument must have a bit-vector sort. + *) + let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract ctx#gno high low t#gno) + + (** + Bit-vector sign extension. + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. + The argument must have a bit-vector sort. + *) + let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext ctx#gno i t#gno) + + (** + Bit-vector zero extension. + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. + The argument must have a bit-vector sort. + *) + let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext ctx#gno i t#gno) + + (** + Bit-vector repetition. + + The argument must have a bit-vector sort. + *) + let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat ctx#gno i t#gno) + + (** + Shift left. + + + It is equivalent to multiplication by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + *) + let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl ctx#gno t1#gno t2#gno) + + (** + Logical shift right + + It is equivalent to unsigned division by 2^x where \c x is the value of . + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + *) + let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr ctx#gno t1#gno t2#gno) + + (** + Arithmetic shift right + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. + *) + let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr ctx#gno t1#gno t2#gno) + + (** + Rotate Left. + + Rotate bits of \c t to the left \c i times. + The argument must have a bit-vector sort. + *) + let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left ctx#gno i t#gno) + + (** + Rotate Right. + + Rotate bits of \c t to the right \c i times. + The argument must have a bit-vector sort. + *) + let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right ctx#gno i t#gno) + + (** + Rotate Left. + + Rotate bits of to the left times. + The arguments must have the same bit-vector sort. + *) + let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left ctx#gno t1#gno t2#gno) + + (** + Rotate Right. + + + Rotate bits of to the right times. + The arguments must have the same bit-vector sort. + *) + let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right ctx#gno t1#gno t2#gno) + + (** + Create an bit bit-vector from the integer argument . + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. + *) + let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv ctx#gno n t#gno) + + (** + Create an integer from the bit-vector argument . + + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in . + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of bit-vector sort. + *) + let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = + (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise addition does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise addition does not underflow. + + The arguments must be of bit-vector sort. + *) + let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow ctx#gno t1#gno t2#gno) + + (** + Create a predicate that checks that the bit-wise subtraction does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow ctx#gno t1#gno t2#gno) + + (** + Create a predicate that checks that the bit-wise subtraction does not underflow. + + The arguments must be of bit-vector sort. + *) + let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise signed division does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow ctx#gno t1#gno t2#gno) + + (** + Create a predicate that checks that the bit-wise negation does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow ctx#gno t#gno) + + (** + Create a predicate that checks that the bit-wise multiplication does not overflow. + + The arguments must be of bit-vector sort. + *) + let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + + (** + Create a predicate that checks that the bit-wise multiplication does not underflow. + + The arguments must be of bit-vector sort. + *) + let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow ctx#gno t1#gno t2#gno) + +end + +(** Functions to manipulate Proof objects *) +module Proofs = +struct (** Indicates whether the term is a Proof for the expression 'true'. *) - let is_proof_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRUE) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) (** Indicates whether the term is a proof for a fact asserted by the user. *) - let is_proof_asserted ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ASSERTED) + let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - let is_proof_goal ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_GOAL) + let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) (** Indicates whether the term is proof via modus ponens @@ -2049,18 +3414,18 @@ struct T1: p T2: (implies p q) [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). + The second antecedents may also be a proof for (iff p q). *) - let is_proof_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS) + let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. This proof object has no antecedents. The only reflexive relations that are used are equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. + That is, R is either '~', '=' or 'iff'. *) - let is_proof_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REFLEXIVITY) + let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) (** Indicates whether the term is proof by symmetricity of a relation @@ -2069,9 +3434,8 @@ struct T1: (R t s) [symmetry T1]: (R s t) T1 is the antecedent of this proof object. - *) - let is_proof_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SYMMETRY) + let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) (** Indicates whether the term is a proof by transitivity of a relation @@ -2081,9 +3445,8 @@ struct T1: (R t s) T2: (R s u) [trans T1 T2]: (R t u) - *) - let is_proof_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY) + let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) (** Indicates whether the term is a proof by condensed transitivity of a relation @@ -2102,9 +3465,8 @@ struct using the antecedents, symmetry and transitivity. That is, if there is a path from s to t, if we view every antecedent (R a b) as an edge between a and b. - *) - let is_proof_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) (** @@ -2116,9 +3478,8 @@ struct [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) Remark: if t_i == s_i, then the antecedent Ti is suppressed. That is, reflexivity proofs are supressed to save space. - *) - let is_proof_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MONOTONICITY) + let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) (** Indicates whether the term is a quant-intro proof @@ -2126,9 +3487,8 @@ struct Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). T1: (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - *) - let is_proof_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INTRO) + let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) (** Indicates whether the term is a distributivity proof object. @@ -2144,9 +3504,8 @@ struct This proof object has no antecedents. Remark. This rule is used by the CNF conversion pass and instantiated by f = or, and g = and. - *) - let is_proof_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) (** Indicates whether the term is a proof by elimination of AND @@ -2154,9 +3513,8 @@ struct Given a proof for (and l_1 ... l_n), produces a proof for l_i T1: (and l_1 ... l_n) [and-elim T1]: l_i - *) - let is_proof_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_AND_ELIM) + let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) (** Indicates whether the term is a proof by eliminiation of not-or @@ -2164,9 +3522,8 @@ struct Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) - *) - let is_proof_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) (** Indicates whether the term is a proof by rewriting @@ -2183,9 +3540,8 @@ struct (= (+ ( x : expr ) 0) x) (= (+ ( x : expr ) 1 2) (+ 3 x)) (iff (or ( x : expr ) false) x) - *) - let is_proof_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE) + let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) (** Indicates whether the term is a proof by rewriting @@ -2199,17 +3555,15 @@ struct - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - When converting bit-vectors to Booleans (BIT2BOOL=true) - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - *) - let is_proof_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_REWRITE_STAR) + let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) (** Indicates whether the term is a proof for pulling quantifiers out. A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - *) - let is_proof_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) (** Indicates whether the term is a proof for pulling quantifiers out. @@ -2217,9 +3571,8 @@ struct A proof for (iff P Q) where Q is in prenex normal form. This proof object is only used if the parameter PROOF_MODE is 1. This proof object has no antecedents - *) - let is_proof_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) (** Indicates whether the term is a proof for pushing quantifiers in. @@ -2230,9 +3583,9 @@ struct ... (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) This proof object has no antecedents - *) - let is_proof_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_PUSH_QUANT) + + let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) (** Indicates whether the term is a proof for elimination of unused variables. @@ -2242,9 +3595,9 @@ struct It is used to justify the elimination of unused variables. This proof object has no antecedents. - *) - let is_proof_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + + let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) (** Indicates whether the term is a proof for destructive equality resolution @@ -2256,23 +3609,22 @@ struct This proof object has no antecedents. Several variables can be eliminated simultaneously. - *) - let is_proof_der ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DER) + + let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) (** Indicates whether the term is a proof for quantifier instantiation A proof of (or (not (forall (x) (P x))) (P a)) - *) - let is_proof_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_QUANT_INST) + let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. + Mark a hypothesis in a natural deduction style proof. *) - let is_proof_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_HYPOTHESIS) + let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) (** Indicates whether the term is a proof by lemma @@ -2283,9 +3635,8 @@ struct This proof object has one antecedent: a hypothetical proof for false. It converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 contains the hypotheses: l_1, ..., l_n. - *) - let is_proof_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_LEMMA) + let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) (** Indicates whether the term is a proof by unit resolution @@ -2295,27 +3646,24 @@ struct ... T(n+1): (not l_n) [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - *) - let is_proof_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) (** Indicates whether the term is a proof by iff-true T1: p [iff-true T1]: (iff p true) - *) - let is_proof_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) (** Indicates whether the term is a proof by iff-false T1: (not p) [iff-false T1]: (iff p false) - *) - let is_proof_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_FALSE) + let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) (** Indicates whether the term is a proof by commutativity @@ -2326,9 +3674,8 @@ struct This proof object has no antecedents. Remark: if f is bool, then = is iff. - *) - let is_proof_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) (** Indicates whether the term is a proof for Tseitin-like axioms @@ -2362,9 +3709,8 @@ struct You can recover the propositional tautologies by unfolding the Boolean connectives in the axioms a small bounded number of steps (=3). - *) - let is_proof_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) (** Indicates whether the term is a proof for introduction of a name @@ -2385,9 +3731,8 @@ struct Otherwise: [def-intro]: (= n e) - *) - let is_proof_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_DEF_INTRO) + let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) (** Indicates whether the term is a proof for application of a definition @@ -2395,18 +3740,16 @@ struct [apply-def T1]: F ~ n F is 'equivalent' to n, given that T1 is a proof that n is a name for F. - *) - let is_proof_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_APPLY_DEF) + let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) (** Indicates whether the term is a proof iff-oeq T1: (iff p q) [iff~ T1]: (~ p q) - *) - let is_proof_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_IFF_OEQ) + let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) (** Indicates whether the term is a proof for a positive NNF step @@ -2432,9 +3775,8 @@ struct for NNF_POS are 'implies', 'iff', 'xor', 'ite'. NNF_NEG furthermore handles the case where negation is pushed over Boolean connectives 'and' and 'or'. - *) - let is_proof_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) (** Indicates whether the term is a proof for a negative NNF step @@ -2457,9 +3799,8 @@ struct T4: s_2 ~ r_2' [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 r_2) (or r_1' r_2'))) - *) - let is_proof_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. @@ -2469,9 +3810,8 @@ struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) - let is_proof_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_NNF_STAR) + let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. @@ -2479,9 +3819,8 @@ struct A proof for (~ P Q) where Q is in conjunctive normal form. This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) - let is_proof_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_CNF_STAR) + let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) (** Indicates whether the term is a proof for a Skolemization step @@ -2492,9 +3831,8 @@ struct [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) This proof object has no antecedents. - *) - let is_proof_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_SKOLEMIZE) + let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. @@ -2503,9 +3841,8 @@ struct T1: p T2: (~ p q) [mp~ T1 T2]: q - *) - let is_proof_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) (** Indicates whether the term is a proof for theory lemma @@ -2520,259 +3857,74 @@ struct - farkas - followed by rational coefficients. Multiply the coefficients to the inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - *) - let is_proof_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_PR_TH_LEMMA) - - (** - Indicates whether the term is of a relation sort. - *) - let is_Relation ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) - - (** - Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. - - *) - let is_relation_store ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_STORE) - - (** - Indicates whether the term is an empty relation - *) - let is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_EMPTY) - - (** - Indicates whether the term is a test for the emptiness of a relation - *) - let is_is_empty_relation ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_IS_EMPTY) - - (** - Indicates whether the term is a relational join - *) - let is_relational_join ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_JOIN) - - (** - Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. - *) - let is_relation_union ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_UNION) - - (** - Indicates whether the term is the widening of two relations - The function takes two arguments. - *) - let is_relation_widen ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_WIDEN) - - (** - Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. - *) - let is_relation_project ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_PROJECT) - - (** - Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. - - *) - let is_relation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_FILTER) - - (** - Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. - - *) - let is_relation_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_NEGATION_FILTER) - - (** - Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. - - *) - let is_relation_rename ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_RENAME) - - (** - Indicates whether the term is the complement of a relation - *) - let is_relation_complement ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_COMPLEMENT) - - (** - Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. - - *) - let is_relation_select ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_SELECT) - - (** - Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind - to perform destructive updates to the first argument. - - *) - let is_relation_clone ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_RA_CLONE) - - (** - Indicates whether the term is of an array sort. - *) - let is_finite_domain ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) - - (** - Indicates whether the term is a less than predicate over a finite domain. - *) - let is_finite_domain_lt ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FD_LT) - - (** - The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. - - *) - let get_index ( x : expr ) = - if not (AST.is_var x) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value x#gnc x#gno + let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end -(** Integer Numerals *) -module IntNum = -struct - (** Retrieve the int value. *) - let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") +(** + Parameter sets (of Solvers, Tactics, ...) - (** Returns a string representation of the numeral. *) - let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno -end - -(** Rational Numerals *) -module RatNum = -struct - - (** The numerator of a rational numeral. *) - let get_numerator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) - - (** The denominator of a rational numeral. *) - let get_denominator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) - - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : rat_num ) (precision : int) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision - - (** Returns a string representation of the numeral. *) - let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno -end - -(** Bit-vector numerals *) -module BitVecNum = -struct - (** Retrieve the int value. *) - let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") - - (** Returns a string representation of the numeral. *) - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno -end - -(** Algebraic numbers *) -module AlgebraicNum = + A Params objects represents a configuration in the form of symbol/value pairs. +*) +module Params = struct (** - Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real + Adds a parameter setting. *) - let to_upper ( x : algebraic_num ) ( precision : int ) = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) - - (** - Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) - let to_lower ( x : algebraic_num ) precision = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + let add_bool (p : params) (name : symbol) (value : bool) = + Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision + (** + Adds a parameter setting. + *) + let add_int (p : params) (name : symbol) (value : int) = + Z3native.params_set_uint p#gnc p#gno name#gno value - (** Returns a string representation of the numeral. *) - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno + (** + Adds a parameter setting. + *) + let add_double (p : params) (name : symbol) (value : float) = + Z3native.params_set_double p#gnc p#gno name#gno value + + (** + Adds a parameter setting. + *) + let add_symbol (p : params) (name : symbol) (value : symbol) = + Z3native.params_set_symbol p#gnc p#gno name#gno value#gno + + (** + Adds a parameter setting. + *) + let add_s_bool (p : params) (name : string) (value : bool) = + add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_int (p : params) (name : string) (value : int) = + add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_double (p : params) (name : string) (value : float) = + add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + Adds a parameter setting. + *) + let add_s_symbol (p : params) (name : string) (value : symbol) = + add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + + (** + A string representation of the parameter set. + *) + let to_string (p : params) = Z3native.params_to_string p#gnc p#gno end -(** Constructors are used for datatype sorts *) -module Constructor = -struct - (** The number of fields of the constructor. *) - let get_num_fields ( x : constructor ) = x#get_n - - (** The function declaration of the constructor. *) - let get_constructor_decl ( x : constructor ) = x#constructor_decl - - (** The function declaration of the tester. *) - let get_tester_decl ( x : constructor ) = x#tester_decl - - (** The function declarations of the accessors *) - let get_accessor_decls ( x : constructor ) = x#accessor_decls -end - - -(** ParamDescrs describe sets of parameters.*) +(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) module ParamDescrs = struct @@ -2917,102 +4069,100 @@ struct | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) - (** Creates a solver that is implemented using the given tactic. + (** creates a solver that is implemented using the given tactic. *) let get_solver ( x : tactic ) = (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) end - -(** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. -*) -module FuncInterp = -struct - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) - module FuncEntry = - struct - (** - Return the (symbolic) value of this entry. - *) - let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) - - (** - The number of arguments of the entry. - *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno - - (** - The arguments of the function entry. - *) - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the function entry. - *) - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") - end - - (** - The number of entries in the function interpretation. - *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno - - (** - The entries in the function interpretation - *) - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in - Array.init n f - - (** - The (symbolic) `else' value of the function interpretation. - *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) - - (** - The arity of the function interpretation - *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno - - (** - A string representation of the function interpretation. - *) - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (Array.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") -end - -(** Models. +(** Models A Model contains interpretations (assignments) of constants and functions. *) module Model = struct - + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. + *) + module FuncInterp = + struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + (** Retrieves the interpretation (the assignment) of in the model. A function declaration of zero arity An expression if the function has an interpretation in the model, null otherwise. *) @@ -3093,7 +4243,7 @@ struct This function may fail if contains quantifiers, is partial (MODEL_PARTIAL enabled), or if is not well-sorted. In this case a ModelEvaluationFailedException is thrown. - + An expression When this flag is enabled, a model value will be assigned to any constant @@ -3120,7 +4270,6 @@ struct Z3 also provides an intepretation for uninterpreted sorts used in a formula. The interpretation for a sort is a finite set of distinct values. We say this finite set is the "universe" of the sort. - *) @@ -3137,8 +4286,8 @@ struct *) let sort_universe ( x : model ) ( s : sort ) = let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in - let n = (ASTVector.get_size n_univ) in - let f i = (ASTVector.get n_univ i) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in Array.init n f (** Conversion of models to strings. @@ -3174,84 +4323,85 @@ struct let to_string ( x : apply_result) = Z3native.apply_result_to_string x#gnc x#gno end -(** Objects that track statistical information about solvers. *) -module Statistics = -struct - - (** - Statistical data is organized into pairs of [Key, Entry], where every - Entry is either a DoubleEntry or a UIntEntry - *) - module Entry = - struct - (** The key of the entry. *) - let get_key (x : statistics_entry) = x#key - - (** The int-value of the entry. *) - let get_int (x : statistics_entry) = x#int - - (** The float-value of the entry. *) - let get_float (x : statistics_entry) = x#float - - (** True if the entry is uint-valued. *) - let is_int (x : statistics_entry) = x#is_int - - (** True if the entry is double-valued. *) - let is_float (x : statistics_entry) = x#is_float - - (** The string representation of the the entry's value. *) - let to_string_value (x : statistics_entry) = - if (is_int x) then - string_of_int (get_int x) - else if (is_float x) then - string_of_float (get_float x) - else - raise (Z3native.Exception "Unknown statistical entry type") - - (** The string representation of the entry (key and value) *) - let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) - end - - (** A string representation of the statistical data. *) - let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno - - (** The number of statistical data. *) - let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno - - (** The data entries. *) - let get_entries ( x : statistics ) = - let n = (get_size x ) in - let f i = ( - let k = Z3native.stats_get_key x#gnc x#gno i in - if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then - ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) - else - ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) - ) in - Array.init n f - - (** - The statistical counters. - *) - let get_keys ( x : statistics ) = - let n = (get_size x) in - let f i = (Z3native.stats_get_key x#gnc x#gno i) in - Array.init n f - - (** - The value of a particular statistical counter. - *) - let get ( x : statistics ) ( key : string ) = - let f p c = (if (Entry.get_key c) = key then (Some c) else p) in - Array.fold_left f None (get_entries x) - -end - (** Solvers *) module Solver = struct type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + (** Objects that track statistical information about solvers. *) + module Statistics = + struct + + (** + Statistical data is organized into pairs of [Key, Entry], where every + Entry is either a DoubleEntry or a UIntEntry + *) + module Entry = + struct + (** The key of the entry. *) + let get_key (x : statistics_entry) = x#key + + (** The int-value of the entry. *) + let get_int (x : statistics_entry) = x#int + + (** The float-value of the entry. *) + let get_float (x : statistics_entry) = x#float + + (** True if the entry is uint-valued. *) + let is_int (x : statistics_entry) = x#is_int + + (** True if the entry is double-valued. *) + let is_float (x : statistics_entry) = x#is_float + + (** The string representation of the the entry's value. *) + let to_string_value (x : statistics_entry) = + if (is_int x) then + string_of_int (get_int x) + else if (is_float x) then + string_of_float (get_float x) + else + raise (Z3native.Exception "Unknown statistical entry type") + + (** The string representation of the entry (key and value) *) + let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) + end + + (** A string representation of the statistical data. *) + let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno + + (** The number of statistical data. *) + let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno + + (** The data entries. *) + let get_entries ( x : statistics ) = + let n = (get_size x ) in + let f i = ( + let k = Z3native.stats_get_key x#gnc x#gno i in + if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then + ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) + else + ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) + ) in + Array.init n f + + (** + The statistical counters. + *) + let get_keys ( x : statistics ) = + let n = (get_size x) in + let f i = (Z3native.stats_get_key x#gnc x#gno i) in + Array.init n f + + (** + The value of a particular statistical counter. + *) + let get ( x : statistics ) ( key : string ) = + let f p c = (if (Entry.get_key c) = key then (Some c) else p) in + Array.fold_left f None (get_entries x) + + end + + (** A string that describes all available solver parameters. *) @@ -3284,14 +4434,14 @@ struct (** Backtracks backtracking points. - Note that an exception is thrown if is not smaller than NumScopes + Note that an exception is thrown if is not smaller than NumScopes *) let pop ( x : solver ) ( n : int ) = Z3native.solver_pop x#gnc x#gno n (** Resets the Solver. - This removes all assertions from the solver. + This removes all assertions from the solver. *) let reset ( x : solver ) = Z3native.solver_reset x#gnc x#gno @@ -3307,7 +4457,7 @@ struct *) let get_num_assertions ( x : solver ) = let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in - (ASTVector.get_size a) + (AST.ASTVector.get_size a) (** @@ -3315,8 +4465,8 @@ struct *) let get_assertions ( x : solver ) = let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in - let n = (ASTVector.get_size a) in - let f i = ((new bool_expr x#gc)#cnstr_obj (ASTVector.get a i)#gno) in + let n = (AST.ASTVector.get_size a) in + let f i = ((new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get a i)#gno) in Array.init n f (** @@ -3325,7 +4475,6 @@ struct - *) let check ( x : solver ) ( assumptions : bool_expr array option) = let r = @@ -3343,7 +4492,6 @@ struct The result is None if Check was not invoked before, if its results was not SATISFIABLE, or if model production is not enabled. - *) let get_model ( x : solver ) = let q = Z3native.solver_get_model x#gnc x#gno in @@ -3357,7 +4505,6 @@ struct The result is null if Check was not invoked before, if its results was not UNSATISFIABLE, or if proof production is disabled. - *) let get_proof ( x : solver ) = let q = Z3native.solver_get_proof x#gnc x#gno in @@ -3372,12 +4519,11 @@ struct The unsat core is a subset of Assertions The result is empty if Check was not invoked before, if its results was not UNSATISFIABLE, or if core production is disabled. - *) let get_unsat_core ( x : solver ) = let cn = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_unsat_core x#gnc x#gno) in - let n = (ASTVector.get_size cn) in - let f i = (ASTVector.get cn i) in + let n = (AST.ASTVector.get_size cn) in + let f i = (AST.ASTVector.get cn i) in Array.init n f (** @@ -3418,3312 +4564,936 @@ struct end -(** The main interaction with Z3 happens via the Context module *) -module Context = -struct +(* STUFF FROM THE CONTEXT *) - (* SYMBOLS *) - - (** - Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) - let mk_symbol_int ( ctx : context ) i = - (new int_symbol ctx)#cnstr_int i - - (** Creates a new symbol using a string. *) - let mk_symbol_string ( ctx : context ) s = - (new string_symbol ctx)#cnstr_string s - - (** - Create an array of symbols. - *) - let mk_symbols_int ( ctx : context ) names = - let f elem = mk_symbol_int ( ctx : context ) elem in - (Array.map f names) - - (** - Create an array of symbols. - *) - let mk_symbols_string ( ctx : context ) names = - let f elem = mk_symbol_string ( ctx : context ) elem in - (Array.map f names) - - - (* SORTS *) - - (** - Create a new Boolean sort. - *) - let mk_bool_sort ( ctx : context ) = - (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted_sort ( ctx : context ) (s : symbol) = - (new uninterpreted_sort ctx)#cnstr_s s - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted_sort_s ( ctx : context ) (s : string) = - mk_uninterpreted_sort ctx ((mk_symbol_string ( ctx : context ) s) :> symbol) - - (** - Create a new integer sort. - *) - let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) - - (** - Create a real sort. - *) - let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) - - (** - Create a new bit-vector sort. - *) - let mk_bitvec_sort ( ctx : context ) size = - (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) - - (** - Create a new array sort. - *) - let mk_array_sort ( ctx : context ) domain range = - (new array_sort ctx)#cnstr_dr domain range - - (** - Create a new tuple sort. - *) - let mk_tuple_sort ( ctx : context ) name field_names field_sorts = - (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts - - (** - Create a new enumeration sort. - *) - let mk_enum_sort ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss name enum_names - - (** - Create a new enumeration sort. - *) - let mk_enum_sort_s ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss - ((mk_symbol_string ( ctx : context ) name) :> symbol) - (let f e = (e :> symbol) in - (Array.map f (mk_symbols_string ( ctx : context ) enum_names)) - ) - - (** - Create a new list sort. - *) - let mk_list_sort ( ctx : context ) (name : symbol) elem_sort = - (new list_sort ctx)#cnstr_ss name elem_sort - - (** - Create a new list sort. - *) - let mk_list_sort_s ( ctx : context ) (name : string) elem_sort = - mk_list_sort ctx ((mk_symbol_string ctx name) :> symbol) elem_sort - - - (** - Create a new finite domain sort. - *) - let mk_finite_domain_sort ( ctx : context ) ( name : symbol ) size = - (new finite_domain_sort ctx)#cnstr_si name size - - (** - Create a new finite domain sort. - *) - let mk_finite_domain_sort_s ( ctx : context ) ( name : string ) size = - (new finite_domain_sort ctx)#cnstr_si ((mk_symbol_string ctx name) :> symbol) size - - (* DATATYPES *) - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs - - - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - mk_constructor ctx ((mk_symbol_string ctx name) :> symbol) recognizer field_names sorts sort_refs - - - (** - Create a new datatype sort. - *) - let mk_datatype_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = - (new datatype_sort ctx)#cnstr_sc name constructors - - (** - Create a new datatype sort. - *) - let mk_datatype_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = - mk_datatype_sort ctx ((mk_symbol_string ctx name) :> symbol) constructors - - (** - Create mutually recursive datatypes. - @param names names of datatype sorts - @param c list of constructors, one list per sort. - *) - let mk_datatype_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = - let n = (Array.length names) in - let f e = ( (new constructor_list ctx)#cnstr_ca e ) in - let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in - let g e = ( (new datatype_sort ctx)#cnstr_obj e) in - (Array.map g r) - - (** Create mutually recursive data-types. *) - let mk_datatype_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = - mk_datatype_sorts ctx - ( - let f e = ((mk_symbol_string ctx e) :> symbol) in - Array.map f names - ) - c - -(** - - -(* FUNCTION DECLARATIONS *) -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(Symbol name, Sort[] domain, Sort range) - { - - - - - - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); - return new Func_Decl(this, name, domain, range); - } - -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(Symbol name, Sort domain, Sort range) - { - - - - - - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); - Sort[] q = new Sort[] { domain }; - return new Func_Decl(this, name, q, range); - } - -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(string name, Sort[] domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new Func_Decl(this, MkSymbol(name), domain, range); - } - -(** - Creates a new function declaration. -*) - public Func_Decl MkFunc_Decl(string name, Sort domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - Sort[] q = new Sort[] { domain }; - return new Func_Decl(this, MkSymbol(name), q, range); - } - -(** - Creates a fresh function declaration with a name prefixed with . -*) - - - let mk_Fresh_Func_Decl(string prefix, Sort[] domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new Func_Decl(this, prefix, domain, range); - } - -(** - Creates a new constant function declaration. -*) - let mk_Const_Decl(Symbol name, Sort range) - { - - - - - CheckContextMatch(name); - CheckContextMatch(range); - return new Func_Decl(this, name, null, range); - } - -(** - Creates a new constant function declaration. -*) - let mk_Const_Decl(string name, Sort range) - { - - - - CheckContextMatch(range); - return new Func_Decl(this, MkSymbol(name), null, range); - } - -(** - Creates a fresh constant function declaration with a name prefixed with . -*) - - - let mk_Fresh_ConstDecl(string prefix, Sort range) - { - - - - CheckContextMatch(range); - return new Func_Decl(this, prefix, null, range); - } - - -(* BOUND VARIABLES *) -(** - Creates a new bound variable. -*) - @param index The de-Bruijn index of the variable - @param ty The sort of the variable - public Expr MkBound(uint index, Sort ty) - { - - - - return Expr.Create(this, Z3native.mk_bound(nCtx, index, ty.x#gno)); - } - - -(* QUANTIFIER PATTERNS *) -(** - Create a quantifier pattern. -*) - public Pattern MkPattern(params Expr[] terms) - { - - if (terms.Length == 0) - throw new Z3Exception("Cannot create a pattern from zero terms"); - - - - - - IntPtr[] termsNative = AST.ArrayToNative(terms); - return new Pattern(this, Z3native.mk_pattern(nCtx, (uint)terms.Length, termsNative)); - } - - -(* CONSTANTS *) -(** - Creates a new Constant of sort and named . -*) - public Expr MkConst(Symbol name, Sort range) - { - - - - - CheckContextMatch(name); - CheckContextMatch(range); - - return Expr.Create(this, Z3native.mk_const(nCtx, name.x#gno, range.x#gno)); - } - -(** - Creates a new Constant of sort and named . -*) - public Expr MkConst(string name, Sort range) - { - - - - return MkConst(MkSymbol(name), range); - } - -(** - Creates a fresh Constant of sort and a - name prefixed with . -*) - let mk_Fresh_Const(string prefix, Sort range) - { - - - - CheckContextMatch(range); - return Expr.Create(this, Z3native.mk_fresh_const(nCtx, prefix, range.x#gno)); - } - -(** - Creates a fresh constant from the Func_Decl . -*) - @param f A decl of a 0-arity function - public Expr MkConst(Func_Decl f) - { - - - - return MkApp(f); - } - -(** - Create a Boolean constant. -*) - let mk_Bool_Const(Symbol name) - { - - - - return (BoolExpr)MkConst(name, BoolSort); - } - -(** - Create a Boolean constant. -*) - let mk_Bool_Const(string name) - { - - - return (BoolExpr)MkConst(MkSymbol(name), BoolSort); - } - -(** - Creates an integer constant. -*) - let mk_Int_Const(Symbol name) - { - - - - return (IntExpr)MkConst(name, IntSort); - } - -(** - Creates an integer constant. -*) - let mk_Int_Const(string name) - { - - - - return (IntExpr)MkConst(name, IntSort); - } - -(** - Creates a real constant. -*) - let mk_Real_Const(Symbol name) - { - - - - return (RealExpr)MkConst(name, RealSort); - } - -(** - Creates a real constant. -*) - let mk_Real_Const(string name) - { - - - return (RealExpr)MkConst(name, RealSort); - } - -(** - Creates a bit-vector constant. -*) - let mk_B_VConst(Symbol name, uint size) - { - - - - return (BitVecExpr)MkConst(name, MkBitVecSort(size)); - } - -(** - Creates a bit-vector constant. -*) - let mk_B_VConst(string name, uint size) - { - - - return (BitVecExpr)MkConst(name, MkBitVecSort(size)); - } - - -(* TERMS *) -(** - Create a new function application. -*) - public Expr MkApp(Func_Decl f, params Expr[] args) - { - - - - - CheckContextMatch(f); - CheckContextMatch(args); - return Expr.Create(this, f, args); - } - -(* PROPOSITIONAL *) -(** - The true Term. -*) - public BoolExpr MkTrue ( ctx : context ) = - { - - - return new BoolExpr(this, Z3native.mk_true(nCtx)); - } - -(** - The false Term. -*) - public BoolExpr MkFalse ( ctx : context ) = - { - - - return new BoolExpr(this, Z3native.mk_false(nCtx)); - } - -(** - Creates a Boolean value. -*) - public BoolExpr MkBool(bool value) - { - - - return value ? MkTrue ( ctx : context ) = : MkFalse ( ctx : context ) =; - } - -(** - Creates the equality = . -*) - public BoolExpr MkEq(Expr x, Expr y) - { - - - - - CheckContextMatch(x); - CheckContextMatch(y); - return new BoolExpr(this, Z3native.mk_eq(nCtx, x.x#gno, y.x#gno)); - } - -(** - Creates a distinct term. -*) - public BoolExpr MkDistinct(params Expr[] args) - { - - - - - - CheckContextMatch(args); - return new BoolExpr(this, Z3native.mk_distinct(nCtx, (uint)args.Length, AST.ArrayToNative(args))); - } - -(** - Mk an expression representing not(a). -*) - public BoolExpr MkNot(BoolExpr a) - { - - - - CheckContextMatch(a); - return new BoolExpr(this, Z3native.mk_not(nCtx, a.x#gno)); - } - -(** - Create an expression representing an if-then-else: ite(t1, t2, t3). -*) - @param t1 An expression with Boolean sort - @param t2 An expression - @param t3 An expression with the same sort as - let mk_I_TE(BoolExpr t1, Expr t2, Expr t3) - { - - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(t3); - return Expr.Create(this, Z3native.mk_ite(nCtx, t1.x#gno, t2.x#gno, t3.x#gno)); - } - -(** - Create an expression representing t1 iff t2. -*) - public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_iff(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 -> t2. -*) - public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_implies(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 xor t2. -*) - public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_xor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t[0] and t[1] and .... -*) - public BoolExpr MkAnd(params BoolExpr[] t) - { - - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_and(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing t[0] or t[1] or .... -*) - public BoolExpr MkOr(params BoolExpr[] t) - { - - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_or(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - - -(* ARITHMETIC *) -(** - Create an expression representing t[0] + t[1] + .... -*) - public ArithExpr MkAdd(params ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_add(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing t[0] * t[1] * .... -*) - public ArithExpr MkMul(params ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_mul(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing t[0] - t[1] - .... -*) - public ArithExpr MkSub(params ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_sub(nCtx, (uint)t.Length, AST.ArrayToNative(t))); - } - -(** - Create an expression representing -t. -*) - let mk_Unary_Minus(ArithExpr t) - { - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Z3native.mk_unary_minus(nCtx, t.x#gno)); - } - -(** - Create an expression representing t1 / t2. -*) - public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr)Expr.Create(this, Z3native.mk_div(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 mod t2. -*) - The arguments must have int type. - public IntExpr MkMod(IntExpr t1, IntExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Z3native.mk_mod(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 rem t2. -*) - The arguments must have int type. - public IntExpr MkRem(IntExpr t1, IntExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Z3native.mk_rem(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 ^ t2. -*) - public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr)Expr.Create(this, Z3native.mk_power(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 < t2 -*) - public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_lt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 <= t2 -*) - public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_le(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 > t2 -*) - public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_gt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an expression representing t1 >= t2 -*) - public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_ge(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Coerce an integer to a real. -*) - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. - - public RealExpr MkInt2Real(IntExpr t) - { - - - - CheckContextMatch(t); - return new RealExpr(this, Z3native.mk_int2real(nCtx, t.x#gno)); - } - -(** - Coerce a real to an integer. -*) - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. - - public IntExpr MkReal2Int(RealExpr t) - { - - - - CheckContextMatch(t); - return new IntExpr(this, Z3native.mk_real2int(nCtx, t.x#gno)); - } - -(** - Creates an expression that checks whether a real number is an integer. -*) - let mk_Is_Integer(RealExpr t) - { - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_is_int(nCtx, t.x#gno)); - } - - -(* BIT-VECTORS *) -(** - Bitwise negation. -*) - The argument must have a bit-vector sort. - let mk_B_VNot(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvnot(nCtx, t.x#gno)); - } - -(** - Take conjunction of bits in a vector, return vector of length 1. -*) - The argument must have a bit-vector sort. - let mk_B_VRedAND(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvredand(nCtx, t.x#gno)); - } - -(** - Take disjunction of bits in a vector, return vector of length 1. -*) - The argument must have a bit-vector sort. - let mk_B_VRedOR(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvredor(nCtx, t.x#gno)); - } - -(** - Bitwise conjunction. -*) - The arguments must have a bit-vector sort. - let mk_B_VAND(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvand(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise disjunction. -*) - The arguments must have a bit-vector sort. - let mk_B_VOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise XOR. -*) - The arguments must have a bit-vector sort. - let mk_B_VXOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvxor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise NAND. -*) - The arguments must have a bit-vector sort. - let mk_B_VNAND(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvnand(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise NOR. -*) - The arguments must have a bit-vector sort. - let mk_B_VNOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvnor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bitwise XNOR. -*) - The arguments must have a bit-vector sort. - let mk_B_VXNOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvxnor(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Standard two's complement unary minus. -*) - The arguments must have a bit-vector sort. - let mk_B_VNeg(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_bvneg(nCtx, t.x#gno)); - } - -(** - Two's complement addition. -*) - The arguments must have the same bit-vector sort. - let mk_B_VAdd(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvadd(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement subtraction. -*) - The arguments must have the same bit-vector sort. - let mk_B_VSub(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsub(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement multiplication. -*) - The arguments must have the same bit-vector sort. - let mk_B_VMul(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvmul(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned division. -*) - - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VUDiv(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvudiv(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Signed division. -*) - - It is defined in the following way: - - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VSDiv(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsdiv(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned remainder. -*) - - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VURem(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvurem(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Signed remainder. -*) - - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VSRem(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsrem(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed remainder (sign follows divisor). -*) - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - - let mk_B_VSMod(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvsmod(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned less-than -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VULT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvult(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed less-than -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSLT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvslt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned less-than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VULE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvule(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed less-than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSLE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsle(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned greater than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VUGE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvuge(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed greater than or equal to. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSGE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsge(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Unsigned greater-than. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VUGT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvugt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Two's complement signed greater-than. -*) - - The arguments must have the same bit-vector sort. - - let mk_B_VSGT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsgt(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bit-vector concatenation. -*) - - The arguments must have a bit-vector sort. - - @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). - - public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_concat(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Bit-vector extraction. -*) - - Extract the bits down to from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. - The argument must have a bit-vector sort. - - public BitVecExpr MkExtract(uint high, uint low, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_extract(nCtx, high, low, t.x#gno)); - } - -(** - Bit-vector sign extension. -*) - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. - The argument must have a bit-vector sort. - - let mk_Sign_Ext(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_sign_ext(nCtx, i, t.x#gno)); - } - -(** - Bit-vector zero extension. -*) - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the - given bit-vector. - The argument must have a bit-vector sort. - - let mk_Zero_Ext(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_zero_ext(nCtx, i, t.x#gno)); - } - -(** - Bit-vector repetition. -*) - - The argument must have a bit-vector sort. - - public BitVecExpr MkRepeat(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_repeat(nCtx, i, t.x#gno)); - } - -(** - Shift left. -*) - - It is equivalent to multiplication by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - - let mk_B_VSHL(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvshl(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Logical shift right -*) - - It is equivalent to unsigned division by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - - let mk_B_VLSHR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvlshr(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Arithmetic shift right -*) - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - - let mk_B_VASHR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_bvashr(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Rotate Left. -*) - - Rotate bits of \c t to the left \c i times. - The argument must have a bit-vector sort. - - let mk_B_VRotateLeft(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_rotate_left(nCtx, i, t.x#gno)); - } - -(** - Rotate Right. -*) - - Rotate bits of \c t to the right \c i times. - The argument must have a bit-vector sort. - - let mk_B_VRotateRight(uint i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_rotate_right(nCtx, i, t.x#gno)); - } - -(** - Rotate Left. -*) - - Rotate bits of to the left times. - The arguments must have the same bit-vector sort. - - let mk_B_VRotateLeft(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_ext_rotate_left(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Rotate Right. -*) - - Rotate bits of to the right times. - The arguments must have the same bit-vector sort. - - let mk_B_VRotateRight(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Z3native.mk_ext_rotate_right(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create an bit bit-vector from the integer argument . -*) - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. - - public BitVecExpr MkInt2BV(uint n, IntExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Z3native.mk_int2bv(nCtx, n, t.x#gno)); - } - -(** - Create an integer from the bit-vector argument . -*) - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where - N are the number of bits in . - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of bit-vector sort. - - let mk_B_V2Int(BitVecExpr t, bool signed) - { - - - - CheckContextMatch(t); - return new IntExpr(this, Z3native.mk_bv2int(nCtx, t.x#gno, (signed) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise addition does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VAddNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvadd_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise addition does not underflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvadd_no_underflow(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise subtraction does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VSubNoOverflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsub_no_overflow(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise subtraction does not underflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsub_no_underflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise signed division does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvsdiv_no_overflow(nCtx, t1.x#gno, t2.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise negation does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VNegNoOverflow(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BoolExpr(this, Z3native.mk_bvneg_no_overflow(nCtx, t.x#gno)); - } - -(** - Create a predicate that checks that the bit-wise multiplication does not overflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VMulNoOverflow(BitVecExpr t1, BitVecExpr t2, bool isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvmul_no_overflow(nCtx, t1.x#gno, t2.x#gno, (isSigned) ? 1 : 0)); - } - -(** - Create a predicate that checks that the bit-wise multiplication does not underflow. -*) - - The arguments must be of bit-vector sort. - - let mk_B_VMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Z3native.mk_bvmul_no_underflow(nCtx, t1.x#gno, t2.x#gno)); - } - - -(* ARRAYS *) -(** - Create an array constant. -*) - let mk_Array_Const(Symbol name, Sort domain, Sort range) - { - - - - - - return (ArrayExpr)MkConst(name, MkArraySort(domain, range)); - } - -(** - Create an array constant. -*) - let mk_Array_Const(string name, Sort domain, Sort range) - { - - - - - return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); - } - -(** - Array read. -*) - - The argument a is the array and i is the index - of the array that gets read. - - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. - - - - public Expr MkSelect(ArrayExpr a, Expr i) - { - - - - - CheckContextMatch(a); - CheckContextMatch(i); - return Expr.Create(this, Z3native.mk_select(nCtx, a.x#gno, i.x#gno)); - } - -(** - Array update. -*) - - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). - - - - public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) - { - - - - - - CheckContextMatch(a); - CheckContextMatch(i); - CheckContextMatch(v); - return new ArrayExpr(this, Z3native.mk_store(nCtx, a.x#gno, i.x#gno, v.x#gno)); - } - -(** - Create a constant array. -*) - - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. - - - - let mk_Const_Array(Sort domain, Expr v) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(v); - return new ArrayExpr(this, Z3native.mk_const_array(nCtx, domain.x#gno, v.x#gno)); - } - -(** - Maps f on the argument arrays. -*) - - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. - - - - - public ArrayExpr MkMap(Func_Decl f, params ArrayExpr[] args) - { - - - - - CheckContextMatch(f); - CheckContextMatch(args); - return (ArrayExpr)Expr.Create(this, Z3native.mk_map(nCtx, f.x#gno, AST.ArrayLength(args), AST.ArrayToNative(args))); - } - -(** - Access the array default value. -*) - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. - - let mk_Term_Array(ArrayExpr array) - { - - - - CheckContextMatch(array); - return Expr.Create(this, Z3native.mk_array_default(nCtx, array.x#gno)); - } - - -(* SETS *) -(** - Create a set type. -*) - let mk_Set_Sort(Sort ty) - { - - - - CheckContextMatch(ty); - return new SetSort(this, ty); - } - -(** - Create an empty set. -*) - let mk_Empty_Set(Sort domain) - { - - - - CheckContextMatch(domain); - return Expr.Create(this, Z3native.mk_empty_set(nCtx, domain.x#gno)); - } - -(** - Create the full set. -*) - let mk_Full_Set(Sort domain) - { - - - - CheckContextMatch(domain); - return Expr.Create(this, Z3native.mk_full_set(nCtx, domain.x#gno)); - } - -(** - Add an element to the set. -*) - let mk_Set_Add(Expr set, Expr element) - { - - - - - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create(this, Z3native.mk_set_add(nCtx, set.x#gno, element.x#gno)); - } - - -(** - Remove an element from a set. -*) - let mk_Set_Del(Expr set, Expr element) - { - - - - - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create(this, Z3native.mk_set_del(nCtx, set.x#gno, element.x#gno)); - } - -(** - Take the union of a list of sets. -*) - let mk_Set_Union(params Expr[] args) - { - - - - CheckContextMatch(args); - return Expr.Create(this, Z3native.mk_set_union(nCtx, (uint)args.Length, AST.ArrayToNative(args))); - } - -(** - Take the intersection of a list of sets. -*) - let mk_Set_Intersection(params Expr[] args) - { - - - - - CheckContextMatch(args); - return Expr.Create(this, Z3native.mk_set_intersect(nCtx, (uint)args.Length, AST.ArrayToNative(args))); - } - -(** - Take the difference between two sets. -*) - let mk_Set_Difference(Expr arg1, Expr arg2) - { - - - - - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create(this, Z3native.mk_set_difference(nCtx, arg1.x#gno, arg2.x#gno)); - } - -(** - Take the complement of a set. -*) - let mk_Set_Complement(Expr arg) - { - - - - CheckContextMatch(arg); - return Expr.Create(this, Z3native.mk_set_complement(nCtx, arg.x#gno)); - } - -(** - Check for set membership. -*) - let mk_Set_Membership(Expr elem, Expr set) - { - - - - - CheckContextMatch(elem); - CheckContextMatch(set); - return Expr.Create(this, Z3native.mk_set_member(nCtx, elem.x#gno, set.x#gno)); - } - -(** - Check for subsetness of sets. -*) - let mk_Set_Subset(Expr arg1, Expr arg2) - { - - - - - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create(this, Z3native.mk_set_subset(nCtx, arg1.x#gno, arg2.x#gno)); - } - +(** (* NUMERALS *) (* GENERAL NUMERALS *) (** - Create a Term of a given sort. + Create a Term of a given sort. *) - @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - @return A Term with value and sort - public Expr MkNumeral(string v, Sort ty) - { + @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + @return A Term with value and sort + public Expr MkNumeral(string v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_numeral(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_numeral ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(int v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(int v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_int(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_int ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(uint v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(uint v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_unsigned_int(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_unsigned_int ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(long v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(long v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_int64(nCtx, v, ty.x#gno)); - } + create_expr ctx (Z3native.mk_int64 ctx#gno v, ty#gno) (** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. *) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(ulong v, Sort ty) - { + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + public Expr MkNumeral(ulong v, Sort ty) - - - CheckContextMatch(ty); - return Expr.Create(this, Z3native.mk_unsigned_int64(nCtx, v, ty.x#gno)); - } - + create_expr ctx (Z3native.mk_unsigned_int64 ctx#gno v, ty#gno) (* REALS *) (** - Create a real from a fraction. + Create a real from a fraction. *) - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - public RatNum MkReal(int num, int den) - { - if (den == 0) - throw new Z3Exception("Denominator is zero"); + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + public RatNum MkReal(int num, int den) + if (den == 0) + throw new Z3Exception("Denominator is zero"); - - - return new RatNum(this, Z3native.mk_real(nCtx, num, den)); - } + new RatNum(this, Z3native.mk_real ctx#gno num, den) (** - Create a real numeral. + Create a real numeral. *) - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - public RatNum MkReal(string v) - { + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + public RatNum MkReal(string v) - - return new RatNum(this, Z3native.mk_numeral(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_numeral ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(int v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(int v) - - return new RatNum(this, Z3native.mk_int(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_int ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(uint v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(uint v) - - return new RatNum(this, Z3native.mk_unsigned_int(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_unsigned_int ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(long v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(long v) - - return new RatNum(this, Z3native.mk_int64(nCtx, v, RealSort.x#gno)); - } + new RatNum(this, Z3native.mk_int64 ctx#gno v, RealSort#gno) (** - Create a real numeral. + Create a real numeral. *) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(ulong v) - { + @param v value of the numeral. + @return A Term with value and sort Real + public RatNum MkReal(ulong v) - - return new RatNum(this, Z3native.mk_unsigned_int64(nCtx, v, RealSort.x#gno)); - } - + new RatNum(this, Z3native.mk_unsigned_int64 ctx#gno v, RealSort#gno) (* INTEGERS *) (** - Create an integer numeral. + Create an integer numeral. *) - @param v A string representing the Term value in decimal notation. - public IntNum MkInt(string v) - { + @param v A string representing the Term value in decimal notation. + public IntNum MkInt(string v) - - return new IntNum(this, Z3native.mk_numeral(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_numeral ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(int v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(int v) - - return new IntNum(this, Z3native.mk_int(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_int ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(uint v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(uint v) - - return new IntNum(this, Z3native.mk_unsigned_int(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_unsigned_int ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(long v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(long v) - - return new IntNum(this, Z3native.mk_int64(nCtx, v, IntSort.x#gno)); - } + new IntNum(this, Z3native.mk_int64 ctx#gno v, IntSort#gno) (** - Create an integer numeral. + Create an integer numeral. *) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(ulong v) - { + @param v value of the numeral. + @return A Term with value and sort Integer + public IntNum MkInt(ulong v) - - return new IntNum(this, Z3native.mk_unsigned_int64(nCtx, v, IntSort.x#gno)); - } - + new IntNum(this, Z3native.mk_unsigned_int64 ctx#gno v, IntSort#gno) (* BIT-VECTORS *) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v A string representing the value in decimal notation. - @param size the size of the bit-vector - let mk_B_V(string v, uint size) - { + @param v A string representing the value in decimal notation. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) string v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(int v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) int v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(uint v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) uint v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(long v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) long v, uint size) - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } + (BitVecNum)MkNumeral(v, MkBitVecSort(size) (** - Create a bit-vector numeral. + Create a bit-vector numeral. *) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_B_V(ulong v, uint size) - { + @param v value of the numeral. + @param size the size of the bit-vector + let mk_bv_ ( ctx : context ) ulong v, uint size) + (BitVecNum)MkNumeral(v, MkBitVecSort(size) - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - - // Numerals + // Numerals (* QUANTIFIERS *) (** - Create a universal Quantifier. + Create a universal Quantifier. + + Creates a forall formula, where is the weight, + is an array of patterns, is an array + with the sorts of the bound variables, is an array with the + 'names' of the bound variables, and is the body of the + quantifier. Quantifiers are associated with weights indicating + the importance of using the quantifier during instantiation. *) - - Creates a forall formula, where is the weight, - is an array of patterns, is an array - with the sorts of the bound variables, is an array with the - 'names' of the bound variables, and is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during instantiation. - - @param sorts the sorts of the bound variables. - @param names names of the bound variables - @param body the body of the quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param patterns array containing the patterns created using MkPattern. - @param noPatterns array containing the anti-patterns created using MkPattern. - @param quantifierID optional symbol to track quantifier. - @param skolemID optional symbol to track skolem constants. - public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { - - - - - - - - - - - - return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + @param sorts the sorts of the bound variables. + @param names names of the bound variables + @param body the body of the quantifier. + @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + @param patterns array containing the patterns created using MkPattern. + @param noPatterns array containing the anti-patterns created using MkPattern. + @param quantifierID optional symbol to track quantifier. + @param skolemID optional symbol to track skolem constants. + public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create a universal Quantifier. + Create a universal Quantifier. *) - public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { + public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - - - - - - return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create an existential Quantifier. + Create an existential Quantifier. *) - - public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { + + public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - - - - - - - - - return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create an existential Quantifier. + Create an existential Quantifier. *) - public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { - - - - - - - return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create a Quantifier. + Create a Quantifier. *) - public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { - - - - - - - - - - - - if (universal) - return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } + public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + if (universal) + MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); (** - Create a Quantifier. + Create a Quantifier. *) - public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - { + public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) + if (universal) + MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); + else + MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - - - - - - if (universal) - return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - - - // Expr + // Expr (* OPTIONS *) (** - Selects the format used for pretty-printing expressions. + Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the Z3_PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. *) - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the Z3_PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. - - - - - - public Z3_ast_print_mode PrintMode - { - set { Z3native.set_ast_print_mode(nCtx, (uint)value); } - } - + + + + + public Z3_ast_print_mode PrintMode + + set { Z3native.set_ast_print_mode ctx#gno (uint)value); } (* SMT Files & Strings *) (** - Convert a benchmark into an SMT-LIB formatted string. + Convert a benchmark into an SMT-LIB formatted string. *) - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - public string BenchmarkToSMTString(string name, string logic, string status, string attributes, - BoolExpr[] assumptions, BoolExpr formula) - { + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) - - - - return Z3native.benchmark_to_smtlib_string(nCtx, name, logic, status, attributes, - (uint)assumptions.Length, AST.ArrayToNative(assumptions), - formula.x#gno); - } + Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula#gno); (** - Parse the given string using the SMT-LIB parser. + Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. - - public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_string(nCtx, str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); - } + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - Parse the given file using the SMT-LIB parser. + Parse the given file using the SMT-LIB parser. *) - - public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_file(nCtx, fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); - } + + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBFormulas { get { return Z3native.get_smtlib_num_formulas(nCtx)) + public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) (** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public BoolExpr[] SMTLIBFormulas - { - get - { + let[] SMTLIBFormulas + get + + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) + res; - uint n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_formula(nCtx, i)); - return res; - } - } (** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBAssumptions { get { return Z3native.get_smtlib_num_assumptions(nCtx)) + public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) (** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public BoolExpr[] SMTLIBAssumptions - { - get - { + let[] SMTLIBAssumptions + get + + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) + res; - uint n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)Expr.Create(this, Z3native.get_smtlib_assumption(nCtx, i)); - return res; - } - } (** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBDecls { get { return Z3native.get_smtlib_num_decls(nCtx)) + public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Func_Decl[] SMTLIBDecls - { - get - { + public Func_Decl[] SMTLIBDecls + get + + uint n = NumSMTLIBDecls; + Func_Decl[] res = new Func_Decl[n]; + for (uint i = 0; i < n; i++) + res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) + res; - uint n = NumSMTLIBDecls; - Func_Decl[] res = new Func_Decl[n]; - for (uint i = 0; i < n; i++) - res[i] = new Func_Decl(this, Z3native.get_smtlib_decl(nCtx, i)); - return res; - } - } (** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBSorts { get { return Z3native.get_smtlib_num_sorts(nCtx)) + public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Sort[] SMTLIBSorts - { - get - { + public Sort[] SMTLIBSorts + get + + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) + res; - uint n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (uint i = 0; i < n; i++) - res[i] = Sort.Create(this, Z3native.get_smtlib_sort(nCtx, i)); - return res; - } - } (** - Parse the given string using the SMT-LIB2 parser. + Parse the given string using the SMT-LIB2 parser. *) - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - public BoolExpr ParseSMTLIB2String(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_string(nCtx, str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); - } + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (** - Parse the given file using the SMT-LIB2 parser. + Parse the given file using the SMT-LIB2 parser. *) - - public BoolExpr ParseSMTLIB2File(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - { + + let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - return (BoolExpr)Expr.Create(this, Z3native.parse_smtlib2_file(nCtx, fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); - } - + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (* GOALS *) (** - Creates a new Goal. + Creates a new Goal. + + Note that the Context must have been created with proof generation support if + is set to true here. *) - - Note that the Context must have been created with proof generation support if - is set to true here. - - @param models Indicates whether model generation should be enabled. - @param unsatCores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - { + @param models Indicates whether model generation should be enabled. + @param unsatCores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - - return new Goal(this, models, unsatCores, proofs); - } - + new Goal(this, models, unsatCores, proofs); (* PARAMETERSETS *) (** - Creates a new ParameterSet. + Creates a new ParameterSet. *) - public Params MkParams ( ctx : context ) = - { + public Params MkParams ( ctx : context ) = - - return new Params(this); - } - + new Params(this); (* TACTICS *) (** - The number of supported tactics. + The number of supported tactics. *) - public uint NumTactics - { - get { return Z3native.get_num_tactics(nCtx); } - } + public uint NumTactics + + get {Z3native.get_num_tactics ctx#gno); } (** - The names of all supported tactics. + The names of all supported tactics. *) - public string[] TacticNames - { - get - { + public string[] TacticNames + get + + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_tactic_name ctx#gno i); + res; - uint n = NumTactics; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_tactic_name(nCtx, i); - return res; - } - } (** - Returns a string containing a description of the tactic with the given name. + Returns a string containing a description of the tactic with the given name. *) - public string TacticDescription(string name) - { + public string TacticDescription(string name) - - return Z3native.tactic_get_descr(nCtx, name); - } + Z3native.tactic_get_descr ctx#gno name); (** - Creates a new Tactic. + Creates a new Tactic. *) - public Tactic MkTactic(string name) - { + public Tactic MkTactic(string name) - - return new Tactic(this, name); - } + new Tactic(this, name); (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . + Create a tactic that applies to a Goal and + then to every subgoal produced by . *) - public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) - { + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) + last = ts[ts.Length - 1]#gno; + for (int i = ts.Length - 2; i >= 0; i--) + last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); + if (last != IntPtr.Zero) + last = Z3native.tactic_and_then ctx#gno t2#gno last); + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(ts); - - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) - { - last = ts[ts.Length - 1].x#gno; - for (int i = ts.Length - 2; i >= 0; i--) - last = Z3native.tactic_and_then(nCtx, ts[i].x#gno, last); - } - if (last != IntPtr.Zero) - { - last = Z3native.tactic_and_then(nCtx, t2.x#gno, last); - return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, last)); - } - else - return new Tactic(this, Z3native.tactic_and_then(nCtx, t1.x#gno, t2.x#gno)); - } + else + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . + Create a tactic that applies to a Goal and + then to every subgoal produced by . + + Shorthand for AndThen. *) - - Shorthand for AndThen. - - public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - { + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - - - - - return AndThen(t1, t2, ts); - } + AndThen(t1, t2, ts); (** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. *) - public Tactic OrElse(Tactic t1, Tactic t2) - { + public Tactic OrElse(Tactic t1, Tactic t2) - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Z3native.tactic_or_else(nCtx, t1.x#gno, t2.x#gno)); - } + new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a goal for milliseconds. + Create a tactic that applies to a goal for milliseconds. + + If does not terminate within milliseconds, then it fails. *) - - If does not terminate within milliseconds, then it fails. - - public Tactic TryFor(Tactic t, uint ms) - { + public Tactic TryFor(Tactic t, uint ms) - - - CheckContextMatch(t); - return new Tactic(this, Z3native.tactic_try_for(nCtx, t.x#gno, ms)); - } + new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) (** - Create a tactic that applies to a given goal if the probe - evaluates to true. + Create a tactic that applies to a given goal if the probe + evaluates to true. + + If evaluates to false, then the new tactic behaves like the skip tactic. *) - - If evaluates to false, then the new tactic behaves like the skip tactic. - - public Tactic When(Probe p, Tactic t) - { + public Tactic When(Probe p, Tactic t) - - - - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Z3native.tactic_when(nCtx, p.x#gno, t.x#gno)); - } + new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) (** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. *) - public Tactic Cond(Probe p, Tactic t1, Tactic t2) - { + public Tactic Cond(Probe p, Tactic t1, Tactic t2) - - - - - CheckContextMatch(p); - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Z3native.tactic_cond(nCtx, p.x#gno, t1.x#gno, t2.x#gno)); - } + new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) (** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. *) - public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - { + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - - - CheckContextMatch(t); - return new Tactic(this, Z3native.tactic_repeat(nCtx, t.x#gno, max)); - } + new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) (** - Create a tactic that just returns the given goal. + Create a tactic that just returns the given goal. *) - public Tactic Skip ( ctx : context ) = - { + public Tactic Skip ( ctx : context ) = - - return new Tactic(this, Z3native.tactic_skip(nCtx)); - } + new Tactic(this, Z3native.tactic_skip ctx#gno) (** - Create a tactic always fails. + Create a tactic always fails. *) - public Tactic Fail ( ctx : context ) = - { + public Tactic Fail ( ctx : context ) = - - return new Tactic(this, Z3native.tactic_fail(nCtx)); - } + new Tactic(this, Z3native.tactic_fail ctx#gno) (** - Create a tactic that fails if the probe evaluates to false. + Create a tactic that fails if the probe evaluates to false. *) - public Tactic FailIf(Probe p) - { + public Tactic FailIf(Probe p) - - - CheckContextMatch(p); - return new Tactic(this, Z3native.tactic_fail_if(nCtx, p.x#gno)); - } + new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) (** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) - public Tactic FailIfNotDecided ( ctx : context ) = - { + public Tactic FailIfNotDecided ( ctx : context ) = - - return new Tactic(this, Z3native.tactic_fail_if_not_decided(nCtx)); - } + new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) (** - Create a tactic that applies using the given set of parameters . + Create a tactic that applies using the given set of parameters . *) - public Tactic UsingParams(Tactic t, Params p) - { + public Tactic UsingParams(Tactic t, Params p) - - - - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Z3native.tactic_using_params(nCtx, t.x#gno, p.x#gno)); - } + new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) (** - Create a tactic that applies using the given set of parameters . -*) - Alias for UsingParams - public Tactic With(Tactic t, Params p) - { + Create a tactic that applies using the given set of parameters . + Alias for UsingParams*) + public Tactic With(Tactic t, Params p) - - - - return UsingParams(t, p); - } + UsingParams(t, p); (** - Create a tactic that applies the given tactics in parallel. + Create a tactic that applies the given tactics in parallel. *) - public Tactic ParOr(params Tactic[] t) - { + public Tactic ParOr(params Tactic[] t) - - - CheckContextMatch(t); - return new Tactic(this, Z3native.tactic_par_or(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); - } + new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) (** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. *) - public Tactic ParAndThen(Tactic t1, Tactic t2) - { + public Tactic ParAndThen(Tactic t1, Tactic t2) - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Z3native.tactic_par_and_then(nCtx, t1.x#gno, t2.x#gno)); - } + new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) (** - Interrupt the execution of a Z3 procedure. + Interrupt the execution of a Z3 procedure. *) - This procedure can be used to interrupt: solvers, simplifiers and tactics. - public void Interrupt ( ctx : context ) = - { - Z3native.interrupt(nCtx); - } - + This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt ( ctx : context ) = + + Z3native.interrupt ctx#gno); (* PROBES *) (** - The number of supported Probes. + The number of supported Probes. *) - public uint NumProbes - { - get { return Z3native.get_num_probes(nCtx); } - } + public uint NumProbes + + get {Z3native.get_num_probes ctx#gno); } (** - The names of all supported Probes. + The names of all supported Probes. *) - public string[] ProbeNames - { - get - { + public string[] ProbeNames + get + + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_probe_name ctx#gno i); + res; - uint n = NumProbes; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_probe_name(nCtx, i); - return res; - } - } (** - Returns a string containing a description of the probe with the given name. + Returns a string containing a description of the probe with the given name. *) - public string ProbeDescription(string name) - { + public string ProbeDescription(string name) - - return Z3native.probe_get_descr(nCtx, name); - } + Z3native.probe_get_descr ctx#gno name); (** - Creates a new Probe. + Creates a new Probe. *) - public Probe MkProbe(string name) - { + public Probe MkProbe(string name) - - return new Probe(this, name); - } + new Probe(this, name); (** - Create a probe that always evaluates to . + Create a probe that always evaluates to . *) - public Probe Const(double val) - { + public Probe Const(double val) - - return new Probe(this, Z3native.probe_const(nCtx, val)); - } + new Probe(this, Z3native.probe_const ctx#gno val) (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by *) - public Probe Lt(Probe p1, Probe p2) - { + public Probe Lt(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_lt(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by *) - public Probe Gt(Probe p1, Probe p2) - { + public Probe Gt(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_gt(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by *) - public Probe Le(Probe p1, Probe p2) - { + public Probe Le(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_le(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by *) - public Probe Ge(Probe p1, Probe p2) - { + public Probe Ge(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_ge(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by *) - public Probe Eq(Probe p1, Probe p2) - { + public Probe Eq(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_eq(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". + Create a probe that evaluates to "true" when the value + and evaluate to "true". *) - public Probe And(Probe p1, Probe p2) - { + public Probe And(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_and(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". + Create a probe that evaluates to "true" when the value + or evaluate to "true". *) - public Probe Or(Probe p1, Probe p2) - { + public Probe Or(Probe p1, Probe p2) - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Z3native.probe_or(nCtx, p1.x#gno, p2.x#gno)); - } + new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". + Create a probe that evaluates to "true" when the value + does not evaluate to "true". *) - public Probe Not(Probe p) - { + public Probe Not(Probe p) - - - CheckContextMatch(p); - return new Probe(this, Z3native.probe_not(nCtx, p.x#gno)); - } - + new Probe(this, Z3native.probe_not ctx#gno p#gno) (* SOLVERS *) (** - Creates a new (incremental) solver. -*) - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. - - public Solver MkSolver(Symbol logic = null) - { + Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. +*) + public Solver MkSolver(Symbol logic = null) - - if (logic == null) - return new Solver(this, Z3native.mk_solver(nCtx)); - else - return new Solver(this, Z3native.mk_solver_for_logic(nCtx, logic.x#gno)); - } + if (logic == null) + new Solver(this, Z3native.mk_solver ctx#gno) + else + new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - - public Solver MkSolver(string logic) - { + + public Solver MkSolver(string logic) - - return MkSolver(MkSymbol(logic)); - } + MkSolver(MkSymbol(logic) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - let mk_Simple_Solver ( ctx : context ) = - { + let mk_Simple_Solver ( ctx : context ) ctx : context ) = - - return new Solver(this, Z3native.mk_simple_solver(nCtx)); - } + new Solver(this, Z3native.mk_simple_solver ctx#gno) (** - Creates a solver that is implemented using the given tactic. + Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. - - public Solver MkSolver(Tactic t) - { + public Solver MkSolver(Tactic t) - - - return new Solver(this, Z3native.mk_solver_from_tactic(nCtx, t.x#gno)); - } - + new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) (* FIXEDPOINTS *) (** - Create a Fixedpoint context. + Create a Fixedpoint context. *) - public Fixedpoint MkFixedpoint ( ctx : context ) = - { - - - return new Fixedpoint(this); - } - + public Fixedpoint MkFixedpoint ( ctx : context ) = + new Fixedpoint(this); (* MISCELLANEOUS *) (** - Wraps an AST. + Wraps an AST. *) - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - public AST WrapAST(IntPtr nativeObject) - { + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) - return AST.Create(this, nativeObject); - } + AST.Create(this, nativeObject); (** - Unwraps an AST. + Unwraps an AST. *) - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - public IntPtr UnwrapAST(AST a) - { - return a.x#gno; - } + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + public IntPtr UnwrapAST(AST a) + + a#gno; (** - Return a string describing all available parameters to Expr.Simplify. + a string describing all available parameters to Expr.Simplify. *) - public string SimplifyHelp ( ctx : context ) = - { + public string SimplifyHelp ( ctx : context ) = - - return Z3native.simplify_get_help(nCtx); - } + Z3native.simplify_get_help ctx#gno); (** - Retrieves parameter descriptions for simplifier. + Retrieves parameter descriptions for simplifier. *) - public ParamDescrs SimplifyParameterDescriptions - { - get { return new ParamDescrs(this, Z3native.simplify_get_param_descrs(nCtx)); } - } + public ParamDescrs SimplifyParameterDescriptions + + get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } (** - Enable/disable printing of warning messages to the console. + Enable/disable printing of warning messages to the console. *) - Note that this function is static and effects the behaviour of - all contexts globally. - public static void ToggleWarningMessages(bool enabled) - { - Z3native.toggle_warning_messages((enabled) ? 1 : 0); - } - + Note that this function is static and effects the behaviour of + all contexts globally. + public static void ToggleWarningMessages(bool enabled) + + Z3native.toggle_warning_messages((enabled) ? 1 : 0); (* ERROR HANDLING *) - //(** - //A delegate which is executed when an error is raised. - //*) - // - //Note that it is possible for memory leaks to occur if error handlers - //throw exceptions. - // - //public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); +(** + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. +*) + public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); - //(** - //The OnError event. - //*) - //public event ErrorHandler OnError = null; - +(** + The OnError event. +*) + public event ErrorHandler OnError = null; (* PARAMETERS *) (** - Update a mutable configuration parameter. + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. *) - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - - - public void UpdateParamValue(string id, string value) - { - Z3native.update_param_value(nCtx, id, value); - } + + public void UpdateParamValue(string id, string value) + + Z3native.update_param_value ctx#gno id, value); (** - Get a configuration parameter. + Get a configuration parameter. + + Returns null if the parameter value does not exist. + *) - - Returns null if the parameter value does not exist. - - - public string GetParamValue(string id) - { - IntPtr res = IntPtr.Zero; - int r = Z3native.get_param_value(nCtx, id, out res); - if (r == (int)Z3_lbool.Z3_L_FALSE) - return null; - else - return Marshal.PtrToStringAnsi(res); - } + public string GetParamValue(string id) - + IntPtr res = IntPtr.Zero; + int r = Z3native.get_param_value ctx#gno id, out res); + if (r == (int)Z3_lbool.L_FALSE) + null; + else + Marshal.PtrToStringAnsi(res); (* INTERNAL *) - internal IntPtr m_ctx = IntPtr.Zero; - internal Z3native.error_handler m_n_err_handler = null; - internal IntPtr nCtx { get { return m_ctx) + internal IntPtr m_ctx = IntPtr.Zero; + internal Z3native.error_handler m_n_err_handler = null; + internal IntPtr nCtx { get {m_ctx) - internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) - { - // Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - } + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + + internal void InitContext ( ctx : context ) = + + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); - internal void InitContext ( ctx : context ) = - { - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); // keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); - } *) -end + From 49a4e77a6df433ea91cc23bfc77063335459841e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 23 Dec 2012 04:00:34 +0000 Subject: [PATCH 367/507] More new ML API. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 8 +- scripts/update_api.py | 13 +- src/api/ml/z3.ml | 1644 ++++++++++++++++++------------------- 3 files changed, 807 insertions(+), 858 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index f414e9d1a..dde9f944a 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,7 +4,7 @@ *) open Z3 -open Z3.Context +open Z3.Arithmetic exception ExampleException of string @@ -16,9 +16,9 @@ let _ = Printf.printf "Running Z3 version %s\n" Version.to_string ; let cfg = [("model", "true"); ("proof", "false")] in let ctx = (new context cfg) in - let is = (mk_symbol_int ctx 42) in - let ss = (mk_symbol_string ctx "mySymbol") in - let bs = (mk_bool_sort ctx) in + let is = (Symbol.mk_int ctx 42) in + let ss = (Symbol.mk_string ctx "mySymbol") in + let bs = (Sort.mk_bool ctx) in let ints = (mk_int_sort ctx) in let rs = (mk_real_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); diff --git a/scripts/update_api.py b/scripts/update_api.py index 27f7dd507..acaa9478e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1154,8 +1154,11 @@ def mk_ml(): for k, v in Type2Str.iteritems(): if is_obj(k): ml_native.write('and %s = ptr\n' % v.lower()) - ml_native.write('\nexternal is_null : ptr -> bool\n') + ml_native.write('\n') + ml_native.write('external is_null : ptr -> bool\n') ml_native.write(' = "n_is_null"\n\n') + ml_native.write('external mk_null : unit -> ptr\n') + ml_native.write(' = "n_mk_null"\n\n') ml_native.write('exception Exception of string\n\n') # ML declarations @@ -1295,6 +1298,14 @@ def mk_ml(): ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') ml_wrapper.write(' return Val_bool(Data_custom_val(p) == 0);\n') ml_wrapper.write('}\n\n') + ml_wrapper.write('CAMLprim value n_mk_null( void ) {\n') + ml_wrapper.write(' CAMLparam0();\n') + ml_wrapper.write(' CAMLlocal1(result);\n') + ml_wrapper.write(' void * z3_result = 0;\n') + ml_wrapper.write(' result = caml_alloc_custom(&default_custom_ops, sizeof(void*), 0, 1);\n') + ml_wrapper.write(' memcpy( Data_custom_val(result), &z3_result, sizeof(void*));\n') + ml_wrapper.write(' CAMLreturn (result);\n') + ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 5f67e11e2..f6454b797 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -593,6 +593,10 @@ object (self) method cnstr_obj obj = (self#sno ctx obj) ; self end +let patternaton (a : pattern array) = + let f (e : pattern) = e#gno in + Array.map f a + (** Parameter description objects *) class param_descrs ctx = object (self) @@ -1607,6 +1611,306 @@ struct *) let mk_or ( ctx : context ) ( args : bool_expr array ) = (new bool_expr ctx)#cnstr_obj (Z3native.mk_or ctx#gno (Array.length args) (astaton args)) + + (** + Create a numeral of a given sort. + @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. + @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. + @return A Term with value and sort + *) + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = + create_expr ctx (Z3native.mk_numeral ctx#gno v ty#gno) + + (** + Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @param v Value of the numeral + @param ty Sort of the numeral + @return A Term with value and type + *) + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = + create_expr ctx (Z3native.mk_int ctx#gno v ty#gno) +end + +(** Quantifier expressions *) +module Quantifiers = +struct + (** + The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. + *) + let get_index ( x : expr ) = + if not (AST.is_var x) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value x#gnc x#gno + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. + *) + module Pattern = + struct + (** + The number of terms in the pattern. + *) + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms x#gnc x#gno + + (** + The terms in the pattern. + *) + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the pattern. + *) + let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno + end + + (** + Indicates whether the quantifier is universal. + *) + let is_universal ( x : quantifier ) = + lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE + + (** + Indicates whether the quantifier is existential. + *) + let is_existential ( x : quantifier ) = not (is_universal x) + + (** + The weight of the quantifier. + *) + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno + + (** + The number of patterns. + *) + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno + + (** + The patterns. + *) + let get_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of no-patterns. + *) + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno + + (** + The no-patterns. + *) + let get_no_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in + Array.init n f + + (** + The number of bound variables. + *) + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno + + (** + The symbols for the bound variables. + *) + let get_bound_variable_names ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + Array.init n f + + (** + The sorts of the bound variables. + *) + let get_bound_variable_sorts ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in + Array.init n f + + (** + The body of the quantifier. + *) + let get_body ( x : quantifier ) = + (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) + + (** + Creates a new bound variable. + @param index The de-Bruijn index of the variable + @param ty The sort of the variable + *) + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) + + (** + Create a quantifier pattern. + *) + let mk_pattern ( ctx : context ) ( terms : expr array ) = + if (Array.length terms) == 0 then + raise (Z3native.Exception "Cannot create a pattern from zero terms") + else + (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) + + (** + Create a universal Quantifier. + + Creates a forall formula, where is the weight, + is an array of patterns, is an array + with the sorts of the bound variables, is an array with the + 'names' of the bound variables, and is the body of the + quantifier. Quantifiers are associated with weights indicating + the importance of using the quantifier during instantiation. + + @param sorts the sorts of the bound variables. + @param names names of the bound variables + @param body the body of the quantifier. + @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + @param patterns array containing the patterns created using MkPattern. + @param noPatterns array containing the anti-patterns created using MkPattern. + @param quantifierID optional symbol to track quantifier. + @param skolemID optional symbol to track skolem constants. + *) + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (Array.length sorts) != (Array.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + + (** + Create a universal Quantifier. + *) + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_TRUE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + (** + Create an existential Quantifier. + + *) + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (Array.length sorts) != (Array.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length sorts) (astaton sorts) + (astaton names) + body#gno) + + (** + Create an existential Quantifier. + *) + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (nopatterns == None && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + else + let null = Z3native.mk_null() in + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_FALSE) + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> x#gno) + (match skolem_id with | None -> null | Some(x) -> x#gno) + (Array.length bound_constants) (expraton bound_constants) + (match patterns with | None -> 0 | Some(x) -> (Array.length x)) + (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) + (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + body#gno) + + (** + Create a Quantifier. + *) + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (universal) then + (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + else + (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + + + (** + Create a Quantifier. + *) + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if (universal) then + mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id + else + mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id end (** Functions to manipulate Array expressions *) @@ -1777,71 +2081,71 @@ struct *) let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) -(** - Create a set type. -*) -let mk_sort ( ctx : context ) ( ty : sort) = - (new set_sort ctx)#cnstr_s ty + (** + Create a set type. + *) + let mk_sort ( ctx : context ) ( ty : sort) = + (new set_sort ctx)#cnstr_s ty -(** - Create an empty set. -*) -let mk_empty ( ctx : context ) ( domain : sort ) = - (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) - - (** - Create the full set. - *) -let mk_full ( ctx : context ) ( domain : sort ) = - create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) + (** + Create an empty set. + *) + let mk_empty ( ctx : context ) ( domain : sort ) = + (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) + + (** + Create the full set. + *) + let mk_full ( ctx : context ) ( domain : sort ) = + create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) -(** - Add an element to the set. -*) -let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) - - (** - Remove an element from a set. - *) -let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) - - (** - Take the union of a list of sets. - *) -let mk_union ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) - -(** - Take the intersection of a list of sets. -*) -let mk_intersection ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) + (** + Add an element to the set. + *) + let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) + + (** + Remove an element from a set. + *) + let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) + + (** + Take the union of a list of sets. + *) + let mk_union ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) + + (** + Take the intersection of a list of sets. + *) + let mk_intersection ( ctx : context ) ( args : expr array ) = + create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) -(** - Take the difference between two sets. -*) -let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) + (** + Take the difference between two sets. + *) + let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) -(** - Take the complement of a set. -*) -let mk_complement ( ctx : context ) ( arg : expr ) = - create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) + (** + Take the complement of a set. + *) + let mk_complement ( ctx : context ) ( arg : expr ) = + create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) -(** - Check for set membership. -*) -let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) + (** + Check for set membership. + *) + let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) - (** - Check for subsetness of sets. - *) -let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) + (** + Check for subsetness of sets. + *) + let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = + create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) end @@ -2001,148 +2305,6 @@ struct Array.init n f end - -(** Quantifier expressions *) -module Quantifiers = -struct - (** - The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. - *) - let get_index ( x : expr ) = - if not (AST.is_var x) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value x#gnc x#gno - - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. - *) - module Pattern = - struct - (** - The number of terms in the pattern. - *) - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms x#gnc x#gno - - (** - The terms in the pattern. - *) - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the pattern. - *) - let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno - end - - (** - Indicates whether the quantifier is universal. - *) - let is_universal ( x : quantifier ) = - lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE - - (** - Indicates whether the quantifier is existential. - *) - let is_existential ( x : quantifier ) = not (is_universal x) - - (** - The weight of the quantifier. - *) - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno - - (** - The number of patterns. - *) - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno - - (** - The patterns. - *) - let get_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in - Array.init n f - - (** - The number of no-patterns. - *) - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno - - (** - The no-patterns. - *) - let get_no_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in - Array.init n f - - (** - The number of bound variables. - *) - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno - - (** - The symbols for the bound variables. - *) - let get_bound_variable_names ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in - Array.init n f - - (** - The sorts of the bound variables. - *) - let get_bound_variable_sorts ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in - Array.init n f - - (** - The body of the quantifier. - *) - let get_body ( x : quantifier ) = - (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) - - (** - Creates a new bound variable. - @param index The de-Bruijn index of the variable - @param ty The sort of the variable - *) - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) - - (** - Create a quantifier pattern. - *) - let mk_pattern ( ctx : context ) ( terms : expr array ) = - if (Array.length terms) == 0 then - raise (Z3native.Exception "Cannot create a pattern from zero terms") - else - (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) -end (** Functions to manipulate Datatype expressions *) module Datatypes = @@ -2638,7 +2800,54 @@ struct The result has at most decimal places.*) let to_decimal_string ( x : algebraic_num ) ( precision : int ) = Z3native.get_numeral_decimal_string x#gnc x#gno precision + + (** + Create a real from a fraction. + + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + *) + let mk_real_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + if (den == 0) then + raise (Z3native.Exception "Denominator is zero") + else + (new rat_num ctx)#cnstr_obj (Z3native.mk_real ctx#gno num den) + + (** + Create a real numeral. + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + *) + let mk_real_numeral_s ( ctx : context ) ( v : string ) = + (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_real_sort ctx)#gno) + + (** + Create a real numeral. + + @param v value of the numeral. + @return A Term with value and sort Real + *) + let mk_real_numeral_i ( ctx : context ) ( v : int ) = + (new rat_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_real_sort ctx)#gno) + + (** + Create an integer numeral. + @param v A string representing the Term value in decimal notation. + *) + let mk_int_numeral_s ( ctx : context ) ( v : string ) = + (new int_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_int_sort ctx)#gno) + + (** + Create an integer numeral. + @param v value of the numeral. + @return A Term with value and sort Integer + *) + let mk_int_numeral_i ( ctx : context ) ( v : int ) = + (new int_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_int_sort ctx)#gno) + (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno end @@ -3386,10 +3595,18 @@ struct *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow ctx#gno t1#gno t2#gno) - + + (** + Create a bit-vector numeral. + + @param v A string representing the value in decimal notation. + @param size the size of the bit-vector + *) + let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = + (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_sort ctx size)#gno) end -(** Functions to manipulate Proof objects *) +(** Functions to manipulate proof expressions *) module Proofs = struct (** @@ -4567,933 +4784,654 @@ end (* STUFF FROM THE CONTEXT *) (** - -(* NUMERALS *) - -(* GENERAL NUMERALS *) -(** - Create a Term of a given sort. -*) - @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - @return A Term with value and sort - public Expr MkNumeral(string v, Sort ty) - - create_expr ctx (Z3native.mk_numeral ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(int v, Sort ty) - - create_expr ctx (Z3native.mk_int ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(uint v, Sort ty) - - create_expr ctx (Z3native.mk_unsigned_int ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(long v, Sort ty) - - create_expr ctx (Z3native.mk_int64 ctx#gno v, ty#gno) - -(** - Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. -*) - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - public Expr MkNumeral(ulong v, Sort ty) - - create_expr ctx (Z3native.mk_unsigned_int64 ctx#gno v, ty#gno) - -(* REALS *) -(** - Create a real from a fraction. -*) - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - public RatNum MkReal(int num, int den) - - if (den == 0) - throw new Z3Exception("Denominator is zero"); - - new RatNum(this, Z3native.mk_real ctx#gno num, den) - -(** - Create a real numeral. -*) - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - public RatNum MkReal(string v) - - new RatNum(this, Z3native.mk_numeral ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(int v) - - new RatNum(this, Z3native.mk_int ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(uint v) - - new RatNum(this, Z3native.mk_unsigned_int ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(long v) - - new RatNum(this, Z3native.mk_int64 ctx#gno v, RealSort#gno) - -(** - Create a real numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Real - public RatNum MkReal(ulong v) - - new RatNum(this, Z3native.mk_unsigned_int64 ctx#gno v, RealSort#gno) - -(* INTEGERS *) -(** - Create an integer numeral. -*) - @param v A string representing the Term value in decimal notation. - public IntNum MkInt(string v) - - new IntNum(this, Z3native.mk_numeral ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(int v) - - new IntNum(this, Z3native.mk_int ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(uint v) - - new IntNum(this, Z3native.mk_unsigned_int ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(long v) - - new IntNum(this, Z3native.mk_int64 ctx#gno v, IntSort#gno) - -(** - Create an integer numeral. -*) - @param v value of the numeral. - @return A Term with value and sort Integer - public IntNum MkInt(ulong v) - - new IntNum(this, Z3native.mk_unsigned_int64 ctx#gno v, IntSort#gno) - -(* BIT-VECTORS *) -(** - Create a bit-vector numeral. -*) - @param v A string representing the value in decimal notation. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) string v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) int v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) uint v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) long v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - -(** - Create a bit-vector numeral. -*) - @param v value of the numeral. - @param size the size of the bit-vector - let mk_bv_ ( ctx : context ) ulong v, uint size) - - (BitVecNum)MkNumeral(v, MkBitVecSort(size) - - // Numerals - -(* QUANTIFIERS *) -(** - Create a universal Quantifier. - - Creates a forall formula, where is the weight, - is an array of patterns, is an array - with the sorts of the bound variables, is an array with the - 'names' of the bound variables, and is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during instantiation. -*) - @param sorts the sorts of the bound variables. - @param names names of the bound variables - @param body the body of the quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param patterns array containing the patterns created using MkPattern. - @param noPatterns array containing the anti-patterns created using MkPattern. - @param quantifierID optional symbol to track quantifier. - @param skolemID optional symbol to track skolem constants. - public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create a universal Quantifier. -*) - public Quantifier MkForall(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create an existential Quantifier. -*) - - public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create an existential Quantifier. -*) - public Quantifier MkExists(Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create a Quantifier. -*) - public Quantifier MkQuantifier(bool universal, Sort[] sorts, Symbol[] names, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - if (universal) - MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - -(** - Create a Quantifier. -*) - public Quantifier MkQuantifier(bool universal, Expr[] boundConstants, Expr body, uint weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, Symbol quantifierID = null, Symbol skolemID = null) - - if (universal) - MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - - // Expr - (* OPTIONS *) (** - Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the Z3_PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the Z3_PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. *) - - - - - public Z3_ast_print_mode PrintMode + + + + + public Z3_ast_print_mode PrintMode - set { Z3native.set_ast_print_mode ctx#gno (uint)value); } + set { Z3native.set_ast_print_mode ctx#gno (uint)value); } (* SMT Files & Strings *) (** - Convert a benchmark into an SMT-LIB formatted string. + Convert a benchmark into an SMT-LIB formatted string. *) - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - public string BenchmarkToSMTString(string name, string logic, string status, string attributes, - BoolExpr[] assumptions, BoolExpr formula) + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + public string BenchmarkToSMTString(string name, string logic, string status, string attributes, + BoolExpr[] assumptions, BoolExpr formula) - Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, - (uint)assumptions.Length, AST.ArrayToNative(assumptions), - formula#gno); + Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, + (uint)assumptions.Length, AST.ArrayToNative(assumptions), + formula#gno); (** - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. + Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) - public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - Parse the given file using the SMT-LIB parser. + Parse the given file using the SMT-LIB parser. *) - - public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Z3native.parse_smtlib_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) (** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) + public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) (** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let[] SMTLIBFormulas + let[] SMTLIBFormulas - get + get - uint n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) - res; + uint n = NumSMTLIBFormulas; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) + res; (** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) + public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) (** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let[] SMTLIBAssumptions + let[] SMTLIBAssumptions - get + get - uint n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) - res; + uint n = NumSMTLIBAssumptions; + BoolExpr[] res = new BoolExpr[n]; + for (uint i = 0; i < n; i++) + res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) + res; (** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) + public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Func_Decl[] SMTLIBDecls + public Func_Decl[] SMTLIBDecls - get + get - uint n = NumSMTLIBDecls; - Func_Decl[] res = new Func_Decl[n]; - for (uint i = 0; i < n; i++) - res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) - res; + uint n = NumSMTLIBDecls; + Func_Decl[] res = new Func_Decl[n]; + for (uint i = 0; i < n; i++) + res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) + res; (** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) + public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - public Sort[] SMTLIBSorts + public Sort[] SMTLIBSorts - get + get - uint n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (uint i = 0; i < n; i++) - res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) - res; + uint n = NumSMTLIBSorts; + Sort[] res = new Sort[n]; + for (uint i = 0; i < n; i++) + res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) + res; (** - Parse the given string using the SMT-LIB2 parser. + Parse the given string using the SMT-LIB2 parser. *) - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (** - Parse the given file using the SMT-LIB2 parser. + Parse the given file using the SMT-LIB2 parser. *) - - let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + + let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) + uint csn = Symbol.ArrayLength(sortNames); + uint cs = Sort.ArrayLength(sorts); + uint cdn = Symbol.ArrayLength(declNames); + uint cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, + AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) (* GOALS *) (** - Creates a new Goal. - - Note that the Context must have been created with proof generation support if - is set to true here. + Creates a new Goal. + + Note that the Context must have been created with proof generation support if + is set to true here. *) - @param models Indicates whether model generation should be enabled. - @param unsatCores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) + @param models Indicates whether model generation should be enabled. + @param unsatCores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - new Goal(this, models, unsatCores, proofs); + new Goal(this, models, unsatCores, proofs); (* PARAMETERSETS *) (** - Creates a new ParameterSet. + Creates a new ParameterSet. *) - public Params MkParams ( ctx : context ) = + public Params MkParams ( ctx : context ) = - new Params(this); + new Params(this); (* TACTICS *) (** - The number of supported tactics. + The number of supported tactics. *) - public uint NumTactics + public uint NumTactics - get {Z3native.get_num_tactics ctx#gno); } + get {Z3native.get_num_tactics ctx#gno); } (** - The names of all supported tactics. + The names of all supported tactics. *) - public string[] TacticNames + public string[] TacticNames - get + get - uint n = NumTactics; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_tactic_name ctx#gno i); - res; + uint n = NumTactics; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_tactic_name ctx#gno i); + res; (** - Returns a string containing a description of the tactic with the given name. + Returns a string containing a description of the tactic with the given name. *) - public string TacticDescription(string name) + public string TacticDescription(string name) - Z3native.tactic_get_descr ctx#gno name); + Z3native.tactic_get_descr ctx#gno name); (** - Creates a new Tactic. + Creates a new Tactic. *) - public Tactic MkTactic(string name) + public Tactic MkTactic(string name) - new Tactic(this, name); + new Tactic(this, name); (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . + Create a tactic that applies to a Goal and + then to every subgoal produced by . *) - public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) + public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) + IntPtr last = IntPtr.Zero; + if (ts != null && ts.Length > 0) - last = ts[ts.Length - 1]#gno; - for (int i = ts.Length - 2; i >= 0; i--) - last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); + last = ts[ts.Length - 1]#gno; + for (int i = ts.Length - 2; i >= 0; i--) + last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); - if (last != IntPtr.Zero) + if (last != IntPtr.Zero) - last = Z3native.tactic_and_then ctx#gno t2#gno last); - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) + last = Z3native.tactic_and_then ctx#gno t2#gno last); + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) - else - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) + else + new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . - - Shorthand for AndThen. + Create a tactic that applies to a Goal and + then to every subgoal produced by . + + Shorthand for AndThen. *) - public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) + public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - AndThen(t1, t2, ts); + AndThen(t1, t2, ts); (** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. *) - public Tactic OrElse(Tactic t1, Tactic t2) + public Tactic OrElse(Tactic t1, Tactic t2) - new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) + new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) (** - Create a tactic that applies to a goal for milliseconds. - - If does not terminate within milliseconds, then it fails. + Create a tactic that applies to a goal for milliseconds. + + If does not terminate within milliseconds, then it fails. *) - public Tactic TryFor(Tactic t, uint ms) + public Tactic TryFor(Tactic t, uint ms) - new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) + new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) (** - Create a tactic that applies to a given goal if the probe - evaluates to true. - - If evaluates to false, then the new tactic behaves like the skip tactic. + Create a tactic that applies to a given goal if the probe + evaluates to true. + + If evaluates to false, then the new tactic behaves like the skip tactic. *) - public Tactic When(Probe p, Tactic t) + public Tactic When(Probe p, Tactic t) - new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) + new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) (** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. *) - public Tactic Cond(Probe p, Tactic t1, Tactic t2) + public Tactic Cond(Probe p, Tactic t1, Tactic t2) - new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) + new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) (** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. *) - public Tactic Repeat(Tactic t, uint max = uint.MaxValue) + public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) + new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) (** - Create a tactic that just returns the given goal. + Create a tactic that just returns the given goal. *) - public Tactic Skip ( ctx : context ) = + public Tactic Skip ( ctx : context ) = - new Tactic(this, Z3native.tactic_skip ctx#gno) + new Tactic(this, Z3native.tactic_skip ctx#gno) (** - Create a tactic always fails. + Create a tactic always fails. *) - public Tactic Fail ( ctx : context ) = + public Tactic Fail ( ctx : context ) = - new Tactic(this, Z3native.tactic_fail ctx#gno) + new Tactic(this, Z3native.tactic_fail ctx#gno) (** - Create a tactic that fails if the probe evaluates to false. + Create a tactic that fails if the probe evaluates to false. *) - public Tactic FailIf(Probe p) + public Tactic FailIf(Probe p) - new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) + new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) (** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) - public Tactic FailIfNotDecided ( ctx : context ) = + public Tactic FailIfNotDecided ( ctx : context ) = - new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) + new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) (** - Create a tactic that applies using the given set of parameters . + Create a tactic that applies using the given set of parameters . *) - public Tactic UsingParams(Tactic t, Params p) + public Tactic UsingParams(Tactic t, Params p) - new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) + new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) (** - Create a tactic that applies using the given set of parameters . - Alias for UsingParams*) - public Tactic With(Tactic t, Params p) + Create a tactic that applies using the given set of parameters . + Alias for UsingParams*) + public Tactic With(Tactic t, Params p) - UsingParams(t, p); + UsingParams(t, p); (** - Create a tactic that applies the given tactics in parallel. + Create a tactic that applies the given tactics in parallel. *) - public Tactic ParOr(params Tactic[] t) + public Tactic ParOr(params Tactic[] t) - new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) + new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) (** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. *) - public Tactic ParAndThen(Tactic t1, Tactic t2) + public Tactic ParAndThen(Tactic t1, Tactic t2) - new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) + new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) (** - Interrupt the execution of a Z3 procedure. + Interrupt the execution of a Z3 procedure. *) - This procedure can be used to interrupt: solvers, simplifiers and tactics. - public void Interrupt ( ctx : context ) = + This procedure can be used to interrupt: solvers, simplifiers and tactics. + public void Interrupt ( ctx : context ) = - Z3native.interrupt ctx#gno); + Z3native.interrupt ctx#gno); (* PROBES *) (** - The number of supported Probes. + The number of supported Probes. *) - public uint NumProbes + public uint NumProbes - get {Z3native.get_num_probes ctx#gno); } + get {Z3native.get_num_probes ctx#gno); } (** - The names of all supported Probes. + The names of all supported Probes. *) - public string[] ProbeNames + public string[] ProbeNames - get + get - uint n = NumProbes; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_probe_name ctx#gno i); - res; + uint n = NumProbes; + string[] res = new string[n]; + for (uint i = 0; i < n; i++) + res[i] = Z3native.get_probe_name ctx#gno i); + res; (** - Returns a string containing a description of the probe with the given name. + Returns a string containing a description of the probe with the given name. *) - public string ProbeDescription(string name) + public string ProbeDescription(string name) - Z3native.probe_get_descr ctx#gno name); + Z3native.probe_get_descr ctx#gno name); (** - Creates a new Probe. + Creates a new Probe. *) - public Probe MkProbe(string name) + public Probe MkProbe(string name) - new Probe(this, name); + new Probe(this, name); (** - Create a probe that always evaluates to . + Create a probe that always evaluates to . *) - public Probe Const(double val) + public Probe Const(double val) - new Probe(this, Z3native.probe_const ctx#gno val) + new Probe(this, Z3native.probe_const ctx#gno val) (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by *) - public Probe Lt(Probe p1, Probe p2) + public Probe Lt(Probe p1, Probe p2) - new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by *) - public Probe Gt(Probe p1, Probe p2) + public Probe Gt(Probe p1, Probe p2) - new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by *) - public Probe Le(Probe p1, Probe p2) + public Probe Le(Probe p1, Probe p2) - new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by *) - public Probe Ge(Probe p1, Probe p2) + public Probe Ge(Probe p1, Probe p2) - new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by *) - public Probe Eq(Probe p1, Probe p2) + public Probe Eq(Probe p1, Probe p2) - new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". + Create a probe that evaluates to "true" when the value + and evaluate to "true". *) - public Probe And(Probe p1, Probe p2) + public Probe And(Probe p1, Probe p2) - new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". + Create a probe that evaluates to "true" when the value + or evaluate to "true". *) - public Probe Or(Probe p1, Probe p2) + public Probe Or(Probe p1, Probe p2) - new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) + new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". + Create a probe that evaluates to "true" when the value + does not evaluate to "true". *) - public Probe Not(Probe p) + public Probe Not(Probe p) - new Probe(this, Z3native.probe_not ctx#gno p#gno) + new Probe(this, Z3native.probe_not ctx#gno p#gno) (* SOLVERS *) (** - Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. + Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) - public Solver MkSolver(Symbol logic = null) + public Solver MkSolver(Symbol logic = null) - if (logic == null) - new Solver(this, Z3native.mk_solver ctx#gno) - else - new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) + if (logic == null) + new Solver(this, Z3native.mk_solver ctx#gno) + else + new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - - public Solver MkSolver(string logic) + + public Solver MkSolver(string logic) - MkSolver(MkSymbol(logic) + MkSolver(MkSymbol(logic) (** - Creates a new (incremental) solver. + Creates a new (incremental) solver. *) - let mk_Simple_Solver ( ctx : context ) ctx : context ) = + let mk_Simple_Solver( ctx : context ) ctx : context ) = - new Solver(this, Z3native.mk_simple_solver ctx#gno) + new Solver(this, Z3native.mk_simple_solver ctx#gno) (** - Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. + Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) - public Solver MkSolver(Tactic t) + public Solver MkSolver(Tactic t) - new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) + new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) (* FIXEDPOINTS *) (** - Create a Fixedpoint context. + Create a Fixedpoint context. *) - public Fixedpoint MkFixedpoint ( ctx : context ) = + public Fixedpoint MkFixedpoint ( ctx : context ) = - new Fixedpoint(this); + new Fixedpoint(this); (* MISCELLANEOUS *) (** - Wraps an AST. + Wraps an AST. *) - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - public AST WrapAST(IntPtr nativeObject) + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + public AST WrapAST(IntPtr nativeObject) - AST.Create(this, nativeObject); + AST.Create(this, nativeObject); (** - Unwraps an AST. + Unwraps an AST. *) - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - public IntPtr UnwrapAST(AST a) + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + public IntPtr UnwrapAST(AST a) - a#gno; + a#gno; (** - a string describing all available parameters to Expr.Simplify. + a string describing all available parameters to Expr.Simplify. *) - public string SimplifyHelp ( ctx : context ) = + public string SimplifyHelp ( ctx : context ) = - Z3native.simplify_get_help ctx#gno); + Z3native.simplify_get_help ctx#gno); (** - Retrieves parameter descriptions for simplifier. + Retrieves parameter descriptions for simplifier. *) - public ParamDescrs SimplifyParameterDescriptions + public ParamDescrs SimplifyParameterDescriptions - get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } + get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } (** - Enable/disable printing of warning messages to the console. + Enable/disable printing of warning messages to the console. *) - Note that this function is static and effects the behaviour of - all contexts globally. - public static void ToggleWarningMessages(bool enabled) + Note that this function is static and effects the behaviour of + all contexts globally. + public static void ToggleWarningMessages(bool enabled) - Z3native.toggle_warning_messages((enabled) ? 1 : 0); + Z3native.toggle_warning_messages((enabled) ? 1 : 0); (* ERROR HANDLING *) (** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. *) - public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); + public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); (** - The OnError event. + The OnError event. *) - public event ErrorHandler OnError = null; + public event ErrorHandler OnError = null; (* PARAMETERS *) (** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. *) - - public void UpdateParamValue(string id, string value) + + public void UpdateParamValue(string id, string value) - Z3native.update_param_value ctx#gno id, value); + Z3native.update_param_value ctx#gno id, value); (** - Get a configuration parameter. - - Returns null if the parameter value does not exist. - + Get a configuration parameter. + + Returns null if the parameter value does not exist. + *) - public string GetParamValue(string id) + public string GetParamValue(string id) - IntPtr res = IntPtr.Zero; - int r = Z3native.get_param_value ctx#gno id, out res); - if (r == (int)Z3_lbool.L_FALSE) - null; - else - Marshal.PtrToStringAnsi(res); + IntPtr res = IntPtr.Zero; + int r = Z3native.get_param_value ctx#gno id, out res); + if (r == (int)Z3_lbool.L_FALSE) + null; + else + Marshal.PtrToStringAnsi(res); (* INTERNAL *) - internal IntPtr m_ctx = IntPtr.Zero; - internal Z3native.error_handler m_n_err_handler = null; - internal IntPtr nCtx { get {m_ctx) + internal IntPtr m_ctx = IntPtr.Zero; + internal Z3native.error_handler m_n_err_handler = null; + internal IntPtr nCtx { get {m_ctx) - internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) + internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - internal void InitContext ( ctx : context ) = + internal void InitContext ( ctx : context ) = - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); + PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); *) - From 77679dc1f508833b3acc034b24a750ae0c2db956 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Dec 2012 02:47:41 +0000 Subject: [PATCH 368/507] More new ML API; Status: everything is there except for error handling. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 1498 +++++++++++++++++++++++++--------------------- 1 file changed, 809 insertions(+), 689 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index f6454b797..088bfbd6f 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,33 +7,52 @@ open Z3enums -(**/**) +(** Context objects. -class virtual idisposable = -object - method virtual dispose : unit -end +Most interactions with Z3 are interpreted in some context; most users will only +require one such object, but power users may require more than one. To start using +Z3, do -(** Context objects *) + + let ctx = (new context [||]) in + (...) + + +where [||] is a (possibly empty) list of pairs of strings, which can +be used to set options on the context, e.g., like so: + + + let cfg = [("model", "true"); ("...", "...")] in + let ctx = (new context cfg) in + (...) + + +*) class context settings = +(**/**) object (self) - inherit idisposable - val mutable m_n_ctx : Z3native.z3_context = let cfg = Z3native.mk_config in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = Z3native.mk_context_rc cfg in Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; v +(* CMW: Install error handler here! + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); +*) + val mutable m_obj_cnt : int = 0 initializer (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) let f = fun o -> o#dispose in let v = self in - Gc.finalise f v + Gc.finalise f v; method dispose : unit = if m_obj_cnt == 0 then ( @@ -47,13 +66,14 @@ object (self) method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 method gno = m_n_ctx +(**/**) end +(**/**) (** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) - inherit idisposable val mutable m_ctx : context = ctx_init val mutable m_n_obj : Z3native.ptr option = obj_init @@ -100,9 +120,10 @@ end (** Parameter set objects *) -class params ctx obj = +class params ctx = object (self) - inherit z3object ctx obj as super + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self method incref nc o = Z3native.params_inc_ref nc o method decref nc o = Z3native.params_dec_ref nc o end @@ -264,6 +285,10 @@ object (self) method decref nc o = super#decref nc o end +let func_declaton (a : func_decl array) = + let f (e : func_decl) = e#gno in + Array.map f a + class parameter = object (self) val mutable m_kind : parameter_kind = PARAMETER_INT; @@ -624,6 +649,10 @@ object (self) method decref nc o = Z3native.tactic_dec_ref nc o end +let tacticaton (a : tactic array) = + let f (e : tactic) = e#gno in + Array.map f a + (** Function interpretation entry objects *) class func_entry ctx = object (self) @@ -715,6 +744,15 @@ object (self) method decref nc o = Z3native.solver_dec_ref nc o end +(** Fixedpoint objects *) +class fixedpoint ctx = +object (self) + inherit z3object ctx None as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method incref nc o = Z3native.fixedpoint_inc_ref nc o + method decref nc o = Z3native.fixedpoint_dec_ref nc o +end + (**/**) @@ -1294,6 +1332,33 @@ struct x else (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) + +(** + Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. +*) + let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = + create_ast ctx ptr + +(** + Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. +*) + let unwrap_ast ( a : ast ) = a#gno end (** General expressions (terms), including Boolean logic *) @@ -1308,6 +1373,18 @@ struct | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) +(** + a string describing all available parameters to Expr.Simplify. +*) + let get_simplify_help ( ctx : context ) = + Z3native.simplify_get_help ctx#gno + +(** + Retrieves parameter descriptions for simplifier. +*) + let get_simplify_parameter_descrs ( ctx : context ) = + (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs ctx#gno) + (** The function declaration of the function that is applied in this expression. *) @@ -4087,6 +4164,30 @@ end *) module Params = struct +(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) +module ParamDescrs = +struct + + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno + + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size x#gnc x#gno in + let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno + + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno +end + (** Adds a parameter setting. *) @@ -4135,37 +4236,18 @@ struct let add_s_symbol (p : params) (name : string) (value : symbol) = add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value + (** + Creates a new parameter set + *) + let mk_params ( ctx : context ) = + (new params ctx)#cnstr_obj (Z3native.mk_params ctx#gno) + (** A string representation of the parameter set. *) let to_string (p : params) = Z3native.params_to_string p#gnc p#gno end -(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) -module ParamDescrs = -struct - - (** Validate a set of parameters. *) - let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) - - (** Retrieve all names of parameters. *) - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size x#gnc x#gno in - let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in - Array.init n f - - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - - (** Retrieves a string representation of the ParamDescrs. *) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno - -end - (** Goals A goal (aka problem). A goal is essentially a @@ -4258,6 +4340,22 @@ struct Z3native.tactic_dec_ref x#gnc tn ; (new goal x#gc)#cnstr_obj res + + (** + Creates a new Goal. + + Note that the Context must have been created with proof generation support if + is set to true here. + @param models Indicates whether model generation should be enabled. + @param unsat_cores Indicates whether unsat core generation should be enabled. + @param proofs Indicates whether proof generation should be enabled. + *) + let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = + (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno + (int_of_lbool (if models then L_TRUE else L_FALSE)) + (int_of_lbool (if unsat_cores then L_TRUE else L_FALSE)) + (int_of_lbool (if proofs then L_TRUE else L_FALSE))) + (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno end @@ -4272,6 +4370,33 @@ end *) module Tactic = struct +(** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) +module ApplyResult = +struct + (** The number of Subgoals. *) + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals x#gnc x#gno + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in + Array.init n f + + (** Convert a model for the subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g + *) + let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = + (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) + + (** A string representation of the ApplyResult. *) + let to_string ( x : apply_result ) = Z3native.apply_result_to_string x#gnc x#gno +end + (** A string containing a description of parameters accepted by the tactic. *) let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno @@ -4291,6 +4416,147 @@ struct let get_solver ( x : tactic ) = (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) + (** + The number of supported tactics. + *) + let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics ctx#gno + + (** + The names of all supported tactics. + *) + let get_tactic_names ( ctx : context ) = + let n = (get_num_tactics ctx ) in + let f i = (Z3native.get_tactic_name ctx#gno i) in + Array.init n f + + + (** + Returns a string containing a description of the tactic with the given name. + *) + let get_tactic_description ( ctx : context ) ( name : string ) = + Z3native.tactic_get_descr ctx#gno name + + (** + Creates a new Tactic. + *) + let mk_tactic ( ctx : context ) ( name : string ) = + (new tactic ctx)#cnstr_obj (Z3native.mk_tactic ctx#gno name) + + (** + Create a tactic that applies to a Goal and + then to every subgoal produced by . + *) + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array option ) = + match + match ts with + | None -> None + | Some(rts) -> ( + let f p c = (match p with + | None -> (Some c#gno) + | Some(x) -> (Some (Z3native.tactic_and_then ctx#gno c#gno x))) in + Array.fold_left f None rts) + with + | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno t2#gno) + | Some(x) -> + let o = (Z3native.tactic_and_then ctx#gno t2#gno x) in + (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno o) + + (** + Create a tactic that first applies to a Goal and + if it fails then returns the result of applied to the Goal. + *) + let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else ctx#gno t1#gno t2#gno) + + (** + Create a tactic that applies to a goal for milliseconds. + + If does not terminate within milliseconds, then it fails. + *) + let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for ctx#gno t#gno ms) + + (** + Create a tactic that applies to a given goal if the probe + evaluates to true. + + If evaluates to false, then the new tactic behaves like the skip tactic. + *) + (* CMW: when is a keyword *) + let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_when ctx#gno p#gno t#gno) + + (** + Create a tactic that applies to a given goal if the probe + evaluates to true and otherwise. + *) + let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) + + (** + Create a tactic that keeps applying until the goal is not + modified anymore or the maximum number of iterations is reached. + *) + let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat ctx#gno t#gno max) + + (** + Create a tactic that just returns the given goal. + *) + let skip ( ctx : context ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_skip ctx#gno) + + (** + Create a tactic always fails. + *) + let fail ( ctx : context ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail ctx#gno) + + (** + Create a tactic that fails if the probe evaluates to false. + *) + let fail_if ( ctx : context ) ( p : probe ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if ctx#gno p#gno) + + (** + Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). + *) + let fail_if_not_decided ( ctx : context ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided ctx#gno) + + (** + Create a tactic that applies using the given set of parameters . + *) + let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params ctx#gno t#gno p#gno) + + (** + Create a tactic that applies using the given set of parameters . + Alias for UsingParams*) + (* CMW: with is a keyword *) + let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = + using_params ctx t p + + (** + Create a tactic that applies the given tactics in parallel. + *) + let par_or ( ctx : context ) ( t : tactic array ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or ctx#gno (Array.length t) (tacticaton t)) + + (** + Create a tactic that applies to a given goal and then + to every subgoal produced by . The subgoals are processed in parallel. + *) + let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) + + (** + Interrupt the execution of a Z3 procedure. + This procedure can be used to interrupt: solvers, simplifiers and tactics. + *) + let interrupt ( ctx : context ) = + Z3native.interrupt ctx#gno end (** Models @@ -4337,7 +4603,7 @@ struct let to_string ( x : func_entry ) = let a = (get_args x) in let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]]") + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") end (** @@ -4513,33 +4779,6 @@ struct let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno end -(** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) -module ApplyResult = -struct - (** The number of Subgoals. *) - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals x#gnc x#gno - - (** Retrieves the subgoals from the apply_result. *) - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in - Array.init n f - - (** Convert a model for the subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g - *) - let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = - (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) - - (** A string representation of the ApplyResult. *) - let to_string ( x : apply_result) = Z3native.apply_result_to_string x#gnc x#gno -end - (** Solvers *) module Solver = struct @@ -4615,10 +4854,8 @@ struct let get ( x : statistics ) ( key : string ) = let f p c = (if (Entry.get_key c) = key then (Some c) else p) in Array.fold_left f None (get_entries x) - end - (** A string that describes all available solver parameters. *) @@ -4755,12 +4992,222 @@ struct let get_statistics ( x : solver ) = (new statistics x#gc)#cnstr_obj (Z3native.solver_get_statistics x#gnc x#gno) + (** + Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. + *) + let mk_solver ( ctx : context ) ( logic : symbol option) = + match logic with + | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver ctx#gno) + | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic ctx#gno x#gno) + + (** + Creates a new (incremental) solver. + + *) + let mk_solver_s ( ctx : context ) ( logic : string ) = + mk_solver ctx (Some ((Symbol.mk_string ctx logic) :> symbol)) + + (** + Creates a new (incremental) solver. + *) + let mk_simple_solver ( ctx : context ) = + (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver ctx#gno) + + (** + Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. + *) + let mk_solver_t ( ctx : context ) ( t : tactic ) = + (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic ctx#gno t#gno) + (** A string representation of the solver. *) let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno end +(** Fixedpoint solving *) +module Fixedpoints = +struct + (** + A string that describes all available fixedpoint solver parameters. + *) + let get_help ( x : fixedpoint ) = + Z3native.fixedpoint_get_help x#gnc x#gno + + (** + Sets the fixedpoint solver parameters. + *) + let set_params ( x : fixedpoint ) ( p : params )= + Z3native.fixedpoint_set_params x#gnc x#gno p#gno + + (** + Retrieves parameter descriptions for Fixedpoint solver. + *) + let get_param_descrs ( x : fixedpoint ) = + (new param_descrs x#gc)#cnstr_obj (Z3native.fixedpoint_get_param_descrs x#gnc x#gno) + + (** + Assert a constraints into the fixedpoint solver. + *) + let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = + let f e = (Z3native.fixedpoint_assert x#gnc x#gno e#gno) in + Array.map f constraints + + (** + Register predicate as recursive relation. + *) + let register_relation ( x : fixedpoint ) ( f : func_decl ) = + Z3native.fixedpoint_register_relation x#gnc x#gno f#gno + + (** + Add rule into the fixedpoint solver. + *) + let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = + match name with + | None -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno (Z3native.mk_null()) + | Some(y) -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno y#gno + + (** + Add table fact to the fixedpoint solver. + *) + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = + Z3native.fixedpoint_add_fact x#gnc x#gno pred#gno (Array.length args) args + + (** + Query the fixedpoint solver. + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. + *) + let query ( x : fixedpoint ) ( query : bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query x#gnc x#gno query#gno)) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + (** + Query the fixedpoint solver. + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. + *) + let query_r ( x : fixedpoint ) ( relations : func_decl array ) = + match (lbool_of_int (Z3native.fixedpoint_query_relations x#gnc x#gno (Array.length relations) (func_declaton relations))) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + (** + Creates a backtracking point. + + *) + let push ( x : fixedpoint ) = + Z3native.fixedpoint_push x#gnc x#gno + + (** + Backtrack one backtracking point. + + Note that an exception is thrown if Pop is called without a corresponding Push + + *) + let pop ( x : fixedpoint ) = + Z3native.fixedpoint_pop x#gnc x#gno + + (** + Update named rule into in the fixedpoint solver. + *) + let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = + Z3native.fixedpoint_update_rule x#gnc x#gno rule#gno name#gno + + (** + Retrieve satisfying instance or instances of solver, + or definitions for the recursive predicates that show unsatisfiability. + *) + let get_answer ( x : fixedpoint ) = + let q = (Z3native.fixedpoint_get_answer x#gnc x#gno) in + if (Z3native.is_null q) then + None + else + Some (create_expr x#gc q) + + (** + Retrieve explanation why fixedpoint engine returned status Unknown. + *) + let get_reason_unknown ( x : fixedpoint ) = + Z3native.fixedpoint_get_reason_unknown x#gnc x#gno + + (** + Retrieve the number of levels explored for a given predicate. + *) + let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = + Z3native.fixedpoint_get_num_levels x#gnc x#gno predicate#gno + + (** + Retrieve the cover of a predicate. + *) + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = + let q = (Z3native.fixedpoint_get_cover_delta x#gnc x#gno level predicate#gno) in + if (Z3native.is_null q) then + None + else + Some (create_expr x#gc q) + + (** + Add property about the predicate. + The property is added at level. + *) + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = + Z3native.fixedpoint_add_cover x#gnc x#gno level predicate#gno, property#gno + + (** + Retrieve internal string representation of fixedpoint object. + *) + let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string x#gnc x#gno 0 [||] + + (** + Instrument the Datalog engine on which table representation to use for recursive predicate. + *) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = + Z3native.fixedpoint_set_predicate_representation x#gnc x#gno f#gno (Array.length kinds) (symbolaton kinds) + + (** + Convert benchmark given as set of axioms, rules and queries to a string. + *) + let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = + Z3native.fixedpoint_to_string x#gnc x#gno (Array.length queries) (astaton queries) + + (** + Retrieve set of rules added to fixedpoint context. + *) + let get_rules ( x : fixedpoint ) = + let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_rules x#gnc x#gno)) in + let n = (AST.ASTVector.get_size v) in + let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + Array.init n f + + (** + Retrieve set of assertions added to fixedpoint context. + *) + let get_assertions ( x : fixedpoint ) = + let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_assertions x#gnc x#gno)) in + let n = (AST.ASTVector.get_size v) in + let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + Array.init n f + + (** + Create a Fixedpoint context. + *) + let mk_fixedpoint ( ctx : context ) = + (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint ctx#gno) +end + (** Probes Probes are used to inspect a goal (aka problem) and collect information that may be used to decide @@ -4778,660 +5225,333 @@ struct *) let apply ( x : probe ) (g : goal) = Z3native.probe_apply x#gnc x#gno g#gno + + (** + The number of supported Probes. + *) + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes ctx#gno + + (** + The names of all supported Probes. + *) + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name ctx#gno i) in + Array.init n f + + (** + Returns a string containing a description of the probe with the given name. + *) + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr ctx#gno name + + (** + Creates a new Probe. + *) + let mk_probe ( ctx : context ) ( name : string ) = + (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) + + (** + Create a probe that always evaluates to . + *) + let const ( ctx : context ) ( v : float ) = + (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by + *) + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by + *) + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by + *) + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by + *) + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by + *) + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + and evaluate to "true". + *) + (* CMW: and is a keyword *) + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + or evaluate to "true". + *) + (* CMW: or is a keyword *) + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". + *) + (* CMW: is not a keyword? *) + let not_ ( ctx : context ) ( p : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) end - -(* STUFF FROM THE CONTEXT *) - -(** -(* OPTIONS *) +(** Global and context options + + Note: This module contains functions that set parameters/options for context + objects as well as functions that set options that are used globally, across + contexts.*) +module Options = +struct (** - Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the Z3_PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + *) - - - - - public Z3_ast_print_mode PrintMode + let update_param_value ( ctx : context ) ( id : string) ( value : string )= + Z3native.update_param_value ctx#gno id value - set { Z3native.set_ast_print_mode ctx#gno (uint)value); } - -(* SMT Files & Strings *) (** - Convert a benchmark into an SMT-LIB formatted string. + Get a configuration parameter. + + Returns None if the parameter value does not exist. + *) - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - public string BenchmarkToSMTString(string name, string logic, string status, string attributes, - BoolExpr[] assumptions, BoolExpr formula) + let get_param_value ( ctx : context ) ( id : string ) = + let (r, v) = (Z3native.get_param_value ctx#gno id) in + if ((lbool_of_int r) == L_FALSE) then + None + else + Some v - Z3native.benchmark_to_smtlib_string ctx#gno name, logic, status, attributes, - (uint)assumptions.Length, AST.ArrayToNative(assumptions), - formula#gno); + (** + Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + + + + + *) + let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = + Z3native.set_ast_print_mode ctx#gno (int_of_ast_print_mode value) (** - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. + Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) - public void ParseSMTLIBString(string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) + let toggle_warning_messages ( enabled: bool ) = + Z3native.toggle_warning_messages (int_of_lbool (if enabled then L_TRUE else L_FALSE)) +end - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) +(** Functions for handling SMT and SMT2 expressions and files *) +module SMT = +struct + (** + Convert a benchmark into an SMT-LIB formatted string. -(** - Parse the given file using the SMT-LIB parser. -*) - - public void ParseSMTLIBFile(string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Z3native.parse_smtlib_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls) - -(** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBFormulas { get {Z3native.get_smtlib_num_formulas ctx#gno)) - -(** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - let[] SMTLIBFormulas - - get - - uint n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_formula ctx#gno i) - res; - - -(** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBAssumptions { get {Z3native.get_smtlib_num_assumptions ctx#gno)) - -(** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - let[] SMTLIBAssumptions - - get - - uint n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (uint i = 0; i < n; i++) - res[i] = (BoolExpr)create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i) - res; - - -(** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBDecls { get {Z3native.get_smtlib_num_decls ctx#gno)) - -(** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public Func_Decl[] SMTLIBDecls - - get - - uint n = NumSMTLIBDecls; - Func_Decl[] res = new Func_Decl[n]; - for (uint i = 0; i < n; i++) - res[i] = new Func_Decl(this, Z3native.get_smtlib_decl ctx#gno i) - res; - - -(** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public uint NumSMTLIBSorts { get {Z3native.get_smtlib_num_sorts ctx#gno)) - -(** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. -*) - public Sort[] SMTLIBSorts - - get - - uint n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (uint i = 0; i < n; i++) - res[i] = Sort.Create(this, Z3native.get_smtlib_sort ctx#gno i) - res; - - -(** - Parse the given string using the SMT-LIB2 parser. -*) - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - let ParseSMTLIB2String ( ctx : context ) string str, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_string ctx#gno str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) - -(** - Parse the given file using the SMT-LIB2 parser. -*) - - let ParseSMTLIB2File ( ctx : context ) string fileName, Symbol[] sortNames = null, Sort[] sorts = null, Symbol[] declNames = null, Func_Decl[] decls = null) - - uint csn = Symbol.ArrayLength(sortNames); - uint cs = Sort.ArrayLength(sorts); - uint cdn = Symbol.ArrayLength(declNames); - uint cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - (BoolExpr)create_expr ctx (Z3native.parse_smtlib2_file ctx#gno fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)) - -(* GOALS *) -(** - Creates a new Goal. - - Note that the Context must have been created with proof generation support if - is set to true here. -*) - @param models Indicates whether model generation should be enabled. - @param unsatCores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - public Goal MkGoal(bool models = true, bool unsatCores = false, bool proofs = false) - - new Goal(this, models, unsatCores, proofs); - -(* PARAMETERSETS *) -(** - Creates a new ParameterSet. -*) - public Params MkParams ( ctx : context ) = - - new Params(this); - -(* TACTICS *) -(** - The number of supported tactics. -*) - public uint NumTactics - - get {Z3native.get_num_tactics ctx#gno); } - -(** - The names of all supported tactics. -*) - public string[] TacticNames - - get - - uint n = NumTactics; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_tactic_name ctx#gno i); - res; - - -(** - Returns a string containing a description of the tactic with the given name. -*) - public string TacticDescription(string name) - - Z3native.tactic_get_descr ctx#gno name); - -(** - Creates a new Tactic. -*) - public Tactic MkTactic(string name) - - new Tactic(this, name); - -(** - Create a tactic that applies to a Goal and - then to every subgoal produced by . -*) - public Tactic AndThen(Tactic t1, Tactic t2, params Tactic[] ts) - - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) - - last = ts[ts.Length - 1]#gno; - for (int i = ts.Length - 2; i >= 0; i--) - last = Z3native.tactic_and_then ctx#gno ts[i]#gno last); - - if (last != IntPtr.Zero) - - last = Z3native.tactic_and_then ctx#gno t2#gno last); - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno last) + @param name Name of the benchmark. The argument is optional. + @param logic The benchmark logic. + @param status The status string (sat, unsat, or unknown) + @param attributes Other attributes, such as source, difficulty or category. + @param assumptions Auxiliary assumptions. + @param formula Formula to be checked for consistency in conjunction with assumptions. + @return A string representation of the benchmark. + *) + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = + Z3native.benchmark_to_smtlib_string ctx#gno name logic status attributes + (Array.length assumptions) (astaton assumptions) + formula#gno + (** + Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays and + don't need to match the names of the sorts and declarations in the arrays + and . This is a useful feature since we can use arbitrary names to + reference sorts and declarations. + *) + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") else - new Tactic(this, Z3native.tactic_and_then ctx#gno t1#gno t2#gno) - -(** - Create a tactic that applies to a Goal and - then to every subgoal produced by . - - Shorthand for AndThen. -*) - public Tactic Then(Tactic t1, Tactic t2, params Tactic[] ts) - - AndThen(t1, t2, ts); - -(** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. -*) - public Tactic OrElse(Tactic t1, Tactic t2) - - new Tactic(this, Z3native.tactic_or_else ctx#gno t1#gno t2#gno) - -(** - Create a tactic that applies to a goal for milliseconds. - - If does not terminate within milliseconds, then it fails. -*) - public Tactic TryFor(Tactic t, uint ms) - - new Tactic(this, Z3native.tactic_try_for ctx#gno t#gno ms) - -(** - Create a tactic that applies to a given goal if the probe - evaluates to true. - - If evaluates to false, then the new tactic behaves like the skip tactic. -*) - public Tactic When(Probe p, Tactic t) - - new Tactic(this, Z3native.tactic_when ctx#gno p#gno t#gno) - -(** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. -*) - public Tactic Cond(Probe p, Tactic t1, Tactic t2) - - new Tactic(this, Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) - -(** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. -*) - public Tactic Repeat(Tactic t, uint max = uint.MaxValue) - - new Tactic(this, Z3native.tactic_repeat ctx#gno t#gno max) - -(** - Create a tactic that just returns the given goal. -*) - public Tactic Skip ( ctx : context ) = - - new Tactic(this, Z3native.tactic_skip ctx#gno) - -(** - Create a tactic always fails. -*) - public Tactic Fail ( ctx : context ) = - - new Tactic(this, Z3native.tactic_fail ctx#gno) - -(** - Create a tactic that fails if the probe evaluates to false. -*) - public Tactic FailIf(Probe p) - - new Tactic(this, Z3native.tactic_fail_if ctx#gno p#gno) - -(** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). -*) - public Tactic FailIfNotDecided ( ctx : context ) = - - new Tactic(this, Z3native.tactic_fail_if_not_decided ctx#gno) - -(** - Create a tactic that applies using the given set of parameters . -*) - public Tactic UsingParams(Tactic t, Params p) - - new Tactic(this, Z3native.tactic_using_params ctx#gno t#gno p#gno) - -(** - Create a tactic that applies using the given set of parameters . - Alias for UsingParams*) - public Tactic With(Tactic t, Params p) - - UsingParams(t, p); - -(** - Create a tactic that applies the given tactics in parallel. -*) - public Tactic ParOr(params Tactic[] t) - - new Tactic(this, Z3native.tactic_par_or ctx#gno Tactic.ArrayLength(t), Tactic.ArrayToNative(t)) - -(** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. -*) - public Tactic ParAndThen(Tactic t1, Tactic t2) - - new Tactic(this, Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) - -(** - Interrupt the execution of a Z3 procedure. -*) - This procedure can be used to interrupt: solvers, simplifiers and tactics. - public void Interrupt ( ctx : context ) = - - Z3native.interrupt ctx#gno); - -(* PROBES *) -(** - The number of supported Probes. -*) - public uint NumProbes - - get {Z3native.get_num_probes ctx#gno); } - -(** - The names of all supported Probes. -*) - public string[] ProbeNames - - get - - uint n = NumProbes; - string[] res = new string[n]; - for (uint i = 0; i < n; i++) - res[i] = Z3native.get_probe_name ctx#gno i); - res; - - -(** - Returns a string containing a description of the probe with the given name. -*) - public string ProbeDescription(string name) - - Z3native.probe_get_descr ctx#gno name); - -(** - Creates a new Probe. -*) - public Probe MkProbe(string name) - - new Probe(this, name); - -(** - Create a probe that always evaluates to . -*) - public Probe Const(double val) - - new Probe(this, Z3native.probe_const ctx#gno val) - -(** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by -*) - public Probe Lt(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_lt ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by -*) - public Probe Gt(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_gt ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by -*) - public Probe Le(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_le ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by -*) - public Probe Ge(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_ge ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by -*) - public Probe Eq(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_eq ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value - and evaluate to "true". -*) - public Probe And(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_and ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value - or evaluate to "true". -*) - public Probe Or(Probe p1, Probe p2) - - new Probe(this, Z3native.probe_or ctx#gno p1#gno p2#gno) - -(** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". -*) - public Probe Not(Probe p) - - new Probe(this, Z3native.probe_not ctx#gno p#gno) - -(* SOLVERS *) -(** - Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. -*) - public Solver MkSolver(Symbol logic = null) - - if (logic == null) - new Solver(this, Z3native.mk_solver ctx#gno) + Z3native.parse_smtlib_string ctx#gno str + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + + (** + Parse the given file using the SMT-LIB parser. + + *) + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") else - new Solver(this, Z3native.mk_solver_for_logic ctx#gno logic#gno) + Z3native.parse_smtlib_file ctx#gno file_name + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (** + The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas ctx#gno -(** - Creates a new (incremental) solver. -*) - - public Solver MkSolver(string logic) + (** + The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_formulas ( ctx : context ) = + let n = (get_num_smtlib_formulas ctx ) in + let f i = ((create_expr ctx (Z3native.get_smtlib_formula ctx#gno i)) :> bool_expr) in + Array.init n f - MkSolver(MkSymbol(logic) -(** - Creates a new (incremental) solver. -*) - let mk_Simple_Solver( ctx : context ) ctx : context ) = + (** + The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions ctx#gno - new Solver(this, Z3native.mk_simple_solver ctx#gno) + (** + The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_assumptions ( ctx : context ) = + let n = (get_num_smtlib_assumptions ctx ) in + let f i = ((create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i)) :> bool_expr ) in + Array.init n f -(** - Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. -*) - public Solver MkSolver(Tactic t) + (** + The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls ctx#gno - new Solver(this, Z3native.mk_solver_from_tactic ctx#gno t#gno) + (** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_decls ( ctx : context ) = + let n = (get_num_smtlib_decls ctx) in + let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl ctx#gno i) in + Array.init n f -(* FIXEDPOINTS *) -(** - Create a Fixedpoint context. -*) - public Fixedpoint MkFixedpoint ( ctx : context ) = + (** + The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts ctx#gno - new Fixedpoint(this); + (** + The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. + *) + let get_smtlib_sorts ( ctx : context ) = + let n = (get_num_smtlib_sorts ctx) in + let f i = (create_sort ctx (Z3native.get_smtlib_sort ctx#gno i)) in + Array.init n f -(* MISCELLANEOUS *) -(** - Wraps an AST. -*) - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - public AST WrapAST(IntPtr nativeObject) + (** + Parse the given string using the SMT-LIB2 parser. - AST.Create(this, nativeObject); - -(** - Unwraps an AST. -*) - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - public IntPtr UnwrapAST(AST a) - - a#gno; - -(** - a string describing all available parameters to Expr.Simplify. -*) - public string SimplifyHelp ( ctx : context ) = - - Z3native.simplify_get_help ctx#gno); - -(** - Retrieves parameter descriptions for simplifier. -*) - public ParamDescrs SimplifyParameterDescriptions - - get {new ParamDescrs(this, Z3native.simplify_get_param_descrs ctx#gno)); } - -(** - Enable/disable printing of warning messages to the console. -*) - Note that this function is static and effects the behaviour of - all contexts globally. - public static void ToggleWarningMessages(bool enabled) - - Z3native.toggle_warning_messages((enabled) ? 1 : 0); - -(* ERROR HANDLING *) -(** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. -*) - public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, string errorString); - -(** - The OnError event. -*) - public event ErrorHandler OnError = null; - -(* PARAMETERS *) -(** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. -*) - - public void UpdateParamValue(string id, string value) - - Z3native.update_param_value ctx#gno id, value); - -(** - Get a configuration parameter. - - Returns null if the parameter value does not exist. - -*) - public string GetParamValue(string id) - - IntPtr res = IntPtr.Zero; - int r = Z3native.get_param_value ctx#gno id, out res); - if (r == (int)Z3_lbool.L_FALSE) - null; + + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. + *) + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") else - Marshal.PtrToStringAnsi(res); + Z3native.parse_smtlib2_string ctx#gno str + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) -(* INTERNAL *) - internal IntPtr m_ctx = IntPtr.Zero; - internal Z3native.error_handler m_n_err_handler = null; - internal IntPtr nCtx { get {m_ctx) + (** + Parse the given file using the SMT-LIB2 parser. + + *) + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = + let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in + let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in + let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in + let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Z3native.parse_smtlib2_string ctx#gno file_name + cs + (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match sorts with | None -> [||] | Some(x) -> (astaton x)) + cd + (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) + (match decls with | None -> [||] | Some(x) -> (func_declaton x)) +end - internal void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) +(* - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. +(** + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. +*) + public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); - internal void InitContext ( ctx : context ) = + internal Z3native.error_handler m_n_err_handler = null; - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); + internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) + + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. *) From c2ff90720e6a7c08e096c096cdcc4cd7feb4b5b3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Dec 2012 03:00:39 +0000 Subject: [PATCH 369/507] ML API: mk_context added. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 4 +- src/api/ml/z3.ml | 687 +++++++++++++++++++------------------- 2 files changed, 349 insertions(+), 342 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index dde9f944a..32c9458f5 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -14,8 +14,8 @@ let _ = else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = [("model", "true"); ("proof", "false")] in - let ctx = (new context cfg) in + let cfg = (Some [("model", "true"); ("proof", "false")]) in + let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in let ss = (Symbol.mk_string ctx "mySymbol") in let bs = (Sort.mk_bool ctx) in diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 088bfbd6f..fee6f9fe0 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,29 +7,9 @@ open Z3enums -(** Context objects. - -Most interactions with Z3 are interpreted in some context; most users will only -require one such object, but power users may require more than one. To start using -Z3, do - - - let ctx = (new context [||]) in - (...) - - -where [||] is a (possibly empty) list of pairs of strings, which can -be used to set options on the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (new context cfg) in - (...) - - -*) -class context settings = (**/**) + +class context settings = object (self) val mutable m_n_ctx : Z3native.z3_context = let cfg = Z3native.mk_config in @@ -66,11 +46,37 @@ object (self) method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 method gno = m_n_ctx -(**/**) end (**/**) +(** Create a context object. + +Most interactions with Z3 are interpreted in some context; many users will only +require one such object, but power users may require more than one. To start using +Z3, do + + + let ctx = (mk_context None) in + (...) + + +where a list of pairs of strings may be passed to set options on +the context, e.g., like so: + + + let cfg = (Some [("model", "true"); ("...", "...")]) in + let ctx = (mk_context cfg) in + (...) + +*) +let mk_context ( cfg : ( string * string ) list option ) = + match cfg with + | None -> new context [] + | Some(x) -> new context x + +(**/**) + (** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) @@ -4559,224 +4565,114 @@ end Z3native.interrupt ctx#gno end -(** Models +(** Probes - A Model contains interpretations (assignments) of constants and functions. *) -module Model = + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe = struct - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. - *) - module FuncInterp = - struct - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) - module FuncEntry = - struct - (** - Return the (symbolic) value of this entry. - *) - let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) - - (** - The number of arguments of the entry. - *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno - - (** - The arguments of the function entry. - *) - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the function entry. - *) - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - (** - The number of entries in the function interpretation. - *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno - - (** - The entries in the function interpretation - *) - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in - Array.init n f - - (** - The (symbolic) `else' value of the function interpretation. - *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) - - (** - The arity of the function interpretation - *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno - - (** - A string representation of the function interpretation. - *) - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (Array.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - (** Retrieves the interpretation (the assignment) of in the model. - A function declaration of zero arity - An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null np) then - None - else - Some (create_expr x#gc np) - - (** Retrieves the interpretation (the assignment) of in the model. - A Constant - An expression if the constant has an interpretation in the model, null otherwise. - *) - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - (** Retrieves the interpretation (the assignment) of a non-constant in the model. - A function declaration of non-zero arity - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl x#gnc n in - get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in - if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno - - (** The function declarations of the constants in the model. *) - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.init n f - - - (** The number of function interpretations in the model. *) - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno - - (** The function declarations of the function interpretations in the model. *) - let get_func_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - Array.init n f - - (** All symbols that have an interpretation in the model. *) - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.append (Array.init n_funcs f) (Array.init n_consts g) - - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - (** - Evaluates the expression in the current model. - - - This function may fail if contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - - An expression - - When this flag is enabled, a model value will be assigned to any constant - or function that does not have an interpretation in the model. - - The evaluation of in the model. + Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in - if (lbool_of_int r) == L_FALSE then - raise (ModelEvaluationFailedException "evaluation failed") - else - create_expr x#gc v + let apply ( x : probe ) (g : goal) = + Z3native.probe_apply x#gnc x#gno g#gno - (** Alias for eval. *) - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - (** The number of uninterpreted sorts that the model has an interpretation for. *) - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - - + (** + The number of supported Probes. *) - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes ctx#gno + + (** + The names of all supported Probes. + *) + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name ctx#gno i) in Array.init n f + (** + Returns a string containing a description of the probe with the given name. + *) + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr ctx#gno name - (** The finite set of distinct values that represent the interpretation for sort . - - An uninterpreted sort - An array of expressions, where each is an element of the universe of + (** + Creates a new Probe. + *) + let mk_probe ( ctx : context ) ( name : string ) = + (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) + + (** + Create a probe that always evaluates to . *) - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - Array.init n f - - (** Conversion of models to strings. - A string representation of the model. + let const ( ctx : context ) ( v : float ) = + (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by *) - let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by + *) + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by + *) + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by + *) + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by + *) + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + and evaluate to "true". + *) + (* CMW: and is a keyword *) + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + or evaluate to "true". + *) + (* CMW: or is a keyword *) + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) + + (** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". + *) + (* CMW: is not a keyword? *) + let not_ ( ctx : context ) ( p : probe ) = + (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) end (** Solvers *) @@ -5032,6 +4928,227 @@ struct let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno end + +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model = +struct + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. + *) + module FuncInterp = + struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + + (** Retrieves the interpretation (the assignment) of in the model. + A function declaration of zero arity + An expression if the function has an interpretation in the model, null otherwise. *) + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null np) then + None + else + Some (create_expr x#gc np) + + (** Retrieves the interpretation (the assignment) of in the model. + A Constant + An expression if the constant has an interpretation in the model, null otherwise. + *) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + (** Retrieves the interpretation (the assignment) of a non-constant in the model. + A function declaration of non-zero arity + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl x#gnc n in + get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in + if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno + + (** The function declarations of the constants in the model. *) + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.init n f + + + (** The number of function interpretations in the model. *) + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno + + (** The function declarations of the function interpretations in the model. *) + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + Array.init n f + + (** All symbols that have an interpretation in the model. *) + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in + let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in + Array.append (Array.init n_funcs f) (Array.init n_consts g) + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** + Evaluates the expression in the current model. + + + This function may fail if contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + + An expression + + When this flag is enabled, a model value will be assigned to any constant + or function that does not have an interpretation in the model. + + The evaluation of in the model. + *) + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in + if (lbool_of_int r) == L_FALSE then + raise (ModelEvaluationFailedException "evaluation failed") + else + create_expr x#gc v + + (** Alias for eval. *) + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + + + *) + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in + Array.init n f + + + (** The finite set of distinct values that represent the interpretation for sort . + + An uninterpreted sort + An array of expressions, where each is an element of the universe of + *) + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in + Array.init n f + + (** Conversion of models to strings. + A string representation of the model. + *) + let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno +end + (** Fixedpoint solving *) module Fixedpoints = struct @@ -5208,116 +5325,6 @@ struct (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint ctx#gno) end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Probe = -struct - (** - Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - *) - let apply ( x : probe ) (g : goal) = - Z3native.probe_apply x#gnc x#gno g#gno - - (** - The number of supported Probes. - *) - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes ctx#gno - - (** - The names of all supported Probes. - *) - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name ctx#gno i) in - Array.init n f - - (** - Returns a string containing a description of the probe with the given name. - *) - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr ctx#gno name - - (** - Creates a new Probe. - *) - let mk_probe ( ctx : context ) ( name : string ) = - (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) - - (** - Create a probe that always evaluates to . - *) - let const ( ctx : context ) ( v : float ) = - (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by - *) - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by - *) - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by - *) - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by - *) - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by - *) - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". - *) - (* CMW: and is a keyword *) - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". - *) - (* CMW: or is a keyword *) - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". - *) - (* CMW: is not a keyword? *) - let not_ ( ctx : context ) ( p : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) -end - (** Global and context options Note: This module contains functions that set parameters/options for context From 25498345e54f30d7f7b3095b41e3707eeb3217b2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 24 Dec 2012 15:16:16 +0000 Subject: [PATCH 370/507] New ML API bugfixes and first example. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 122 ++++++++++++++++++++++++++++++++++++++ scripts/update_api.py | 10 +++- src/api/ml/z3.ml | 112 +++++++++++++++++----------------- 3 files changed, 186 insertions(+), 58 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 32c9458f5..945c9a494 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -4,10 +4,131 @@ *) open Z3 +open Z3.Symbol +open Z3.Sort +open Z3.Expr +open Z3.FuncDecl +open Z3.Goal +open Z3.Tactic +open Z3.Probe +open Z3.Solver open Z3.Arithmetic exception ExampleException of string + +(** + Some basic tests. +*) +let basic_tests ( ctx : context ) = + Printf.printf "BasicTests\n" ; + let qi = (mk_int ctx 1) in + let fname = ((mk_string ctx "f") :> symbol) in + let x = ((mk_string ctx "x") :> symbol) in + let y = ((mk_string ctx "y") :> symbol) in + let bs = (Sort.mk_bool ctx) in + let domain = [| bs; bs |] in + let f = (FuncDecl.mk_func_decl ctx fname domain bs) in + let fapp = (mk_app ctx f + [| (mk_const ctx x bs); (mk_const ctx y bs) |]) in + let fargs2 = [| (mk_fresh_const ctx "cp" bs) |] in + let domain2 = [| bs |] in + let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in + let trivial_eq = (mk_eq ctx fapp fapp) in + let nontrivial_eq = (mk_eq ctx fapp fapp2) in + let g = (mk_goal ctx true false false) in + (Goal.assert_ g [| trivial_eq |]) ; + (Goal.assert_ g [| nontrivial_eq |]) ; + Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; + let solver = (mk_solver ctx None) in + (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; + if (check solver None) != SATISFIABLE then + raise (ExampleException "") + else + Printf.printf "Test passed.\n" ; + () + +(* + ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); + if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) + throw new TestFailedException(); + + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + + g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), + ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + + Goal g2 = ctx.MkGoal(true, true); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) + throw new TestFailedException(); + + g2 = ctx.MkGoal(true, true); + g2.Assert(ctx.MkFalse()); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + Goal g3 = ctx.MkGoal(true, true); + Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); + Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); + g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); + g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort))); + BoolExpr constr = ctx.MkEq(xc, yc); + g3.Assert(constr); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); + if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) + throw new TestFailedException(); + + ModelConverterTest(ctx); + + // Real num/den test. + RatNum rn = ctx.MkReal(42, 43); + Expr inum = rn.Numerator; + Expr iden = rn.Denominator; + Console.WriteLine("Numerator: " + inum + " Denominator: " + iden); + if (inum.ToString() != "42" || iden.ToString() != "43") + throw new TestFailedException(); + + if (rn.ToDecimalString(3) != "0.976?") + throw new TestFailedException(); + + BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-234234333")); + BigIntCheck(ctx, ctx.MkReal("234234333/2")); + + + string bn = "1234567890987654321"; + + if (ctx.MkInt(bn).BigInteger.ToString() != bn) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 128).BigInteger.ToString() != bn) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn) + throw new TestFailedException(); + + // Error handling test. + try + { + IntExpr i = ctx.MkInt("1/2"); + throw new TestFailedException(); // unreachable + } + catch (Z3Exception) + { + } + } +*) + + let _ = if not (Log.open_ "z3.log") then raise (ExampleException "Log couldn't be opened.") @@ -27,6 +148,7 @@ let _ = Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); Printf.printf "Disposing...\n"; + basic_tests ctx ; Gc.full_major () ); Printf.printf "Exiting.\n"; diff --git a/scripts/update_api.py b/scripts/update_api.py index acaa9478e..5d95a12f8 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -159,7 +159,7 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I # Mapping to ML types Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', STRING : 'string', STRING_PTR : 'char**', - BOOL : 'int', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } + BOOL : 'bool', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID @@ -1109,7 +1109,9 @@ def arrayparams(params): def ml_unwrap(t, ts, s): if t == STRING: return '(' + ts + ') String_val(' + s + ')' - elif t == BOOL or t == INT or t == PRINT_MODE or t == ERROR_CODE: + elif t == BOOL: + return '(' + ts + ') Bool_val(' + s + ')' + elif t == INT or t == PRINT_MODE or t == ERROR_CODE: return '(' + ts + ') Int_val(' + s + ')' elif t == UINT: return '(' + ts + ') Unsigned_int_val(' + s + ')' @@ -1125,7 +1127,9 @@ def ml_unwrap(t, ts, s): def ml_set_wrap(t, d, n): if t == VOID: return d + ' = Val_unit;' - elif t == BOOL or t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: + elif t == BOOL: + return d + ' = Val_bool(' + n + ');' + elif t == INT or t == UINT or t == PRINT_MODE or t == ERROR_CODE: return d + ' = Val_int(' + n + ');' elif t == INT64 or t == UINT64: return d + ' = Val_long(' + n + ');' diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index fee6f9fe0..b4d58711c 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -874,7 +874,7 @@ struct if a#gnc != b#gnc then false else - ((lbool_of_int (Z3native.is_eq_sort a#gnc a#gno b#gno)) == L_TRUE) + (Z3native.is_eq_sort a#gnc a#gno b#gno) (** Returns a unique identifier for the sort. @@ -922,10 +922,10 @@ let create_expr ctx obj = else let s = Z3native.get_sort ctx#gno obj in let sk = (sort_kind_of_int (Z3native.get_sort_kind ctx#gno s)) in - if (lbool_of_int (Z3native.is_algebraic_number ctx#gno obj) == L_TRUE) then + if (Z3native.is_algebraic_number ctx#gno obj) then (((new algebraic_num ctx)#cnstr_obj obj) :> expr) else - if ((lbool_of_int (Z3native.is_numeral_ast ctx#gno obj)) == L_TRUE) && + if (Z3native.is_numeral_ast ctx#gno obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) @@ -1016,6 +1016,7 @@ struct raise (Z3native.Exception "parameter is not a ratinoal string") else x#rational + end (** Creates a new function declaration. @@ -1058,7 +1059,6 @@ struct let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = (new func_decl ctx)#cnstr_pdr prefix [||] range - end (** Comparison operator. @@ -1071,7 +1071,7 @@ struct if a#gnc == a#gnc then false else - ((lbool_of_int (Z3native.is_eq_func_decl a#gnc a#gno b#gno)) == L_TRUE) + (Z3native.is_eq_func_decl a#gnc a#gno b#gno) (** A string representations of the function declaration. *) @@ -1202,7 +1202,7 @@ struct @param k An AST @return True if is a key in the map, false otherwise. *) let contains ( m : ast_map ) ( key : ast ) = - (lbool_of_int (Z3native.ast_map_contains m#gnc m#gno key#gno)) == L_TRUE + (Z3native.ast_map_contains m#gnc m#gno key#gno) (** Finds the value associated with the key . @@ -1313,7 +1313,7 @@ struct if a#gnc == b#gnc then false else - ((lbool_of_int (Z3native.is_eq_ast a#gnc a#gno b#gno)) == L_TRUE) + (Z3native.is_eq_ast a#gnc a#gno b#gno) (** Object Comparison. @@ -1472,13 +1472,13 @@ struct (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno) == L_TRUE + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast x#gnc x#gno) (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = lbool_of_int (Z3native.is_well_sorted x#gnc x#gno) == L_TRUE + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted x#gnc x#gno (** The Sort of the term. @@ -1489,9 +1489,9 @@ struct Indicates whether the term has Boolean sort. *) let is_bool ( x : expr ) = (AST.is_expr x) && - (lbool_of_int (Z3native.is_eq_sort x#gnc - (Z3native.mk_bool_sort x#gnc) - (Z3native.get_sort x#gnc x#gno))) == L_TRUE + (Z3native.is_eq_sort x#gnc + (Z3native.mk_bool_sort x#gnc) + (Z3native.get_sort x#gnc x#gno)) (** Indicates whether the term represents a constant. @@ -1774,7 +1774,7 @@ struct Indicates whether the quantifier is universal. *) let is_universal ( x : quantifier ) = - lbool_of_int (Z3native.is_quantifier_forall x#gnc x#gno) == L_TRUE + Z3native.is_quantifier_forall x#gnc x#gno (** Indicates whether the quantifier is existential. @@ -1879,7 +1879,7 @@ struct if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) (match patterns with | None -> [||] | Some(x) -> (patternaton x)) @@ -1888,7 +1888,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -1905,7 +1905,7 @@ struct *) let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) @@ -1913,7 +1913,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_TRUE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -1931,7 +1931,7 @@ struct if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) (match patterns with | None -> [||] | Some(x) -> (patternaton x)) @@ -1940,7 +1940,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -1957,7 +1957,7 @@ struct *) let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) (match patterns with | None -> 0 | Some(x) -> (Array.length x)) @@ -1965,7 +1965,7 @@ struct body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno (int_of_lbool L_FALSE) + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) @@ -2046,7 +2046,7 @@ struct Indicates whether the term is of an array sort. *) let is_array ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (Z3native.is_app x#gnc x#gno) && ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) (** The domain of the array sort. *) @@ -2252,7 +2252,7 @@ struct Indicates whether the term is of an array sort. *) let is_finite_domain ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && + (Z3native.is_app x#gnc x#gno) && (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) (** @@ -2263,7 +2263,7 @@ struct (** The size of the finite domain sort. *) let get_size (x : finite_domain_sort) = let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v + if r then v else raise (Z3native.Exception "Conversion failed.") end @@ -2274,8 +2274,8 @@ struct Indicates whether the term is of a relation sort. *) let is_relation ( x : expr ) = - ((lbool_of_int (Z3native.is_app x#gnc x#gno)) == L_TRUE) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT) + ((Z3native.is_app x#gnc x#gno) && + (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT)) (** Indicates whether the term is an relation store @@ -2604,7 +2604,7 @@ struct Indicates whether the term is of integer sort. *) let is_int ( x : expr ) = - ((lbool_of_int (Z3native.is_numeral_ast x#gnc x#gno)) == L_TRUE) && + (Z3native.is_numeral_ast x#gnc x#gno) && ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) (** @@ -2706,12 +2706,13 @@ struct (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : expr ) = lbool_of_int(Z3native.is_algebraic_number x#gnc x#gno) == L_TRUE + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number x#gnc x#gno (** Retrieve the int value. *) - let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") + let get_int ( x : int_num ) = + let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if r then v + else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3219,9 +3220,10 @@ struct let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno (** Retrieve the int value. *) - let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if lbool_of_int(r) == L_TRUE then v - else raise (Z3native.Exception "Conversion failed.") + let get_int ( x : bitvec_num ) = + let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + if r then v + else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3613,7 +3615,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3621,7 +3623,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3645,7 +3647,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3669,7 +3671,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno (int_of_lbool (if (signed) then L_TRUE else L_FALSE))) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -4198,7 +4200,7 @@ end Adds a parameter setting. *) let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno (int_of_lbool (if value then L_TRUE else L_FALSE)) + Z3native.params_set_bool p#gnc p#gno name#gno value (** Adds a parameter setting. @@ -4291,11 +4293,12 @@ struct (* CMW: assert seems to be a keyword. *) let assert_ ( x : goal ) ( constraints : bool_expr array ) = let f e = Z3native.goal_assert x#gnc x#gno e#gno in - Array.map f constraints + ignore (Array.map f constraints) ; + () (** Indicates whether the goal contains `false'. *) let is_inconsistent ( x : goal ) = - (lbool_of_int (Z3native.goal_inconsistent x#gnc x#gno)) == L_TRUE + Z3native.goal_inconsistent x#gnc x#gno (** The depth of the goal. This tracks how many transformations were applied to it. *) @@ -4318,11 +4321,11 @@ struct (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) let is_decided_sat ( x : goal ) = - (lbool_of_int (Z3native.goal_is_decided_sat x#gnc x#gno)) == L_TRUE + Z3native.goal_is_decided_sat x#gnc x#gno (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) let is_decided_unsat ( x : goal ) = - (lbool_of_int (Z3native.goal_is_decided_unsat x#gnc x#gno)) == L_TRUE + Z3native.goal_is_decided_unsat x#gnc x#gno (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = @@ -4357,10 +4360,7 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno - (int_of_lbool (if models then L_TRUE else L_FALSE)) - (int_of_lbool (if unsat_cores then L_TRUE else L_FALSE)) - (int_of_lbool (if proofs then L_TRUE else L_FALSE))) + (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno models unsat_cores proofs) (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno @@ -4729,7 +4729,7 @@ struct let n = (get_size x ) in let f i = ( let k = Z3native.stats_get_key x#gnc x#gno i in - if (lbool_of_int (Z3native.stats_is_uint x#gnc x#gno i)) == L_TRUE then + if (Z3native.stats_is_uint x#gnc x#gno i) then ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) else ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) @@ -4800,7 +4800,8 @@ struct *) let assert_ ( x : solver ) ( constraints : bool_expr array ) = let f e = (Z3native.solver_assert x#gnc x#gno e#gno) in - Array.map f constraints + ignore (Array.map f constraints) ; + () (** The number of assertions in the solver. @@ -5049,7 +5050,7 @@ struct else match sk with | ARRAY_SORT -> - if (lbool_of_int (Z3native.is_as_array x#gnc n)) == L_FALSE then + if not (Z3native.is_as_array x#gnc n) then raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl x#gnc n in @@ -5105,8 +5106,8 @@ struct The evaluation of in the model. *) let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno (int_of_lbool (if completion then L_TRUE else L_FALSE))) in - if (lbool_of_int r) == L_FALSE then + let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno completion) in + if not r then raise (ModelEvaluationFailedException "evaluation failed") else create_expr x#gc v @@ -5175,7 +5176,8 @@ struct *) let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = let f e = (Z3native.fixedpoint_assert x#gnc x#gno e#gno) in - Array.map f constraints + ignore (Array.map f constraints) ; + () (** Register predicate as recursive relation. @@ -5353,7 +5355,7 @@ struct *) let get_param_value ( ctx : context ) ( id : string ) = let (r, v) = (Z3native.get_param_value ctx#gno id) in - if ((lbool_of_int r) == L_FALSE) then + if not r then None else Some v @@ -5383,7 +5385,7 @@ struct all contexts globally. *) let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages (int_of_lbool (if enabled then L_TRUE else L_FALSE)) + Z3native.toggle_warning_messages enabled end (** Functions for handling SMT and SMT2 expressions and files *) From c03d5277bc179a561083151549177f33fe087823 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 26 Dec 2012 16:54:45 +0000 Subject: [PATCH 371/507] more ML Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 58 +++++++++++++++++++++------------------ src/api/ml/z3.ml | 4 +++ 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 945c9a494..7fcd2e9f7 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -10,11 +10,12 @@ open Z3.Expr open Z3.FuncDecl open Z3.Goal open Z3.Tactic +open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic -exception ExampleException of string +exception TestFailedException of string (** @@ -43,32 +44,37 @@ let basic_tests ( ctx : context ) = let solver = (mk_solver ctx None) in (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; if (check solver None) != SATISFIABLE then - raise (ExampleException "") + raise (TestFailedException "") else Printf.printf "Test passed.\n" ; - () - -(* - ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); - if (ar.NumSubgoals == 1 && (ar.Subgoals[0].IsDecidedSat || ar.Subgoals[0].IsDecidedUnsat)) - throw new TestFailedException(); - - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) - throw new TestFailedException(); - - g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), - ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) - throw new TestFailedException(); - - - Goal g2 = ctx.MkGoal(true, true); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) - throw new TestFailedException(); - + () ; + let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) + (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) + ; + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + let g2 = (mk_goal ctx true true false) in + let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + () +(* g2 = ctx.MkGoal(true, true); g2.Assert(ctx.MkFalse()); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); @@ -131,7 +137,7 @@ let basic_tests ( ctx : context ) = let _ = if not (Log.open_ "z3.log") then - raise (ExampleException "Log couldn't be opened.") + raise (TestFailedException "Log couldn't be opened.") else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b4d58711c..8806a70ee 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -4391,6 +4391,10 @@ struct let n = (get_num_subgoals x) in let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in Array.init n f + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoal ( x : apply_result ) ( i : int ) = + (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) (** Convert a model for the subgoal into a model for the original goal g, that the ApplyResult was obtained from. From e2f6b10e3200bef881e0e3dcd2d84c8ab5570d37 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 27 Dec 2012 15:51:42 +0000 Subject: [PATCH 372/507] ML API bugfixes More ML examples Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 165 ++++++++++++++++++++++++++------------ src/api/ml/z3.ml | 5 ++ 2 files changed, 119 insertions(+), 51 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 7fcd2e9f7..0e8122ae0 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -17,6 +17,50 @@ open Z3.Arithmetic exception TestFailedException of string +(** + Model Converter test +*) +let model_converter_test ( ctx : context ) = + Printf.printf "ModelConverterTest\n"; + let xr = ((mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_real_sort ctx )) :> arith_expr) in + let yr = ((mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_real_sort ctx )) :> arith_expr) in + let g4 = (mk_goal ctx true false false ) in + (Goal.assert_ g4 [| (mk_gt ctx xr (mk_real_numeral_nd ctx 10 1)) |]) ; + (Goal.assert_ g4 [| (mk_eq ctx yr (mk_add ctx [| xr; (mk_real_numeral_nd ctx 1 1) |] )) |] ) ; + (Goal.assert_ g4 [| (mk_gt ctx yr (mk_real_numeral_nd ctx 1 1)) |]) ; + ( + let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") None) g4 None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ; + let solver = (mk_solver ctx None) in + let f e = (Solver.assert_ solver [| e |]) in + ignore (Array.map f (get_formulas (get_subgoal ar 0))) ; + let q = (check solver None) in + if q != SATISFIABLE then + raise (TestFailedException "") + else + let m = (get_model solver) in + match m with + | None -> raise (TestFailedException "") + | Some (m) -> + Printf.printf "Solver says: %s\n" (string_of_status q) ; + Printf.printf "Model: \n%s\n" (Model.to_string m) ; + Printf.printf "Converted Model: \n%s\n" (Model.to_string (convert_model ar 0 m)) + ) (** Some basic tests. @@ -41,59 +85,78 @@ let basic_tests ( ctx : context ) = (Goal.assert_ g [| trivial_eq |]) ; (Goal.assert_ g [| nontrivial_eq |]) ; Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; - let solver = (mk_solver ctx None) in - (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; - if (check solver None) != SATISFIABLE then - raise (TestFailedException "") - else - Printf.printf "Test passed.\n" ; - () ; - let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in - if ((get_num_subgoals ar) == 1 && - ((is_decided_sat (get_subgoal ar 0)) || - (is_decided_unsat (get_subgoal ar 0)))) then + ( + let solver = (mk_solver ctx None) in + (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; + if (check solver None) != SATISFIABLE then raise (TestFailedException "") else - let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_sat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) - (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) - ; - let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_unsat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - let g2 = (mk_goal ctx true true false) in - let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in - if ((get_num_subgoals ar) == 1 && - (not (is_decided_sat (get_subgoal ar 0)))) then - raise (TestFailedException "") - else - () -(* - g2 = ctx.MkGoal(true, true); - g2.Assert(ctx.MkFalse()); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) - throw new TestFailedException(); - - Goal g3 = ctx.MkGoal(true, true); - Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); - Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); - g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); - g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort))); - BoolExpr constr = ctx.MkEq(xc, yc); - g3.Assert(constr); - ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); - if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) - throw new TestFailedException(); - - ModelConverterTest(ctx); - + Printf.printf "Test passed.\n" + ); + ( + let ar = (Tactic.apply (mk_tactic ctx "simplify") g None) in + if ((get_num_subgoals ar) == 1 && + ((is_decided_sat (get_subgoal ar 0)) || + (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) + (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) + ; + ( + let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let g2 = (mk_goal ctx true true false) in + let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_sat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let g2 = (mk_goal ctx true true false) in + (Goal.assert_ g2 [| (mk_false ctx) |]) ; + let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); + ( + let g3 = (mk_goal ctx true true false) in + let xc = (mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_int_sort ctx)) in + let yc = (mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_int_sort ctx)) in + (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (mk_int_sort ctx))) |]) ; + (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (mk_int_sort ctx))) |]) ; + let constr = (mk_eq ctx xc yc) in + (Goal.assert_ g3 [| constr |] ) ; + let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in + if ((get_num_subgoals ar) == 1 && + (not (is_decided_unsat (get_subgoal ar 0)))) then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ) ; + model_converter_test ctx +(* // Real num/den test. RatNum rn = ctx.MkReal(42, 43); Expr inum = rn.Numerator; diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8806a70ee..c0711b4eb 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -4684,6 +4684,11 @@ module Solver = struct type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + let string_of_status ( s : status) = match s with + | UNSATISFIABLE -> "unsatisfiable" + | SATISFIABLE -> "satisfiable" + | _ -> "unknown" + (** Objects that track statistical information about solvers. *) module Statistics = struct From 7eb95bf6c20943f9324e52b1671d11ebfb6537b5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 15:32:25 +0000 Subject: [PATCH 373/507] ML API: made native layer ANSI-C compliant to avoid compilation issues. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 +++- scripts/update_api.py | 55 ++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 849644a18..020653272 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1440,7 +1440,10 @@ class MLComponent(Component): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + if WINDOWS: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) + else: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) out.write('z3.cmxa: %s\n' % libfile) out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) out.write('z3.cma: %s\n' % libfile) diff --git a/scripts/update_api.py b/scripts/update_api.py index 5d95a12f8..1986f4a7e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1262,39 +1262,39 @@ def mk_ml(): ml_wrapper.write('#include \n\n') ml_wrapper.write('#define CAMLlocal6(X1,X2,X3,X4,X5,X6) \\\n') ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal1(X6); \n') + ml_wrapper.write(' CAMLlocal1(X6) \n') ml_wrapper.write('#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \\\n') ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal2(X6,X7); \n') + ml_wrapper.write(' CAMLlocal2(X6,X7) \n') ml_wrapper.write('#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') ml_wrapper.write(' CAMLlocal5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLlocal3(X6,X7,X8); \n') + ml_wrapper.write(' CAMLlocal3(X6,X7,X8) \n') ml_wrapper.write('\n') ml_wrapper.write('#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam2(X6,X7); \n') + ml_wrapper.write(' CAMLxparam2(X6,X7) \n') ml_wrapper.write('#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam3(X6,X7,X8); \n') + ml_wrapper.write(' CAMLxparam3(X6,X7,X8) \n') ml_wrapper.write('#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') - ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9); \n') + ml_wrapper.write(' CAMLxparam4(X6,X7,X8,X9) \n') ml_wrapper.write('#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') - ml_wrapper.write(' CAMLxparam2(X11,X12); \n') + ml_wrapper.write(' CAMLxparam2(X11,X12) \n') ml_wrapper.write('#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \\\n') ml_wrapper.write(' CAMLparam5(X1,X2,X3,X4,X5); \\\n') ml_wrapper.write(' CAMLxparam5(X6,X7,X8,X9,X10); \\\n') - ml_wrapper.write(' CAMLxparam3(X11,X12,X13); \n') + ml_wrapper.write(' CAMLxparam3(X11,X12,X13) \n') ml_wrapper.write('\n\n') ml_wrapper.write('static struct custom_operations default_custom_ops = {\n') - ml_wrapper.write(' identifier: (char*) "default handling",\n') - ml_wrapper.write(' finalize: custom_finalize_default,\n') - ml_wrapper.write(' compare: custom_compare_default,\n') - ml_wrapper.write(' hash: custom_hash_default,\n') - ml_wrapper.write(' serialize: custom_serialize_default,\n') - ml_wrapper.write(' deserialize: custom_deserialize_default\n') + ml_wrapper.write(' (char*) "default handling",\n') + ml_wrapper.write(' custom_finalize_default,\n') + ml_wrapper.write(' custom_compare_default,\n') + ml_wrapper.write(' custom_hash_default,\n') + ml_wrapper.write(' custom_serialize_default,\n') + ml_wrapper.write(' custom_deserialize_default\n') ml_wrapper.write('};\n\n') ml_wrapper.write('#ifdef __cplusplus\n') ml_wrapper.write('extern "C" {\n') @@ -1358,7 +1358,10 @@ def mk_ml(): i = i + 1 ml_wrapper.write(');\n') - # preprocess arrays, strings, in/out arguments + if len(ap) != 0: + ml_wrapper.write(' unsigned _i;\n') + + # declare locals, preprocess arrays, strings, in/out arguments i = 0 for param in params: k = param_kind(param) @@ -1372,22 +1375,32 @@ def mk_ml(): elif k == IN_ARRAY or k == INOUT_ARRAY: t = param_type(param) ts = type2str(t) - ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) - ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) _a%s[i] = %s;\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', i)'))) + ml_wrapper.write(' %s * _a%s = (%s*) malloc(sizeof(%s) * _a%s);\n' % (ts, i, ts, ts, param_array_capacity_pos(param))) elif k == IN: t = param_type(param) ml_wrapper.write(' %s _a%s = %s;\n' % (type2str(t), i, ml_unwrap(t, type2str(t), 'a' + str(i)))) elif k == OUT: ml_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) elif k == INOUT: - ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) - + ml_wrapper.write(' %s _a%s = a%s;\n' % (type2str(param_type(param)), i, i)) + i = i + 1 + + if result != VOID: + ml_wrapper.write(' %s z3_result;\n' % type2str(result)) + + i = 0 + for param in params: + k = param_kind(param) + if k == IN_ARRAY or k == INOUT_ARRAY: + t = param_type(param) + ts = type2str(t) + ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { _a%s[_i] = %s; }\n' % (param_array_capacity_pos(param), i, ml_unwrap(t, ts, 'Field(a' + str(i) + ', _i)'))) i = i + 1 # invoke procedure ml_wrapper.write(' ') if result != VOID: - ml_wrapper.write('%s z3_result = ' % type2str(result)) + ml_wrapper.write('z3_result = ') ml_wrapper.write('%s(' % name) i = 0 first = True @@ -1412,7 +1425,7 @@ def mk_ml(): for p in params: if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) - ml_wrapper.write(' for (unsigned i = 0; i < _a%s; i++) { value t; %s Store_field(_a%s, i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[i]'), i)) + ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) elif is_out_param(p): ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) i = i + 1 From 3e8c1e3a29494a6b893f5015ba2dccce9477a2d5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 18:56:19 +0000 Subject: [PATCH 374/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 020653272..9bb0e0efe 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1440,7 +1440,7 @@ class MLComponent(Component): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - if WINDOWS: + if IS_WINDOWS: out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) else: out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) From 4a606dbe600d09fb8b9db059583a865edea4b5be Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 7 Jan 2013 22:44:55 +0000 Subject: [PATCH 375/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 9bb0e0efe..9dcf43813 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1439,7 +1439,7 @@ class MLComponent(Component): for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I%s -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) + out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I"%s" -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) if IS_WINDOWS: out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) else: From 49dd2e4a07a48ce106c86cb0b6fefee804bc47ee Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 20:56:49 +0000 Subject: [PATCH 376/507] ML API: build system changes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 48 +++++++++++++++++++++++++++++++++++----------- src/api/ml/README | 2 +- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 9dcf43813..4c39ff13b 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1342,6 +1342,7 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): +<<<<<<< HEAD CP_CMD = "cp" if IS_WINDOWS: CP_CMD = "copy" @@ -1436,18 +1437,31 @@ class MLComponent(Component): mk_dir(bld_dir) libfile = '%s$(SO_EXT)' % self.lib_name out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) +======= + src_dir = self.to_src_dir + sub_dir = os.path.join('api', 'ml') + mk_dir(os.path.join(BUILD_DIR, sub_dir)) + for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): + shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): + shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + out.write('z3.cmxa:') + for mlfile in get_ml_files(self.src_dir): + out.write(' %s' % os.path.join(src_dir, mlfile)) + out.write('\n') + out.write('\tpushd %s && %s ' % (sub_dir, OCAMLOPT)) + if DEBUG_MODE: + out.write('-g ') + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cmxa -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) + out.write('z3.cma:') +>>>>>>> ML API: build system changes for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT) -I"%s" -I%s %s/z3native.c\n' % (get_component(API_COMPONENT).to_src_dir, OCAML_LIB, self.to_src_dir)) - if IS_WINDOWS: - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(LIB_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) - else: - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) %s$(OBJ_EXT) libz3$(SO_EXT)\n' % (libfile, os.path.join('api', 'ml', 'z3native'))) - out.write('z3.cmxa: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3.cmxa z3native$(OBJ_EXT) && cd -\n' % (self.to_src_dir,BUILD_DIR)) - out.write('z3.cma: %s\n' % libfile) - out.write('\tcd %s && ocamlbuild -cflags \'-g\' -lflags -custom,-cclib,-L../..,-cclib,-lz3,-cclib,-lz3ml,-linkall -build-dir ../../../%s/api/ml z3native$(OBJ_EXT) z3.cma && cd -\n' % (self.to_src_dir,BUILD_DIR)) + out.write('\tpushd %s && %s ' % (sub_dir, OCAMLC)) + if DEBUG_MODE: + out.write('-g ') + out.write('-custom -ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cma -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) out.write('ml: z3.cmxa z3.cma\n') out.write('\n') @@ -1576,7 +1590,10 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') - out.write('\tocamlc -g -o ml_example.byte -I . z3.cma -I api/ml') + out.write('\t%s ' % OCAMLC) + if DEBUG_MODE: + out.write('-g ') + out.write('-custom -o ml_example.byte -I . z3.cma -I api/ml') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -1584,7 +1601,10 @@ class MLExampleComponent(ExampleComponent): for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') - out.write('\tocamlopt -g -o ml_example -I . z3.cmxa -I api/ml') + out.write('\t%s ' % OCAMLOPT) + if DEBUG_MODE: + out.write('-g ') + out.write('-o ml_example($EXE_EXT) -I . z3.cmxa -I api/ml') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -1862,9 +1882,15 @@ def mk_config(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) if is_ml_enabled(): +<<<<<<< HEAD print('Ocaml Compiler: %s' % OCAMLC) print('Ocaml Native: %s' % OCAMLOPT) print('Ocaml Library: %s' % OCAML_LIB) +======= + print('OCaml Compiler: %s' % OCAMLC) + print('OCaml Native: %s' % OCAMLOPT) + print('OCaml Library: %s' % OCAML_LIB) +>>>>>>> ML API: build system changes def mk_install(out): out.write('install: ') diff --git a/src/api/ml/README b/src/api/ml/README index 36f903925..beee7d864 100644 --- a/src/api/ml/README +++ b/src/api/ml/README @@ -5,4 +5,4 @@ We are currently working on a brand new ML API. On Windows, there are no less than four different ports of OCaml. The Z3 build system assumes that either the win32 or the win64 port is installed. This means that OCaml will use `cl' as the underlying C compiler and not the cygwin or -mingw compilers. +mingw compilers. \ No newline at end of file From 09292437db25600e12a590ea6151784005843f3c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 21:02:44 +0000 Subject: [PATCH 377/507] ML API: build system fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4c39ff13b..503c3dadd 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -357,6 +357,7 @@ def check_ml(): rmf('hello.cmo') rmf('hello.cmx') rmf('a.out') + t.__del__() find_ml_lib() find_ocaml_find() From f94fa8544476845742078bad95b1627cdec6f0bb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 8 Jan 2013 21:22:45 +0000 Subject: [PATCH 378/507] ML API: build system fix --- scripts/mk_util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 503c3dadd..4c39ff13b 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -357,7 +357,6 @@ def check_ml(): rmf('hello.cmo') rmf('hello.cmx') rmf('a.out') - t.__del__() find_ml_lib() find_ocaml_find() From f0e61ee52342dccf32039b44186afb4c77ac71f3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 10 Jan 2013 17:25:55 +0000 Subject: [PATCH 379/507] ML API: build system fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 128 ++++++--------------------------------------- 1 file changed, 15 insertions(+), 113 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4c39ff13b..c7b48b891 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1342,102 +1342,6 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): -<<<<<<< HEAD - CP_CMD = "cp" - if IS_WINDOWS: - CP_CMD = "copy" - src_dir = self.to_src_dir - sub_dir = os.path.join('api', 'ml') - mk_dir(os.path.join(BUILD_DIR, sub_dir)) - api_src = get_component(API_COMPONENT).to_src_dir - for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): - out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) - str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) - out.write(str) - for f in filter(lambda f: f.endswith('.mli'), os.listdir(self.src_dir)): - out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) - str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) - out.write(str) - for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): - out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) - str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) - out.write(str) - modules = ["z3enums", "z3native", "z3"] # dependencies in this order! - mls = '' - mlis = '' - cmis = '' - archives = '' - - for m in modules: - fn = os.path.join(self.src_dir, ('%s.mli' % m)) - if not os.path.exists(fn): - out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),mlis)) - out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) - out.write('%s.cmi: %s.mli%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m), cmis)) - out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) - out.write('%s.cma: %s.ml %s.cmi%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),os.path.join(sub_dir,m), archives)) - out.write('\t%s -a -o %s.ml -o %s.cma\n' % (OCAMLC,os.path.join(sub_dir,m), os.path.join(sub_dir,m))) - mlis = mlis + ' ' + os.path.join(sub_dir, m) + '.mli' - cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - archives = archives + ' ' + os.path.join(sub_dir,m) + '.cma' - mls = mls + ' ' + os.path.join(sub_dir, m) + '.ml' - - out.write('%s: %s %s\n' % - (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), - os.path.join(sub_dir, 'z3native_stubs.c'), - get_component(Z3_DLL_COMPONENT).dll_name+'$(SO_EXT)')); - out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % - (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) - - out.write('%s: %s %s %s$(SO_EXT)' % ( - os.path.join(sub_dir, "z3ml.cmxa"), - cmis, - archives, - get_component(Z3_DLL_COMPONENT).dll_name)) - out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tocamlmklib -o %s -I %s -ldopt \"-L. -lz3\" ' % (os.path.join(sub_dir, 'z3ml'), sub_dir)) - for m in modules: - out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) - out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) - self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) - if OCAMLFIND != '': - out.write('\nocamlfind_install: %s %s %s\n' % ( - get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)', - os.path.join(sub_dir, 'z3ml.cmxa'), - os.path.join(sub_dir, 'META'))) - out.write('\t%s remove Z3\n' % (OCAMLFIND)) - out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) - for m in modules: - out.write(' %s.cma' % (os.path.join(sub_dir, m))) - out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - out.write(' %s.cmo' % (os.path.join(sub_dir, m))) - out.write(' %s.ml' % (os.path.join(sub_dir, m))) - out.write(' %s.mli' % (os.path.join(sub_dir, m))) - out.write(' %s$(OBJ_EXT)' % (os.path.join(sub_dir, m))) - out.write(' %s' % ((os.path.join(sub_dir, 'z3ml$(LIB_EXT)')))) - out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cma')))) - out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cmxa')))) - out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) - out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) - if IS_WINDOWS: - out.write('.dll') - else: - out.write('.so') # .so also on OSX! - out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') - if IS_WINDOWS: - out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') - out.write('\n\n') - deffile = open('%s.mllib' % os.path.join(self.src_dir, "z3"), 'w') - for mlfile in get_ml_files(self.src_dir): - deffile.write('%s\n' % (string.upper(mlfile[0]) + mlfile[1:-3])) - deffile.close() - bld_dir = os.path.join(BUILD_DIR, 'api', 'ml') - mk_dir(bld_dir) - libfile = '%s$(SO_EXT)' % self.lib_name - out.write('%s: libz3$(SO_EXT) %s' % (libfile, os.path.join(self.to_src_dir, 'z3native.c'))) -======= src_dir = self.to_src_dir sub_dir = os.path.join('api', 'ml') mk_dir(os.path.join(BUILD_DIR, sub_dir)) @@ -1445,24 +1349,28 @@ class MLComponent(Component): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) - out.write('z3.cmxa:') + out.write('libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s api/ml/z3native.c $(CXX_OUTFLAG) api/ml/z3native$(OBJ_EXT)\n' % get_component(API_COMPONENT).to_src_dir) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG) libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('api/ml/z3.cmxa: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) out.write('\n') - out.write('\tpushd %s && %s ' % (sub_dir, OCAMLOPT)) + out.write('\tcd %s && %s ' % (sub_dir, OCAMLOPT)) if DEBUG_MODE: out.write('-g ') out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cmxa -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) out.write('z3.cma:') ->>>>>>> ML API: build system changes + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cmxa -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) + out.write('api/ml/z3.cma: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\tpushd %s && %s ' % (sub_dir, OCAMLC)) + out.write('\tcd %s && %s ' % (sub_dir, OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-custom -ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cma -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) - out.write('ml: z3.cmxa z3.cma\n') + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cma -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) + out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') def main_component(self): @@ -1586,29 +1494,29 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: z3.cma ') + out.write('ml_example.byte: api/ml/z3.cma ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLC) if DEBUG_MODE: out.write('-g ') - out.write('-custom -o ml_example.byte -I . z3.cma -I api/ml') + out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" z3.cma') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example($EXE_EXT): z3.cmxa ml_example.byte') + out.write('ml_example$(EXE_EXT): api/ml/z3.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: out.write('-g ') - out.write('-o ml_example($EXE_EXT) -I . z3.cmxa -I api/ml') + out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" z3.cmxa') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('_ex_%s: ml_example.byte ml_example($EXE_EXT)\n\n' % self.name) + out.write('_ex_%s: ml_example.byte ml_example$(EXE_EXT)\n\n' % self.name) class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): @@ -1882,15 +1790,9 @@ def mk_config(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) if is_ml_enabled(): -<<<<<<< HEAD print('Ocaml Compiler: %s' % OCAMLC) print('Ocaml Native: %s' % OCAMLOPT) print('Ocaml Library: %s' % OCAML_LIB) -======= - print('OCaml Compiler: %s' % OCAMLC) - print('OCaml Native: %s' % OCAMLOPT) - print('OCaml Library: %s' % OCAML_LIB) ->>>>>>> ML API: build system changes def mk_install(out): out.write('install: ') From e57dbbb56dcdc951e3c8460f4882f1a7d46e7e48 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 10 Jan 2013 18:39:43 +0000 Subject: [PATCH 380/507] ML API: build system fixes --- scripts/mk_util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index c7b48b891..befd78be6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1350,8 +1350,8 @@ class MLComponent(Component): for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) out.write('libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s api/ml/z3native.c $(CXX_OUTFLAG) api/ml/z3native$(OBJ_EXT)\n' % get_component(API_COMPONENT).to_src_dir) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG) libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s api/ml/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, get_component(API_COMPONENT).to_src_dir)) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') out.write('api/ml/z3.cmxa: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) From 1e2b546b037ce87675580e860dcfe183305d35eb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 11 Jan 2013 14:33:28 +0000 Subject: [PATCH 381/507] ML API: changed context from object to normal type. Removed optional array parameters. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 8 +- src/api/ml/z3.ml | 661 ++++++++++++++++++-------------------- 2 files changed, 323 insertions(+), 346 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 0e8122ae0..129f73d4d 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -38,7 +38,7 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ); ( - let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") None) g4 None) in + let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") [||]) g4 None) in if ((get_num_subgoals ar) == 1 && ((is_decided_sat (get_subgoal ar 0)) || (is_decided_unsat (get_subgoal ar 0)))) then @@ -49,7 +49,7 @@ let model_converter_test ( ctx : context ) = let solver = (mk_solver ctx None) in let f e = (Solver.assert_ solver [| e |]) in ignore (Array.map f (get_formulas (get_subgoal ar 0))) ; - let q = (check solver None) in + let q = (check solver [||]) in if q != SATISFIABLE then raise (TestFailedException "") else @@ -88,7 +88,7 @@ let basic_tests ( ctx : context ) = ( let solver = (mk_solver ctx None) in (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; - if (check solver None) != SATISFIABLE then + if (check solver [||]) != SATISFIABLE then raise (TestFailedException "") else Printf.printf "Test passed.\n" @@ -204,7 +204,7 @@ let _ = else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = (Some [("model", "true"); ("proof", "false")]) in + let cfg = [("model", "true"); ("proof", "false")] in let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in let ss = (Symbol.mk_string ctx "mySymbol") in diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c0711b4eb..c91d909bc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,46 +7,39 @@ open Z3enums +type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } + (**/**) +let context_dispose ctx = + if ctx.m_n_obj_cnt == 0 then ( + (* Printf.printf "Disposing context \n" ; *) + (Z3native.del_context ctx.m_n_ctx) + ) else ( + Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; + (* re-queue for finalization? *) + ) -class context settings = -object (self) - val mutable m_n_ctx : Z3native.z3_context = - let cfg = Z3native.mk_config in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - v - +let context_init settings = + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + (* Printf.printf "Installing finalizer on context \n" ; *) + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> context_dispose o in + Gc.finalise f res; + res (* CMW: Install error handler here! m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. Z3native.set_error_handler(m_ctx, m_n_err_handler); GC.SuppressFinalize(this); *) - val mutable m_obj_cnt : int = 0 - - initializer - (* Printf.printf "Installing finalizer on context %d \n" (Oo.id self) ; *) - let f = fun o -> o#dispose in - let v = self in - Gc.finalise f v; - - method dispose : unit = - if m_obj_cnt == 0 then ( - (* Printf.printf "Disposing context %d \n" (Oo.id self) ; *) - (Z3native.del_context m_n_ctx) - ) else ( - Printf.printf "NOT DISPOSING context %d because it still has %d objects alive\n" (Oo.id self) m_obj_cnt; - (* re-queue for finalization? *) - ) - - method add_one_ctx_obj = m_obj_cnt <- m_obj_cnt + 1 - method sub_one_ctx_obj = m_obj_cnt <- m_obj_cnt - 1 - method gno = m_n_ctx -end +let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) +let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) +let context_gno ctx = ctx.m_n_ctx (**/**) @@ -70,10 +63,8 @@ the context, e.g., like so: (...) *) -let mk_context ( cfg : ( string * string ) list option ) = - match cfg with - | None -> new context [] - | Some(x) -> new context x +let mk_context ( cfg : ( string * string ) list ) = + context_init cfg (**/**) @@ -85,8 +76,8 @@ object (self) initializer (match m_n_obj with - | Some (x) -> self#incref m_ctx#gno x; - m_ctx#add_one_ctx_obj + | Some (x) -> self#incref (context_gno m_ctx) x; + (context_add1 m_ctx) | None -> () ); (* Printf.printf "Installing finalizer on z3object %d \n" (Oo.id self) ; *) @@ -101,8 +92,8 @@ object (self) (* Printf.printf "Disposing z3object %d \n" (Oo.id self) ; *) (match m_n_obj with | Some (x) -> - self#decref m_ctx#gno x; - m_ctx#sub_one_ctx_obj ; + self#decref (context_gno m_ctx) x; + (context_sub1 m_ctx) ; m_n_obj <- None; | None -> () ); @@ -112,16 +103,16 @@ object (self) | None -> raise (Z3native.Exception "Z3 object lost") method sno (ctx : context) o = - m_ctx#add_one_ctx_obj ; - self#incref ctx#gno o ; + (context_add1 m_ctx) ; + self#incref (context_gno ctx) o ; (match m_n_obj with - | Some(x) -> self#decref ctx#gno x ; m_ctx#sub_one_ctx_obj + | Some(x) -> self#decref (context_gno ctx) x ; (context_sub1 m_ctx) | None -> () ); m_n_obj <- Some o method gc = m_ctx - method gnc = m_ctx#gno + method gnc = (context_gno m_ctx) end @@ -134,37 +125,38 @@ object (self) method decref nc o = Z3native.params_dec_ref nc o end + (** Symbol objects *) -class symbol ctx = +class symbol ctx = object (self) - inherit z3object ctx None as super + inherit z3object ctx None as super method cnstr_obj obj = (self#sno ctx obj) ; self method incref nc o = () method decref nc o = () end +(** Int symbol objects *) +class int_symbol ctx = +object(self) + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol (context_gno ctx) i)) ; self +end + +(** String symbol objects *) +class string_symbol ctx = +object(self) + inherit symbol ctx as super + method cnstr_obj obj = (self#sno ctx obj) ; self + method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol (context_gno ctx) name)) ; self +end + let symbolaton (a : symbol array) = let f (e : symbol) = e#gno in Array.map f a -(** Int symbol objects *) -class int_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol ctx#gno i)) ; self -end - -(** String symbol objects *) -class string_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol ctx#gno name)) ; self -end - let create_symbol ctx no = - match (symbol_kind_of_int (Z3native.get_symbol_kind ctx#gno no)) with + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) @@ -205,7 +197,7 @@ class array_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort ctx#gno domain#gno range#gno)) ; self + method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort (context_gno ctx) domain#gno range#gno)) ; self end (** Bit-vector sort objects *) @@ -241,7 +233,7 @@ class uninterpreted_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort ctx#gno s#gno)) ; self + method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) s#gno)) ; self end (** Finite domain sort objects *) @@ -249,7 +241,7 @@ class finite_domain_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort ctx#gno s#gno sz)) ; self + method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) s#gno sz)) ; self end (** Relation sort objects *) @@ -273,7 +265,7 @@ object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = - let (x,_,_) = (Z3native.mk_tuple_sort ctx#gno name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in + let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in (self#sno ctx x) ; self end @@ -284,8 +276,8 @@ class func_decl ctx = object (self) inherit ast ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl ctx#gno name#gno (Array.length domain) (astaton domain) range#gno)) ; self - method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl ctx#gno prefix (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (astaton domain) range#gno)) ; self method incref nc o = super#incref nc o method decref nc o = super#decref nc o @@ -341,7 +333,7 @@ object (self) val mutable _testerdecls : func_decl array option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (enum_names : symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort ctx#gno name#gno (Array.length enum_names) (symbolaton enum_names)) in + let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) name#gno (Array.length enum_names) (symbolaton enum_names)) in _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; (self#sno ctx r) ; @@ -368,7 +360,7 @@ object (self) val mutable _taildecl : func_decl option = None method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ss (name : symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort ctx#gno name#gno elem_sort#gno) in + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) name#gno elem_sort#gno) in _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; @@ -426,7 +418,7 @@ object (self) if m_n != (Array.length sort_refs) then raise (Z3native.Exception "Number of field names does not match number of sort refs") else - let o = (Z3native.mk_constructor ctx#gno name#gno recognizer#gno m_n (symbolaton field_names) + let o = (Z3native.mk_constructor (context_gno ctx) name#gno recognizer#gno m_n (symbolaton field_names) (sortaton sorts) sort_refs) in self#sno ctx o ; @@ -473,7 +465,7 @@ object (self) Gc.finalise f v method cnstr_obj obj = (self#sno ctx obj) ; self method cnstr_ca ( c : constructor array ) = - self#sno ctx (Z3native.mk_constructor_list ctx#gno (Array.length c) (constructoraton c)) ; + self#sno ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (constructoraton c)) ; self end @@ -486,11 +478,11 @@ class datatype_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype ctx#gno name#gno (Array.length constructors) (constructoraton constructors)))) ; self + method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) name#gno (Array.length constructors) (constructoraton constructors)))) ; self end let create_sort ctx obj = - match (sort_kind_of_int (Z3native.get_sort_kind ctx#gno obj)) with + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) obj)) with | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) @@ -900,7 +892,7 @@ struct Create a new Boolean sort. *) let mk_bool ( ctx : context ) = - (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort ctx#gno) + (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort (context_gno ctx)) (** Create a new uninterpreted sort. @@ -917,15 +909,15 @@ end (**/**) let create_expr ctx obj = - if ast_kind_of_int (Z3native.get_ast_kind ctx#gno obj) == QUANTIFIER_AST then + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then (((new quantifier ctx)#cnstr_obj obj) :> expr) else - let s = Z3native.get_sort ctx#gno obj in - let sk = (sort_kind_of_int (Z3native.get_sort_kind ctx#gno s)) in - if (Z3native.is_algebraic_number ctx#gno obj) then + let s = Z3native.get_sort (context_gno ctx) obj in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) obj) then (((new algebraic_num ctx)#cnstr_obj obj) :> expr) else - if (Z3native.is_numeral_ast ctx#gno obj) && + if (Z3native.is_numeral_ast (context_gno ctx) obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) @@ -943,11 +935,11 @@ let create_expr ctx obj = | _ -> (new expr ctx)#cnstr_obj obj let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = - let o = Z3native.mk_app ctx#gno f#gno (Array.length args) (astaton args) in + let o = Z3native.mk_app (context_gno ctx) f#gno (Array.length args) (astaton args) in create_expr ctx o let create_ast ctx no = - match (ast_kind_of_int (Z3native.get_ast_kind ctx#gno no)) with + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) | SORT_AST -> ((create_sort ctx no) :> ast) @@ -1188,7 +1180,7 @@ struct @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = - (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno to_ctx#gno) + (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno (context_gno to_ctx)) (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = @@ -1337,7 +1329,7 @@ struct if x#gc == to_ctx then x else - (create_ast to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno)) + (create_ast to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx))) (** Wraps an AST. @@ -1383,13 +1375,13 @@ struct a string describing all available parameters to Expr.Simplify. *) let get_simplify_help ( ctx : context ) = - Z3native.simplify_get_help ctx#gno + Z3native.simplify_get_help (context_gno ctx) (** Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs ctx#gno) + (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. @@ -1462,7 +1454,7 @@ struct if x#gc == to_ctx then x else - create_expr to_ctx (Z3native.translate x#gnc x#gno to_ctx#gno) + create_expr to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx)) (** Returns a string representation of the expression. @@ -1578,7 +1570,7 @@ struct Creates a new Constant of sort and named . *) let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = - create_expr ctx (Z3native.mk_const ctx#gno name#gno range#gno) + create_expr ctx (Z3native.mk_const (context_gno ctx) name#gno range#gno) (** @@ -1600,7 +1592,7 @@ struct name prefixed with . *) let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort) = - create_expr ctx (Z3native.mk_fresh_const ctx#gno prefix range#gno) + create_expr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix range#gno) (** Create a Boolean constant. @@ -1624,13 +1616,13 @@ struct The true Term. *) let mk_true ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_true ctx#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_true (context_gno ctx)) (** The false Term. *) let mk_false ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_false ctx#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_false (context_gno ctx)) (** Creates a Boolean value. @@ -1642,19 +1634,19 @@ struct Creates the equality = . *) let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq ctx#gno x#gno y#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq (context_gno ctx) x#gno y#gno) (** Creates a distinct term. *) let mk_distinct ( ctx : context ) ( args : expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct ctx#gno (Array.length args) (astaton args)) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct (context_gno ctx) (Array.length args) (astaton args)) (** Mk an expression representing not(a). *) let mk_not ( ctx : context ) ( a : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_not ctx#gno a#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_not (context_gno ctx) a#gno) (** Create an expression representing an if-then-else: ite(t1, t2, t3). @@ -1663,37 +1655,37 @@ struct @param t3 An expression with the same sort as *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create_expr ctx (Z3native.mk_ite ctx#gno t1#gno t2#gno t3#gno) + create_expr ctx (Z3native.mk_ite (context_gno ctx) t1#gno t2#gno t3#gno) (** Create an expression representing t1 iff t2. *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 -> t2. *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 xor t2. *) let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor (context_gno ctx) t1#gno t2#gno) (** Create an expression representing the AND of args *) let mk_and ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_and ctx#gno (Array.length args) (astaton args)) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_and (context_gno ctx) (Array.length args) (astaton args)) (** Create an expression representing the OR of args *) let mk_or ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_or ctx#gno (Array.length args) (astaton args)) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_or (context_gno ctx) (Array.length args) (astaton args)) (** Create a numeral of a given sort. @@ -1702,7 +1694,7 @@ struct @return A Term with value and sort *) let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - create_expr ctx (Z3native.mk_numeral ctx#gno v ty#gno) + create_expr ctx (Z3native.mk_numeral (context_gno ctx) v ty#gno) (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. @@ -1712,7 +1704,7 @@ struct @return A Term with value and type *) let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_int ctx#gno v ty#gno) + create_expr ctx (Z3native.mk_int (context_gno ctx) v ty#gno) end (** Quantifier expressions *) @@ -1845,7 +1837,7 @@ struct @param ty The sort of the variable *) let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_bound ctx#gno index ty#gno) + create_expr ctx (Z3native.mk_bound (context_gno ctx) index ty#gno) (** Create a quantifier pattern. @@ -1854,7 +1846,7 @@ struct if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - (new pattern ctx)#cnstr_obj (Z3native.mk_pattern ctx#gno (Array.length terms) (astaton terms)) + (new pattern ctx)#cnstr_obj (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (astaton terms)) (** Create a universal Quantifier. @@ -1875,27 +1867,24 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno true + else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno true + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) @@ -1903,51 +1892,45 @@ struct (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = - if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno true + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno true + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) body#gno) (** Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier ctx#gno false + else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex ctx#gno false + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) (astaton names) body#gno) @@ -1955,31 +1938,28 @@ struct (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = - if (nopatterns == None && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const ctx#gno false + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) body#gno) else let null = Z3native.mk_null() in - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex ctx#gno false + (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) (match skolem_id with | None -> null | Some(x) -> x#gno) (Array.length bound_constants) (expraton bound_constants) - (match patterns with | None -> 0 | Some(x) -> (Array.length x)) - (match patterns with | None -> [||] | Some(x) -> (patternaton x)) - (match nopatterns with | None -> 0 | Some(x) -> (Array.length x)) - (match nopatterns with | None -> [||] | Some(x) -> (patternaton x)) + (Array.length patterns) (patternaton patterns) + (Array.length nopatterns) (patternaton nopatterns) body#gno) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -1989,7 +1969,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array option ) ( nopatterns : pattern array option ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -2081,7 +2061,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - ((create_expr ctx (Z3native.mk_select ctx#gno a#gno i#gno)) :> array_expr) + ((create_expr ctx (Z3native.mk_select (context_gno ctx) a#gno i#gno)) :> array_expr) (** Array update. @@ -2100,7 +2080,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_store ctx#gno a#gno i#gno v#gno) + (new array_expr ctx)#cnstr_obj (Z3native.mk_store (context_gno ctx) a#gno i#gno v#gno) (** Create a constant array. @@ -2111,7 +2091,7 @@ struct *) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array ctx#gno domain#gno v#gno) + (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array (context_gno ctx) domain#gno v#gno) (** Maps f on the argument arrays. @@ -2124,7 +2104,7 @@ struct *) let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = - ((create_expr ctx (Z3native.mk_map ctx#gno f#gno (Array.length args) (astaton args))) :> array_expr) + ((create_expr ctx (Z3native.mk_map (context_gno ctx) f#gno (Array.length args) (astaton args))) :> array_expr) (** Access the array default value. @@ -2133,7 +2113,7 @@ struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - ((create_expr ctx (Z3native.mk_array_default ctx#gno arg#gno)) :> array_expr) + ((create_expr ctx (Z3native.mk_array_default (context_gno ctx) arg#gno)) :> array_expr) end (** Functions to manipulate Set expressions *) @@ -2174,61 +2154,61 @@ struct Create an empty set. *) let mk_empty ( ctx : context ) ( domain : sort ) = - (create_expr ctx (Z3native.mk_empty_set ctx#gno domain#gno)) + (create_expr ctx (Z3native.mk_empty_set (context_gno ctx) domain#gno)) (** Create the full set. *) let mk_full ( ctx : context ) ( domain : sort ) = - create_expr ctx (Z3native.mk_full_set ctx#gno domain#gno) + create_expr ctx (Z3native.mk_full_set (context_gno ctx) domain#gno) (** Add an element to the set. *) let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_add ctx#gno set#gno element#gno) + create_expr ctx (Z3native.mk_set_add (context_gno ctx) set#gno element#gno) (** Remove an element from a set. *) let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_del ctx#gno set#gno element#gno) + create_expr ctx (Z3native.mk_set_del (context_gno ctx) set#gno element#gno) (** Take the union of a list of sets. *) let mk_union ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_union ctx#gno (Array.length args) (astaton args)) + create_expr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (astaton args)) (** Take the intersection of a list of sets. *) let mk_intersection ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_intersect ctx#gno (Array.length args) (astaton args)) + create_expr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (astaton args)) (** Take the difference between two sets. *) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_difference ctx#gno arg1#gno arg2#gno) + create_expr ctx (Z3native.mk_set_difference (context_gno ctx) arg1#gno arg2#gno) (** Take the complement of a set. *) let mk_complement ( ctx : context ) ( arg : expr ) = - create_expr ctx (Z3native.mk_set_complement ctx#gno arg#gno) + create_expr ctx (Z3native.mk_set_complement (context_gno ctx) arg#gno) (** Check for set membership. *) let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - create_expr ctx (Z3native.mk_set_member ctx#gno elem#gno set#gno) + create_expr ctx (Z3native.mk_set_member (context_gno ctx) elem#gno set#gno) (** Check for subsetness of sets. *) let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_subset ctx#gno arg1#gno arg2#gno) + create_expr ctx (Z3native.mk_set_subset (context_gno ctx) arg1#gno arg2#gno) end @@ -2458,7 +2438,7 @@ struct let n = (Array.length names) in let f e = ( (new constructor_list ctx)#cnstr_ca e ) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes ctx#gno n (symbolaton names) (constructor_listaton cla)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (symbolaton names) (constructor_listaton cla)) in let g e = ( (new datatype_sort ctx)#cnstr_obj e) in (Array.map g r) @@ -2592,13 +2572,13 @@ struct Create a new integer sort. *) let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort ctx#gno) + (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort (context_gno ctx)) (** Create a real sort. *) let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort ctx#gno) + (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort (context_gno ctx)) (** Indicates whether the term is of integer sort. @@ -2761,75 +2741,75 @@ struct Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_add ctx#gno (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_mul ctx#gno (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_sub ctx#gno (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - (create_expr ctx (Z3native.mk_unary_minus ctx#gno t#gno) :> arith_expr) + (create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) t#gno) :> arith_expr) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - (create_expr ctx (Z3native.mk_div ctx#gno t1#gno t2#gno) :> arith_expr) + (create_expr ctx (Z3native.mk_div (context_gno ctx) t1#gno t2#gno) :> arith_expr) (** Create an expression representing t1 mod t2. The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_mod ctx#gno t1#gno t2#gno) + (new int_expr ctx)#cnstr_obj (Z3native.mk_mod (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_rem ctx#gno t1#gno t2#gno) + (new int_expr ctx)#cnstr_obj (Z3native.mk_rem (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 ^ t2. *) let mk_Power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (create_expr ctx (Z3native.mk_power ctx#gno t1#gno t2#gno) :> arith_expr) + (create_expr ctx (Z3native.mk_power (context_gno ctx) t1#gno t2#gno) :> arith_expr) (** Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_le ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_le (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt (context_gno ctx) t1#gno t2#gno) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge (context_gno ctx) t1#gno t2#gno) (** Coerce an integer to a real. @@ -2842,7 +2822,7 @@ struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real ctx#gno t#gno) + (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real (context_gno ctx) t#gno) (** Coerce a real to an integer. @@ -2852,13 +2832,13 @@ struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int ctx#gno t#gno) + (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int (context_gno ctx) t#gno) (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int ctx#gno t#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int (context_gno ctx) t#gno) (** Return a upper bound for a given real algebraic number. @@ -2898,7 +2878,7 @@ struct raise (Z3native.Exception "Denominator is zero") else - (new rat_num ctx)#cnstr_obj (Z3native.mk_real ctx#gno num den) + (new rat_num ctx)#cnstr_obj (Z3native.mk_real (context_gno ctx) num den) (** Create a real numeral. @@ -2906,7 +2886,7 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_s ( ctx : context ) ( v : string ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_real_sort ctx)#gno) + (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create a real numeral. @@ -2915,14 +2895,14 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_i ( ctx : context ) ( v : int ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_real_sort ctx)#gno) + (new rat_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create an integer numeral. @param v A string representing the Term value in decimal notation. *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_int_sort ctx)#gno) + (new int_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) (** Create an integer numeral. @@ -2930,7 +2910,7 @@ struct @return A Term with value and sort Integer *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_int ctx#gno v (mk_int_sort ctx)#gno) + (new int_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -2944,7 +2924,7 @@ struct Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort ctx#gno size) + (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. @@ -3245,91 +3225,91 @@ struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg ctx#gno t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) (** Unsigned division. @@ -3341,7 +3321,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) (** Signed division. @@ -3356,7 +3336,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) (** Unsigned remainder. @@ -3366,7 +3346,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) (** Signed remainder. @@ -3378,7 +3358,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) (** Two's complement signed remainder (sign follows divisor). @@ -3387,7 +3367,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) (** Unsigned less-than @@ -3395,7 +3375,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult (context_gno ctx) t1#gno t2#gno) (** Two's complement signed less-than @@ -3403,7 +3383,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt (context_gno ctx) t1#gno t2#gno) (** Unsigned less-than or equal to. @@ -3411,7 +3391,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule (context_gno ctx) t1#gno t2#gno) (** Two's complement signed less-than or equal to. @@ -3419,7 +3399,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle (context_gno ctx) t1#gno t2#gno) (** Unsigned greater than or equal to. @@ -3427,7 +3407,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge (context_gno ctx) t1#gno t2#gno) (** Two's complement signed greater than or equal to. @@ -3435,7 +3415,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge (context_gno ctx) t1#gno t2#gno) (** Unsigned greater-than. @@ -3443,7 +3423,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt (context_gno ctx) t1#gno t2#gno) (** Two's complement signed greater-than. @@ -3451,7 +3431,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt (context_gno ctx) t1#gno t2#gno) (** Bit-vector concatenation. @@ -3462,7 +3442,7 @@ struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat (context_gno ctx) t1#gno t2#gno) (** Bit-vector extraction. @@ -3473,7 +3453,7 @@ struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract ctx#gno high low t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) (** Bit-vector sign extension. @@ -3483,7 +3463,7 @@ struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext (context_gno ctx) i t#gno) (** Bit-vector zero extension. @@ -3494,7 +3474,7 @@ struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext (context_gno ctx) i t#gno) (** Bit-vector repetition. @@ -3502,7 +3482,7 @@ struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat (context_gno ctx) i t#gno) (** Shift left. @@ -3517,7 +3497,7 @@ struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl (context_gno ctx) t1#gno t2#gno) (** Logical shift right @@ -3531,7 +3511,7 @@ struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr (context_gno ctx) t1#gno t2#gno) (** Arithmetic shift right @@ -3547,7 +3527,7 @@ struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr (context_gno ctx) t1#gno t2#gno) (** Rotate Left. @@ -3556,7 +3536,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left (context_gno ctx) i t#gno) (** Rotate Right. @@ -3565,7 +3545,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right ctx#gno i t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right (context_gno ctx) i t#gno) (** Rotate Left. @@ -3574,7 +3554,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left (context_gno ctx) t1#gno t2#gno) (** Rotate Right. @@ -3584,7 +3564,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right ctx#gno t1#gno t2#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right (context_gno ctx) t1#gno t2#gno) (** Create an bit bit-vector from the integer argument . @@ -3597,7 +3577,7 @@ struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv ctx#gno n t#gno) + (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv (context_gno ctx) n t#gno) (** Create an integer from the bit-vector argument . @@ -3615,7 +3595,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int ctx#gno t#gno signed) + (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3623,7 +3603,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow ctx#gno t1#gno t2#gno signed) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow (context_gno ctx) t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3631,7 +3611,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow (context_gno ctx) t1#gno t2#gno) (** Create a predicate that checks that the bit-wise subtraction does not overflow. @@ -3639,7 +3619,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow (context_gno ctx) t1#gno t2#gno) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3647,7 +3627,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow ctx#gno t1#gno t2#gno signed) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow (context_gno ctx) t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3655,7 +3635,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) t1#gno t2#gno) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3663,7 +3643,7 @@ struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow ctx#gno t#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow (context_gno ctx) t#gno) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3671,7 +3651,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow ctx#gno t1#gno t2#gno signed) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow (context_gno ctx) t1#gno t2#gno signed) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3679,7 +3659,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow ctx#gno t1#gno t2#gno) + (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow (context_gno ctx) t1#gno t2#gno) (** Create a bit-vector numeral. @@ -3688,7 +3668,7 @@ struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = - (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral ctx#gno v (mk_sort ctx size)#gno) + (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) end (** Functions to manipulate proof expressions *) @@ -4248,7 +4228,7 @@ end Creates a new parameter set *) let mk_params ( ctx : context ) = - (new params ctx)#cnstr_obj (Z3native.mk_params ctx#gno) + (new params ctx)#cnstr_obj (Z3native.mk_params (context_gno ctx)) (** A string representation of the parameter set. @@ -4329,7 +4309,7 @@ struct (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = - (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno to_ctx#gno) + (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) let simplify ( x : goal ) ( p : params option ) = @@ -4360,7 +4340,7 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - (new goal ctx)#cnstr_obj (Z3native.mk_goal ctx#gno models unsat_cores proofs) + (new goal ctx)#cnstr_obj (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno @@ -4429,14 +4409,14 @@ end (** The number of supported tactics. *) - let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics ctx#gno + let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) (** The names of all supported tactics. *) let get_tactic_names ( ctx : context ) = let n = (get_num_tactics ctx ) in - let f i = (Z3native.get_tactic_name ctx#gno i) in + let f i = (Z3native.get_tactic_name (context_gno ctx) i) in Array.init n f @@ -4444,39 +4424,34 @@ end Returns a string containing a description of the tactic with the given name. *) let get_tactic_description ( ctx : context ) ( name : string ) = - Z3native.tactic_get_descr ctx#gno name + Z3native.tactic_get_descr (context_gno ctx) name (** Creates a new Tactic. *) let mk_tactic ( ctx : context ) ( name : string ) = - (new tactic ctx)#cnstr_obj (Z3native.mk_tactic ctx#gno name) + (new tactic ctx)#cnstr_obj (Z3native.mk_tactic (context_gno ctx) name) (** Create a tactic that applies to a Goal and then to every subgoal produced by . *) - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array option ) = - match - match ts with - | None -> None - | Some(rts) -> ( - let f p c = (match p with - | None -> (Some c#gno) - | Some(x) -> (Some (Z3native.tactic_and_then ctx#gno c#gno x))) in - Array.fold_left f None rts) - with - | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno t2#gno) + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = + let f p c = (match p with + | None -> (Some c#gno) + | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) c#gno x))) in + match (Array.fold_left f None ts) with + | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno t2#gno) | Some(x) -> - let o = (Z3native.tactic_and_then ctx#gno t2#gno x) in - (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then ctx#gno t1#gno o) + let o = (Z3native.tactic_and_then (context_gno ctx) t2#gno x) in + (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno o) (** Create a tactic that first applies to a Goal and if it fails then returns the result of applied to the Goal. *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else ctx#gno t1#gno t2#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else (context_gno ctx) t1#gno t2#gno) (** Create a tactic that applies to a goal for milliseconds. @@ -4484,7 +4459,7 @@ end If does not terminate within milliseconds, then it fails. *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for ctx#gno t#gno ms) + (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for (context_gno ctx) t#gno ms) (** Create a tactic that applies to a given goal if the probe @@ -4494,52 +4469,52 @@ end *) (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_when ctx#gno p#gno t#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) p#gno t#gno) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_cond ctx#gno p#gno t1#gno t2#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) p#gno t1#gno t2#gno) (** Create a tactic that keeps applying until the goal is not modified anymore or the maximum number of iterations is reached. *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat ctx#gno t#gno max) + (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat (context_gno ctx) t#gno max) (** Create a tactic that just returns the given goal. *) let skip ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_skip ctx#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_skip (context_gno ctx)) (** Create a tactic always fails. *) let fail ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail ctx#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail (context_gno ctx)) (** Create a tactic that fails if the probe evaluates to false. *) let fail_if ( ctx : context ) ( p : probe ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if ctx#gno p#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) p#gno) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) or trivially unsatisfiable (i.e., contains `false'). *) let fail_if_not_decided ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided ctx#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided (context_gno ctx)) (** Create a tactic that applies using the given set of parameters . *) let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params ctx#gno t#gno p#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params (context_gno ctx) t#gno p#gno) (** Create a tactic that applies using the given set of parameters . @@ -4552,21 +4527,21 @@ end Create a tactic that applies the given tactics in parallel. *) let par_or ( ctx : context ) ( t : tactic array ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or ctx#gno (Array.length t) (tacticaton t)) + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (tacticaton t)) (** Create a tactic that applies to a given goal and then to every subgoal produced by . The subgoals are processed in parallel. *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then ctx#gno t1#gno t2#gno) + (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then (context_gno ctx) t1#gno t2#gno) (** Interrupt the execution of a Z3 procedure. This procedure can be used to interrupt: solvers, simplifiers and tactics. *) let interrupt ( ctx : context ) = - Z3native.interrupt ctx#gno + Z3native.interrupt (context_gno ctx) end (** Probes @@ -4591,68 +4566,68 @@ struct The number of supported Probes. *) let get_num_probes ( ctx : context ) = - Z3native.get_num_probes ctx#gno + Z3native.get_num_probes (context_gno ctx) (** The names of all supported Probes. *) let get_probe_names ( ctx : context ) = let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name ctx#gno i) in + let f i = (Z3native.get_probe_name (context_gno ctx) i) in Array.init n f (** Returns a string containing a description of the probe with the given name. *) let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr ctx#gno name + Z3native.probe_get_descr (context_gno ctx) name (** Creates a new Probe. *) let mk_probe ( ctx : context ) ( name : string ) = - (new probe ctx)#cnstr_obj (Z3native.mk_probe ctx#gno name) + (new probe ctx)#cnstr_obj (Z3native.mk_probe (context_gno ctx) name) (** Create a probe that always evaluates to . *) let const ( ctx : context ) ( v : float ) = - (new probe ctx)#cnstr_obj (Z3native.probe_const ctx#gno v) + (new probe ctx)#cnstr_obj (Z3native.probe_const (context_gno ctx) v) (** Create a probe that evaluates to "true" when the value returned by is less than the value returned by *) let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_lt ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_lt (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is greater than the value returned by *) let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_gt ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_gt (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is less than or equal the value returned by *) let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_le ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_le (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is greater than or equal the value returned by *) let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_ge ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_ge (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value returned by is equal to the value returned by *) let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_eq ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_eq (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value @@ -4660,7 +4635,7 @@ struct *) (* CMW: and is a keyword *) let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_and ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_and (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value @@ -4668,7 +4643,7 @@ struct *) (* CMW: or is a keyword *) let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_or ctx#gno p1#gno p2#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_or (context_gno ctx) p1#gno p2#gno) (** Create a probe that evaluates to "true" when the value @@ -4676,7 +4651,7 @@ struct *) (* CMW: is not a keyword? *) let not_ ( ctx : context ) ( p : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_not ctx#gno p#gno) + (new probe ctx)#cnstr_obj (Z3native.probe_not (context_gno ctx) p#gno) end (** Solvers *) @@ -4836,11 +4811,12 @@ struct *) - let check ( x : solver ) ( assumptions : bool_expr array option) = + let check ( x : solver ) ( assumptions : bool_expr array) = let r = - match assumptions with - | None -> lbool_of_int (Z3native.solver_check x#gnc x#gno) - | Some (ass) -> lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length ass) (astaton ass)) + if ((Array.length assumptions) == 0) then + lbool_of_int (Z3native.solver_check x#gnc x#gno) + else + lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length assumptions) (astaton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -4907,8 +4883,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : symbol option) = match logic with - | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver ctx#gno) - | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic ctx#gno x#gno) + | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver (context_gno ctx)) + | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic (context_gno ctx) x#gno) (** Creates a new (incremental) solver. @@ -4921,7 +4897,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver ctx#gno) + (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver (context_gno ctx)) (** Creates a solver that is implemented using the given tactic. @@ -4930,7 +4906,7 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : tactic ) = - (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic ctx#gno t#gno) + (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno) (** A string representation of the solver. @@ -5333,7 +5309,7 @@ struct Create a Fixedpoint context. *) let mk_fixedpoint ( ctx : context ) = - (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint ctx#gno) + (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint (context_gno ctx)) end (** Global and context options @@ -5354,7 +5330,7 @@ struct *) let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value ctx#gno id value + Z3native.update_param_value (context_gno ctx) id value (** Get a configuration parameter. @@ -5363,7 +5339,7 @@ struct *) let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value ctx#gno id) in + let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in if not r then None else @@ -5385,7 +5361,7 @@ struct *) let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode ctx#gno (int_of_ast_print_mode value) + Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) (** Enable/disable printing of warning messages to the console. @@ -5412,7 +5388,7 @@ struct @return A string representation of the benchmark. *) let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = - Z3native.benchmark_to_smtlib_string ctx#gno name logic status attributes + Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes (Array.length assumptions) (astaton assumptions) formula#gno @@ -5425,92 +5401,93 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib_string ctx#gno str + Z3native.parse_smtlib_string (context_gno ctx) str cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib_file ctx#gno file_name + Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) + (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas ctx#gno + let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_formula ctx#gno i)) :> bool_expr) in + let f i = ((create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) :> bool_expr) in Array.init n f (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions ctx#gno + let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_assumption ctx#gno i)) :> bool_expr ) in + let f i = ((create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) :> bool_expr ) in Array.init n f (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls ctx#gno + let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl ctx#gno i) in + let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts ctx#gno + let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in - let f i = (create_sort ctx (Z3native.get_smtlib_sort ctx#gno i)) in + let f i = (create_sort ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f (** @@ -5519,41 +5496,41 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string ctx#gno str + Z3native.parse_smtlib2_string (context_gno ctx) str cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array option ) ( sorts : sort array option ) ( decl_names : symbol array option ) ( decls : func_decl array option ) = - let csn = (match sort_names with | None -> 0 | Some(x) -> Array.length x) in - let cs = (match sorts with | None -> 0 | Some(x) -> Array.length x) in - let cdn = (match decl_names with | None -> 0 | Some(x) -> Array.length x) in - let cd = (match decls with | None -> 0 | Some(x) -> Array.length x) in + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let csn = (Array.length sort_names) in + let cs = (Array.length sorts) in + let cdn = (Array.length decl_names) in + let cd = (Array.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string ctx#gno file_name + Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (match sort_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match sorts with | None -> [||] | Some(x) -> (astaton x)) + (symbolaton sort_names) + (astaton sorts) cd - (match decl_names with | None -> [||] | Some(x) -> (symbolaton x)) - (match decls with | None -> [||] | Some(x) -> (func_declaton x)) + (symbolaton decl_names) + (func_declaton decls) end (* From 6257c56901179e6560e57a4483a41d1f6f51c820 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 12 Jan 2013 00:01:50 +0000 Subject: [PATCH 382/507] ML API: bugfixes; starting to replace objects with normal types. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 3 +- scripts/update_api.py | 3 +- src/api/ml/z3.ml | 711 ++++++++++++++++++++------------------ 3 files changed, 382 insertions(+), 335 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 129f73d4d..97985a7bc 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -14,6 +14,7 @@ open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic +open Z3.Fixedpoints exception TestFailedException of string @@ -216,8 +217,8 @@ let _ = Printf.printf "bool sort: %s\n" (Sort.to_string bs); Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); - Printf.printf "Disposing...\n"; basic_tests ctx ; + Printf.printf "Disposing...\n"; Gc.full_major () ); Printf.printf "Exiting.\n"; diff --git a/scripts/update_api.py b/scripts/update_api.py index 1986f4a7e..c730a325e 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1300,7 +1300,8 @@ def mk_ml(): ml_wrapper.write('extern "C" {\n') ml_wrapper.write('#endif\n\n') ml_wrapper.write('CAMLprim value n_is_null(value p) {\n') - ml_wrapper.write(' return Val_bool(Data_custom_val(p) == 0);\n') + ml_wrapper.write(' void * t = * (void**) Data_custom_val(p);\n') + ml_wrapper.write(' return Val_bool(t == 0);\n') ml_wrapper.write('}\n\n') ml_wrapper.write('CAMLprim value n_mk_null( void ) {\n') ml_wrapper.write(' CAMLparam0();\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c91d909bc..1e8ffe92e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,9 +7,13 @@ open Z3enums -type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } + +(**/**) + +let null = Z3native.mk_null() +let is_null o = (Z3native.is_null o) -(**/**) let context_dispose ctx = if ctx.m_n_obj_cnt == 0 then ( (* Printf.printf "Disposing context \n" ; *) @@ -19,7 +23,7 @@ let context_dispose ctx = (* re-queue for finalization? *) ) -let context_init settings = +let context_cnstr settings = let cfg = Z3native.mk_config in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; @@ -50,7 +54,7 @@ require one such object, but power users may require more than one. To start usi Z3, do - let ctx = (mk_context None) in + let ctx = (mk_context []) in (...) @@ -58,17 +62,18 @@ where a list of pairs of strings may be passed to set options on the context, e.g., like so: - let cfg = (Some [("model", "true"); ("...", "...")]) in + let cfg = [("model", "true"); ("...", "...")] in let ctx = (mk_context cfg) in (...) *) let mk_context ( cfg : ( string * string ) list ) = - context_init cfg + context_cnstr cfg + + +(* type z3object = { m_ctx : context; m_n_obj : Z3native.ptr option; } *) (**/**) - -(** Z3 objects *) class virtual z3object ctx_init obj_init = object (self) val mutable m_ctx : context = ctx_init @@ -669,15 +674,6 @@ object (self) method decref nc o = Z3native.func_interp_dec_ref nc o end -(** Model objects *) -class model ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.model_inc_ref nc o - method decref nc o = Z3native.model_dec_ref nc o -end - (** Tactic application result objects *) class apply_result ctx = object (self) @@ -724,32 +720,38 @@ object (self) method is_float = m_is_float end -(** Statistics objects *) -class statistics ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.stats_inc_ref nc o - method decref nc o = Z3native.stats_dec_ref nc o -end -(** Solver objects *) -class solver ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.solver_inc_ref nc o - method decref nc o = Z3native.solver_dec_ref nc o -end +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } -(** Fixedpoint objects *) -class fixedpoint ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.fixedpoint_inc_ref nc o - method decref nc o = Z3native.fixedpoint_dec_ref nc o -end +let z3obj_gc o = o.m_ctx +let z3obj_gnc o = (context_gno o.m_ctx) + +let z3obj_gno o = o.m_n_obj +let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + +let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + +let z3obj_cnstr o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o (**/**) @@ -1878,7 +1880,6 @@ struct (astaton names) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -1900,7 +1901,6 @@ struct (Array.length patterns) (patternaton patterns) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -1924,7 +1924,6 @@ struct (astaton names) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -1946,7 +1945,6 @@ struct (Array.length patterns) (patternaton patterns) body#gno) else - let null = Z3native.mk_null() in (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> x#gno) @@ -4347,6 +4345,240 @@ struct end +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model = +struct + type model = z3_native_object + + (**/**) + let model_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : model = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.model_inc_ref ; + dec_ref = Z3native.model_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. + *) + module FuncInterp = + struct + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. + *) + module FuncEntry = + struct + (** + Return the (symbolic) value of this entry. + *) + let get_value ( x : func_entry ) = + create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + + (** + The number of arguments of the entry. + *) + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + + (** + The arguments of the function entry. + *) + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + Array.init n f + + (** + A string representation of the function entry. + *) + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + end + + (** + The number of entries in the function interpretation. + *) + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + + (** + The entries in the function interpretation + *) + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + Array.init n f + + (** + The (symbolic) `else' value of the function interpretation. + *) + let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + + (** + The arity of the function interpretation + *) + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + + (** + A string representation of the function interpretation. + *) + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (Array.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + + (** Retrieves the interpretation (the assignment) of in the model. + A function declaration of zero arity + An expression if the function has an interpretation in the model, null otherwise. *) + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + if (Z3native.is_null np) then + None + else + Some (create_expr (z3obj_gc x) np) + + (** Retrieves the interpretation (the assignment) of in the model. + A Constant + An expression if the constant has an interpretation in the model, null otherwise. + *) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + (** Retrieves the interpretation (the assignment) of a non-constant in the model. + A function declaration of non-zero arity + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range f#gnc f#gno))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if not (Z3native.is_as_array (z3obj_gnc x) n) then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in + get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in + if (Z3native.is_null n) then None else Some ((new func_interp (z3obj_gc x))#cnstr_obj n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) + + (** The function declarations of the constants in the model. *) + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + + (** The number of function interpretations in the model. *) + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) + + (** The function declarations of the function interpretations in the model. *) + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + (** All symbols that have an interpretation in the model. *) + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + Array.append (Array.init n_funcs f) (Array.init n_consts g) + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** + Evaluates the expression in the current model. + + + This function may fail if contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + + An expression + + When this flag is enabled, a model value will be assigned to any constant + or function that does not have an interpretation in the model. + + The evaluation of in the model. + *) + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) t#gno completion) in + if not r then + raise (ModelEvaluationFailedException "evaluation failed") + else + create_expr (z3obj_gc x) v + + (** Alias for eval. *) + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + + + *) + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (create_sort (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + Array.init n f + + + (** The finite set of distinct values that represent the interpretation for sort . + + An uninterpreted sort + An array of expressions, where each is an element of the universe of + *) + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in + Array.init n f + + (** Conversion of models to strings. + A string representation of the model. + *) + let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) +end + + (** Tactics Tactics are the basic building block for creating custom solvers for specific problem domains. @@ -4380,8 +4612,8 @@ struct goal g, that the ApplyResult was obtained from. #return A model for g *) - let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = - (new model x#gc)#cnstr_obj (Z3native.apply_result_convert_model x#gnc x#gno i m#gno) + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + Model.model_cnstr x#gc (Z3native.apply_result_convert_model x#gnc x#gno i (z3obj_gno m)) (** A string representation of the ApplyResult. *) let to_string ( x : apply_result ) = Z3native.apply_result_to_string x#gnc x#gno @@ -4401,11 +4633,6 @@ end | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) - (** creates a solver that is implemented using the given tactic. - *) - let get_solver ( x : tactic ) = - (new solver x#gc)#cnstr_obj (Z3native.mk_solver_from_tactic x#gnc x#gno) - (** The number of supported tactics. *) @@ -4654,9 +4881,23 @@ struct (new probe ctx)#cnstr_obj (Z3native.probe_not (context_gno ctx) p#gno) end + (** Solvers *) module Solver = struct + type solver = z3_native_object + +(**/**) + let solver_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : solver = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.solver_inc_ref ; + dec_ref = Z3native.solver_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res +(**/**) + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE let string_of_status ( s : status) = match s with @@ -4667,6 +4908,18 @@ struct (** Objects that track statistical information about solvers. *) module Statistics = struct + type statistics = z3_native_object + + (**/**) + let statistics_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : statistics = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.stats_inc_ref ; + dec_ref = Z3native.stats_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) (** Statistical data is organized into pairs of [Key, Entry], where every @@ -4703,20 +4956,20 @@ struct end (** A string representation of the statistical data. *) - let to_string ( x : statistics ) = Z3native.stats_to_string x#gnc x#gno + let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) (** The number of statistical data. *) - let get_size ( x : statistics ) = Z3native.stats_size x#gnc x#gno + let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) (** The data entries. *) let get_entries ( x : statistics ) = let n = (get_size x ) in let f i = ( - let k = Z3native.stats_get_key x#gnc x#gno i in - if (Z3native.stats_is_uint x#gnc x#gno i) then - ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value x#gnc x#gno i)) + let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in + if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then + ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value x#gnc x#gno i)) + ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in Array.init n f @@ -4725,7 +4978,7 @@ struct *) let get_keys ( x : statistics ) = let n = (get_size x) in - let f i = (Z3native.stats_get_key x#gnc x#gno i) in + let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** @@ -4739,51 +4992,51 @@ struct (** A string that describes all available solver parameters. *) - let get_help ( x : solver ) = Z3native.solver_get_help x#gnc x#gno + let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) (** Sets the solver parameters. *) let set_parameters ( x : solver ) ( value : params )= - Z3native.solver_set_params x#gnc x#gno value#gno + Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) value#gno (** Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - (new param_descrs x#gc)#cnstr_obj (Z3native.solver_get_param_descrs x#gnc x#gno) + (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). *) - let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes x#gnc x#gno + let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) (** Creates a backtracking point. *) - let push ( x : solver ) = Z3native.solver_push x#gnc x#gno + let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) (** Backtracks backtracking points. Note that an exception is thrown if is not smaller than NumScopes *) - let pop ( x : solver ) ( n : int ) = Z3native.solver_pop x#gnc x#gno n + let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n (** Resets the Solver. This removes all assertions from the solver. *) - let reset ( x : solver ) = Z3native.solver_reset x#gnc x#gno + let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) (** Assert a constraint (or multiple) into the solver. *) let assert_ ( x : solver ) ( constraints : bool_expr array ) = - let f e = (Z3native.solver_assert x#gnc x#gno e#gno) in + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in ignore (Array.map f constraints) ; () @@ -4791,7 +5044,7 @@ struct The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -4799,9 +5052,9 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_assertions x#gnc x#gno) in + let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = ((new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get a i)#gno) in + let f i = ((new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get a i)#gno) in Array.init n f (** @@ -4814,9 +5067,9 @@ struct let check ( x : solver ) ( assumptions : bool_expr array) = let r = if ((Array.length assumptions) == 0) then - lbool_of_int (Z3native.solver_check x#gnc x#gno) + lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions x#gnc x#gno (Array.length assumptions) (astaton assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (astaton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -4830,11 +5083,11 @@ struct if its results was not SATISFIABLE, or if model production is not enabled. *) let get_model ( x : solver ) = - let q = Z3native.solver_get_model x#gnc x#gno in + let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then None else - Some ((new model x#gc)#cnstr_obj q) + Some (Model.model_cnstr (z3obj_gc x) q) (** The proof of the last Check. @@ -4843,11 +5096,11 @@ struct if its results was not UNSATISFIABLE, or if proof production is disabled. *) let get_proof ( x : solver ) = - let q = Z3native.solver_get_proof x#gnc x#gno in + let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then None else - Some (create_expr x#gc q) + Some (create_expr (z3obj_gc x) q) (** The unsat core of the last Check. @@ -4857,7 +5110,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = (new ast_vector x#gc)#cnstr_obj (Z3native.solver_get_unsat_core x#gnc x#gno) in + let cn = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -4865,14 +5118,14 @@ struct (** A brief justification of why the last call to Check returned UNKNOWN. *) - let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown x#gnc x#gno + let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) (** Solver statistics. *) let get_statistics ( x : solver ) = - (new statistics x#gc)#cnstr_obj (Z3native.solver_get_statistics x#gnc x#gno) + (Statistics.statistics_cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) (** Creates a new (incremental) solver. @@ -4883,8 +5136,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : symbol option) = match logic with - | None -> (new solver ctx)#cnstr_obj (Z3native.mk_solver (context_gno ctx)) - | Some (x) -> (new solver ctx)#cnstr_obj (Z3native.mk_solver_for_logic (context_gno ctx) x#gno) + | None -> (solver_cnstr ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (solver_cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) (** Creates a new (incremental) solver. @@ -4897,7 +5150,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (new solver ctx)#cnstr_obj (Z3native.mk_simple_solver (context_gno ctx)) + (solver_cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) (** Creates a solver that is implemented using the given tactic. @@ -4906,261 +5159,54 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : tactic ) = - (new solver ctx)#cnstr_obj (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno) + (solver_cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) (** A string representation of the solver. *) - let to_string ( x : solver ) = Z3native.solver_to_string x#gnc x#gno + let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) -module Model = -struct - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. - *) - module FuncInterp = - struct - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) - module FuncEntry = - struct - (** - Return the (symbolic) value of this entry. - *) - let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) - - (** - The number of arguments of the entry. - *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno - - (** - The arguments of the function entry. - *) - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in - Array.init n f - - (** - A string representation of the function entry. - *) - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - (** - The number of entries in the function interpretation. - *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno - - (** - The entries in the function interpretation - *) - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in - Array.init n f - - (** - The (symbolic) `else' value of the function interpretation. - *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) - - (** - The arity of the function interpretation - *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno - - (** - A string representation of the function interpretation. - *) - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (Array.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - (** Retrieves the interpretation (the assignment) of in the model. - A function declaration of zero arity - An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null np) then - None - else - Some (create_expr x#gc np) - - (** Retrieves the interpretation (the assignment) of in the model. - A Constant - An expression if the constant has an interpretation in the model, null otherwise. - *) - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - (** Retrieves the interpretation (the assignment) of a non-constant in the model. - A function declaration of non-zero arity - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_range f#gnc f#gno))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp x#gnc x#gno f#gno in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if not (Z3native.is_as_array x#gnc n) then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl x#gnc n in - get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp x#gnc x#gno f#gno) in - if (Z3native.is_null n) then None else Some ((new func_interp x#gc)#cnstr_obj n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts x#gnc x#gno - - (** The function declarations of the constants in the model. *) - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.init n f - - - (** The number of function interpretations in the model. *) - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs x#gnc x#gno - - (** The function declarations of the function interpretations in the model. *) - let get_func_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - Array.init n f - - (** All symbols that have an interpretation in the model. *) - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_func_decl x#gnc x#gno i) in - let g i = (new func_decl x#gc)#cnstr_obj (Z3native.model_get_const_decl x#gnc x#gno i) in - Array.append (Array.init n_funcs f) (Array.init n_consts g) - - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - - (** - Evaluates the expression in the current model. - - - This function may fail if contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - - An expression - - When this flag is enabled, a model value will be assigned to any constant - or function that does not have an interpretation in the model. - - The evaluation of in the model. - *) - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval x#gnc x#gno t#gno completion) in - if not r then - raise (ModelEvaluationFailedException "evaluation failed") - else - create_expr x#gc v - - (** Alias for eval. *) - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - (** The number of uninterpreted sorts that the model has an interpretation for. *) - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts x#gnc x#gno - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - - - *) - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (create_sort x#gc (Z3native.model_get_sort x#gnc x#gno i)) in - Array.init n f - - - (** The finite set of distinct values that represent the interpretation for sort . - - An uninterpreted sort - An array of expressions, where each is an element of the universe of - *) - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = (new ast_vector x#gc)#cnstr_obj (Z3native.model_get_sort_universe x#gnc x#gno s#gno) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - Array.init n f - - (** Conversion of models to strings. - A string representation of the model. - *) - let to_string ( x : model ) = Z3native.model_to_string x#gnc x#gno -end - (** Fixedpoint solving *) module Fixedpoints = struct + type fixedpoint = z3_native_object + +(**/**) + let fixedpoint_cnstr ( ctx : context ) = + let res : fixedpoint = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.fixedpoint_inc_ref ; + dec_ref = Z3native.fixedpoint_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; + (z3obj_cnstr res) ; + res +(**/**) + (** A string that describes all available fixedpoint solver parameters. *) let get_help ( x : fixedpoint ) = - Z3native.fixedpoint_get_help x#gnc x#gno + Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) (** Sets the fixedpoint solver parameters. *) let set_params ( x : fixedpoint ) ( p : params )= - Z3native.fixedpoint_set_params x#gnc x#gno p#gno + Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) p#gno (** Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - (new param_descrs x#gc)#cnstr_obj (Z3native.fixedpoint_get_param_descrs x#gnc x#gno) + (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. *) let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = - let f e = (Z3native.fixedpoint_assert x#gnc x#gno e#gno) in + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in ignore (Array.map f constraints) ; () @@ -5168,21 +5214,21 @@ struct Register predicate as recursive relation. *) let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation x#gnc x#gno f#gno + Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) f#gno (** Add rule into the fixedpoint solver. *) let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno (Z3native.mk_null()) - | Some(y) -> Z3native.fixedpoint_add_rule x#gnc x#gno rule#gno y#gno + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno y#gno (** Add table fact to the fixedpoint solver. *) let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = - Z3native.fixedpoint_add_fact x#gnc x#gno pred#gno (Array.length args) args + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) pred#gno (Array.length args) args (** Query the fixedpoint solver. @@ -5191,7 +5237,7 @@ struct The query is unsatisfiable if there are no derivations satisfying the query variables. *) let query ( x : fixedpoint ) ( query : bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query x#gnc x#gno query#gno)) with + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) query#gno)) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5203,7 +5249,7 @@ struct The query is unsatisfiable if there are no derivations satisfying any of the relations. *) let query_r ( x : fixedpoint ) ( relations : func_decl array ) = - match (lbool_of_int (Z3native.fixedpoint_query_relations x#gnc x#gno (Array.length relations) (func_declaton relations))) with + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (func_declaton relations))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5213,7 +5259,7 @@ struct *) let push ( x : fixedpoint ) = - Z3native.fixedpoint_push x#gnc x#gno + Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) (** Backtrack one backtracking point. @@ -5222,94 +5268,93 @@ struct *) let pop ( x : fixedpoint ) = - Z3native.fixedpoint_pop x#gnc x#gno + Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) (** Update named rule into in the fixedpoint solver. *) let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = - Z3native.fixedpoint_update_rule x#gnc x#gno rule#gno name#gno + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno name#gno (** Retrieve satisfying instance or instances of solver, or definitions for the recursive predicates that show unsatisfiability. *) let get_answer ( x : fixedpoint ) = - let q = (Z3native.fixedpoint_get_answer x#gnc x#gno) in + let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in if (Z3native.is_null q) then None else - Some (create_expr x#gc q) + Some (create_expr (z3obj_gc x) q) (** Retrieve explanation why fixedpoint engine returned status Unknown. *) let get_reason_unknown ( x : fixedpoint ) = - Z3native.fixedpoint_get_reason_unknown x#gnc x#gno + Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) (** Retrieve the number of levels explored for a given predicate. *) let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels x#gnc x#gno predicate#gno + Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) predicate#gno (** Retrieve the cover of a predicate. *) let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta x#gnc x#gno level predicate#gno) in + let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level predicate#gno) in if (Z3native.is_null q) then None else - Some (create_expr x#gc q) + Some (create_expr (z3obj_gc x) q) (** Add property about the predicate. The property is added at level. *) let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover x#gnc x#gno level predicate#gno, property#gno + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level predicate#gno property#gno (** Retrieve internal string representation of fixedpoint object. *) - let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string x#gnc x#gno 0 [||] + let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = - Z3native.fixedpoint_set_predicate_representation x#gnc x#gno f#gno (Array.length kinds) (symbolaton kinds) + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (symbolaton kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - Z3native.fixedpoint_to_string x#gnc x#gno (Array.length queries) (astaton queries) + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (astaton queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_rules x#gnc x#gno)) in + let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = ((new ast_vector x#gc)#cnstr_obj (Z3native.fixedpoint_get_assertions x#gnc x#gno)) in + let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr x#gc)#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Create a Fixedpoint context. *) - let mk_fixedpoint ( ctx : context ) = - (new fixedpoint ctx)#cnstr_obj (Z3native.mk_fixedpoint (context_gno ctx)) + let mk_fixedpoint ( ctx : context ) = fixedpoint_cnstr ctx end (** Global and context options From 3347d7ca8c74c21fef3218fb486abfb66810fcd2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 12 Jan 2013 01:15:23 +0000 Subject: [PATCH 383/507] ML API: moved more objects into normal types. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 1 - src/api/ml/z3.ml | 766 +++++++++++++++++++------------------- 2 files changed, 392 insertions(+), 375 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 97985a7bc..38b5fe642 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -14,7 +14,6 @@ open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic -open Z3.Fixedpoints exception TestFailedException of string diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 1e8ffe92e..545c7c227 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -20,7 +20,7 @@ let context_dispose ctx = (Z3native.del_context ctx.m_n_ctx) ) else ( Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; - (* re-queue for finalization? *) + (* re-queue for finalization? *) ) let context_cnstr settings = @@ -38,7 +38,7 @@ let context_cnstr settings = (* CMW: Install error handler here! m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); + GC.SuppressFinalize(this); *) let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) @@ -49,23 +49,23 @@ let context_gno ctx = ctx.m_n_ctx (** Create a context object. -Most interactions with Z3 are interpreted in some context; many users will only -require one such object, but power users may require more than one. To start using -Z3, do + Most interactions with Z3 are interpreted in some context; many users will only + require one such object, but power users may require more than one. To start using + Z3, do - + let ctx = (mk_context []) in (...) - + -where a list of pairs of strings may be passed to set options on -the context, e.g., like so: + where a list of pairs of strings may be passed to set options on + the context, e.g., like so: - + let cfg = [("model", "true"); ("...", "...")] in let ctx = (mk_context cfg) in (...) - + *) let mk_context ( cfg : ( string * string ) list ) = context_cnstr cfg @@ -656,70 +656,6 @@ let tacticaton (a : tactic array) = let f (e : tactic) = e#gno in Array.map f a -(** Function interpretation entry objects *) -class func_entry ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.func_entry_inc_ref nc o - method decref nc o = Z3native.func_entry_dec_ref nc o -end - -(** Function interpretation objects *) -class func_interp ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.func_interp_inc_ref nc o - method decref nc o = Z3native.func_interp_dec_ref nc o -end - -(** Tactic application result objects *) -class apply_result ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.apply_result_inc_ref nc o - method decref nc o = Z3native.apply_result_dec_ref nc o -end - -(** Probe objects *) -class probe ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.probe_inc_ref nc o - method decref nc o = Z3native.probe_dec_ref nc o -end - -(** Statistical value objects *) -class statistics_entry = -object (self) - val mutable m_key : string = "" - val mutable m_is_int = false - val mutable m_is_float = false - val mutable m_int = 0 - val mutable m_float = 0.0 - - method cnstr_si k v = - m_key <- k; - m_is_int <- true; - m_int <- v; - self - - method cnstr_sd k v = - m_key <- k; - m_is_float <- true; - m_float <- v; - self - - method key = m_key - method int = m_int - method float = m_float - method is_int = m_is_int - method is_float = m_is_float -end - type z3_native_object = { m_ctx : context ; @@ -1012,46 +948,46 @@ struct x#rational end - (** - Creates a new function declaration. - *) - let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name domain range + (** + Creates a new function declaration. + *) + let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name domain range - (** - Creates a new function declaration. - *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = - mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range + (** + Creates a new function declaration. + *) + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = + mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range - (** - Creates a fresh function declaration with a name prefixed with . - - - *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix domain range + (** + Creates a fresh function declaration with a name prefixed with . + + + *) + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix domain range - (** - Creates a new constant function declaration. - *) - let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name [||] range + (** + Creates a new constant function declaration. + *) + let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr name [||] range - (** - Creates a new constant function declaration. - *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range + (** + Creates a new constant function declaration. + *) + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = + (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range - (** - Creates a fresh constant function declaration with a name prefixed with . - - - *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix [||] range + (** + Creates a fresh constant function declaration with a name prefixed with . + + + *) + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = + (new func_decl ctx)#cnstr_pdr prefix [||] range (** @@ -1333,31 +1269,31 @@ struct else (create_ast to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx))) -(** - Wraps an AST. + (** + Wraps an AST. - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. -*) + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + *) let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - create_ast ctx ptr + create_ast ctx ptr -(** - Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. -*) + (** + Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + *) let unwrap_ast ( a : ast ) = a#gno end @@ -1373,17 +1309,17 @@ struct | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) -(** - a string describing all available parameters to Expr.Simplify. -*) + (** + a string describing all available parameters to Expr.Simplify. + *) let get_simplify_help ( ctx : context ) = Z3native.simplify_get_help (context_gno ctx) -(** - Retrieves parameter descriptions for simplifier. -*) - let get_simplify_parameter_descrs ( ctx : context ) = - (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) + (** + Retrieves parameter descriptions for simplifier. + *) + let get_simplify_parameter_descrs ( ctx : context ) = + (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. @@ -2691,7 +2627,7 @@ struct let (r, v) = Z3native.get_numeral_int x#gnc x#gno in if r then v else raise (Z3native.Exception "Conversion failed.") - + (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3202,7 +3138,7 @@ struct let (r, v) = Z3native.get_numeral_int x#gnc x#gno in if r then v else raise (Z3native.Exception "Conversion failed.") - + (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -4150,29 +4086,29 @@ end *) module Params = struct -(** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) -module ParamDescrs = -struct + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs = + struct - (** Validate a set of parameters. *) - let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - (** Retrieve all names of parameters. *) - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size x#gnc x#gno in - let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in - Array.init n f + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size x#gnc x#gno in + let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - - (** Retrieves a string representation of the ParamDescrs. *) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno -end + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno + end (** Adds a parameter setting. @@ -4353,11 +4289,11 @@ struct type model = z3_native_object (**/**) - let model_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.model_inc_ref ; - dec_ref = Z3native.model_dec_ref } in + m_n_obj = null ; + inc_ref = Z3native.model_inc_ref ; + dec_ref = Z3native.model_dec_ref } in (z3obj_sno res ctx no) ; (z3obj_cnstr res) ; res @@ -4370,6 +4306,18 @@ struct *) module FuncInterp = struct + type func_interp = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_interp = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_interp_inc_ref ; + dec_ref = Z3native.func_interp_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) (** Function interpretations entries @@ -4377,23 +4325,36 @@ struct *) module FuncEntry = struct + type func_entry = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_entry = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_entry_inc_ref ; + dec_ref = Z3native.func_entry_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** Return the (symbolic) value of this entry. *) let get_value ( x : func_entry ) = - create_expr x#gc (Z3native.func_entry_get_value x#gnc x#gno) + create_expr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) (** The number of arguments of the entry. *) - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args x#gnc x#gno + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) (** The arguments of the function entry. *) let get_args ( x : func_entry ) = let n = (get_num_args x) in - let f i = (create_expr x#gc (Z3native.func_entry_get_arg x#gnc x#gno i)) in + let f i = (create_expr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4408,25 +4369,25 @@ struct (** The number of entries in the function interpretation. *) - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries x#gnc x#gno + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) (** The entries in the function interpretation *) let get_entries ( x : func_interp ) = let n = (get_num_entries x) in - let f i = ((new func_entry x#gc)#cnstr_obj (Z3native.func_interp_get_entry x#gnc x#gno i)) in + let f i = (FuncEntry.cnstr (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** The (symbolic) `else' value of the function interpretation. *) - let get_else ( x : func_interp ) = create_expr x#gc (Z3native.func_interp_get_else x#gnc x#gno) + let get_else ( x : func_interp ) = create_expr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) (** The arity of the function interpretation *) - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity x#gnc x#gno + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) (** A string representation of the function interpretation. @@ -4486,7 +4447,7 @@ struct | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in - if (Z3native.is_null n) then None else Some ((new func_interp (z3obj_gc x))#cnstr_obj n) + if (Z3native.is_null n) then None else Some (FuncInterp.cnstr (z3obj_gc x) n) (** The number of constants that have an interpretation in the model. *) let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) @@ -4579,6 +4540,130 @@ struct end +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe = +struct + type probe = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : probe = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.probe_inc_ref ; + dec_ref = Z3native.probe_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** + Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. + *) + let apply ( x : probe ) (g : goal) = + Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) g#gno + + (** + The number of supported Probes. + *) + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes (context_gno ctx) + + (** + The names of all supported Probes. + *) + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name (context_gno ctx) i) in + Array.init n f + + (** + Returns a string containing a description of the probe with the given name. + *) + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr (context_gno ctx) name + + (** + Creates a new Probe. + *) + let mk_probe ( ctx : context ) ( name : string ) = + (cnstr ctx (Z3native.mk_probe (context_gno ctx) name)) + + (** + Create a probe that always evaluates to . + *) + let const ( ctx : context ) ( v : float ) = + (cnstr ctx (Z3native.probe_const (context_gno ctx) v)) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than the value returned by + *) + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than the value returned by + *) + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is less than or equal the value returned by + *) + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is greater than or equal the value returned by + *) + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value returned by + is equal to the value returned by + *) + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value + and evaluate to "true". + *) + (* CMW: and is a keyword *) + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value + or evaluate to "true". + *) + (* CMW: or is a keyword *) + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (cnstr ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + (** + Create a probe that evaluates to "true" when the value + does not evaluate to "true". + *) + (* CMW: is not a keyword? *) + let not_ ( ctx : context ) ( p : probe ) = + (cnstr ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) +end + + (** Tactics Tactics are the basic building block for creating custom solvers for specific problem domains. @@ -4588,36 +4673,49 @@ end *) module Tactic = struct -(** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) -module ApplyResult = -struct - (** The number of Subgoals. *) - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals x#gnc x#gno + (** Tactic application results - (** Retrieves the subgoals from the apply_result. *) - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) in - Array.init n f - - (** Retrieves the subgoals from the apply_result. *) - let get_subgoal ( x : apply_result ) ( i : int ) = - (new goal x#gc)#cnstr_obj (Z3native.apply_result_get_subgoal x#gnc x#gno i) - - (** Convert a model for the subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g - *) - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.model_cnstr x#gc (Z3native.apply_result_convert_model x#gnc x#gno i (z3obj_gno m)) - - (** A string representation of the ApplyResult. *) - let to_string ( x : apply_result ) = Z3native.apply_result_to_string x#gnc x#gno -end + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) + module ApplyResult = + struct + type apply_result = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : apply_result = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.apply_result_inc_ref ; + dec_ref = Z3native.apply_result_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** The number of Subgoals. *) + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + (** Retrieves the subgoals from the apply_result. *) + let get_subgoal ( x : apply_result ) ( i : int ) = + (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + + (** Convert a model for the subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g + *) + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + Model.cnstr (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) + + (** A string representation of the ApplyResult. *) + let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) + end (** A string containing a description of parameters accepted by the tactic. *) let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno @@ -4630,8 +4728,8 @@ end (** Apply the tactic to the goal. *) let apply ( x : tactic ) ( g : goal ) ( p : params option ) = match p with - | None -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply x#gnc x#gno g#gno) - | Some (pn) -> (new apply_result x#gc)#cnstr_obj (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno) + | None -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply x#gnc x#gno g#gno)) + | Some (pn) -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno)) (** The number of supported tactics. @@ -4695,15 +4793,15 @@ end If evaluates to false, then the new tactic behaves like the skip tactic. *) (* CMW: when is a keyword *) - let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) p#gno t#gno) + let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) t#gno) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) - let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) p#gno t1#gno t2#gno) + let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) t1#gno t2#gno) (** Create a tactic that keeps applying until the goal is not @@ -4727,8 +4825,8 @@ end (** Create a tactic that fails if the probe evaluates to false. *) - let fail_if ( ctx : context ) ( p : probe ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) p#gno) + let fail_if ( ctx : context ) ( p : Probe.probe ) = + (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) @@ -4771,124 +4869,14 @@ end Z3native.interrupt (context_gno ctx) end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Probe = -struct - (** - Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - *) - let apply ( x : probe ) (g : goal) = - Z3native.probe_apply x#gnc x#gno g#gno - - (** - The number of supported Probes. - *) - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes (context_gno ctx) - - (** - The names of all supported Probes. - *) - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name (context_gno ctx) i) in - Array.init n f - - (** - Returns a string containing a description of the probe with the given name. - *) - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr (context_gno ctx) name - - (** - Creates a new Probe. - *) - let mk_probe ( ctx : context ) ( name : string ) = - (new probe ctx)#cnstr_obj (Z3native.mk_probe (context_gno ctx) name) - - (** - Create a probe that always evaluates to . - *) - let const ( ctx : context ) ( v : float ) = - (new probe ctx)#cnstr_obj (Z3native.probe_const (context_gno ctx) v) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by - *) - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_lt (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by - *) - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_gt (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by - *) - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_le (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by - *) - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_ge (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by - *) - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_eq (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". - *) - (* CMW: and is a keyword *) - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_and (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". - *) - (* CMW: or is a keyword *) - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_or (context_gno ctx) p1#gno p2#gno) - - (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". - *) - (* CMW: is not a keyword? *) - let not_ ( ctx : context ) ( p : probe ) = - (new probe ctx)#cnstr_obj (Z3native.probe_not (context_gno ctx) p#gno) -end - (** Solvers *) module Solver = struct type solver = z3_native_object -(**/**) - let solver_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.solver_inc_ref ; @@ -4896,7 +4884,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_cnstr res) ; res -(**/**) + (**/**) type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE @@ -4911,7 +4899,7 @@ struct type statistics = z3_native_object (**/**) - let statistics_cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.stats_inc_ref ; @@ -4919,28 +4907,58 @@ struct (z3obj_sno res ctx no) ; (z3obj_cnstr res) ; res - (**/**) + (**/**) (** - Statistical data is organized into pairs of [Key, Entry], where every - Entry is either a DoubleEntry or a UIntEntry + Statistical data is organized into pairs of \[Key, Entry\], where every + Entry is either a floating point or integer value. + *) module Entry = struct + type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } + + (**/**) + let cnstr_si k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = true ; + m_is_float = false ; + m_int = v ; + m_float = 0.0 + } in + res + + let cnstr_sd k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = false ; + m_is_float = true ; + m_int = 0 ; + m_float = v + } in + res + (**/**) + (** The key of the entry. *) - let get_key (x : statistics_entry) = x#key + let get_key (x : statistics_entry) = x.m_key (** The int-value of the entry. *) - let get_int (x : statistics_entry) = x#int + let get_int (x : statistics_entry) = x.m_int (** The float-value of the entry. *) - let get_float (x : statistics_entry) = x#float + let get_float (x : statistics_entry) = x.m_float (** True if the entry is uint-valued. *) - let is_int (x : statistics_entry) = x#is_int + let is_int (x : statistics_entry) = x.m_is_int (** True if the entry is double-valued. *) - let is_float (x : statistics_entry) = x#is_float + let is_float (x : statistics_entry) = x.m_is_float (** The string representation of the the entry's value. *) let to_string_value (x : statistics_entry) = @@ -4967,9 +4985,9 @@ struct let f i = ( let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - ((new statistics_entry)#cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - ((new statistics_entry)#cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in Array.init n f @@ -5087,7 +5105,7 @@ struct if (Z3native.is_null q) then None else - Some (Model.model_cnstr (z3obj_gc x) q) + Some (Model.cnstr (z3obj_gc x) q) (** The proof of the last Check. @@ -5125,7 +5143,7 @@ struct Solver statistics. *) let get_statistics ( x : solver ) = - (Statistics.statistics_cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) + (Statistics.cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) (** Creates a new (incremental) solver. @@ -5136,8 +5154,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : symbol option) = match logic with - | None -> (solver_cnstr ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (solver_cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) + | None -> (cnstr ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) (** Creates a new (incremental) solver. @@ -5150,7 +5168,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (solver_cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) + (cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) (** Creates a solver that is implemented using the given tactic. @@ -5159,7 +5177,7 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : tactic ) = - (solver_cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) + (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) (** A string representation of the solver. @@ -5169,12 +5187,12 @@ end (** Fixedpoint solving *) -module Fixedpoints = +module Fixedpoint = struct type fixedpoint = z3_native_object -(**/**) - let fixedpoint_cnstr ( ctx : context ) = + (**/**) + let cnstr ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.fixedpoint_inc_ref ; @@ -5182,7 +5200,7 @@ struct (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; (z3obj_cnstr res) ; res -(**/**) + (**/**) (** A string that describes all available fixedpoint solver parameters. @@ -5320,7 +5338,7 @@ struct Retrieve internal string representation of fixedpoint object. *) let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - + (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) @@ -5354,7 +5372,7 @@ struct (** Create a Fixedpoint context. *) - let mk_fixedpoint ( ctx : context ) = fixedpoint_cnstr ctx + let mk_fixedpoint ( ctx : context ) = cnstr ctx end (** Global and context options @@ -5365,24 +5383,24 @@ end module Options = struct -(** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - -*) + (** + Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + + *) let update_param_value ( ctx : context ) ( id : string) ( value : string )= Z3native.update_param_value (context_gno ctx) id value -(** - Get a configuration parameter. - - Returns None if the parameter value does not exist. - -*) + (** + Get a configuration parameter. + + Returns None if the parameter value does not exist. + + *) let get_param_value ( ctx : context ) ( id : string ) = let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in if not r then @@ -5408,12 +5426,12 @@ struct let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) -(** - Enable/disable printing of warning messages to the console. + (** + Enable/disable printing of warning messages to the console. - Note that this function is static and effects the behaviour of - all contexts globally. -*) + Note that this function is static and effects the behaviour of + all contexts globally. + *) let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled end @@ -5581,17 +5599,17 @@ end (* (** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. + A delegate which is executed when an error is raised. + + Note that it is possible for memory leaks to occur if error handlers + throw exceptions. *) - public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); + public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); - internal Z3native.error_handler m_n_err_handler = null; + internal Z3native.error_handler m_n_err_handler = null; - internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) + internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. + Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. *) From 1b3e1d1a6c6e18c53cdf8ec893bb52b544a04e8d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 12 Jan 2013 23:18:05 +0000 Subject: [PATCH 384/507] ML API: moved more objects into normal types. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 734 ++++++++++++++++++++++++++--------------------- 1 file changed, 412 insertions(+), 322 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 545c7c227..8c0f24c4b 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,13 +7,30 @@ open Z3enums -type context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } - -(**/**) - +(**/**) +(* Some helpers. *) + let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) +let mk_list ( f : int -> 'a ) ( n : int ) = + let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = + if (i >= n) then + tail + else + (mk_list' f (i+1) n ((f i) :: tail)) + in + mk_list' f 0 n [] +(**/**) + + +(**/**) +type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +(**/**) +type context = z3_native_context + +(**/**) + let context_dispose ctx = if ctx.m_n_obj_cnt == 0 then ( (* Printf.printf "Disposing context \n" ; *) @@ -71,8 +88,6 @@ let mk_context ( cfg : ( string * string ) list ) = context_cnstr cfg -(* type z3object = { m_ctx : context; m_n_obj : Z3native.ptr option; } *) - (**/**) class virtual z3object ctx_init obj_init = object (self) @@ -120,17 +135,6 @@ object (self) method gnc = (context_gno m_ctx) end - -(** Parameter set objects *) -class params ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.params_inc_ref nc o - method decref nc o = Z3native.params_dec_ref nc o -end - - (** Symbol objects *) class symbol ctx = object (self) @@ -292,44 +296,6 @@ let func_declaton (a : func_decl array) = let f (e : func_decl) = e#gno in Array.map f a -class parameter = -object (self) - val mutable m_kind : parameter_kind = PARAMETER_INT; - val mutable m_i : int = 0 - val mutable m_d : float = 0.0 - val mutable m_sym : symbol option = None - val mutable m_srt : sort option = None - val mutable m_ast : ast option = None - val mutable m_fd : func_decl option = None - val mutable m_r : string = "" - - method cnstr_int i = m_kind <- PARAMETER_INT; m_i <- i - method cnstr_double d = m_kind <- PARAMETER_DOUBLE; m_d <- d - method cnstr_symbol sym = m_kind <- PARAMETER_SYMBOL; m_sym <- sym - method cnstr_sort srt = m_kind <- PARAMETER_SORT; m_srt <- srt - method cnstr_ast ast = m_kind <- PARAMETER_AST; m_ast <- ast - method cnstr_func_decl fd = m_kind <- PARAMETER_FUNC_DECL; m_fd <- fd - method cnstr_rational r = m_kind <- PARAMETER_RATIONAL; m_r <- r - - method kind = m_kind - method int = m_i - method double = m_d - method symbol = match m_sym with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter symbol") - method sort = match m_srt with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter sort") - method ast = match m_ast with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter ast") - method func_decl = match m_fd with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing parameter func_decl") - method rational = m_r -end - - (** Enum sort objects *) class enum_sort ctx = object (self) @@ -499,26 +465,6 @@ let create_sort ctx obj = | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") -(** AST vector objects *) -class ast_vector ctx = -object (self) - inherit z3object ctx None - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.ast_vector_inc_ref nc o - method decref nc o = Z3native.ast_vector_dec_ref nc o -end - - -(** AST map objects *) -class ast_map ctx = -object (self) - inherit z3object ctx None - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.ast_map_inc_ref nc o - method decref nc o = Z3native.ast_map_dec_ref nc o -end - - (** Expression objects *) class expr ctx = object(self) @@ -625,37 +571,6 @@ let patternaton (a : pattern array) = let f (e : pattern) = e#gno in Array.map f a -(** Parameter description objects *) -class param_descrs ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.param_descrs_inc_ref nc o - method decref nc o = Z3native.param_descrs_dec_ref nc o -end - -(** Goal objects *) -class goal ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.goal_inc_ref nc o - method decref nc o = Z3native.goal_dec_ref nc o -end - -(** Tactic objects *) -class tactic ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = Z3native.tactic_inc_ref nc o - method decref nc o = Z3native.tactic_dec_ref nc o -end - -let tacticaton (a : tactic array) = - let f (e : tactic) = e#gno in - Array.map f a - type z3_native_object = { m_ctx : context ; @@ -689,6 +604,10 @@ let z3obj_cnstr o = let f = fun o -> (z3obj_dispose o) in Gc.finalise f o +let array_to_native a = + let f e = (z3obj_gno e) in + Array.map f a + (**/**) @@ -890,62 +809,153 @@ let create_ast ctx no = (** Function declarations *) module FuncDecl = struct + (** Parameters of Func_Decls *) module Parameter = struct + type parameter = { + m_kind : parameter_kind ; + m_i : int ; + m_d : float ; + m_sym : symbol option ; + m_srt : sort option ; + m_ast : ast option ; + m_fd : func_decl option ; + m_r : string ; + } + + (**/**) + let cnstr_int i = { + m_kind = PARAMETER_INT ; + m_i = i ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_double d = { + m_kind = PARAMETER_DOUBLE ; + m_i = 0 ; + m_d = d ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_symbol sym = { + m_kind = PARAMETER_SYMBOL ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = sym ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_sort srt = { + m_kind = PARAMETER_SORT ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = srt ; + m_ast = None ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_ast ast = { + m_kind = PARAMETER_AST ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = ast ; + m_fd = None ; + m_r = "" ; + } + + let cnstr_func_decl fd ={ + m_kind = PARAMETER_FUNC_DECL ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = fd ; + m_r = "" ; + } + + let cnstr_rational r = { + m_kind = PARAMETER_RATIONAL ; + m_i = 0 ; + m_d = 0.0 ; + m_sym = None ; + m_srt = None ; + m_ast = None ; + m_fd = None ; + m_r = r ; + } + (**/**) + (** The kind of the parameter. *) - let get_kind (x : parameter) = x#kind + let get_kind ( x : parameter ) = x.m_kind (**The int value of the parameter.*) - let get_int (x : parameter) = - if (x#kind != PARAMETER_INT) then + let get_int ( x : parameter ) = + if ((get_kind x) != PARAMETER_INT) then raise (Z3native.Exception "parameter is not an int") else - x#int + x.m_i (**The double value of the parameter.*) - let get_double (x : parameter) = - if (x#kind != PARAMETER_DOUBLE) then + let get_double ( x : parameter ) = + if ((get_kind x) != PARAMETER_DOUBLE) then raise (Z3native.Exception "parameter is not a double") else - x#double + x.m_d (**The Symbol value of the parameter.*) - let get_symbol (x : parameter) = - if (x#kind != PARAMETER_SYMBOL) then + let get_symbol ( x : parameter ) = + if ((get_kind x) != PARAMETER_SYMBOL) then raise (Z3native.Exception "parameter is not a symbol") else - x#symbol + x.m_sym (**The Sort value of the parameter.*) - let get_sort (x : parameter) = - if (x#kind != PARAMETER_SORT) then + let get_sort ( x : parameter ) = + if ((get_kind x) != PARAMETER_SORT) then raise (Z3native.Exception "parameter is not a sort") else - x#sort + x.m_srt (**The AST value of the parameter.*) - let get_ast (x : parameter) = - if (x#kind != PARAMETER_AST) then + let get_ast ( x : parameter ) = + if ((get_kind x) != PARAMETER_AST) then raise (Z3native.Exception "parameter is not an ast") else - x#ast + x.m_ast (**The FunctionDeclaration value of the parameter.*) - let get_ast (x : parameter) = - if (x#kind != PARAMETER_FUNC_DECL) then + let get_ast ( x : parameter ) = + if ((get_kind x) != PARAMETER_FUNC_DECL) then raise (Z3native.Exception "parameter is not an function declaration") else - x#func_decl + x.m_fd (**The rational string value of the parameter.*) - let get_rational (x : parameter) = - if (x#kind != PARAMETER_RATIONAL) then + let get_rational ( x : parameter ) = + if ((get_kind x) != PARAMETER_RATIONAL) then raise (Z3native.Exception "parameter is not a ratinoal string") else - x#rational + x.m_r end (** @@ -1051,7 +1061,7 @@ struct The number of parameters of the function declaration *) let get_num_parameters (x : func_decl) = (Z3native.get_decl_num_parameters x#gnc x#gno) - + (** The parameters of the function declaration *) @@ -1059,15 +1069,15 @@ struct let n = (get_num_parameters x) in let f i = ( match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with - | PARAMETER_INT -> (new parameter)#cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) - | PARAMETER_DOUBLE -> (new parameter)#cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) - | PARAMETER_SYMBOL-> (new parameter)#cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) - | PARAMETER_SORT -> (new parameter)#cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) - | PARAMETER_AST -> (new parameter)#cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) - | PARAMETER_FUNC_DECL -> (new parameter)#cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) - | PARAMETER_RATIONAL -> (new parameter)#cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) + | PARAMETER_INT -> Parameter.cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) + | PARAMETER_DOUBLE -> Parameter.cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) + | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) + | PARAMETER_SORT -> Parameter.cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) + | PARAMETER_AST -> Parameter.cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) + | PARAMETER_FUNC_DECL -> Parameter.cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) + | PARAMETER_RATIONAL -> Parameter.cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) ) in - Array.init n f + mk_list f n (** Create expression that applies function to arguments. @@ -1083,9 +1093,22 @@ struct (** Vectors of ASTs *) module ASTVector = struct + type ast_vector = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_vector = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_vector_inc_ref ; + dec_ref = Z3native.ast_vector_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** The size of the vector *) let get_size ( x : ast_vector ) = - Z3native.ast_vector_size x#gnc x#gno + Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) (** Retrieves the i-th object in the vector. @@ -1093,16 +1116,16 @@ struct @return An AST *) let get ( x : ast_vector ) ( i : int ) = - create_ast x#gc (Z3native.ast_vector_get x#gnc x#gno i) + create_ast (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) (** Sets the i-th object in the vector. *) let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set x#gnc x#gno i value#gno + Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i value#gno (** Resize the vector to . @param newSize The new size of the vector. *) let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize x#gnc x#gno new_size + Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size (** Add the AST to the back of the vector. The size @@ -1110,7 +1133,7 @@ struct @param a An AST *) let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push x#gnc x#gno a#gno + Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) a#gno (** Translates all ASTs in the vector to . @@ -1118,60 +1141,73 @@ struct @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = - (new ast_vector to_ctx)#cnstr_obj (Z3native.ast_vector_translate x#gnc x#gno (context_gno to_ctx)) + cnstr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string x#gnc x#gno + Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) end (** Map from AST to AST *) module ASTMap = struct + type ast_map = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_map = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_map_inc_ref ; + dec_ref = Z3native.ast_map_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** Checks whether the map contains the key . @param k An AST @return True if is a key in the map, false otherwise. *) - let contains ( m : ast_map ) ( key : ast ) = - (Z3native.ast_map_contains m#gnc m#gno key#gno) + let contains ( x : ast_map ) ( key : ast ) = + (Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) key#gno) (** Finds the value associated with the key . This function signs an error when is not a key in the map. @param k An AST *) - let find ( m : ast_map ) ( key : ast ) = - create_ast m#gc (Z3native.ast_map_find m#gnc m#gno key#gno) + let find ( x : ast_map ) ( key : ast ) = + create_ast (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) key#gno) (** Stores or replaces a new key/value pair in the map. @param k The key AST @param v The value AST *) - let insert ( m : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert m#gnc m#gno key#gno value#gno + let insert ( x : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) key#gno value#gno (** Erases the key from the map. @param k An AST *) - let erase ( m : ast_map ) ( key : ast ) = - Z3native.ast_map_erase m#gnc m#gno key#gno + let erase ( x : ast_map ) ( key : ast ) = + Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) key#gno (** Removes all keys from the map. *) - let reset ( m : ast_map ) = - Z3native.ast_map_reset m#gnc m#gno + let reset ( x : ast_map ) = + Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) (** The size of the map *) - let get_size ( m : ast_map ) = - Z3native.ast_map_size m#gnc m#gno + let get_size ( x : ast_map ) = + Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) (** The keys stored in the map. *) - let get_keys ( m : ast_map ) = - (new ast_vector m#gc)#cnstr_obj (Z3native.ast_map_keys m#gnc m#gno) + let get_keys ( x : ast_map ) = + ASTVector.cnstr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) - let to_strnig ( m : ast_map ) = - Z3native.ast_map_to_string m#gnc m#gno + let to_string ( x : ast_map ) = + Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) end (** @@ -1297,6 +1333,125 @@ struct let unwrap_ast ( a : ast ) = a#gno end + +(** + Parameter sets (of Solvers, Tactics, ...) + + A Params objects represents a configuration in the form of symbol/value pairs. +*) +module Params = +struct + type params = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : params = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.params_inc_ref ; + dec_ref = Z3native.params_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs = + struct + type param_descrs = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : param_descrs = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.param_descrs_inc_ref ; + dec_ref = Z3native.param_descrs_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + + (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params ) = + Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) + + (** Retrieve kind of parameter. *) + let get_kind ( x : param_descrs ) ( name : symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) name#gno)) + + (** Retrieve all names of parameters. *) + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in + let f i = create_symbol (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in + Array.init n f + + (** The size of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) + + (** Retrieves a string representation of the ParamDescrs. *) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) + end + + (** + Adds a parameter setting. + *) + let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = + Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) name#gno value + + (** + Adds a parameter setting. + *) + let add_int ( x : params ) (name : symbol ) ( value : int ) = + Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) name#gno value + + (** + Adds a parameter setting. + *) + let add_double ( x : params ) ( name : symbol ) ( value : float ) = + Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) name#gno value + + (** + Adds a parameter setting. + *) + let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = + Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) name#gno value#gno + + (** + Adds a parameter setting. + *) + let add_s_bool ( x : params ) ( name : string) ( value : bool ) = + add_bool x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Adds a parameter setting. + *) + let add_s_int ( x : params) ( name : string ) ( value : int ) = + add_int x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Adds a parameter setting. + *) + let add_s_double ( x : params ) ( name : string ) ( value : float ) = + add_double x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Adds a parameter setting. + *) + let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = + add_symbol x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + + (** + Creates a new parameter set + *) + let mk_params ( ctx : context ) = + cnstr ctx (Z3native.mk_params (context_gno ctx)) + + (** + A string representation of the parameter set. + *) + let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) +end + + (** General expressions (terms), including Boolean logic *) module Expr = struct @@ -1305,9 +1460,9 @@ struct @param p A set of parameters to configure the simplifier *) - let simplify ( x : expr ) ( p : params option ) = match p with + let simplify ( x : expr ) ( p : Params.params option ) = match p with | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) - | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno pp#gno) + | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno (z3obj_gno pp)) (** a string describing all available parameters to Expr.Simplify. @@ -1319,7 +1474,7 @@ struct Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - (new param_descrs ctx)#cnstr_obj (Z3native.simplify_get_param_descrs (context_gno ctx)) + Params.ParamDescrs.cnstr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. @@ -4079,96 +4234,6 @@ struct let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end -(** - Parameter sets (of Solvers, Tactics, ...) - - A Params objects represents a configuration in the form of symbol/value pairs. -*) -module Params = -struct - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs = - struct - - (** Validate a set of parameters. *) - let validate ( x : param_descrs ) ( p : params )= Z3native.params_validate x#gnc p#gno x#gno - - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind x#gnc x#gno name#gno)) - - (** Retrieve all names of parameters. *) - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size x#gnc x#gno in - let f i = create_symbol x#gc (Z3native.param_descrs_get_name x#gnc x#gno i) in - Array.init n f - - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size x#gnc x#gno - - (** Retrieves a string representation of the ParamDescrs. *) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string x#gnc x#gno - end - - (** - Adds a parameter setting. - *) - let add_bool (p : params) (name : symbol) (value : bool) = - Z3native.params_set_bool p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_int (p : params) (name : symbol) (value : int) = - Z3native.params_set_uint p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_double (p : params) (name : symbol) (value : float) = - Z3native.params_set_double p#gnc p#gno name#gno value - - (** - Adds a parameter setting. - *) - let add_symbol (p : params) (name : symbol) (value : symbol) = - Z3native.params_set_symbol p#gnc p#gno name#gno value#gno - - (** - Adds a parameter setting. - *) - let add_s_bool (p : params) (name : string) (value : bool) = - add_bool p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_int (p : params) (name : string) (value : int) = - add_int p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_double (p : params) (name : string) (value : float) = - add_double p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Adds a parameter setting. - *) - let add_s_symbol (p : params) (name : string) (value : symbol) = - add_symbol p ((new symbol p#gc)#cnstr_obj (Z3native.mk_string_symbol p#gnc name)) value - - (** - Creates a new parameter set - *) - let mk_params ( ctx : context ) = - (new params ctx)#cnstr_obj (Z3native.mk_params (context_gno ctx)) - - (** - A string representation of the parameter set. - *) - let to_string (p : params) = Z3native.params_to_string p#gnc p#gno -end (** Goals @@ -4177,6 +4242,18 @@ end tactics and solvers. *) module Goal = struct + type goal = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : goal = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.goal_inc_ref ; + dec_ref = Z3native.goal_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) (** The precision of the goal. @@ -4185,7 +4262,7 @@ struct An over approximation is applied when the objective is to find a proof for a given goal. *) let get_precision ( x : goal ) = - goal_prec_of_int (Z3native.goal_precision x#gnc x#gno) + goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) (** Indicates whether the goal is precise. *) let is_precise ( x : goal ) = @@ -4206,62 +4283,62 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) let assert_ ( x : goal ) ( constraints : bool_expr array ) = - let f e = Z3native.goal_assert x#gnc x#gno e#gno in + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) e#gno in ignore (Array.map f constraints) ; () (** Indicates whether the goal contains `false'. *) let is_inconsistent ( x : goal ) = - Z3native.goal_inconsistent x#gnc x#gno + Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) (** The depth of the goal. This tracks how many transformations were applied to it. *) - let get_depth ( x : goal ) = Z3native.goal_depth x#gnc x#gno + let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) (** Erases all formulas from the given goal. *) - let reset ( x : goal ) = Z3native.goal_reset x#gnc x#gno + let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) (** The number of formulas in the goal. *) - let get_size ( x : goal ) = Z3native.goal_size x#gnc x#gno + let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (new bool_expr x#gc)#cnstr_obj (Z3native.goal_formula x#gnc x#gno i) in + let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) - let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs x#gnc x#gno + let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) let is_decided_sat ( x : goal ) = - Z3native.goal_is_decided_sat x#gnc x#gno + Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) let is_decided_unsat ( x : goal ) = - Z3native.goal_is_decided_unsat x#gnc x#gno + Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = - (new goal to_ctx)#cnstr_obj (Z3native.goal_translate x#gnc x#gno (context_gno to_ctx)) + cnstr to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - let simplify ( x : goal ) ( p : params option ) = - let tn = Z3native.mk_tactic x#gnc "simplify" in - Z3native.tactic_inc_ref x#gnc tn ; + let simplify ( x : goal ) ( p : Params.params option ) = + let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in + Z3native.tactic_inc_ref (z3obj_gnc x) tn ; let arn = match p with - | None -> Z3native.tactic_apply x#gnc tn x#gno - | Some(pn) -> Z3native.tactic_apply_ex x#gnc tn x#gno pn#gno + | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) + | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) in - Z3native.apply_result_inc_ref x#gnc arn ; - let sg = Z3native.apply_result_get_num_subgoals x#gnc arn in + Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; + let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in let res = if sg == 0 then raise (Z3native.Exception "No subgoals") else - Z3native.apply_result_get_subgoal x#gnc arn 0 in - Z3native.apply_result_dec_ref x#gnc arn ; - Z3native.tactic_dec_ref x#gnc tn ; - (new goal x#gc)#cnstr_obj res + Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in + Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; + Z3native.tactic_dec_ref (z3obj_gnc x) tn ; + cnstr (z3obj_gc x) res (** @@ -4274,10 +4351,10 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - (new goal ctx)#cnstr_obj (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) + cnstr ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) (** A string representation of the Goal. *) - let to_string ( x : goal ) = Z3native.goal_to_string x#gnc x#gno + let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) end @@ -4326,7 +4403,7 @@ struct module FuncEntry = struct type func_entry = z3_native_object - + (**/**) let cnstr ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; @@ -4528,7 +4605,7 @@ struct An array of expressions, where each is an element of the universe of *) let sort_universe ( x : model ) ( s : sort ) = - let n_univ = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in + let n_univ = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f @@ -4568,8 +4645,8 @@ struct A probe always produce a double value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let apply ( x : probe ) (g : goal) = - Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) g#gno + let apply ( x : probe ) (g : Goal.goal) = + Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (** The number of supported Probes. @@ -4673,6 +4750,19 @@ end *) module Tactic = struct + type tactic = z3_native_object + + (**/**) + let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let res : tactic = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.tactic_inc_ref ; + dec_ref = Z3native.tactic_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + (**/**) + (** Tactic application results ApplyResult objects represent the result of an application of a @@ -4699,12 +4789,12 @@ struct (** Retrieves the subgoals from the apply_result. *) let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in - let f i = (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** Retrieves the subgoals from the apply_result. *) let get_subgoal ( x : apply_result ) ( i : int ) = - (new goal (z3obj_gc x))#cnstr_obj (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) (** Convert a model for the subgoal into a model for the original goal g, that the ApplyResult was obtained from. @@ -4718,18 +4808,17 @@ struct end (** A string containing a description of parameters accepted by the tactic. *) - let get_help ( x : tactic ) = Z3native.tactic_get_help x#gnc x#gno - + let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = - (new param_descrs x#gc)#cnstr_obj (Z3native.tactic_get_param_descrs x#gnc x#gno) + Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) - let apply ( x : tactic ) ( g : goal ) ( p : params option ) = + let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with - | None -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply x#gnc x#gno g#gno)) - | Some (pn) -> (ApplyResult.cnstr x#gc (Z3native.tactic_apply_ex x#gnc x#gno g#gno pn#gno)) + | None -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) + | Some (pn) -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) (** The number of supported tactics. @@ -4755,7 +4844,7 @@ struct Creates a new Tactic. *) let mk_tactic ( ctx : context ) ( name : string ) = - (new tactic ctx)#cnstr_obj (Z3native.mk_tactic (context_gno ctx) name) + cnstr ctx (Z3native.mk_tactic (context_gno ctx) name) (** Create a tactic that applies to a Goal and @@ -4763,20 +4852,21 @@ struct *) let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = let f p c = (match p with - | None -> (Some c#gno) - | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) c#gno x))) in + | None -> (Some (z3obj_gno c)) + | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in match (Array.fold_left f None ts) with - | None -> (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno t2#gno) + | None -> + cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) | Some(x) -> - let o = (Z3native.tactic_and_then (context_gno ctx) t2#gno x) in - (new tactic ctx)#cnstr_obj (Z3native.tactic_and_then (context_gno ctx) t1#gno o) + let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in + cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) (** Create a tactic that first applies to a Goal and if it fails then returns the result of applied to the Goal. *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_or_else (context_gno ctx) t1#gno t2#gno) + cnstr ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that applies to a goal for milliseconds. @@ -4784,7 +4874,7 @@ struct If does not terminate within milliseconds, then it fails. *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_try_for (context_gno ctx) t#gno ms) + cnstr ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) (** Create a tactic that applies to a given goal if the probe @@ -4794,72 +4884,72 @@ struct *) (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) t#gno) + cnstr ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) t1#gno t2#gno) + cnstr ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that keeps applying until the goal is not modified anymore or the maximum number of iterations is reached. *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_repeat (context_gno ctx) t#gno max) + cnstr ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) (** Create a tactic that just returns the given goal. *) let skip ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_skip (context_gno ctx)) + cnstr ctx (Z3native.tactic_skip (context_gno ctx)) (** Create a tactic always fails. *) let fail ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail (context_gno ctx)) + cnstr ctx (Z3native.tactic_fail (context_gno ctx)) (** Create a tactic that fails if the probe evaluates to false. *) let fail_if ( ctx : context ) ( p : Probe.probe ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) + cnstr ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) or trivially unsatisfiable (i.e., contains `false'). *) let fail_if_not_decided ( ctx : context ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_fail_if_not_decided (context_gno ctx)) + cnstr ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) (** Create a tactic that applies using the given set of parameters . *) - let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_using_params (context_gno ctx) t#gno p#gno) + let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + cnstr ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . Alias for UsingParams*) (* CMW: with is a keyword *) - let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = + let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p (** Create a tactic that applies the given tactics in parallel. *) let par_or ( ctx : context ) ( t : tactic array ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (tacticaton t)) + cnstr ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) (** Create a tactic that applies to a given goal and then to every subgoal produced by . The subgoals are processed in parallel. *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - (new tactic ctx)#cnstr_obj (Z3native.tactic_par_and_then (context_gno ctx) t1#gno t2#gno) + cnstr ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Interrupt the execution of a Z3 procedure. @@ -5015,14 +5105,14 @@ struct (** Sets the solver parameters. *) - let set_parameters ( x : solver ) ( value : params )= - Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) value#gno + let set_parameters ( x : solver ) ( p : Params.params )= + Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). @@ -5062,7 +5152,7 @@ struct The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -5070,7 +5160,7 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = ((new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get a i)#gno) in Array.init n f @@ -5128,7 +5218,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = (new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -5176,8 +5266,8 @@ struct The solver supports the commands Push and Pop, but it will always solve each check from scratch. *) - let mk_solver_t ( ctx : context ) ( t : tactic ) = - (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) t#gno)) + let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = + (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** A string representation of the solver. @@ -5211,14 +5301,14 @@ struct (** Sets the fixedpoint solver parameters. *) - let set_params ( x : fixedpoint ) ( p : params )= - Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) p#gno + let set_params ( x : fixedpoint ) ( p : Params.params )= + Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - (new param_descrs (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. @@ -5355,7 +5445,7 @@ struct Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f @@ -5364,7 +5454,7 @@ struct Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = ((new ast_vector (z3obj_gc x))#cnstr_obj (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in Array.init n f From 8d1413bcc82a52034599f7136f6ddcd342b49b8a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sun, 13 Jan 2013 00:02:38 +0000 Subject: [PATCH 385/507] ML API: Symbols are now normal types with visible hierarchy. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 468 ++++++++++++++++++++++++----------------------- 1 file changed, 241 insertions(+), 227 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8c0f24c4b..378988d59 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -135,39 +135,145 @@ object (self) method gnc = (context_gno m_ctx) end -(** Symbol objects *) -class symbol ctx = -object (self) - inherit z3object ctx None as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method incref nc o = () - method decref nc o = () -end -(** Int symbol objects *) -class int_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_int i = (self#sno ctx (Z3native.mk_int_symbol (context_gno ctx) i)) ; self -end -(** String symbol objects *) -class string_symbol ctx = -object(self) - inherit symbol ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_string name = (self#sno ctx (Z3native.mk_string_symbol (context_gno ctx) name)) ; self -end +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } -let symbolaton (a : symbol array) = - let f (e : symbol) = e#gno in +let z3obj_gc o = o.m_ctx +let z3obj_gnc o = (context_gno o.m_ctx) + +let z3obj_gno o = o.m_n_obj +let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + +let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + +let z3obj_cnstr o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o + +let z3obj_nil_ref x y = () + +let array_to_native a = + let f e = (z3obj_gno e) in Array.map f a +(**/**) -let create_symbol ctx no = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> (((new int_symbol ctx)#cnstr_obj no) :> symbol) - | STRING_SYMBOL -> (((new string_symbol ctx)#cnstr_obj no) :> symbol) + +(** Symbols are used to name several term and type constructors *) +module Symbol = +struct + (** Int symbol objects *) + type int_symbol = z3_native_object + + (** String symbol objects *) + and string_symbol = z3_native_object + + and symbol = + | IntSymbol of int_symbol + | StringSymbol of string_symbol + + (**/**) + let cnstr_i ( ctx : context ) ( no : Z3native.ptr ) = + let res : int_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + let cnstr_s ( ctx : context ) ( no : Z3native.ptr ) = + let res : string_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_cnstr res) ; + res + + let gnc ( x : symbol ) = + match x with + | IntSymbol(n) -> (z3obj_gnc n) + | StringSymbol(n) -> (z3obj_gnc n) + + let gno ( x : symbol ) = + match x with + | IntSymbol(n) -> (z3obj_gno n) + | StringSymbol(n) -> (z3obj_gno n) + + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with + | INT_SYMBOL -> IntSymbol (cnstr_i ctx no) + | STRING_SYMBOL -> StringSymbol (cnstr_s ctx no) + + let aton a = + let f e = (gno e) in + Array.map f a + (**/**) + + (** The kind of the symbol (int or string) *) + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) + + (** Indicates whether the symbol is of Int kind *) + let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL + + (** Indicates whether the symbol is of string kind. *) + let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL + + (** The int value of the symbol. *) + let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) + + (** The string value of the symbol. *) + let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) + + (** A string representation of the symbol. *) + let to_string ( o : symbol ) = + match (kind o) with + | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) + | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) + + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) + let mk_int ( ctx : context ) ( i : int ) = + IntSymbol (cnstr_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + + (** Creates a new symbol using a string. *) + let mk_string ( ctx : context ) ( s : string ) = + StringSymbol (cnstr_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + + (** Create an array of symbols. *) + let mk_ints ( ctx : context ) ( names : int array ) = + let f elem = mk_int ( ctx : context ) elem in + (Array.map f names) + + (** Create an array of symbols. *) + let mk_strings ( ctx : context ) ( names : string array ) = + let f elem = mk_string ( ctx : context ) elem in + (Array.map f names) +end + +(**/**) (** AST objects *) class ast ctx = @@ -242,7 +348,7 @@ class uninterpreted_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) s#gno)) ; self + method cnstr_s (s : Symbol.symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; self end (** Finite domain sort objects *) @@ -250,7 +356,7 @@ class finite_domain_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_si (s : symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) s#gno sz)) ; self + method cnstr_si (s : Symbol.symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno s) sz)) ; self end (** Relation sort objects *) @@ -273,8 +379,8 @@ class tuple_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_siss (name : symbol) (num_fields: int) (field_names : symbol array) (field_sorts : sort array) = - let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) name#gno num_fields (symbolaton field_names) (astaton field_sorts)) in + method cnstr_siss (name : Symbol.symbol) (num_fields: int) (field_names : Symbol.symbol array) (field_sorts : sort array) = + let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) num_fields (Symbol.aton field_names) (astaton field_sorts)) in (self#sno ctx x) ; self end @@ -285,7 +391,7 @@ class func_decl ctx = object (self) inherit ast ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ndr (name : symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) name#gno (Array.length domain) (astaton domain) range#gno)) ; self + method cnstr_ndr (name : Symbol.symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (astaton domain) range#gno)) ; self method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (astaton domain) range#gno)) ; self method incref nc o = super#incref nc o @@ -303,8 +409,8 @@ object (self) val mutable _constdecls : func_decl array option = None val mutable _testerdecls : func_decl array option = None method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (enum_names : symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) name#gno (Array.length enum_names) (symbolaton enum_names)) in + method cnstr_ss (name : Symbol.symbol) (enum_names : Symbol.symbol array) = + let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; (self#sno ctx r) ; @@ -330,8 +436,8 @@ object (self) val mutable _headdecl : func_decl option = None val mutable _taildecl : func_decl option = None method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) name#gno elem_sort#gno) in + method cnstr_ss (name : Symbol.symbol) (elem_sort : sort) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) elem_sort#gno) in _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; @@ -381,7 +487,7 @@ object (self) let v = self in Gc.finalise f v - method cnstr_ssssi (name : symbol) (recognizer : symbol) (field_names : symbol array) (sorts : sort array) (sort_refs : int array) = + method cnstr_ssssi (name : Symbol.symbol) (recognizer : Symbol.symbol) (field_names : Symbol.symbol array) (sorts : sort array) (sort_refs : int array) = m_n <- (Array.length field_names) ; if m_n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -389,7 +495,7 @@ object (self) if m_n != (Array.length sort_refs) then raise (Z3native.Exception "Number of field names does not match number of sort refs") else - let o = (Z3native.mk_constructor (context_gno ctx) name#gno recognizer#gno m_n (symbolaton field_names) + let o = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) m_n (Symbol.aton field_names) (sortaton sorts) sort_refs) in self#sno ctx o ; @@ -449,7 +555,7 @@ class datatype_sort ctx = object (self) inherit sort ctx as super method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) name#gno (Array.length constructors) (constructoraton constructors)))) ; self + method cnstr_sc (name : Symbol.symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (constructoraton constructors)))) ; self end let create_sort ctx obj = @@ -571,43 +677,6 @@ let patternaton (a : pattern array) = let f (e : pattern) = e#gno in Array.map f a - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - -let z3obj_gc o = o.m_ctx -let z3obj_gnc o = (context_gno o.m_ctx) - -let z3obj_gno o = o.m_n_obj -let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - -let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - -let z3obj_cnstr o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - -let array_to_native a = - let f e = (z3obj_gno e) in - Array.map f a - (**/**) @@ -656,58 +725,6 @@ struct string_of_int rev ^ "." end -(** Symbols are used to name several term and type constructors *) -module Symbol = -struct - (** The kind of the symbol (int or string) *) - let kind (o : symbol) = (symbol_kind_of_int (Z3native.get_symbol_kind o#gnc o#gno)) - - (** Indicates whether the symbol is of Int kind *) - let is_int_symbol (o : symbol) = (kind o) == INT_SYMBOL - - (** Indicates whether the symbol is of string kind. *) - let is_string_symbol (o : symbol) = (kind o) == STRING_SYMBOL - - (** The int value of the symbol. *) - let get_int (o : int_symbol) = Z3native.get_symbol_int o#gnc o#gno - - (** The string value of the symbol. *) - let get_string (o : string_symbol) = Z3native.get_symbol_string o#gnc o#gno - - (** A string representation of the symbol. *) - let to_string (o : symbol) = - match (kind o) with - | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int o#gnc o#gno)) - | STRING_SYMBOL -> (Z3native.get_symbol_string o#gnc o#gno) - - (** - Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) - let mk_int ( ctx : context ) i = - (new int_symbol ctx)#cnstr_int i - - (** Creates a new symbol using a string. *) - let mk_string ( ctx : context ) s = - (new string_symbol ctx)#cnstr_string s - - (** - Create an array of symbols. - *) - let mk_ints ( ctx : context ) ( names : int array ) = - let f elem = mk_int ( ctx : context ) elem in - (Array.map f names) - - (** - Create an array of symbols. - *) - let mk_strings ( ctx : context ) ( names : string array ) = - let f elem = mk_string ( ctx : context ) elem in - (Array.map f names) -end - (** The Sort module implements type information for ASTs *) module Sort = @@ -738,7 +755,7 @@ struct (** The name of the sort *) - let get_name (x : sort) = (create_symbol x#gc (Z3native.get_sort_name x#gnc x#gno)) + let get_name (x : sort) = (Symbol.create x#gc (Z3native.get_sort_name x#gnc x#gno)) (** A string representation of the sort. @@ -754,14 +771,14 @@ struct (** Create a new uninterpreted sort. *) - let mk_uninterpreted ( ctx : context ) (s : symbol) = + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = (new uninterpreted_sort ctx)#cnstr_s s (** Create a new uninterpreted sort. *) - let mk_uninterpreted_s ( ctx : context ) (s : string) = - mk_uninterpreted ctx ((Symbol.mk_string ( ctx : context ) s) :> symbol) + let mk_uninterpreted_s ( ctx : context ) ( s : string ) = + mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) end (**/**) @@ -817,7 +834,7 @@ struct m_kind : parameter_kind ; m_i : int ; m_d : float ; - m_sym : symbol option ; + m_sym : Symbol.symbol option ; m_srt : sort option ; m_ast : ast option ; m_fd : func_decl option ; @@ -961,14 +978,14 @@ struct (** Creates a new function declaration. *) - let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort) = (new func_decl ctx)#cnstr_ndr name domain range (** Creates a new function declaration. *) let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = - mk_func_decl ctx ((Symbol.mk_string ctx name) :> symbol) domain range + mk_func_decl ctx (Symbol.mk_string ctx name) domain range (** Creates a fresh function declaration with a name prefixed with . @@ -981,7 +998,7 @@ struct (** Creates a new constant function declaration. *) - let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort) = + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort) = (new func_decl ctx)#cnstr_ndr name [||] range @@ -989,7 +1006,7 @@ struct Creates a new constant function declaration. *) let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr ((Symbol.mk_string ctx name) :> symbol) [||] range + (new func_decl ctx)#cnstr_ndr (Symbol.mk_string ctx name) [||] range (** Creates a fresh constant function declaration with a name prefixed with . @@ -1055,7 +1072,7 @@ struct (** The name of the function declaration *) - let get_name (x : func_decl) = (create_symbol x#gc (Z3native.get_decl_name x#gnc x#gno)) + let get_name (x : func_decl) = (Symbol.create x#gc (Z3native.get_decl_name x#gnc x#gno)) (** The number of parameters of the function declaration @@ -1071,7 +1088,7 @@ struct match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with | PARAMETER_INT -> Parameter.cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) | PARAMETER_DOUBLE -> Parameter.cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) - | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (create_symbol x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) + | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (Symbol.create x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) | PARAMETER_SORT -> Parameter.cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) | PARAMETER_AST -> Parameter.cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) | PARAMETER_FUNC_DECL -> Parameter.cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) @@ -1375,13 +1392,13 @@ struct Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) name#gno)) + let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) (** Retrieve all names of parameters. *) let get_names ( x : param_descrs ) = let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in - let f i = create_symbol (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The size of the ParamDescrs. *) @@ -1394,50 +1411,50 @@ struct (** Adds a parameter setting. *) - let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = - Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) name#gno value + let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = + Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_int ( x : params ) (name : symbol ) ( value : int ) = - Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) name#gno value + let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = + Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_double ( x : params ) ( name : symbol ) ( value : float ) = - Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) name#gno value + let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = - Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) name#gno value#gno + let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = + Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) (** Adds a parameter setting. *) - let add_s_bool ( x : params ) ( name : string) ( value : bool ) = - add_bool x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = + add_bool x (Symbol.mk_string (z3obj_gc x) name) value (** Adds a parameter setting. *) let add_s_int ( x : params) ( name : string ) ( value : int ) = - add_int x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + add_int x (Symbol.mk_string (z3obj_gc x) name) value (** Adds a parameter setting. *) let add_s_double ( x : params ) ( name : string ) ( value : float ) = - add_double x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + add_double x (Symbol.mk_string (z3obj_gc x) name) value (** Adds a parameter setting. *) - let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = - add_symbol x ((new symbol (z3obj_gc x))#cnstr_obj (Z3native.mk_string_symbol (z3obj_gnc x) name)) value + let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = + add_symbol x (Symbol.mk_string (z3obj_gc x) name) value (** Creates a new parameter set @@ -1662,15 +1679,15 @@ struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = - create_expr ctx (Z3native.mk_const (context_gno ctx) name#gno range#gno) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + create_expr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) range#gno) (** Creates a new Constant of sort and named . *) let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx ((Symbol.mk_string ctx name) :> symbol) range + mk_const ctx (Symbol.mk_string ctx name)range (** @@ -1690,14 +1707,14 @@ struct (** Create a Boolean constant. *) - let mk_bool_const ( ctx : context ) ( name : symbol ) = + let mk_bool_const ( ctx : context ) ( name : Symbol.symbol ) = ((mk_const ctx name (Sort.mk_bool ctx)) :> bool_expr) (** Create a Boolean constant. *) let mk_bool_const_s ( ctx : context ) ( name : string ) = - mk_bool_const ctx ((Symbol.mk_string ctx name) :> symbol) + mk_bool_const ctx (Symbol.mk_string ctx name) (** Create a new function application. @@ -1907,7 +1924,7 @@ struct *) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (create_symbol x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + let f i = (Symbol.create x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in Array.init n f (** @@ -1960,7 +1977,7 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -1968,23 +1985,23 @@ struct (match weight with | None -> 1 | Some(x) -> x) (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) @@ -1994,8 +2011,8 @@ struct else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expraton bound_constants) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) @@ -2004,7 +2021,7 @@ struct Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -2012,23 +2029,23 @@ struct (match weight with | None -> 1 | Some(x) -> x) (Array.length patterns) (patternaton patterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) (Array.length sorts) (astaton sorts) - (astaton names) + (Symbol.aton names) body#gno) (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) @@ -2038,8 +2055,8 @@ struct else (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> x#gno) - (match skolem_id with | None -> null | Some(x) -> x#gno) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expraton bound_constants) (Array.length patterns) (patternaton patterns) (Array.length nopatterns) (patternaton nopatterns) @@ -2048,7 +2065,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -2058,7 +2075,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -2128,14 +2145,14 @@ struct (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = ((Expr.mk_const ctx name ((mk_sort ctx domain range) :> sort)) :> array_expr) (** Create an array constant. *) let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = - mk_const ctx ((Symbol.mk_string ctx name) :> symbol) domain range + mk_const ctx (Symbol.mk_string ctx name) domain range (** Array read. @@ -2307,14 +2324,14 @@ struct (** Create a new finite domain sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) size = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) size = (new finite_domain_sort ctx)#cnstr_si name size (** Create a new finite domain sort. *) let mk_sort_s ( ctx : context ) ( name : string ) size = - (new finite_domain_sort ctx)#cnstr_si ((Symbol.mk_string ctx name) :> symbol) size + (new finite_domain_sort ctx)#cnstr_si (Symbol.mk_string ctx name) size (** @@ -2488,7 +2505,7 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array) = (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs @@ -2502,32 +2519,32 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - mk_constructor ctx ((Symbol.mk_string ctx name) :> symbol) recognizer field_names sorts sort_refs + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : constructor array) = (new datatype_sort ctx)#cnstr_sc name constructors (** Create a new datatype sort. *) let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = - mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) constructors + mk_sort ctx (Symbol.mk_string ctx name) constructors (** Create mutually recursive datatypes. @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : constructor array array ) = let n = (Array.length names) in let f e = ( (new constructor_list ctx)#cnstr_ca e ) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (symbolaton names) (constructor_listaton cla)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (constructor_listaton cla)) in let g e = ( (new datatype_sort ctx)#cnstr_obj e) in (Array.map g r) @@ -2535,7 +2552,7 @@ struct let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = mk_sorts ctx ( - let f e = ((Symbol.mk_string ctx e) :> symbol) in + let f e = (Symbol.mk_string ctx e) in Array.map f names ) c @@ -2581,10 +2598,8 @@ struct *) let mk_sort_s ( ctx : context ) name enum_names = (new enum_sort ctx)#cnstr_ss - ((Symbol.mk_string ( ctx : context ) name) :> symbol) - (let f e = (e :> symbol) in - (Array.map f (Symbol.mk_strings ( ctx : context ) enum_names)) - ) + (Symbol.mk_string ctx name) + (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) let get_const_decls (x : enum_sort) = x#const_decls @@ -2599,15 +2614,14 @@ struct (** Create a new list sort. *) - let mk_sort ( ctx : context ) (name : symbol) elem_sort = + let mk_sort ( ctx : context ) (name : Symbol.symbol) elem_sort = (new list_sort ctx)#cnstr_ss name elem_sort (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = - mk_sort ctx ((Symbol.mk_string ctx name) :> symbol) elem_sort - + mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) let get_nil_decl (x : list_sort) = x#nil_decl @@ -2805,26 +2819,26 @@ struct (** Creates an integer constant. *) - let mk_int_const ( ctx : context ) ( name : symbol ) = + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = ((Expr.mk_const ctx name (mk_int_sort ctx)) :> int_expr) (** Creates an integer constant. *) let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx ((Symbol.mk_string ctx name) :> symbol) + mk_int_const ctx (Symbol.mk_string ctx name) (** Creates a real constant. *) - let mk_real_const ( ctx : context ) ( name : symbol ) = + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = ((Expr.mk_const ctx name (mk_real_sort ctx)) :> real_expr) (** Creates a real constant. *) let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx ((Symbol.mk_string ctx name) :> symbol) + mk_real_const ctx (Symbol.mk_string ctx name) (** Create an expression representing t[0] + t[1] + .... @@ -3300,14 +3314,14 @@ struct (** Creates a bit-vector constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = ((Expr.mk_const ctx name (mk_sort ctx size)) :> bitvec_expr) (** Creates a bit-vector constant. *) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_const ctx ((Symbol.mk_string ctx name) :> symbol) size + mk_const ctx (Symbol.mk_string ctx name) size (** Bitwise negation. @@ -5242,17 +5256,17 @@ struct check-sat command, and check-sat commands that take more than a given number of milliseconds to be solved. *) - let mk_solver ( ctx : context ) ( logic : symbol option) = + let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with | None -> (cnstr ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) x#gno)) + | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) (** Creates a new (incremental) solver. *) let mk_solver_s ( ctx : context ) ( logic : string ) = - mk_solver ctx (Some ((Symbol.mk_string ctx logic) :> symbol)) + mk_solver ctx (Some (Symbol.mk_string ctx logic)) (** Creates a new (incremental) solver. @@ -5327,10 +5341,10 @@ struct (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol option ) = match name with | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno y#gno + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno y) (** Add table fact to the fixedpoint solver. @@ -5381,8 +5395,8 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno name#gno + let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno name) (** Retrieve satisfying instance or instances of solver, @@ -5432,8 +5446,8 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (symbolaton kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (Symbol.aton kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. @@ -5554,7 +5568,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5564,17 +5578,17 @@ struct else Z3native.parse_smtlib_string (context_gno ctx) str cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5584,10 +5598,10 @@ struct else Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) (** @@ -5649,7 +5663,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5659,17 +5673,17 @@ struct else Z3native.parse_smtlib2_string (context_gno ctx) str cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5679,10 +5693,10 @@ struct else Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (symbolaton sort_names) + (Symbol.aton sort_names) (astaton sorts) cd - (symbolaton decl_names) + (Symbol.aton decl_names) (func_declaton decls) end From 9ed926498f424871e8dd8ab06f0d3d4d2f166b8c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Jan 2013 11:37:39 +0000 Subject: [PATCH 386/507] ML API: updated example Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 38b5fe642..3b13a2462 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -22,8 +22,8 @@ exception TestFailedException of string *) let model_converter_test ( ctx : context ) = Printf.printf "ModelConverterTest\n"; - let xr = ((mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_real_sort ctx )) :> arith_expr) in - let yr = ((mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_real_sort ctx )) :> arith_expr) in + let xr = ((mk_const ctx (Symbol.mk_string ctx "x") (mk_real_sort ctx )) :> arith_expr) in + let yr = ((mk_const ctx (Symbol.mk_string ctx "y") (mk_real_sort ctx )) :> arith_expr) in let g4 = (mk_goal ctx true false false ) in (Goal.assert_ g4 [| (mk_gt ctx xr (mk_real_numeral_nd ctx 10 1)) |]) ; (Goal.assert_ g4 [| (mk_eq ctx yr (mk_add ctx [| xr; (mk_real_numeral_nd ctx 1 1) |] )) |] ) ; @@ -68,9 +68,9 @@ let model_converter_test ( ctx : context ) = let basic_tests ( ctx : context ) = Printf.printf "BasicTests\n" ; let qi = (mk_int ctx 1) in - let fname = ((mk_string ctx "f") :> symbol) in - let x = ((mk_string ctx "x") :> symbol) in - let y = ((mk_string ctx "y") :> symbol) in + let fname = (mk_string ctx "f") in + let x = (mk_string ctx "x") in + let y = (mk_string ctx "y") in let bs = (Sort.mk_bool ctx) in let domain = [| bs; bs |] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in @@ -142,8 +142,8 @@ let basic_tests ( ctx : context ) = ); ( let g3 = (mk_goal ctx true true false) in - let xc = (mk_const ctx ((Symbol.mk_string ctx "x") :> symbol) (mk_int_sort ctx)) in - let yc = (mk_const ctx ((Symbol.mk_string ctx "y") :> symbol) (mk_int_sort ctx)) in + let xc = (mk_const ctx (Symbol.mk_string ctx "x") (mk_int_sort ctx)) in + let yc = (mk_const ctx (Symbol.mk_string ctx "y") (mk_int_sort ctx)) in (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (mk_int_sort ctx))) |]) ; (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (mk_int_sort ctx))) |]) ; let constr = (mk_eq ctx xc yc) in @@ -211,8 +211,8 @@ let _ = let bs = (Sort.mk_bool ctx) in let ints = (mk_int_sort ctx) in let rs = (mk_real_sort ctx) in - Printf.printf "int symbol: %s\n" (Symbol.to_string (is :> symbol)); - Printf.printf "string symbol: %s\n" (Symbol.to_string (ss :> symbol)); + Printf.printf "int symbol: %s\n" (Symbol.to_string is); + Printf.printf "string symbol: %s\n" (Symbol.to_string ss); Printf.printf "bool sort: %s\n" (Sort.to_string bs); Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); From b895d4c8269343216022d0f9bc7103c4f9ce75b2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Jan 2013 17:51:16 +0000 Subject: [PATCH 387/507] ML API: added functions for global parameter management. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 378988d59..0dfb173c4 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -5700,6 +5700,53 @@ struct (func_declaton decls) end + +(* Global functions *) + +(** + * Set a global (or module) parameter, which is shared by all Z3 contexts. + * + * When a Z3 module is initialized it will use the value of these parameters + * when Z3_params objects are not provided. + * The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + * The character '.' is a delimiter (more later). + * The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + * Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + * This function can be used to set parameters for a specific Z3 module. + * This can be done by using .. + * For example: + * (set_global_param "pp.decimal" "true") + * will set the parameter "decimal" in the module "pp" to true. +*) +let set_global_param ( id : string ) ( value : string ) = + (Z3native.global_param_set id value) + +(** + * Get a global (or module) parameter. + * + * Returns None if the parameter does not exist. + * The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + * This function cannot be invoked simultaneously from different threads without synchronization. + * The result string stored in param_value is stored in a shared location. +*) +let get_global_param ( id : string ) = + let (r, v) = (Z3native.global_param_get id) in + if not r then + None + else + Some v + +(** + * Restore the value of all global (and module) parameters. + * + * This command will not affect already created objects (such as tactics and solvers) + * +*) +let global_param_reset_all = + Z3native.global_param_reset_all + + + (* (** From 3a0af6d15fc7591594cb0aeed5a3eb9e1f2b6a40 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Jan 2013 19:47:51 +0000 Subject: [PATCH 388/507] ML API: Added Solver.assert_and_track Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0dfb173c4..f5c3e3d82 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -5159,8 +5159,42 @@ struct *) let assert_ ( x : solver ) ( constraints : bool_expr array ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in - ignore (Array.map f constraints) ; - () + ignore (Array.map f constraints) + + (** + * Assert multiple constraints (cs) into the solver, and track them (in the + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using + * and the Boolean literals + * provided using with assumptions. + *) + let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = + if ((Array.length cs) != (Array.length ps)) then + raise (Z3native.Exception "Argument size mismatch") + else + let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) e#gno (Array.get ps i)#gno) in + ignore (Array.iteri f cs) + + (** + * Assert a constraint (c) into the solver, and track it (in the unsat) core + * using the Boolean constant p. + * + * This API is an alternative to with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using + * and the Boolean literals + * provided using with assumptions. + *) + let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) c#gno p#gno (** The number of assertions in the solver. From 364954e25a0c1495570bbf9c319d501d751d8555 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 31 Jan 2013 12:51:31 +0000 Subject: [PATCH 389/507] ML build Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index befd78be6..1d3412c30 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1345,31 +1345,30 @@ class MLComponent(Component): src_dir = self.to_src_dir sub_dir = os.path.join('api', 'ml') mk_dir(os.path.join(BUILD_DIR, sub_dir)) + api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) - out.write('libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s api/ml/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, get_component(API_COMPONENT).to_src_dir)) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') - out.write('api/ml/z3.cmxa: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, src_dir)) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) out.write('\n') - out.write('\tcd %s && %s ' % (sub_dir, OCAMLOPT)) + out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3" z3native.c z3enums.ml z3native.ml z3.ml -a -o ../../z3.cmxa -linkall && popd\n' % get_component(API_COMPONENT).to_src_dir) - out.write('z3.cma:') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cmxa -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) - out.write('api/ml/z3.cma: libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) + out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') - out.write('\tcd %s && %s ' % (sub_dir, OCAMLC)) + out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" z3enums.ml z3native.ml z3.ml -a -o z3.cma -linkall && cd ../..\n' % get_component(API_COMPONENT).to_src_dir) + out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') From 313ccfbe8de02d0ed61b9330012f6b43ffb2b327 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 4 Feb 2013 21:18:25 +0000 Subject: [PATCH 390/507] Checkpoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2989 ++++++++++++++++++++++++---------------------- 1 file changed, 1544 insertions(+), 1445 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index f5c3e3d82..0e47912ae 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,6 +7,51 @@ open Z3enums +(** Interaction logging for Z3 + + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log = +struct + (** Open an interaction log file. + @param filename the name of the file to open. + @return True if opening the log file succeeds, false otherwise. + *) + (* CMW: "open" seems to be a reserved keyword? *) + let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) + + (** Closes the interaction log. *) + let close = Z3native.close_log + + (** Appends a user-provided string to the interaction log. + @param s the string to append*) + let append s = Z3native.append_log s +end + +(** Version information *) +module Version = +struct + (** The major version. *) + let major = let (x, _, _, _) = Z3native.get_version in x + + (** The minor version. *) + let minor = let (_, x, _, _) = Z3native.get_version in x + + (** The build version. *) + let build = let (_, _, x, _) = Z3native.get_version in x + + (** The revision. *) + let revision = let (_, _, _, x) = Z3native.get_version in x + + (** A string representation of the version information. *) + let to_string = + let (mj, mn, bld, rev) = Z3native.get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + (**/**) (* Some helpers. *) @@ -40,7 +85,7 @@ let context_dispose ctx = (* re-queue for finalization? *) ) -let context_cnstr settings = +let context_create settings = let cfg = Z3native.mk_config in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; @@ -85,7 +130,7 @@ let context_gno ctx = ctx.m_n_ctx *) let mk_context ( cfg : ( string * string ) list ) = - context_cnstr cfg + context_create cfg (**/**) @@ -165,7 +210,7 @@ let z3obj_dispose o = ) ; o.m_n_obj <- null -let z3obj_cnstr o = +let z3obj_create o = let f = fun o -> (z3obj_dispose o) in Gc.finalise f o @@ -184,44 +229,51 @@ struct type int_symbol = z3_native_object (** String symbol objects *) - and string_symbol = z3_native_object + type string_symbol = z3_native_object - and symbol = - | IntSymbol of int_symbol - | StringSymbol of string_symbol + (** Symbol Objects *) + type symbol = + | S_Int of int_symbol + | S_Str of string_symbol (**/**) - let cnstr_i ( ctx : context ) ( no : Z3native.ptr ) = + let create_i ( ctx : context ) ( no : Z3native.ptr ) = let res : int_symbol = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res - let cnstr_s ( ctx : context ) ( no : Z3native.ptr ) = + + let create_s ( ctx : context ) ( no : Z3native.ptr ) = let res : string_symbol = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res + + let gc ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gc n) + | S_Str(n) -> (z3obj_gc n) let gnc ( x : symbol ) = match x with - | IntSymbol(n) -> (z3obj_gnc n) - | StringSymbol(n) -> (z3obj_gnc n) + | S_Int(n) -> (z3obj_gnc n) + | S_Str(n) -> (z3obj_gnc n) let gno ( x : symbol ) = match x with - | IntSymbol(n) -> (z3obj_gno n) - | StringSymbol(n) -> (z3obj_gno n) + | S_Int(n) -> (z3obj_gno n) + | S_Str(n) -> (z3obj_gno n) let create ( ctx : context ) ( no : Z3native.ptr ) = match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> IntSymbol (cnstr_i ctx no) - | STRING_SYMBOL -> StringSymbol (cnstr_s ctx no) + | INT_SYMBOL -> S_Int (create_i ctx no) + | STRING_SYMBOL -> S_Str (create_s ctx no) let aton a = let f e = (gno e) in @@ -256,11 +308,11 @@ struct The legal range of unsigned integers is 0 to 2^30-1. *) let mk_int ( ctx : context ) ( i : int ) = - IntSymbol (cnstr_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) (** Creates a new symbol using a string. *) let mk_string ( ctx : context ) ( s : string ) = - StringSymbol (cnstr_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) (** Create an array of symbols. *) let mk_ints ( ctx : context ) ( names : int array ) = @@ -273,853 +325,47 @@ struct (Array.map f names) end -(**/**) - -(** AST objects *) -class ast ctx = -object (self) - inherit z3object ctx None as super (* CMW: derive from icomparable? *) - method cnstr_obj obj = (self#sno ctx obj) ; self - - method incref nc o = Z3native.inc_ref nc o - method decref nc o = Z3native.dec_ref nc o -end - -let astaton (a : ast array) = - let f (e : ast) = e#gno in - Array.map f a - -(** Sort objects *) -class sort ctx = -object (self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -let sortaton (a : sort array) = - let f (e : sort) = e#gno in - Array.map f a - -(** Arithmetic sort objects, i.e., Int or Real. *) -class arith_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Array sorts objects *) -class array_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_dr (domain : sort) (range : sort) = (self#sno ctx (Z3native.mk_array_sort (context_gno ctx) domain#gno range#gno)) ; self -end - -(** Bit-vector sort objects *) -class bitvec_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Boolean sort objects *) -class bool_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Int sort objects *) -class int_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Real sort objects *) -class real_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Uninterpreted sort objects *) -class uninterpreted_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : Symbol.symbol) = (self #sno ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; self -end - -(** Finite domain sort objects *) -class finite_domain_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_si (s : Symbol.symbol) ( sz : int )= (self #sno ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno s) sz)) ; self -end - -(** Relation sort objects *) -class relation_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Set sort objects *) -class set_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_s (s : sort) = (self#sno ctx s#gno) ; self -end - -(** Tuple sort objects *) -class tuple_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_siss (name : Symbol.symbol) (num_fields: int) (field_names : Symbol.symbol array) (field_sorts : sort array) = - let (x,_,_) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) num_fields (Symbol.aton field_names) (astaton field_sorts)) in - (self#sno ctx x) ; - self -end - - -(** Function declaration objects *) -class func_decl ctx = -object (self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ndr (name : Symbol.symbol) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (astaton domain) range#gno)) ; self - method cnstr_pdr (prefix : string) (domain : sort array) (range : sort) = (self#sno ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (astaton domain) range#gno)) ; self - - method incref nc o = super#incref nc o - method decref nc o = super#decref nc o -end - -let func_declaton (a : func_decl array) = - let f (e : func_decl) = e#gno in - Array.map f a - -(** Enum sort objects *) -class enum_sort ctx = -object (self) - inherit sort ctx as super - val mutable _constdecls : func_decl array option = None - val mutable _testerdecls : func_decl array option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : Symbol.symbol) (enum_names : Symbol.symbol array) = - let (r, a, b) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in - _constdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f a)) ; - _testerdecls <- Some (let f e = (new func_decl ctx)#cnstr_obj e in (Array.map f b)) ; - (self#sno ctx r) ; - self - - method const_decls = match _constdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing const decls") - - method tester_decls = match _testerdecls with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tester decls") -end - -(** List sort objects *) -class list_sort ctx = -object (self) - inherit sort ctx as super - val mutable _nildecl : func_decl option = None - val mutable _is_nildecl : func_decl option = None - val mutable _consdecl : func_decl option = None - val mutable _is_consdecl : func_decl option = None - val mutable _headdecl : func_decl option = None - val mutable _taildecl : func_decl option = None - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ss (name : Symbol.symbol) (elem_sort : sort) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) elem_sort#gno) in - _nildecl <- Some ((new func_decl ctx)#cnstr_obj a) ; - _is_nildecl <- Some ((new func_decl ctx)#cnstr_obj b) ; - _consdecl <- Some ((new func_decl ctx)#cnstr_obj c) ; - _is_consdecl <- Some ((new func_decl ctx)#cnstr_obj d) ; - _headdecl <- Some ((new func_decl ctx)#cnstr_obj e) ; - _taildecl <- Some ((new func_decl ctx)#cnstr_obj f) ; - (self#sno ctx r) ; - self - - method nil_decl = match _nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing nil decl") - - method is_nil_decl = match _is_nildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_nil decl") - - method cons_decl = match _consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing cons decl") - - method is_cons_decl = match _is_consdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing is_cons decl") - - method head_decl = match _headdecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing head decl") - - method tail_decl = match _taildecl with - | Some(x) -> x - | None -> raise (Z3native.Exception "Missing tail decl") -end - -(** Constructor objects *) -class constructor ctx = -object (self) - inherit z3object ctx None as super - val mutable m_n : int = 0 - val mutable m_tester_decl : func_decl option = None - val mutable m_constructor_decl : func_decl option = None - val mutable m_accessor_decls : func_decl array option = None - method incref nc o = () - method decref nc o = () - initializer - let f = fun o -> Z3native.del_constructor o#gnc o#gno in - let v = self in - Gc.finalise f v - - method cnstr_ssssi (name : Symbol.symbol) (recognizer : Symbol.symbol) (field_names : Symbol.symbol array) (sorts : sort array) (sort_refs : int array) = - m_n <- (Array.length field_names) ; - if m_n != (Array.length sorts) then - raise (Z3native.Exception "Number of field names does not match number of sorts") - else - if m_n != (Array.length sort_refs) then - raise (Z3native.Exception "Number of field names does not match number of sort refs") - else - let o = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) m_n (Symbol.aton field_names) - (sortaton sorts) - sort_refs) in - self#sno ctx o ; - self - - method private init = - match m_tester_decl with - | None -> - let (a, b, c) = (Z3native.query_constructor self#gnc self#gno m_n) in - m_constructor_decl <- Some ((new func_decl ctx)#cnstr_obj a) ; - m_tester_decl <- Some ((new func_decl ctx)#cnstr_obj b) ; - m_accessor_decls <- Some (let f e = ((new func_decl ctx)#cnstr_obj e) in Array.map f c) ; - () - | _ -> () - - method get_n = m_n - - method tester_decl = match m_tester_decl with - | Some(x) -> x - | None -> self#init ; self#tester_decl - - method constructor_decl = match m_constructor_decl with - | Some(x) -> x - | None -> self#init ; self#constructor_decl - - method accessor_decls = match m_accessor_decls with - | Some(x) -> x - | None -> self#init ; self#accessor_decls -end - -let constructoraton (a : constructor array) = - let f (e : constructor) = e#gno in - Array.map f a - -(** Constructor list objects *) -class constructor_list ctx = -object (self) - inherit z3object ctx None - method incref nc o = () - method decref nc o = () - initializer - let f = fun o -> Z3native.del_constructor_list o#gnc o#gno in - let v = self in - Gc.finalise f v - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_ca ( c : constructor array ) = - self#sno ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (constructoraton c)) ; - self -end - -let constructor_listaton (a : constructor_list array) = - let f (e : constructor_list) = e#gno in - Array.map f a - -(** Datatype sort objects *) -class datatype_sort ctx = -object (self) - inherit sort ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self - method cnstr_sc (name : Symbol.symbol) (constructors : constructor array) = (self#sno ctx (fst (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (constructoraton constructors)))) ; self -end - -let create_sort ctx obj = - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) obj)) with - | ARRAY_SORT -> (((new array_sort ctx)#cnstr_obj obj) :> sort) - | BOOL_SORT -> (((new bool_sort ctx)#cnstr_obj obj) :> sort) - | BV_SORT -> (((new bitvec_sort ctx)#cnstr_obj obj) :> sort) - | DATATYPE_SORT -> (((new datatype_sort ctx)#cnstr_obj obj) :> sort) - | INT_SORT -> (((new int_sort ctx)#cnstr_obj obj) :> sort) - | REAL_SORT -> (((new real_sort ctx)#cnstr_obj obj) :> sort) - | UNINTERPRETED_SORT -> (((new uninterpreted_sort ctx)#cnstr_obj obj) :> sort) - | FINITE_DOMAIN_SORT -> (((new finite_domain_sort ctx)#cnstr_obj obj) :> sort) - | RELATION_SORT -> (((new relation_sort ctx)#cnstr_obj obj) :> sort) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - -(** Expression objects *) -class expr ctx = -object(self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -let expraton (a : expr array) = - let f (e : expr) = e#gno in - Array.map f a - -(** Boolean expression objects *) -class bool_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Arithmetic expression objects (int/real) *) -class arith_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Int expression objects *) -class int_expr ctx = -object (self) - inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Real expression objects *) -class real_expr ctx = -object (self) - inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Bit-vector expression objects *) -class bitvec_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Array expression objects *) -class array_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Datatype expression objects *) -class datatype_expr ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Integer numeral expression objects *) -class int_num ctx = -object (self) - inherit int_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Rational numeral expression objects *) -class rat_num ctx = -object (self) - inherit real_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Bit-vector numeral expression objects *) -class bitvec_num ctx = -object (self) - inherit bitvec_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Algebraic numeral expression objects *) -class algebraic_num ctx = -object (self) - inherit arith_expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Quantifier objects *) -class quantifier ctx = -object (self) - inherit expr ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -(** Quantifier pattern objects *) -class pattern ctx = -object (self) - inherit ast ctx as super - method cnstr_obj obj = (self#sno ctx obj) ; self -end - -let patternaton (a : pattern array) = - let f (e : pattern) = e#gno in - Array.map f a - -(**/**) - - -(** Interaction logging for Z3 - - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) -module Log = -struct - (** Open an interaction log file. - @param filename the name of the file to open. - @return True if opening the log file succeeds, false otherwise. - *) - (* CMW: "open" seems to be a reserved keyword? *) - let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - - (** Closes the interaction log. *) - let close = Z3native.close_log - - (** Appends a user-provided string to the interaction log. - @param s the string to append*) - let append s = Z3native.append_log s -end - -(** Version information *) -module Version = -struct - (** The major version. *) - let major = let (x, _, _, _) = Z3native.get_version in x - - (** The minor version. *) - let minor = let (_, x, _, _) = Z3native.get_version in x - - (** The build version. *) - let build = let (_, _, x, _) = Z3native.get_version in x - - (** The revision. *) - let revision = let (_, _, _, x) = Z3native.get_version in x - - (** A string representation of the version information. *) - let to_string = - let (mj, mn, bld, rev) = Z3native.get_version in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev ^ "." -end - - -(** The Sort module implements type information for ASTs *) -module Sort = -struct - (** - Comparison operator. - @param a A sort - @param b A sort - @return True if and are from the same context - and represent the same sort; false otherwise. - *) - let ( = ) (a : sort) (b : sort) = (a == b) || - if a#gnc != b#gnc then - false - else - (Z3native.is_eq_sort a#gnc a#gno b#gno) - - (** - Returns a unique identifier for the sort. - *) - let get_id (x : sort) = Z3native.get_sort_id x#gnc x#gno - - (** - The kind of the sort. - *) - let get_sort_kind (x : sort) = (sort_kind_of_int (Z3native.get_sort_kind x#gnc x#gno)) - - (** - The name of the sort - *) - let get_name (x : sort) = (Symbol.create x#gc (Z3native.get_sort_name x#gnc x#gno)) - - (** - A string representation of the sort. - *) - let to_string (x : sort) = Z3native.sort_to_string x#gnc x#gno - - (** - Create a new Boolean sort. - *) - let mk_bool ( ctx : context ) = - (new bool_sort ctx)#cnstr_obj (Z3native.mk_bool_sort (context_gno ctx)) - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = - (new uninterpreted_sort ctx)#cnstr_s s - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted_s ( ctx : context ) ( s : string ) = - mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) -end - -(**/**) -let create_expr ctx obj = - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then - (((new quantifier ctx)#cnstr_obj obj) :> expr) - else - let s = Z3native.get_sort (context_gno ctx) obj in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (((new algebraic_num ctx)#cnstr_obj obj) :> expr) - else - if (Z3native.is_numeral_ast (context_gno ctx) obj) && - (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - match sk with - | INT_SORT -> (((new int_num ctx)#cnstr_obj obj) :> expr) - | REAL_SORT -> (((new rat_num ctx)#cnstr_obj obj) :> expr) - | BV_SORT -> (((new bitvec_num ctx)#cnstr_obj obj) :> expr) - | _ -> raise (Z3native.Exception "Unsupported numeral object") - else - match sk with - | BOOL_SORT -> (((new bool_expr ctx)#cnstr_obj obj) :> expr) - | INT_SORT -> (((new int_expr ctx)#cnstr_obj obj) :> expr) - | REAL_SORT -> (((new real_expr ctx)#cnstr_obj obj) :> expr) - | BV_SORT -> (((new bitvec_expr ctx)#cnstr_obj obj) :> expr) - | ARRAY_SORT -> (((new array_expr ctx)#cnstr_obj obj) :> expr) - | DATATYPE_SORT -> (((new datatype_expr ctx)#cnstr_obj obj) :> expr) - | _ -> (new expr ctx)#cnstr_obj obj - -let create_expr_fa (ctx : context) (f : func_decl) (args : expr array) = - let o = Z3native.mk_app (context_gno ctx) f#gno (Array.length args) (astaton args) in - create_expr ctx o - -let create_ast ctx no = - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST -> (((new func_decl ctx)#cnstr_obj no) :> ast) - | QUANTIFIER_AST -> (((new quantifier ctx)#cnstr_obj no) :> ast) - | SORT_AST -> ((create_sort ctx no) :> ast) - | APP_AST - | NUMERAL_AST - | VAR_AST -> ((create_expr ctx no) :> ast) - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") -(**/**) - -(** Function declarations *) -module FuncDecl = -struct - - (** Parameters of Func_Decls *) - module Parameter = - struct - type parameter = { - m_kind : parameter_kind ; - m_i : int ; - m_d : float ; - m_sym : Symbol.symbol option ; - m_srt : sort option ; - m_ast : ast option ; - m_fd : func_decl option ; - m_r : string ; - } - - (**/**) - let cnstr_int i = { - m_kind = PARAMETER_INT ; - m_i = i ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_double d = { - m_kind = PARAMETER_DOUBLE ; - m_i = 0 ; - m_d = d ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_symbol sym = { - m_kind = PARAMETER_SYMBOL ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = sym ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_sort srt = { - m_kind = PARAMETER_SORT ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = srt ; - m_ast = None ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_ast ast = { - m_kind = PARAMETER_AST ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = ast ; - m_fd = None ; - m_r = "" ; - } - - let cnstr_func_decl fd ={ - m_kind = PARAMETER_FUNC_DECL ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = fd ; - m_r = "" ; - } - - let cnstr_rational r = { - m_kind = PARAMETER_RATIONAL ; - m_i = 0 ; - m_d = 0.0 ; - m_sym = None ; - m_srt = None ; - m_ast = None ; - m_fd = None ; - m_r = r ; - } - (**/**) - - (** - The kind of the parameter. - *) - let get_kind ( x : parameter ) = x.m_kind - - (**The int value of the parameter.*) - let get_int ( x : parameter ) = - if ((get_kind x) != PARAMETER_INT) then - raise (Z3native.Exception "parameter is not an int") - else - x.m_i - - (**The double value of the parameter.*) - let get_double ( x : parameter ) = - if ((get_kind x) != PARAMETER_DOUBLE) then - raise (Z3native.Exception "parameter is not a double") - else - x.m_d - - (**The Symbol value of the parameter.*) - let get_symbol ( x : parameter ) = - if ((get_kind x) != PARAMETER_SYMBOL) then - raise (Z3native.Exception "parameter is not a symbol") - else - x.m_sym - - (**The Sort value of the parameter.*) - let get_sort ( x : parameter ) = - if ((get_kind x) != PARAMETER_SORT) then - raise (Z3native.Exception "parameter is not a sort") - else - x.m_srt - - (**The AST value of the parameter.*) - let get_ast ( x : parameter ) = - if ((get_kind x) != PARAMETER_AST) then - raise (Z3native.Exception "parameter is not an ast") - else - x.m_ast - - (**The FunctionDeclaration value of the parameter.*) - let get_ast ( x : parameter ) = - if ((get_kind x) != PARAMETER_FUNC_DECL) then - raise (Z3native.Exception "parameter is not an function declaration") - else - x.m_fd - - (**The rational string value of the parameter.*) - let get_rational ( x : parameter ) = - if ((get_kind x) != PARAMETER_RATIONAL) then - raise (Z3native.Exception "parameter is not a ratinoal string") - else - x.m_r - end - - (** - Creates a new function declaration. - *) - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name domain range - - (** - Creates a new function declaration. - *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort) = - mk_func_decl ctx (Symbol.mk_string ctx name) domain range - - (** - Creates a fresh function declaration with a name prefixed with . - - - *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix domain range - - (** - Creates a new constant function declaration. - *) - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr name [||] range - - - (** - Creates a new constant function declaration. - *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort) = - (new func_decl ctx)#cnstr_ndr (Symbol.mk_string ctx name) [||] range - - (** - Creates a fresh constant function declaration with a name prefixed with . - - - *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort) = - (new func_decl ctx)#cnstr_pdr prefix [||] range - - - (** - Comparison operator. - @param a A func_decl - @param b A func_decl - @return True if and are from the same context - and represent the same func_decl; false otherwise. - *) - let ( = ) (a : func_decl) (b : func_decl) = (a == b) || - if a#gnc == a#gnc then - false - else - (Z3native.is_eq_func_decl a#gnc a#gno b#gno) - (** - A string representations of the function declaration. - *) - let to_string (x : func_decl) = Z3native.func_decl_to_string x#gnc x#gno - - (** - Returns a unique identifier for the function declaration. - *) - let get_id (x : func_decl) = Z3native.get_func_decl_id x#gnc x#gno - - (** - The arity of the function declaration - *) - let get_arity (x : func_decl) = Z3native.get_arity x#gnc x#gno - - (** - The size of the domain of the function declaration - - *) - let get_domain_size (x : func_decl) = Z3native.get_domain_size x#gnc x#gno - - (** - The domain of the function declaration - *) - let get_domain (x : func_decl) = - let n = (get_domain_size x) in - let f i = create_sort x#gc (Z3native.get_domain x#gnc x#gno i) in - Array.init n f - - (** - The range of the function declaration - *) - let get_range (x : func_decl) = - create_sort x#gc (Z3native.get_range x#gnc x#gno) - - (** - The kind of the function declaration. - *) - let get_decl_kind (x : func_decl) = (decl_kind_of_int (Z3native.get_decl_kind x#gnc x#gno)) - - (** - The name of the function declaration - *) - let get_name (x : func_decl) = (Symbol.create x#gc (Z3native.get_decl_name x#gnc x#gno)) - - (** - The number of parameters of the function declaration - *) - let get_num_parameters (x : func_decl) = (Z3native.get_decl_num_parameters x#gnc x#gno) - - (** - The parameters of the function declaration - *) - let get_parameters (x : func_decl) = - let n = (get_num_parameters x) in - let f i = ( - match (parameter_kind_of_int (Z3native.get_decl_parameter_kind x#gnc x#gno i)) with - | PARAMETER_INT -> Parameter.cnstr_int (Z3native.get_decl_int_parameter x#gnc x#gno i) - | PARAMETER_DOUBLE -> Parameter.cnstr_double (Z3native.get_decl_double_parameter x#gnc x#gno i) - | PARAMETER_SYMBOL-> Parameter.cnstr_symbol (Some (Symbol.create x#gc (Z3native.get_decl_symbol_parameter x#gnc x#gno i))) - | PARAMETER_SORT -> Parameter.cnstr_sort (Some (create_sort x#gc (Z3native.get_decl_sort_parameter x#gnc x#gno i))) - | PARAMETER_AST -> Parameter.cnstr_ast (Some (create_ast x#gc (Z3native.get_decl_ast_parameter x#gnc x#gno i))) - | PARAMETER_FUNC_DECL -> Parameter.cnstr_func_decl (Some ((new func_decl x#gc)#cnstr_obj (Z3native.get_decl_func_decl_parameter x#gnc x#gno i))) - | PARAMETER_RATIONAL -> Parameter.cnstr_rational (Z3native.get_decl_rational_parameter x#gnc x#gno i) - ) in - mk_list f n - - (** - Create expression that applies function to arguments. - @param args The arguments - *) - let apply (x : func_decl) (args : expr array) = create_expr_fa x#gc x args - -end (** The abstract syntax tree (AST) module *) -module AST = -struct +module rec AST : +sig + type ast = z3_native_object + + val create : context -> Z3native.ptr -> ast + val aton : ast array -> Z3native.ptr array + + val is_expr : ast -> bool + val is_var : ast -> bool +end = struct + type ast = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let aton (a : ast array) = + let f (e : ast) = (z3obj_gno e) in + Array.map f a + + (** Vectors of ASTs *) module ASTVector = struct type ast_vector = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_vector_inc_ref ; dec_ref = Z3native.ast_vector_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -1133,11 +379,11 @@ struct @return An AST *) let get ( x : ast_vector ) ( i : int ) = - create_ast (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) + create (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) (** Sets the i-th object in the vector. *) let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i value#gno + Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) (** Resize the vector to . @param newSize The new size of the vector. *) @@ -1150,7 +396,7 @@ struct @param a An AST *) let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) a#gno + Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) (** Translates all ASTs in the vector to . @@ -1158,7 +404,7 @@ struct @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = - cnstr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = @@ -1171,13 +417,13 @@ struct type ast_map = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_map_inc_ref ; dec_ref = Z3native.ast_map_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -1185,7 +431,7 @@ struct @param k An AST @return True if is a key in the map, false otherwise. *) let contains ( x : ast_map ) ( key : ast ) = - (Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) key#gno) + Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (** Finds the value associated with the key . @@ -1193,7 +439,7 @@ struct @param k An AST *) let find ( x : ast_map ) ( key : ast ) = - create_ast (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) key#gno) + create (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) (** Stores or replaces a new key/value pair in the map. @@ -1201,14 +447,14 @@ struct @param v The value AST *) let insert ( x : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) key#gno value#gno + Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) (** Erases the key from the map. @param k An AST *) let erase ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) key#gno + Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (** Removes all keys from the map. *) let reset ( x : ast_map ) = @@ -1220,7 +466,7 @@ struct (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVector.cnstr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = @@ -1231,23 +477,23 @@ struct The AST's hash code. @return A hash code *) - let get_hash_code ( x : ast) = Z3native.get_ast_hash x#gnc x#gno + let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) (** A unique identifier for the AST (unique among all ASTs). *) - let get_id ( x : ast) = Z3native.get_ast_id x#gnc x#gno + let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) (** The kind of the AST. *) - let get_ast_kind ( x : ast) = (ast_kind_of_int (Z3native.get_ast_kind x#gnc x#gno)) + let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) (** Indicates whether the AST is an Expr *) - let is_expr ( x : ast) = - match get_ast_kind ( x : ast) with + let is_expr ( x : ast ) = + match get_ast_kind ( x : ast ) with | APP_AST | NUMERAL_AST | QUANTIFIER_AST @@ -1257,33 +503,33 @@ struct (** Indicates whether the AST is a bound variable *) - let is_var ( x : ast) = (get_ast_kind x) == VAR_AST + let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST (** Indicates whether the AST is a Quantifier *) - let is_quantifier ( x : ast) = (get_ast_kind x) == QUANTIFIER_AST + let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST (** Indicates whether the AST is a Sort *) - let is_sort ( x : ast) = (get_ast_kind x) == SORT_AST + let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST (** Indicates whether the AST is a FunctionDeclaration *) - let is_func_decl ( x : ast) = (get_ast_kind x) == FUNC_DECL_AST + let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST (** A string representation of the AST. *) - let to_string ( x : ast) = Z3native.ast_to_string x#gnc x#gno + let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) (** A string representation of the AST in s-expression notation. *) - let to_sexpr ( x : ast) = Z3native.ast_to_string x#gnc x#gno + let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) (** Comparison operator. @@ -1292,11 +538,11 @@ struct @return True if and are from the same context and represent the same sort; false otherwise. *) - let ( = ) (a : expr) (b : expr) = (a == b) || - if a#gnc == b#gnc then + let ( = ) ( a : ast ) ( b : ast ) = (a == b) || + if (z3obj_gnc a) != (z3obj_gnc b) then false else - (Z3native.is_eq_ast a#gnc a#gno b#gno) + Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) (** Object Comparison. @@ -1316,11 +562,11 @@ struct @param ctx A context @return A copy of the AST which is associated with *) - let translate ( x : ast) to_ctx = - if x#gc == to_ctx then + let translate ( x : ast ) ( to_ctx : context ) = + if (z3obj_gnc x) == (context_gno to_ctx) then x else - (create_ast to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx))) + create to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Wraps an AST. @@ -1334,7 +580,7 @@ struct @param nativeObject The native pointer to wrap. *) let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - create_ast ctx ptr + create ctx ptr (** Unwraps an AST. @@ -1347,43 +593,413 @@ struct @param a The AST to unwrap. *) - let unwrap_ast ( a : ast ) = a#gno + let unwrap_ast ( x : ast ) = (z3obj_gno x) + + (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST -> (match (FuncDecl.create ctx no) with FuncDecl.FuncDecl(x) -> x) + | SORT_AST -> (match (Sort.create ctx no) with Sort.Sort(x) -> x) + | QUANTIFIER_AST -> (match (Quantifiers.create ctx no) with Quantifiers.Quantifier(Expr.Expr(x)) -> x) + | APP_AST + | NUMERAL_AST + | VAR_AST -> (match (Expr.create ctx no) with Expr.Expr(x) -> x) + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") +(**/**) end +(** The Sort module implements type information for ASTs *) +and Sort : +sig + type sort = Sort of AST.ast + type bitvec_sort = BitvecSort of sort + type uninterpreted_sort = UninterpretedSort of sort + + val create : context -> Z3native.ptr -> sort + val gno : sort -> Z3native.ptr + val gnc : sort -> Z3native.ptr + val aton : sort array -> Z3native.ptr array +end = struct + type sort = Sort of AST.ast + type bitvec_sort = BitvecSort of sort + type uninterpreted_sort = UninterpretedSort of sort + + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) + let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) + let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) + + let aton : sort array -> Z3native.ptr array = fun a -> + let f e = (gno e) in + Array.map f a + + let create : context -> Z3native.ptr -> sort = fun ctx no -> + let q : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno q ctx no) ; + (z3obj_create q) ; + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + + (** + Comparison operator. + @param a A sort + @param b A sort + @return True if and are from the same context + and represent the same sort; false otherwise. + *) + let ( = ) : sort -> sort -> bool = fun a b -> + (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) + + (** + Returns a unique identifier for the sort. + *) + let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) + + (** + The kind of the sort. + *) + let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) + + (** + The name of the sort + *) + let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) + + (** + A string representation of the sort. + *) + let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; + (z3obj_create res) ; + UninterpretedSort(Sort(res)) + + (** + Create a new uninterpreted sort. + *) + let mk_uninterpreted_s ( ctx : context ) ( s : string ) = + mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) +end + + +(** Function declarations *) +and FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + + val create : context -> Z3native.ptr -> func_decl + val gno : func_decl -> Z3native.ptr + val gnc : func_decl -> Z3native.ptr + + val get_domain_size : func_decl -> int + val get_decl_kind : func_decl -> Z3enums.decl_kind +end = struct + open Sort + + type func_decl = FuncDecl of AST.ast + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + FuncDecl(res) + + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) + let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) + let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) + + let aton (a : func_decl array) = + let f (e : func_decl) = (gno e) in + Array.map f a + + (** Parameters of Func_Decls *) + module Parameter = + struct + type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + (** The kind of the parameter. *) + let get_kind ( x : parameter ) = + (match x with + | P_Int(_) -> PARAMETER_INT + | P_Dbl(_) -> PARAMETER_DOUBLE + | P_Sym(_) -> PARAMETER_SYMBOL + | P_Srt(_) -> PARAMETER_SORT + | P_Ast(_) -> PARAMETER_AST + | P_Fdl(_) -> PARAMETER_FUNC_DECL + | P_Rat(_) -> PARAMETER_RATIONAL) + + (**The int value of the parameter.*) + let get_int ( x : parameter ) = + match x with + | P_Int(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an int") + + (**The double value of the parameter.*) + let get_float ( x : parameter ) = + match x with + | P_Dbl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a double") + + (**The Symbol value of the parameter.*) + let get_symbol ( x : parameter ) = + match x with + | P_Sym(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a symbol") + + (**The Sort value of the parameter.*) + let get_sort ( x : parameter ) = + match x with + | P_Srt(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a sort") + + (**The AST value of the parameter.*) + let get_ast ( x : parameter ) = + match x with + | P_Ast(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an ast") + + (**The FunctionDeclaration value of the parameter.*) + let get_func_decl ( x : parameter ) = + match x with + | P_Fdl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a func_decl") + + (**The rational string value of the parameter.*) + let get_func_decl ( x : parameter ) = + match x with + | P_Rat(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a rational string") + end + + open Parameter + + (** + Creates a new function declaration. + *) + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + create_ndr ctx name domain range + + (** + Creates a new function declaration. + *) + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = + mk_func_decl ctx (Symbol.mk_string ctx name) domain range + + (** + Creates a fresh function declaration with a name prefixed with . + + + *) + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + create_pdr ctx prefix domain range + + (** + Creates a new constant function declaration. + *) + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + create_ndr ctx name [||] range + + (** + Creates a new constant function declaration. + *) + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = + create_ndr ctx (Symbol.mk_string ctx name) [||] range + + (** + Creates a fresh constant function declaration with a name prefixed with . + + + *) + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = + create_pdr ctx prefix [||] range + + + (** + Comparison operator. + @param a A func_decl + @param b A func_decl + @return True if and are from the same context + and represent the same func_decl; false otherwise. + *) + let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) + + (** + A string representations of the function declaration. + *) + let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) + + (** + Returns a unique identifier for the function declaration. + *) + let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) + + (** + The arity of the function declaration + *) + let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) + + (** + The size of the domain of the function declaration + + *) + let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) + + (** + The domain of the function declaration + *) + let get_domain ( x : func_decl ) = + let n = (get_domain_size x) in + let f i = Sort.create (gc x) (Z3native.get_domain (gnc x) (gno x) i) in + Array.init n f + + (** + The range of the function declaration + *) + let get_range ( x : func_decl ) = + Sort.create (gc x) (Z3native.get_range (gnc x) (gno x)) + + (** + The kind of the function declaration. + *) + let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) + + (** + The name of the function declaration + *) + let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) + + (** + The number of parameters of the function declaration + *) + let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) + + (** + The parameters of the function declaration + *) + let get_parameters ( x : func_decl ) = + let n = (get_num_parameters x) in + let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with + | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + ) in + mk_list f n + + (** + Create expression that applies function to arguments. + @param args The arguments + *) + let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.create_fa (gc x) x args +end + (** Parameter sets (of Solvers, Tactics, ...) A Params objects represents a configuration in the form of symbol/value pairs. *) -module Params = -struct +and Params : +sig + type params = z3_native_object + + val create : context -> Z3native.ptr -> params + + module ParamDescrs : sig + type param_descrs = z3_native_object + + val create : context -> Z3native.ptr -> param_descrs + end +end = struct type params = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : params = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.params_inc_ref ; dec_ref = Z3native.params_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs = - struct + module ParamDescrs : + sig + type param_descrs = z3_native_object + + val create : context -> Z3native.ptr -> param_descrs + end = struct type param_descrs = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : param_descrs = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.param_descrs_inc_ref ; dec_ref = Z3native.param_descrs_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -1449,7 +1065,6 @@ struct *) let add_s_double ( x : params ) ( name : string ) ( value : float ) = add_double x (Symbol.mk_string (z3obj_gc x) name) value - (** Adds a parameter setting. *) @@ -1460,7 +1075,7 @@ struct Creates a new parameter set *) let mk_params ( ctx : context ) = - cnstr ctx (Z3native.mk_params (context_gno ctx)) + create ctx (Z3native.mk_params (context_gno ctx)) (** A string representation of the parameter set. @@ -1468,18 +1083,69 @@ struct let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) end - (** General expressions (terms), including Boolean logic *) -module Expr = -struct +and Expr : +sig + type expr = Expr of AST.ast + + val create : context -> Z3native.ptr -> expr + val create_fa : context -> FuncDecl.func_decl -> expr array -> expr + val gc : expr -> context + val gno : expr -> Z3native.ptr + val gnc : expr -> Z3native.ptr + val aton : expr array -> Z3native.ptr array + + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val get_func_decl : expr -> FuncDecl.func_decl +end = struct + type expr = Expr of AST.ast + + let create ( ctx : context ) ( obj : Z3native.ptr ) = + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then + (match (Quantifiers.create ctx obj) with Quantifiers.Quantifier(e) -> e) + else + let s = Z3native.get_sort (context_gno ctx) obj in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) obj) then + (match (Arithmetic.create_algebraic_num ctx obj) with Arithmetic.AlgebraicNum(Arithmetic.Expr(e)) -> e) + else + if (Z3native.is_numeral_ast (context_gno ctx) obj) && + (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + match sk with + | INT_SORT -> (match (Arithmetic.create_int_num ctx obj) with Arithmetic.IntNum(Arithmetic.IntExpr(Arithmetic.Expr(e))) -> e) + | REAL_SORT -> (match (Arithmetic.create_rat_num ctx obj) with Arithmetic.RatNum(Arithmetic.RealExpr(Arithmetic.Expr(e))) -> e) + | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) + | _ -> raise (Z3native.Exception "Unsupported numeral object") + else + match sk with + | BOOL_SORT -> (match (Booleans.create ctx obj) with Booleans.BoolExpr(e) -> e) + | INT_SORT -> (match (Arithmetic.create_int_expr ctx obj) with Arithmetic.IntExpr(Arithmetic.Expr(e)) -> e) + | REAL_SORT -> (match (Arithmetic.create_real_expr ctx obj) with Arithmetic.RealExpr(Arithmetic.Expr(e)) -> e) + | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) + | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) + | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) + | _ -> Expr(AST.create ctx obj) + + let aton ( a : expr array ) = + let f ( e : expr ) = match e with Expr(a) -> (z3obj_gno a) in + Array.map f a + + let create_fa ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = + let o = Z3native.mk_app (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args) in + Expr.create ctx o + + let gc ( x : expr ) = match x with Expr(a) -> (z3obj_gc a) + let gnc ( x : expr ) = match x with Expr(a) -> (z3obj_gnc a) + let gno ( x : expr ) = match x with Expr(a) -> (z3obj_gno a) + (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier *) let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> create_expr x#gc (Z3native.simplify x#gnc x#gno) - | Some pp -> create_expr x#gc (Z3native.simplify_ex x#gnc x#gno (z3obj_gno pp)) + | None -> Expr.create (gc x) (Z3native.simplify (gnc x) (gno x)) + | Some pp -> Expr.create (gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) (** a string describing all available parameters to Expr.Simplify. @@ -1491,29 +1157,29 @@ struct Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.cnstr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) + Params.ParamDescrs.create ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. *) - let get_func_decl ( x : expr ) = (new func_decl x#gc)#cnstr_obj (Z3native.get_app_decl x#gnc x#gno) + let get_func_decl ( x : expr ) = FuncDecl.create (gc x) (Z3native.get_app_decl (gnc x) (gno x)) (** Indicates whether the expression is the true or false expression or something else (L_UNDEF). *) - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value x#gnc x#gno) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) (** The number of arguments of the expression. *) - let get_num_args ( x : expr ) = Z3native.get_app_num_args x#gnc x#gno + let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) (** The arguments of the expression. *) let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = create_expr x#gc (Z3native.get_app_arg x#gnc x#gno i) in + let f i = create (gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in Array.init n f (** @@ -1524,7 +1190,7 @@ struct if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - x#sno x#gc (Z3native.update_term x#gnc x#gno (Array.length args) (expraton args)) + create (gc x) (Z3native.update_term (gnc x) (gno x) (Array.length args) (aton args)) (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. @@ -1537,7 +1203,7 @@ struct if (Array.length from) <> (Array.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - create_expr x#gc (Z3native.substitute x#gnc x#gno (Array.length from) (expraton from) (expraton to_)) + create (gc x) (Z3native.substitute (gnc x) (gno x) (Array.length from) (aton from) (aton to_)) (** Substitute every occurrence of from in the expression with to. @@ -1552,7 +1218,7 @@ struct For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) let substitute_vars ( x : expr ) to_ = - create_expr x#gc (Z3native.substitute_vars x#gnc x#gno (Array.length to_) (expraton to_)) + create (gc x) (Z3native.substitute_vars (gnc x) (gno x) (Array.length to_) (aton to_)) (** @@ -1561,46 +1227,46 @@ struct @return A copy of the term which is associated with *) let translate ( x : expr ) to_ctx = - if x#gc == to_ctx then + if (gc x) == to_ctx then x else - create_expr to_ctx (Z3native.translate x#gnc x#gno (context_gno to_ctx)) + create to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) (** Returns a string representation of the expression. *) - let to_string ( x : expr ) = Z3native.ast_to_string x#gnc x#gno + let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast x#gnc x#gno) + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted x#gnc x#gno + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) (** The Sort of the term. *) - let get_sort ( x : expr ) = create_sort x#gc (Z3native.get_sort x#gnc x#gno) + let get_sort ( x : expr ) = Sort.create (gc x) (Z3native.get_sort (gnc x) (gno x)) (** Indicates whether the term has Boolean sort. *) - let is_bool ( x : expr ) = (AST.is_expr x) && - (Z3native.is_eq_sort x#gnc - (Z3native.mk_bool_sort x#gnc) - (Z3native.get_sort x#gnc x#gno)) - + let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (Z3native.is_eq_sort (gnc x) + (Z3native.mk_bool_sort (gnc x)) + (Z3native.get_sort (gnc x) (gno x))) + (** Indicates whether the term represents a constant. *) - let is_const ( x : expr ) = (AST.is_expr x) && + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (get_num_args x) == 0 && - FuncDecl.get_domain_size(get_func_decl x) == 0 + (FuncDecl.get_domain_size (get_func_decl x)) == 0 (** Indicates whether the term is the constant true. @@ -1679,123 +1345,36 @@ struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_expr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) range#gno) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = + create ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) (** Creates a new Constant of sort and named . *) - let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name)range + let mk_const_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = + mk_const ctx (Symbol.mk_string ctx name) range (** Creates a constant from the func_decl . @param f An expression of a 0-arity function *) - let mk_const_f ( ctx : context ) ( f : func_decl ) = - create_expr_fa ctx f [||] + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = + create_fa ctx f [||] (** Creates a fresh constant of sort and a name prefixed with . *) - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort) = - create_expr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix range#gno) - - (** - Create a Boolean constant. - *) - let mk_bool_const ( ctx : context ) ( name : Symbol.symbol ) = - ((mk_const ctx name (Sort.mk_bool ctx)) :> bool_expr) - - (** - Create a Boolean constant. - *) - let mk_bool_const_s ( ctx : context ) ( name : string ) = - mk_bool_const ctx (Symbol.mk_string ctx name) + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = + create ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) (** Create a new function application. *) - let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = - create_expr_fa ctx f args - - (** - The true Term. - *) - let mk_true ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_true (context_gno ctx)) - - (** - The false Term. - *) - let mk_false ( ctx : context ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_false (context_gno ctx)) - - (** - Creates a Boolean value. - *) - let mk_bool ( ctx : context ) ( value : bool) = - if value then mk_true ctx else mk_false ctx - - (** - Creates the equality = . - *) - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_eq (context_gno ctx) x#gno y#gno) - - (** - Creates a distinct term. - *) - let mk_distinct ( ctx : context ) ( args : expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_distinct (context_gno ctx) (Array.length args) (astaton args)) - - (** - Mk an expression representing not(a). - *) - let mk_not ( ctx : context ) ( a : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_not (context_gno ctx) a#gno) - - (** - Create an expression representing an if-then-else: ite(t1, t2, t3). - @param t1 An expression with Boolean sort - @param t2 An expression - @param t3 An expression with the same sort as - *) - let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create_expr ctx (Z3native.mk_ite (context_gno ctx) t1#gno t2#gno t3#gno) - - (** - Create an expression representing t1 iff t2. - *) - let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_iff (context_gno ctx) t1#gno t2#gno) - - (** - Create an expression representing t1 -> t2. - *) - let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_implies (context_gno ctx) t1#gno t2#gno) - - (** - Create an expression representing t1 xor t2. - *) - let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_xor (context_gno ctx) t1#gno t2#gno) - - (** - Create an expression representing the AND of args - *) - let mk_and ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_and (context_gno ctx) (Array.length args) (astaton args)) - - (** - Create an expression representing the OR of args - *) - let mk_or ( ctx : context ) ( args : bool_expr array ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_or (context_gno ctx) (Array.length args) (astaton args)) + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = + create_fa ctx f args (** Create a numeral of a given sort. @@ -1803,8 +1382,8 @@ struct @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. @return A Term with value and sort *) - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - create_expr ctx (Z3native.mk_numeral (context_gno ctx) v ty#gno) + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : Sort.sort ) = + create ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. @@ -1813,13 +1392,147 @@ struct @param ty Sort of the numeral @return A Term with value and type *) - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_int (context_gno ctx) v ty#gno) + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : Sort.sort ) = + create ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) + + let aton (a : expr array) = + let f (e : expr) = (gno e) in + Array.map f a +end + +(** Boolean expressions *) +and Booleans : +sig + type bool_expr = BoolExpr of Expr.expr + type bool_sort = BoolSort of Sort.sort + + val create : context -> Z3native.ptr -> bool_expr + val aton : bool_expr array -> Z3native.ptr array +end = struct + type bool_expr = BoolExpr of Expr.expr + type bool_sort = BoolSort of Sort.sort + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let a = (AST.create ctx no) in + BoolExpr(Expr.Expr(a)) + + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gc e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gnc e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gno e) + + let aton ( a : bool_expr array ) = + let f (e : bool_expr) = (gno e) in + Array.map f a + + let mk_sort ( ctx : context ) = + BoolSort(Sort.create ctx (Z3native.mk_bool_sort (context_gno ctx))) + + (** + Create a Boolean constant. + *) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = + let s = (match (mk_sort ctx) with BoolSort(q) -> q) in + BoolExpr(Expr.mk_const ctx name s) + + (** + Create a Boolean constant. + *) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) + + (** + The true Term. + *) + let mk_true ( ctx : context ) = + create ctx (Z3native.mk_true (context_gno ctx)) + + (** + The false Term. + *) + let mk_false ( ctx : context ) = + create ctx (Z3native.mk_false (context_gno ctx)) + + (** + Creates a Boolean value. + *) + let mk_val ( ctx : context ) ( value : bool ) = + if value then mk_true ctx else mk_false ctx + + (** + Creates the equality = . + *) + let mk_eq ( ctx : context ) ( x : Expr.expr ) ( y : Expr.expr ) = + create ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + + (** + Creates a distinct term. + *) + let mk_distinct ( ctx : context ) ( args : Expr.expr array ) = + create ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) + + (** + Mk an expression representing not(a). + *) + let mk_not ( ctx : context ) ( a : bool_expr ) = + create ctx (Z3native.mk_not (context_gno ctx) (gno a)) + + (** + Create an expression representing an if-then-else: ite(t1, t2, t3). + @param t1 An expression with Boolean sort + @param t2 An expression + @param t3 An expression with the same sort as + *) + let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = + create ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + + (** + Create an expression representing t1 iff t2. + *) + let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + create ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + + (** + Create an expression representing t1 -> t2. + *) + let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + create ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + (** + Create an expression representing t1 xor t2. + *) + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + create ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + + (** + Create an expression representing the AND of args + *) + let mk_and ( ctx : context ) ( args : bool_expr array ) = + create ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) + + (** + Create an expression representing the OR of args + *) + let mk_or ( ctx : context ) ( args : bool_expr array ) = + create ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) end (** Quantifier expressions *) -module Quantifiers = -struct +and Quantifiers : +sig + type quantifier = Quantifier of Expr.expr + + val create : context -> Z3native.ptr -> quantifier +end = struct + type quantifier = Quantifier of Expr.expr + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let a = (AST.create ctx no) in + Quantifier(Expr.Expr(a)) + + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) + + (** The de-Burijn index of a bound variable. @@ -1838,11 +1551,11 @@ struct on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its index. *) - let get_index ( x : expr ) = - if not (AST.is_var x) then + let get_index ( x : Expr.expr ) = + if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else - Z3native.get_index_value x#gnc x#gno + Z3native.get_index_value (Expr.gnc x) (Expr.gno x) (** Quantifier patterns @@ -1850,33 +1563,57 @@ struct non-empty. If the list comprises of more than one term, it is also called a multi-pattern. *) - module Pattern = - struct + module Patterns : + sig + type pattern = Pattern of AST.ast + + val create : context -> Z3native.ptr -> pattern + val aton : pattern array -> Z3native.ptr array + end = struct + type pattern = Pattern of AST.ast + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + Pattern(res) + + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) + let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) + let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) + (** The number of terms in the pattern. *) let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms x#gnc x#gno + Z3native.get_pattern_num_terms (gnc x) (gno x) (** The terms in the pattern. *) let get_terms ( x : pattern ) = let n = (get_num_terms x) in - let f i = (create_expr x#gc (Z3native.get_pattern x#gnc x#gno i)) in + let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in Array.init n f (** A string representation of the pattern. *) - let to_string ( x : pattern ) = Z3native.pattern_to_string x#gnc x#gno + let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) + + let aton (a : pattern array) = + let f (e : pattern) = (gno e) in + Array.map f a end (** Indicates whether the quantifier is universal. *) let is_universal ( x : quantifier ) = - Z3native.is_quantifier_forall x#gnc x#gno + Z3native.is_quantifier_forall (gnc x) (gno x) (** Indicates whether the quantifier is existential. @@ -1886,45 +1623,45 @@ struct (** The weight of the quantifier. *) - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight x#gnc x#gno + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) (** The number of patterns. *) - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns x#gnc x#gno + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) (** The patterns. *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_pattern_ast x#gnc x#gno i)) in + let f i = (Patterns.create (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** The number of no-patterns. *) - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns x#gnc x#gno + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) (** The no-patterns. *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = ((new pattern x#gc)#cnstr_obj (Z3native.get_quantifier_no_pattern_ast x#gnc x#gno i)) in + let f i = (Patterns.create (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** The number of bound variables. *) - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound x#gnc x#gno + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) (** The symbols for the bound variables. *) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (Symbol.create x#gc (Z3native.get_quantifier_bound_name x#gnc x#gno i)) in + let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in Array.init n f (** @@ -1932,31 +1669,31 @@ struct *) let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (create_sort x#gc (Z3native.get_quantifier_bound_sort x#gnc x#gno i)) in + let f i = (Sort.create (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in Array.init n f (** The body of the quantifier. *) let get_body ( x : quantifier ) = - (new bool_expr x#gc)#cnstr_obj (Z3native.get_quantifier_body x#gnc x#gno) + Booleans.create (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) (** Creates a new bound variable. @param index The de-Bruijn index of the variable @param ty The sort of the variable *) - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - create_expr ctx (Z3native.mk_bound (context_gno ctx) index ty#gno) + let mk_bound ( ctx : context ) ( index : int ) ( ty : Sort.sort ) = + Expr.create ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) (** Create a quantifier pattern. *) - let mk_pattern ( ctx : context ) ( terms : expr array ) = + let mk_pattern ( ctx : context ) ( terms : Expr.expr array ) = if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - (new pattern ctx)#cnstr_obj (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (astaton terms)) + Patterns.create ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (Expr.aton terms)) (** Create a universal Quantifier. @@ -1977,95 +1714,96 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (patternaton patterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) + create ctx (Z3native.mk_quantifier (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (Patterns.aton patterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) + create ctx (Z3native.mk_quantifier_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - body#gno) + create ctx (Z3native.mk_quantifier_const (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - body#gno) + create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Expr.gno body)) + (** Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (patternaton patterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) + create ctx (Z3native.mk_quantifier (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (Patterns.aton patterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - (Array.length sorts) (astaton sorts) - (Symbol.aton names) - body#gno) - + create ctx (Z3native.mk_quantifier_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Array.length sorts) (Sort.aton sorts) + (Symbol.aton names) + (Expr.gno body)) + (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - body#gno) + create ctx (Z3native.mk_quantifier_const (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Expr.gno body)) else - (new quantifier ctx)#cnstr_obj (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expraton bound_constants) - (Array.length patterns) (patternaton patterns) - (Array.length nopatterns) (patternaton nopatterns) - body#gno) + create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (Expr.aton bound_constants) + (Array.length patterns) (Patterns.aton patterns) + (Array.length nopatterns) (Expr.aton nopatterns) + (Expr.gno body)) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -2075,7 +1813,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : pattern array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -2083,75 +1821,104 @@ struct end (** Functions to manipulate Array expressions *) -module Arrays = -struct +and Arrays : +sig + type array_expr = ArrayExpr of Expr.expr + type array_sort = ArraySort of Sort.sort + + val create_expr : context -> Z3native.ptr -> array_expr +end = struct + type array_expr = ArrayExpr of Expr.expr + type array_sort = ArraySort of Sort.sort + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (Expr.create ctx no) in + ArrayExpr(e) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + ArraySort(s) + + let sgc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gno s) + + let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gc e) + let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gnc e) + let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gno e) + + let aton (a : array_expr array) = + let f (e : array_expr) = (egno e) in + Array.map f a + + (** Create a new array sort. *) - let mk_sort ( ctx : context ) domain range = - (new array_sort ctx)#cnstr_dr domain range + let mk_sort ( ctx : context ) ( domain : Sort.sort ) ( range : Sort.sort ) = + create_sort ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) (** Indicates whether the term is an array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). Array store takes at least 3 arguments. *) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) (** Indicates whether the term is an array select. *) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) (** Indicates whether the term is a constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_constant_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) (** Indicates whether the term is a default array. For example default(const(v)) = v. The function is unary. *) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_default_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) (** Indicates whether the term is an array map. It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_array_map ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) (** Indicates whether the term is an as-array term. An as-array term is n array value that behaves as the function graph of the function passed as parameter. *) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_as_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) (** Indicates whether the term is of an array sort. *) - let is_array ( x : expr ) = - (Z3native.is_app x#gnc x#gno) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == ARRAY_SORT) + let is_array ( x : Expr.expr ) = + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) (** The domain of the array sort. *) - let get_domain (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_domain x#gnc x#gno) + let get_domain ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) (** The range of the array sort. *) - let get_range (x : array_sort) = create_sort x#gc (Z3native.get_array_sort_range x#gnc x#gno) + let get_range ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - ((Expr.mk_const ctx name ((mk_sort ctx domain range) :> sort)) :> array_expr) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort ) ( range : Sort.sort ) = + ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) (** Create an array constant. *) - let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = + let mk_const_s ( ctx : context ) ( name : string ) ( domain : Sort.sort ) ( range : Sort.sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range (** @@ -2166,8 +1933,8 @@ struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - ((create_expr ctx (Z3native.mk_select (context_gno ctx) a#gno i#gno)) :> array_expr) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) = + create_expr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) (** Array update. @@ -2185,8 +1952,8 @@ struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_store (context_gno ctx) a#gno i#gno v#gno) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) ( v : Expr.expr ) = + create_expr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) (** Create a constant array. @@ -2196,8 +1963,8 @@ struct *) - let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - (new array_expr ctx)#cnstr_obj (Z3native.mk_const_array (context_gno ctx) domain#gno v#gno) + let mk_const_array ( ctx : context ) ( domain : Sort.sort ) ( v : Expr.expr ) = + create_expr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) (** Maps f on the argument arrays. @@ -2209,8 +1976,8 @@ struct *) - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = - ((create_expr ctx (Z3native.mk_map (context_gno ctx) f#gno (Array.length args) (astaton args))) :> array_expr) + let mk_map ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : array_expr array ) = + create_expr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args)) (** Access the array default value. @@ -2219,149 +1986,184 @@ struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - ((create_expr ctx (Z3native.mk_array_default (context_gno ctx) arg#gno)) :> array_expr) + create_expr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end (** Functions to manipulate Set expressions *) -module Sets = -struct +and Sets : +sig + type set_sort = SetSort of Sort.sort + +end = struct + type set_sort = SetSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + SetSort(s) + (** Indicates whether the term is set union *) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) (** Indicates whether the term is set intersection *) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_intersect ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) (** Indicates whether the term is set difference *) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_difference ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) (** Indicates whether the term is set complement *) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) (** Indicates whether the term is set subset *) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + let is_subset ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) (** Create a set type. *) - let mk_sort ( ctx : context ) ( ty : sort) = - (new set_sort ctx)#cnstr_s ty + let mk_sort ( ctx : context ) ( ty : Sort.sort ) = + create_sort ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) (** Create an empty set. *) - let mk_empty ( ctx : context ) ( domain : sort ) = - (create_expr ctx (Z3native.mk_empty_set (context_gno ctx) domain#gno)) + let mk_empty ( ctx : context ) ( domain : Sort.sort ) = + (Expr.create ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) (** Create the full set. *) - let mk_full ( ctx : context ) ( domain : sort ) = - create_expr ctx (Z3native.mk_full_set (context_gno ctx) domain#gno) + let mk_full ( ctx : context ) ( domain : Sort.sort ) = + Expr.create ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) (** Add an element to the set. *) - let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_add (context_gno ctx) set#gno element#gno) + let mk_set_add ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) (** Remove an element from a set. *) - let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - create_expr ctx (Z3native.mk_set_del (context_gno ctx) set#gno element#gno) + let mk_del ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) (** Take the union of a list of sets. *) - let mk_union ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (astaton args)) + let mk_union ( ctx : context ) ( args : Expr.expr array ) = + Expr.create ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (Expr.aton args)) (** Take the intersection of a list of sets. *) - let mk_intersection ( ctx : context ) ( args : expr array ) = - create_expr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (astaton args)) + let mk_intersection ( ctx : context ) ( args : Expr.expr array ) = + Expr.create ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (Expr.aton args)) (** Take the difference between two sets. *) - let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_difference (context_gno ctx) arg1#gno arg2#gno) + let mk_difference ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) (** Take the complement of a set. *) - let mk_complement ( ctx : context ) ( arg : expr ) = - create_expr ctx (Z3native.mk_set_complement (context_gno ctx) arg#gno) + let mk_complement ( ctx : context ) ( arg : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) (** Check for set membership. *) - let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - create_expr ctx (Z3native.mk_set_member (context_gno ctx) elem#gno set#gno) + let mk_membership ( ctx : context ) ( elem : Expr.expr ) ( set : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) (** Check for subsetness of sets. *) - let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr) = - create_expr ctx (Z3native.mk_set_subset (context_gno ctx) arg1#gno arg2#gno) + let mk_subset ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = + Expr.create ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) end (** Functions to manipulate Finite Domain expressions *) -module FiniteDomains = -struct - (** - Create a new finite domain sort. - *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) size = - (new finite_domain_sort ctx)#cnstr_si name size +and FiniteDomains : +sig + type finite_domain_sort = FiniteDomainSort of Sort.sort + +end = struct + type finite_domain_sort = FiniteDomainSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + FiniteDomainSort(s) + + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gc s) + let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gnc s) + let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s))-> (z3obj_gno s) (** Create a new finite domain sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) size = - (new finite_domain_sort ctx)#cnstr_si (Symbol.mk_string ctx name) size + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + create_sort ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size) + + (** + Create a new finite domain sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_sort ctx (Symbol.mk_string ctx name) size (** Indicates whether the term is of an array sort. *) - let is_finite_domain ( x : expr ) = - (Z3native.is_app x#gnc x#gno) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == FINITE_DOMAIN_SORT) + let is_finite_domain ( x : Expr.expr ) = + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == FINITE_DOMAIN_SORT) (** Indicates whether the term is a less than predicate over a finite domain. *) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) (** The size of the finite domain sort. *) - let get_size (x : finite_domain_sort) = - let (r, v) = Z3native.get_finite_domain_sort_size x#gnc x#gno in + let get_size ( x : finite_domain_sort ) = + let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in if r then v else raise (Z3native.Exception "Conversion failed.") end (** Functions to manipulate Relation expressions *) -module Relations = -struct +and Relations : +sig + type relation_sort = RelationSort of Sort.sort + +end = struct + type relation_sort = RelationSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + RelationSort(s) + + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gc s) + let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gnc s) + let gno ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s))-> (z3obj_gno s) + (** Indicates whether the term is of a relation sort. *) - let is_relation ( x : expr ) = - ((Z3native.is_app x#gnc x#gno) && - (sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno)) == RELATION_SORT)) + let is_relation ( x : Expr.expr ) = + ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == RELATION_SORT)) (** Indicates whether the term is an relation store @@ -2370,40 +2172,40 @@ struct The function takes n+1 arguments, where the first argument is the relation and the remaining n elements correspond to the n columns of the relation. *) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) (** Indicates whether the term is an empty relation *) - let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) (** Indicates whether the term is a test for the emptiness of a relation *) - let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) (** Indicates whether the term is a relational join *) - let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_join ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) (** Indicates whether the term is the union or convex hull of two relations. The function takes two arguments. *) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) (** Indicates whether the term is the widening of two relations The function takes two arguments. *) - let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_widen ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). The function takes one argument. *) - let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_project ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) (** Indicates whether the term is a relation filter @@ -2414,7 +2216,7 @@ struct corresponding to the columns of the relation. So the first column in the relation has index 0. *) - let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) (** Indicates whether the term is an intersection of a relation with the negation of another. @@ -2429,7 +2231,7 @@ struct target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with ( x : expr ) on the columns c1, d1, .., cN, dN. *) - let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_negation_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) (** Indicates whether the term is the renaming of a column in a relation @@ -2437,12 +2239,12 @@ struct The function takes one argument. The parameters contain the renaming as a cycle. *) - let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_rename ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) (** Indicates whether the term is the complement of a relation *) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) (** Indicates whether the term is a relational select @@ -2451,7 +2253,7 @@ struct The function takes n+1 arguments, where the first argument is a relation, and the remaining n arguments correspond to a record. *) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) (** Indicates whether the term is a relational clone (copy) @@ -2462,38 +2264,153 @@ struct for terms of kind to perform destructive updates to the first argument. *) - let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + let is_clone ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) (** The arity of the relation sort. *) - let get_arity (x : relation_sort) = Z3native.get_relation_arity x#gnc x#gno + let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) (** The sorts of the columns of the relation sort. *) - let get_column_sorts (x : relation_sort) = + let get_column_sorts ( x : relation_sort ) = let n = get_arity x in - let f i = create_sort x#gc (Z3native.get_relation_column x#gnc x#gno i) in + let f i = (create_sort (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in Array.init n f end (** Functions to manipulate Datatype expressions *) -module Datatypes = -struct +and Datatypes : +sig + type datatype_expr = DatatypeExpr of Expr.expr + type datatype_sort = DatatypeSort of Sort.sort + + val create_expr : context -> Z3native.ptr -> datatype_expr +end = struct + type datatype_expr = DatatypeExpr of Expr.expr + type datatype_sort = DatatypeSort of Sort.sort + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (Expr.create ctx no) in + DatatypeExpr(e) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + DatatypeSort(s) + + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s))-> (z3obj_gno s) + + (** Constructors *) module Constructor = struct + type constructor_extra = { + m_n : int; + mutable m_tester_decl : FuncDecl.func_decl option; + mutable m_constructor_decl : FuncDecl.func_decl option ; + mutable m_accessor_decls : FuncDecl.func_decl array option} + type constructor = Constructor of (z3_native_object * constructor_extra) + + let create_ssssi ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + let n = (Array.length field_names) in + if n != (Array.length sorts) then + raise (Z3native.Exception "Number of field names does not match number of sorts") + else + if n != (Array.length sort_refs) then + raise (Z3native.Exception "Number of field names does not match number of sort refs") + else + let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) + (Symbol.gno recognizer) + n + (Symbol.aton field_names) + (Sort.aton sorts) + sort_refs) in + let no : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + let ex : constructor_extra = { m_n = n; + m_tester_decl = None; + m_constructor_decl = None; + m_accessor_decls = None} in + (z3obj_sno no ctx ptr) ; + (z3obj_create no) ; + let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f no ; + Constructor(no, ex) + + let init_extra ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_tester_decl with + | None -> + let (a, b, c) = (Z3native.query_constructor (z3obj_gnc no) (z3obj_gno no) ex.m_n) in + ex.m_constructor_decl <- Some (FuncDecl.create (z3obj_gc no) a) ; + ex.m_tester_decl <- Some (FuncDecl.create (z3obj_gc no) b) ; + ex.m_accessor_decls <- Some (let f e = (FuncDecl.create (z3obj_gc no) e) in Array.map f c) ; + () + | _ -> () + + let get_n ( x : constructor ) = + match x with Constructor(no, ex) -> + ex.m_n + + let rec tester_decl ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_tester_decl with + | Some(s) -> s + | None -> init_extra x ; tester_decl x + + let rec constructor_decl ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_constructor_decl with + | Some(s) -> s + | None -> init_extra x ; constructor_decl x + + let rec accessor_decls ( x : constructor ) = + match x with Constructor(no, ex) -> + match ex.m_accessor_decls with + | Some(s) -> s + | None -> init_extra x ; accessor_decls x + + let aton ( a : constructor array ) = + let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in + Array.map f a + + (** The number of fields of the constructor. *) - let get_num_fields ( x : constructor ) = x#get_n + let get_num_fields ( x : constructor ) = get_n x (** The function declaration of the constructor. *) - let get_constructor_decl ( x : constructor ) = x#constructor_decl + let get_constructor_decl ( x : constructor ) = constructor_decl x (** The function declaration of the tester. *) - let get_tester_decl ( x : constructor ) = x#tester_decl + let get_tester_decl ( x : constructor ) = tester_decl x (** The function declarations of the accessors *) - let get_accessor_decls ( x : constructor ) = x#accessor_decls + let get_accessor_decls ( x : constructor ) = accessor_decls x end + (** Constructor list objects *) + module ConstructorList = + struct + type constructor_list = z3_native_object + + let create ( ctx : context )( c : Constructor.constructor array ) = + let res : constructor_list = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Constructor.aton c))) ; + (z3obj_create res) ; + let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f res; + res + + let aton (a : constructor_list array) = + let f (e : constructor_list) = (z3obj_gno e) in + Array.map f a + end + (* DATATYPES *) (** Create a datatype constructor. @@ -2505,8 +2422,8 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array) = - (new constructor ctx)#cnstr_ssssi name recognizer field_names sorts sort_refs + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array) = + Constructor.create_ssssi ctx name recognizer field_names sorts sort_refs (** @@ -2519,20 +2436,21 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : constructor array) = - (new datatype_sort ctx)#cnstr_sc name constructors + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array) = + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Constructor.aton constructors)) in + create_sort ctx x (** Create a new datatype sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors (** @@ -2540,16 +2458,16 @@ struct @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : constructor array array ) = + let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = let n = (Array.length names) in - let f e = ( (new constructor_list ctx)#cnstr_ca e ) in + let f e = (ConstructorList.create ctx e) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (constructor_listaton cla)) in - let g e = ( (new datatype_sort ctx)#cnstr_obj e) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (ConstructorList.aton cla)) in + let g e = (create_sort ctx e) in (Array.map g r) (** Create mutually recursive data-types. *) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in @@ -2558,130 +2476,230 @@ struct c (** The number of constructors of the datatype sort. *) - let get_num_constructors (x : datatype_sort) = Z3native.get_datatype_sort_num_constructors x#gnc x#gno + let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) (** The range of the array sort. *) - let get_constructors (x : datatype_sort) = + let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i) in + let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in Array.init n f (** The recognizers. *) - let get_recognizers (x : datatype_sort) = + let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_recognizer x#gnc x#gno i) in + let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in Array.init n f (** The constructor accessors. *) - let get_accessors (x : datatype_sort) = + let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = ( - let fd = ((new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor x#gnc x#gno i)) in - let ds = (Z3native.get_domain_size fd#gnc fd#gno) in - let g j = (new func_decl x#gc)#cnstr_obj (Z3native.get_datatype_sort_constructor_accessor x#gnc x#gno i j) in + let fd = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in + let g j = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in Array.init ds g ) in Array.init n f end (** Functions to manipulate Enumeration expressions *) -module Enumerations = -struct - (** - Create a new enumeration sort. - *) - let mk_sort ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss name enum_names +and Enumerations : +sig + type enum_sort_data + type enum_sort = EnumSort of (Sort.sort * enum_sort_data) +end = struct + type enum_sort_data = { mutable _constdecls : FuncDecl.func_decl array ; + mutable _testerdecls : FuncDecl.func_decl array } + type enum_sort = EnumSort of (Sort.sort * enum_sort_data) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = + let s = (Sort.create ctx no) in + let e = { _constdecls = (let f e = FuncDecl.create ctx e in (Array.map f cdecls)) ; + _testerdecls = (let f e = FuncDecl.create ctx e in (Array.map f tdecls)) } in + EnumSort(s, e) + + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gc s) + let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gnc s) + let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_)-> (z3obj_gno s) + (** Create a new enumeration sort. *) - let mk_sort_s ( ctx : context ) name enum_names = - (new enum_sort ctx)#cnstr_ss - (Symbol.mk_string ctx name) - (Symbol.mk_strings ctx enum_names) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in + create_sort ctx a b c + + (** + Create a new enumeration sort. + *) + let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string array ) = + mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) - let get_const_decls (x : enum_sort) = x#const_decls + let get_const_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._constdecls (** The test predicates for the constants in the enumeration. *) - let get_tester_decls (x : enum_sort) = x#tester_decls + let get_tester_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._testerdecls end (** Functions to manipulate List expressions *) -module Lists = -struct - (** - Create a new list sort. - *) - let mk_sort ( ctx : context ) (name : Symbol.symbol) elem_sort = - (new list_sort ctx)#cnstr_ss name elem_sort +and Lists : +sig + type list_sort_data + type list_sort = ListSort of (Sort.sort * list_sort_data) - (** - Create a new list sort. - *) +end = struct + type list_sort_data = { _nildecl : FuncDecl.func_decl ; + _is_nildecl : FuncDecl.func_decl ; + _consdecl : FuncDecl.func_decl ; + _is_consdecl : FuncDecl.func_decl ; + _headdecl : FuncDecl.func_decl ; + _taildecl : FuncDecl.func_decl } + type list_sort = ListSort of (Sort.sort * list_sort_data) + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = + let s = (Sort.create ctx no) in + let e = {_nildecl = FuncDecl.create ctx nildecl; + _is_nildecl = FuncDecl.create ctx is_nildecl; + _consdecl = FuncDecl.create ctx consdecl; + _is_consdecl = FuncDecl.create ctx is_consdecl; + _headdecl = FuncDecl.create ctx headdecl; + _taildecl = FuncDecl.create ctx taildecl} in + ListSort(s, e) + + let sgc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gc s) + let sgnc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gnc s) + let sgno ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_)-> (z3obj_gno s) + + + (** Create a new list sort. *) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : Sort.sort ) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in + create_sort ctx r a b c d e f + + (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) - let get_nil_decl (x : list_sort) = x#nil_decl + let get_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._nildecl (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl (x : list_sort) = x#is_nil_decl + let get_is_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_nildecl (** The declaration of the cons function of this list sort. *) - let get_cons_decl (x : list_sort) = x#cons_decl + let get_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._consdecl (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl (x : list_sort) = x#is_cons_decl + let get_is_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_consdecl (** The declaration of the head function of this list sort. *) - let get_head_decl (x : list_sort) = x#head_decl + let get_head_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._headdecl (** The declaration of the tail function of this list sort. *) - let get_tail_decl (x : list_sort) = x#tail_decl + let get_tail_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._taildecl (** The empty list. *) - let nil (x : list_sort) = create_expr_fa x#gc (get_nil_decl x) [||] + let nil ( x : list_sort ) = Expr.create_fa (sgc x) (get_nil_decl x) [||] end (** Functions to manipulate Tuple expressions *) -module Tuples = -struct - (** - Create a new tuple sort. - *) - let mk_sort ( ctx : context ) name field_names field_sorts = - (new tuple_sort ctx)#cnstr_siss name (Array.length field_names) field_names field_sorts +and Tuples : +sig + type tuple_sort = TupleSort of Sort.sort +end = struct + type tuple_sort = TupleSort of Sort.sort + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let s = (Sort.create ctx no) in + TupleSort(s) + + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s))-> (z3obj_gno s) + + (** Create a new tuple sort. *) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : Sort.sort array ) = + let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Symbol.aton field_names) (Sort.aton field_sorts)) in + (* CMW: leaks a,b? *) + create_sort ctx r (** The constructor function of the tuple. *) - let get_mk_decl (x : tuple_sort) = - (new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_mk_decl x#gnc x#gno) + let get_mk_decl ( x : tuple_sort ) = + FuncDecl.create (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) (** The number of fields in the tuple. *) - let get_num_fields (x : tuple_sort) = Z3native.get_tuple_sort_num_fields x#gnc x#gno + let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) (** The field declarations. *) - let get_field_decls (x : tuple_sort) = + let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in - let f i = ((new func_decl x#gc)#cnstr_obj (Z3native.get_tuple_sort_field_decl x#gnc x#gno i)) in + let f i = FuncDecl.create (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in Array.init n f end (** Functions to manipulate arithmetic expressions *) -module Arithmetic = -struct +and Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type int_sort = IntSort of Sort.sort + type real_sort = RealSort of Sort.sort + + type arith_expr = Expr of Expr.expr + type int_expr = IntExpr of arith_expr + type real_expr = RealExpr of arith_expr + + type int_num = IntNum of int_expr + type rat_num = RatNum of real_expr + type algebraic_num = AlgebraicNum of arith_expr + + + val create_arith_expr : context -> Z3native.ptr -> arith_expr + val create_int_expr : context -> Z3native.ptr -> int_expr + val create_real_expr : context -> Z3native.ptr -> real_expr + val create_int_num : context -> Z3native.ptr -> int_num + val create_rat_num : context -> Z3native.ptr -> rat_num + val create_algebraic_num : context -> Z3native.ptr -> algebraic_num +end = struct + type arith_sort = ArithSort of Sort.sort + type int_sort = IntSort of Sort.sort + type real_sort = RealSort of Sort.sort + + type arith_expr = ArithExpr of Expr.expr + type int_expr = IntExpr of arith_expr + type real_expr = RealExpr of arith_expr + + type int_num = IntNum of int_expr + type rat_num = RatNum of real_expr + type algebraic_num = AlgebraicNum of arith_expr + + let create_arith_expr ( ctx : context ) ( no : Z3native.ptr ) = + ArithExpr(Expr.create ctx no) + + let create_int_expr ( ctx : context ) ( no : Z3native.ptr ) = + IntExpr(create_arith_expr ctx no) + + let create_real_expr ( ctx : context ) ( no : Z3native.ptr ) = + RealExpr(create_arith_expr ctx no) + + let create_int_num ( ctx : context ) ( no : Z3native.ptr ) = + IntNum(create_int_expr ctx no) + + let create_rat_num ( ctx : context ) ( no : Z3native.ptr ) = + RatNum(create_real_expr ctx no) + (** Create a new integer sort. *) let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#cnstr_obj (Z3native.mk_int_sort (context_gno ctx)) + (new int_sort ctx)#create_obj (Z3native.mk_int_sort (context_gno ctx)) (** Create a real sort. *) let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#cnstr_obj (Z3native.mk_real_sort (context_gno ctx)) + (new real_sort ctx)#create_obj (Z3native.mk_real_sort (context_gno ctx)) (** Indicates whether the term is of integer sort. @@ -2802,11 +2820,11 @@ struct (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_numerator x#gnc x#gno) + (new int_num x#gc)#create_obj (Z3native.get_numerator x#gnc x#gno) (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = - (new int_num x#gc)#cnstr_obj (Z3native.get_denominator x#gnc x#gno) + (new int_num x#gc)#create_obj (Z3native.get_denominator x#gnc x#gno) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2844,75 +2862,92 @@ struct Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (astaton t)) :> arith_expr) + (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - (create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) t#gno) :> arith_expr) + ArithExpr(create ctx (Z3native.mk_unary_minus (context_gno ctx) + (gno (match t with ArithExpr(b) -> b)))) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - (create_expr ctx (Z3native.mk_div (context_gno ctx) t1#gno t2#gno) :> arith_expr) + ArithExpr(create ctx (Z3native.mk_div (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 mod t2. The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_mod (context_gno ctx) t1#gno t2#gno) + IntExpr(create ctx (Z3native.mk_mod (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_rem (context_gno ctx) t1#gno t2#gno) + IntExpr(create ctx (Z3native.mk_rem (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 ^ t2. *) - let mk_Power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (create_expr ctx (Z3native.mk_power (context_gno ctx) t1#gno t2#gno) :> arith_expr) + let mk_power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + ArithExpr(create_expr ctx (Z3native.mk_power (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_lt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_lt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_le (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_le (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_gt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_gt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_ge (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_ge (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Coerce an integer to a real. @@ -2925,7 +2960,8 @@ struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - (new real_expr ctx)#cnstr_obj (Z3native.mk_int2real (context_gno ctx) t#gno) + RealExpr(create (Z3native.mk_int2real (context_gno ctx) + (gno (match t with BoolExpr(b) -> b)))) (** Coerce a real to an integer. @@ -2935,14 +2971,14 @@ struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_real2int (context_gno ctx) t#gno) + (new int_expr ctx)#create_obj (Z3native.mk_real2int (context_gno ctx) t#gno) (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_is_int (context_gno ctx) t#gno) - + BoolExpr(create ctx (Z3native.mk_is_int (context_gno ctx) + (gno (match t with BoolExpr(b) -> b)))) (** Return a upper bound for a given real algebraic number. The interval isolating the number is smaller than 1/10^. @@ -2951,7 +2987,7 @@ struct @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) + (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) (** Return a lower bound for the given real algebraic number. @@ -2961,7 +2997,7 @@ struct @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = - (new rat_num x#gc)#cnstr_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) + (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2981,7 +3017,7 @@ struct raise (Z3native.Exception "Denominator is zero") else - (new rat_num ctx)#cnstr_obj (Z3native.mk_real (context_gno ctx) num den) + (new rat_num ctx)#create_obj (Z3native.mk_real (context_gno ctx) num den) (** Create a real numeral. @@ -2989,7 +3025,7 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_s ( ctx : context ) ( v : string ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) + (new rat_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create a real numeral. @@ -2998,14 +3034,14 @@ struct @return A Term with value and sort Real *) let mk_real_numeral_i ( ctx : context ) ( v : int ) = - (new rat_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) + (new rat_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) (** Create an integer numeral. @param v A string representing the Term value in decimal notation. *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) + (new int_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) (** Create an integer numeral. @@ -3013,7 +3049,7 @@ struct @return A Term with value and sort Integer *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - (new int_num ctx)#cnstr_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) + (new int_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno @@ -3021,13 +3057,30 @@ end (** Functions to manipulate bit-vector expressions *) -module BitVectors = -struct +and BitVectors : +sig + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val create_expr : context -> Z3native.ptr -> bitvec_expr + val create_num : context -> Z3native.ptr -> bitvec_num +end = struct + type bitvec_expr = Expr of Expr.expr + type bitvec_num = BitVecExpr of bitvec_expr + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (Expr.create ctx no) in + BitVecExpr(e) + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + let e = (create_expr ctx no) in + BitVecNum(e) + (** Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - (new bitvec_sort ctx)#cnstr_obj (Z3native.mk_bv_sort (context_gno ctx) size) + (new bitvec_sort ctx)#create_obj (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. @@ -3328,91 +3381,91 @@ struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) (** Unsigned division. @@ -3424,7 +3477,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) (** Signed division. @@ -3439,7 +3492,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) (** Unsigned remainder. @@ -3449,7 +3502,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) (** Signed remainder. @@ -3461,7 +3514,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) (** Two's complement signed remainder (sign follows divisor). @@ -3470,7 +3523,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) (** Unsigned less-than @@ -3478,7 +3531,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvult (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvult (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed less-than @@ -3486,7 +3541,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvslt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvslt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Unsigned less-than or equal to. @@ -3494,7 +3551,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvule (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvule (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed less-than or equal to. @@ -3502,7 +3561,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsle (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsle (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Unsigned greater than or equal to. @@ -3510,7 +3571,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvuge (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvuge (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed greater than or equal to. @@ -3518,7 +3581,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsge (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsge (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Unsigned greater-than. @@ -3526,7 +3591,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvugt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvugt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Two's complement signed greater-than. @@ -3534,7 +3601,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsgt (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsgt (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Bit-vector concatenation. @@ -3545,7 +3614,9 @@ struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_concat (context_gno ctx) t1#gno t2#gno) + BitVectors.BitVecExpr(create ctx (Z3native.mk_concat (context_gno ctx) + (gno (match t1 with BitVecExpr(b) -> b)) + (gno (match t2 with BitVecExpr(b) -> b)))) (** Bit-vector extraction. @@ -3556,7 +3627,7 @@ struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) + (new bitvec_expr ctx)#create_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) (** Bit-vector sign extension. @@ -3566,7 +3637,7 @@ struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_sign_ext (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_sign_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) (** Bit-vector zero extension. @@ -3577,7 +3648,7 @@ struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_zero_ext (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_zero_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) (** Bit-vector repetition. @@ -3585,7 +3656,7 @@ struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_repeat (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_repeat (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) (** Shift left. @@ -3600,7 +3671,9 @@ struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvshl (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_bvshl (context_gno ctx) + (gno (match t1 with BitVecExpr(b) -> b)) + (gno (match t2 with BitVecExpr(b) -> b)))) (** Logical shift right @@ -3614,7 +3687,9 @@ struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvlshr (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_bvlshr (context_gno ctx) + (gno (match t1 with BitVecExpr(b) -> b)) + (gno (match t2 with BitVecExpr(b) -> b)))) (** Arithmetic shift right @@ -3630,7 +3705,9 @@ struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_bvashr (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_bvashr (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Rotate Left. @@ -3639,7 +3716,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_left (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_rotate_left (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) (** Rotate Right. @@ -3648,7 +3725,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_rotate_right (context_gno ctx) i t#gno) + BitVecExpr(create ctx (Z3native.mk_rotate_right (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) (** Rotate Left. @@ -3657,7 +3734,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_left (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_ext_rotate_left (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Rotate Right. @@ -3667,7 +3746,9 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_ext_rotate_right (context_gno ctx) t1#gno t2#gno) + BitVecExpr(create ctx (Z3native.mk_ext_rotate_right (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create an bit bit-vector from the integer argument . @@ -3680,7 +3761,7 @@ struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - (new bitvec_expr ctx)#cnstr_obj (Z3native.mk_int2bv (context_gno ctx) n t#gno) + BitVecExpr(create ctx (Z3native.mk_int2bv (context_gno ctx) n (gno (match t with IntExpr(b) -> b)))) (** Create an integer from the bit-vector argument . @@ -3698,7 +3779,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#cnstr_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) + (new int_expr ctx)#create_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3706,7 +3787,10 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_overflow (context_gno ctx) t1#gno t2#gno signed) + BoolExpr(create ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)) + signed)) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3714,23 +3798,30 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvadd_no_underflow (context_gno ctx) t1#gno t2#gno) - + BoolExpr(create ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) + (** Create a predicate that checks that the bit-wise subtraction does not overflow. The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_overflow (context_gno ctx) t1#gno t2#gno) - + BoolExpr(create ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) + (** Create a predicate that checks that the bit-wise subtraction does not underflow. The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsub_no_underflow (context_gno ctx) t1#gno t2#gno signed) + BoolExpr(create ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)) + signed)) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3738,7 +3829,9 @@ struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3746,7 +3839,7 @@ struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvneg_no_overflow (context_gno ctx) t#gno) + BoolExpr(create ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (gno (match t with BitVecExpr(b) -> b)))) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3754,7 +3847,10 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_overflow (context_gno ctx) t1#gno t2#gno signed) + BoolExpr(create ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)) + signed)) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3762,7 +3858,9 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bool_expr ctx)#cnstr_obj (Z3native.mk_bvmul_no_underflow (context_gno ctx) t1#gno t2#gno) + BoolExpr(create ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) + (gno (match t1 with BoolExpr(b) -> b)) + (gno (match t2 with BoolExpr(b) -> b)))) (** Create a bit-vector numeral. @@ -3771,12 +3869,13 @@ struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = - (new bitvec_num ctx)#cnstr_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) + (new bitvec_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) end (** Functions to manipulate proof expressions *) -module Proofs = -struct +and Proofs : +sig +end = struct (** Indicates whether the term is a Proof for the expression 'true'. *) @@ -4259,13 +4358,13 @@ struct type goal = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : goal = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.goal_inc_ref ; dec_ref = Z3native.goal_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4318,7 +4417,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new bool_expr (z3obj_gc x))#create_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) @@ -4334,7 +4433,7 @@ struct (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = - cnstr to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) let simplify ( x : goal ) ( p : Params.params option ) = @@ -4352,7 +4451,7 @@ struct Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; Z3native.tactic_dec_ref (z3obj_gnc x) tn ; - cnstr (z3obj_gc x) res + create (z3obj_gc x) res (** @@ -4365,7 +4464,7 @@ struct @param proofs Indicates whether proof generation should be enabled. *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - cnstr ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) + create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) @@ -4380,13 +4479,13 @@ struct type model = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.model_inc_ref ; dec_ref = Z3native.model_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4400,13 +4499,13 @@ struct type func_interp = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_interp = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.func_interp_inc_ref ; dec_ref = Z3native.func_interp_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4419,13 +4518,13 @@ struct type func_entry = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.func_entry_inc_ref ; dec_ref = Z3native.func_entry_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4467,7 +4566,7 @@ struct *) let get_entries ( x : func_interp ) = let n = (get_num_entries x) in - let f i = (FuncEntry.cnstr (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4534,11 +4633,11 @@ struct raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x ((new func_decl f#gc)#cnstr_obj fd) + get_func_interp x ((new func_decl f#gc)#create_obj fd) | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in - if (Z3native.is_null n) then None else Some (FuncInterp.cnstr (z3obj_gc x) n) + if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) (** The number of constants that have an interpretation in the model. *) let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) @@ -4546,7 +4645,7 @@ struct (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f @@ -4556,15 +4655,15 @@ struct (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in - let f i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = (new func_decl (z3obj_gc x))#cnstr_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) @@ -4619,7 +4718,7 @@ struct An array of expressions, where each is an element of the universe of *) let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in + let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f @@ -4644,13 +4743,13 @@ struct type probe = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : probe = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.probe_inc_ref ; dec_ref = Z3native.probe_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4686,48 +4785,48 @@ struct Creates a new Probe. *) let mk_probe ( ctx : context ) ( name : string ) = - (cnstr ctx (Z3native.mk_probe (context_gno ctx) name)) + (create ctx (Z3native.mk_probe (context_gno ctx) name)) (** Create a probe that always evaluates to . *) let const ( ctx : context ) ( v : float ) = - (cnstr ctx (Z3native.probe_const (context_gno ctx) v)) + (create ctx (Z3native.probe_const (context_gno ctx) v)) (** Create a probe that evaluates to "true" when the value returned by is less than the value returned by *) let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is greater than the value returned by *) let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is less than or equal the value returned by *) let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is greater than or equal the value returned by *) let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value returned by is equal to the value returned by *) let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value @@ -4735,7 +4834,7 @@ struct *) (* CMW: and is a keyword *) let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value @@ -4743,7 +4842,7 @@ struct *) (* CMW: or is a keyword *) let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (cnstr ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) (** Create a probe that evaluates to "true" when the value @@ -4751,7 +4850,7 @@ struct *) (* CMW: is not a keyword? *) let not_ ( ctx : context ) ( p : probe ) = - (cnstr ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) + (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) end @@ -4767,13 +4866,13 @@ struct type tactic = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : tactic = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.tactic_inc_ref ; dec_ref = Z3native.tactic_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4786,13 +4885,13 @@ struct type apply_result = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : apply_result = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.apply_result_inc_ref ; dec_ref = Z3native.apply_result_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -4803,19 +4902,19 @@ struct (** Retrieves the subgoals from the apply_result. *) let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in - let f i = Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** Retrieves the subgoals from the apply_result. *) let get_subgoal ( x : apply_result ) ( i : int ) = - Goal.cnstr (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) (** Convert a model for the subgoal into a model for the original goal g, that the ApplyResult was obtained from. #return A model for g *) let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.cnstr (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) + Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) (** A string representation of the ApplyResult. *) let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) @@ -4826,13 +4925,13 @@ struct (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.create (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with - | None -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) - | Some (pn) -> (ApplyResult.cnstr (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) + | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) + | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) (** The number of supported tactics. @@ -4858,7 +4957,7 @@ struct Creates a new Tactic. *) let mk_tactic ( ctx : context ) ( name : string ) = - cnstr ctx (Z3native.mk_tactic (context_gno ctx) name) + create ctx (Z3native.mk_tactic (context_gno ctx) name) (** Create a tactic that applies to a Goal and @@ -4870,17 +4969,17 @@ struct | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in match (Array.fold_left f None ts) with | None -> - cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) | Some(x) -> let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in - cnstr ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) (** Create a tactic that first applies to a Goal and if it fails then returns the result of applied to the Goal. *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - cnstr ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that applies to a goal for milliseconds. @@ -4888,7 +4987,7 @@ struct If does not terminate within milliseconds, then it fails. *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - cnstr ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) + create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) (** Create a tactic that applies to a given goal if the probe @@ -4898,52 +4997,52 @@ struct *) (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - cnstr ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) + create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - cnstr ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** Create a tactic that keeps applying until the goal is not modified anymore or the maximum number of iterations is reached. *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - cnstr ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) + create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) (** Create a tactic that just returns the given goal. *) let skip ( ctx : context ) = - cnstr ctx (Z3native.tactic_skip (context_gno ctx)) + create ctx (Z3native.tactic_skip (context_gno ctx)) (** Create a tactic always fails. *) let fail ( ctx : context ) = - cnstr ctx (Z3native.tactic_fail (context_gno ctx)) + create ctx (Z3native.tactic_fail (context_gno ctx)) (** Create a tactic that fails if the probe evaluates to false. *) let fail_if ( ctx : context ) ( p : Probe.probe ) = - cnstr ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) + create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) or trivially unsatisfiable (i.e., contains `false'). *) let fail_if_not_decided ( ctx : context ) = - cnstr ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) + create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) (** Create a tactic that applies using the given set of parameters . *) let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - cnstr ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) + create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . @@ -4956,14 +5055,14 @@ struct Create a tactic that applies the given tactics in parallel. *) let par_or ( ctx : context ) ( t : tactic array ) = - cnstr ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) + create ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) (** Create a tactic that applies to a given goal and then to every subgoal produced by . The subgoals are processed in parallel. *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - cnstr ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) (** Interrupt the execution of a Z3 procedure. @@ -4980,13 +5079,13 @@ struct type solver = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.solver_inc_ref ; dec_ref = Z3native.solver_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -5003,13 +5102,13 @@ struct type statistics = z3_native_object (**/**) - let cnstr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.stats_inc_ref ; dec_ref = Z3native.stats_dec_ref } in (z3obj_sno res ctx no) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -5028,7 +5127,7 @@ struct mutable m_float : float } (**/**) - let cnstr_si k v = + let create_si k v = let res : statistics_entry = { m_key = k ; m_is_int = true ; @@ -5038,7 +5137,7 @@ struct } in res - let cnstr_sd k v = + let create_sd k v = let res : statistics_entry = { m_key = k ; m_is_int = false ; @@ -5089,9 +5188,9 @@ struct let f i = ( let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - (Entry.cnstr_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - (Entry.cnstr_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in Array.init n f @@ -5126,7 +5225,7 @@ struct Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.create (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). @@ -5200,7 +5299,7 @@ struct The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -5208,9 +5307,9 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = ((new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get a i)#gno) in + let f i = ((new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get a i)#gno) in Array.init n f (** @@ -5225,7 +5324,7 @@ struct if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (astaton assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (AST.aton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -5243,7 +5342,7 @@ struct if (Z3native.is_null q) then None else - Some (Model.cnstr (z3obj_gc x) q) + Some (Model.create (z3obj_gc x) q) (** The proof of the last Check. @@ -5266,7 +5365,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.cnstr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -5281,7 +5380,7 @@ struct Solver statistics. *) let get_statistics ( x : solver ) = - (Statistics.cnstr (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) + (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) (** Creates a new (incremental) solver. @@ -5292,8 +5391,8 @@ struct *) let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with - | None -> (cnstr ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (cnstr ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) + | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) (** Creates a new (incremental) solver. @@ -5306,7 +5405,7 @@ struct Creates a new (incremental) solver. *) let mk_simple_solver ( ctx : context ) = - (cnstr ctx (Z3native.mk_simple_solver (context_gno ctx))) + (create ctx (Z3native.mk_simple_solver (context_gno ctx))) (** Creates a solver that is implemented using the given tactic. @@ -5315,7 +5414,7 @@ struct will always solve each check from scratch. *) let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = - (cnstr ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) + (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** A string representation of the solver. @@ -5330,13 +5429,13 @@ struct type fixedpoint = z3_native_object (**/**) - let cnstr ( ctx : context ) = + let create ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.fixedpoint_inc_ref ; dec_ref = Z3native.fixedpoint_dec_ref } in (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; - (z3obj_cnstr res) ; + (z3obj_create res) ; res (**/**) @@ -5356,7 +5455,7 @@ struct Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.create (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. @@ -5487,30 +5586,30 @@ struct Convert benchmark given as set of axioms, rules and queries to a string. *) let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (astaton queries) + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (AST.aton queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.cnstr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#cnstr_obj (AST.ASTVector.get v i)#gno in + let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in Array.init n f (** Create a Fixedpoint context. *) - let mk_fixedpoint ( ctx : context ) = cnstr ctx + let mk_fixedpoint ( ctx : context ) = create ctx end (** Global and context options @@ -5590,7 +5689,7 @@ struct *) let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (astaton assumptions) + (Array.length assumptions) (AST.aton assumptions) formula#gno (** @@ -5613,7 +5712,7 @@ struct Z3native.parse_smtlib_string (context_gno ctx) str cs (Symbol.aton sort_names) - (astaton sorts) + (AST.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) @@ -5633,7 +5732,7 @@ struct Z3native.parse_smtlib_file (context_gno ctx) file_name cs (Symbol.aton sort_names) - (astaton sorts) + (AST.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) @@ -5675,7 +5774,7 @@ struct *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = (new func_decl ctx)#cnstr_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in + let f i = (new func_decl ctx)#create_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** @@ -5708,7 +5807,7 @@ struct Z3native.parse_smtlib2_string (context_gno ctx) str cs (Symbol.aton sort_names) - (astaton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) @@ -5728,7 +5827,7 @@ struct Z3native.parse_smtlib2_string (context_gno ctx) file_name cs (Symbol.aton sort_names) - (astaton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) (func_declaton decls) From 12afbfe6dbc5a74f5fd036bd3c97e20a25a4fcdf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 4 Feb 2013 23:18:55 +0000 Subject: [PATCH 391/507] Checkpoint. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 643 ++++++++++++++++++++++++++--------------------- 1 file changed, 355 insertions(+), 288 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0e47912ae..58c319d4d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1097,6 +1097,7 @@ sig val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val get_func_decl : expr -> FuncDecl.func_decl + val is_numeral : expr -> bool end = struct type expr = Expr of AST.ast @@ -1107,20 +1108,20 @@ end = struct let s = Z3native.get_sort (context_gno ctx) obj in let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (match (Arithmetic.create_algebraic_num ctx obj) with Arithmetic.AlgebraicNum(Arithmetic.Expr(e)) -> e) + (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.Expr(e)) -> e) else if (Z3native.is_numeral_ast (context_gno ctx) obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with - | INT_SORT -> (match (Arithmetic.create_int_num ctx obj) with Arithmetic.IntNum(Arithmetic.IntExpr(Arithmetic.Expr(e))) -> e) - | REAL_SORT -> (match (Arithmetic.create_rat_num ctx obj) with Arithmetic.RatNum(Arithmetic.RealExpr(Arithmetic.Expr(e))) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.Expr(e))) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.Expr(e))) -> e) | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) | _ -> raise (Z3native.Exception "Unsupported numeral object") else match sk with - | BOOL_SORT -> (match (Booleans.create ctx obj) with Booleans.BoolExpr(e) -> e) - | INT_SORT -> (match (Arithmetic.create_int_expr ctx obj) with Arithmetic.IntExpr(Arithmetic.Expr(e)) -> e) - | REAL_SORT -> (match (Arithmetic.create_real_expr ctx obj) with Arithmetic.RealExpr(Arithmetic.Expr(e)) -> e) + | BOOL_SORT -> (match (Booleans.create_expr ctx obj) with Booleans.BoolExpr(e) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.Expr(e)) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.Expr(e)) -> e) | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) @@ -1406,16 +1407,20 @@ sig type bool_expr = BoolExpr of Expr.expr type bool_sort = BoolSort of Sort.sort - val create : context -> Z3native.ptr -> bool_expr + val create_expr : context -> Z3native.ptr -> bool_expr + val create_sort : context -> Z3native.ptr -> bool_sort val aton : bool_expr array -> Z3native.ptr array end = struct type bool_expr = BoolExpr of Expr.expr type bool_sort = BoolSort of Sort.sort - let create ( ctx : context ) ( no : Z3native.ptr ) = + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let a = (AST.create ctx no) in BoolExpr(Expr.Expr(a)) + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + BoolSort(Sort.create ctx no) + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gc e) let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gnc e) let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gno e) @@ -1444,13 +1449,13 @@ end = struct The true Term. *) let mk_true ( ctx : context ) = - create ctx (Z3native.mk_true (context_gno ctx)) + create_expr ctx (Z3native.mk_true (context_gno ctx)) (** The false Term. *) let mk_false ( ctx : context ) = - create ctx (Z3native.mk_false (context_gno ctx)) + create_expr ctx (Z3native.mk_false (context_gno ctx)) (** Creates a Boolean value. @@ -1462,19 +1467,19 @@ end = struct Creates the equality = . *) let mk_eq ( ctx : context ) ( x : Expr.expr ) ( y : Expr.expr ) = - create ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + create_expr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) (** Creates a distinct term. *) let mk_distinct ( ctx : context ) ( args : Expr.expr array ) = - create ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) + create_expr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) (** Mk an expression representing not(a). *) let mk_not ( ctx : context ) ( a : bool_expr ) = - create ctx (Z3native.mk_not (context_gno ctx) (gno a)) + create_expr ctx (Z3native.mk_not (context_gno ctx) (gno a)) (** Create an expression representing an if-then-else: ite(t1, t2, t3). @@ -1483,36 +1488,36 @@ end = struct @param t3 An expression with the same sort as *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + create_expr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) (** Create an expression representing t1 iff t2. *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + create_expr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 -> t2. *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + create_expr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 xor t2. *) let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + create_expr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing the AND of args *) let mk_and ( ctx : context ) ( args : bool_expr array ) = - create ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) + create_expr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) (** Create an expression representing the OR of args *) let mk_or ( ctx : context ) ( args : bool_expr array ) = - create ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) + create_expr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) end (** Quantifier expressions *) @@ -1676,7 +1681,7 @@ end = struct The body of the quantifier. *) let get_body ( x : quantifier ) = - Booleans.create (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + Booleans.create_expr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) (** Creates a new bound variable. @@ -2643,416 +2648,478 @@ end and Arithmetic : sig type arith_sort = ArithSort of Sort.sort - type int_sort = IntSort of Sort.sort - type real_sort = RealSort of Sort.sort - type arith_expr = Expr of Expr.expr - type int_expr = IntExpr of arith_expr - type real_expr = RealExpr of arith_expr - - type int_num = IntNum of int_expr - type rat_num = RatNum of real_expr - type algebraic_num = AlgebraicNum of arith_expr - - val create_arith_expr : context -> Z3native.ptr -> arith_expr - val create_int_expr : context -> Z3native.ptr -> int_expr - val create_real_expr : context -> Z3native.ptr -> real_expr - val create_int_num : context -> Z3native.ptr -> int_num - val create_rat_num : context -> Z3native.ptr -> rat_num - val create_algebraic_num : context -> Z3native.ptr -> algebraic_num + val create_expr : context -> Z3native.ptr -> arith_expr + val aton : arith_expr array -> Z3native.ptr array + + module Integers : sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val create_sort : context -> Z3native.ptr -> int_sort + val create_expr : context -> Z3native.ptr -> int_expr + val create_num : context -> Z3native.ptr -> int_num + end + + module Reals : sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val create_sort : context -> Z3native.ptr -> real_sort + val create_expr : context -> Z3native.ptr -> real_expr + val create_num : context -> Z3native.ptr -> rat_num + end + + module AlgebraicNumbers : sig + type algebraic_num = AlgebraicNum of arith_expr + + val create_num : context -> Z3native.ptr -> algebraic_num + end + end = struct type arith_sort = ArithSort of Sort.sort - type int_sort = IntSort of Sort.sort - type real_sort = RealSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - type int_expr = IntExpr of arith_expr - type real_expr = RealExpr of arith_expr - - type int_num = IntNum of int_expr - type rat_num = RatNum of real_expr - type algebraic_num = AlgebraicNum of arith_expr let create_arith_expr ( ctx : context ) ( no : Z3native.ptr ) = ArithExpr(Expr.create ctx no) - let create_int_expr ( ctx : context ) ( no : Z3native.ptr ) = - IntExpr(create_arith_expr ctx no) + let create_arith_sort ( ctx : context ) ( no : Z3native.ptr ) = + ArithSort(Sort.create ctx no) - let create_real_expr ( ctx : context ) ( no : Z3native.ptr ) = - RealExpr(create_arith_expr ctx no) + let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gc s) + let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gnc s) + let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gno s) + let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) + let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) + let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) - let create_int_num ( ctx : context ) ( no : Z3native.ptr ) = - IntNum(create_int_expr ctx no) - let create_rat_num ( ctx : context ) ( no : Z3native.ptr ) = - RatNum(create_real_expr ctx no) - - (** - Create a new integer sort. - *) - let mk_int_sort ( ctx : context ) = - (new int_sort ctx)#create_obj (Z3native.mk_int_sort (context_gno ctx)) + module rec Integers : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr - (** - Create a real sort. - *) - let mk_real_sort ( ctx : context ) = - (new real_sort ctx)#create_obj (Z3native.mk_real_sort (context_gno ctx)) + val create_sort : context -> Z3native.ptr -> int_sort + val create_expr : context -> Z3native.ptr -> int_expr + val create_num : context -> Z3native.ptr -> int_num + end = struct + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + IntSort(create_arith_sort ctx no) + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + IntExpr(create_arith_expr ctx no) + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + IntNum(create_expr ctx no) + + let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) + let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) + let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) + let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) + let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) + let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) + let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) + let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) + let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) + + (** Create a new integer sort. *) + let mk_sort ( ctx : context ) = + create_sort ctx (Z3native.mk_int_sort (context_gno ctx)) + + (** Retrieve the int value. *) + let get_int ( x : int_num ) = + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + if r then v + else raise (Z3native.Exception "Conversion failed.") + + (** Returns a string representation of the numeral. *) + let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + (** + Creates an integer constant. + *) + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) + + (** + Creates an integer constant. + *) + let mk_int_const_s ( ctx : context ) ( name : string ) = + mk_int_const ctx (Symbol.mk_string ctx name) + + (** + Create an expression representing t1 mod t2. + The arguments must have int type. + *) + let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + create_expr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + + (** + Create an expression representing t1 rem t2. + The arguments must have int type. + *) + let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + create_expr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + + (** + Create an integer numeral. + @param v A string representing the Term value in decimal notation. + *) + let mk_int_numeral_s ( ctx : context ) ( v : string ) = + create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + (** + Create an integer numeral. + @param v value of the numeral. + @return A Term with value and sort Integer + *) + let mk_int_numeral_i ( ctx : context ) ( v : int ) = + create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + (** + Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. + *) + let mk_int2real ( ctx : context ) ( t : int_expr ) = + Reals.create_expr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)) + end + + and Reals : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val create_sort : context -> Z3native.ptr -> real_sort + val create_expr : context -> Z3native.ptr -> real_expr + val create_num : context -> Z3native.ptr -> rat_num + end = struct + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + RealSort(create_arith_sort ctx no) + + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + RealExpr(create_arith_expr ctx no) + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + RatNum(create_expr ctx no) + + let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) + let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) + let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) + let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) + let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) + let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) + let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) + let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) + let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) + + (** Create a real sort. *) + let mk_sort ( ctx : context ) = + create_sort ctx (Z3native.mk_real_sort (context_gno ctx)) + + (** The numerator of a rational numeral. *) + let get_numerator ( x : rat_num ) = + Integers.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + + (** The denominator of a rational numeral. *) + let get_denominator ( x : rat_num ) = + Integers.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : rat_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + (** Creates a real constant. *) + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) + + (** Creates a real constant. *) + let mk_real_const_s ( ctx : context ) ( name : string ) = + mk_real_const ctx (Symbol.mk_string ctx name) + + (** + Create a real from a fraction. + + @param num numerator of rational. + @param den denominator of rational. + @return A Term with value / and sort Real + + *) + let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + if (den == 0) then + raise (Z3native.Exception "Denominator is zero") + else + create_num ctx (Z3native.mk_real (context_gno ctx) num den) + + (** + Create a real numeral. + @param v A string representing the Term value in decimal notation. + @return A Term with value and sort Real + *) + let mk_numeral_s ( ctx : context ) ( v : string ) = + create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + (** + Create a real numeral. + + @param v value of the numeral. + @return A Term with value and sort Real + *) + let mk_numeral_i ( ctx : context ) ( v : int ) = + create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + (** Creates an expression that checks whether a real number is an integer. *) + let mk_is_integer ( ctx : context ) ( t : real_expr ) = + Booleans.create_expr ctx (Z3native.mk_is_int (context_gno ctx) (egno t)) + + (** + Coerce a real to an integer. + + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. + *) + let mk_real2int ( ctx : context ) ( t : real_expr ) = + Integers.create_expr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)) + end + + and AlgebraicNumbers : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val create_num : context -> Z3native.ptr -> algebraic_num + end = struct + type algebraic_num = AlgebraicNum of arith_expr + + let create_num ( ctx : context ) ( no : Z3native.ptr ) = + AlgebraicNum(create_arith_expr ctx no) + + let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) + let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) + let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) + + (** + Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_upper ( x : algebraic_num ) ( precision : int ) = + Reals.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + + (** + Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^. + + @param precision the precision of the result + @return A numeral Expr of sort Real + *) + let to_lower ( x : algebraic_num ) precision = + Reals.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + + (** Returns a string representation in decimal notation. + The result has at most decimal places.*) + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + (** Returns a string representation of the numeral. *) + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + end + + let aton (a : arith_expr array) = + let f (e : arith_expr) = (egno e) in + Array.map f a (** Indicates whether the term is of integer sort. *) - let is_int ( x : expr ) = - (Z3native.is_numeral_ast x#gnc x#gno) && - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == INT_SORT) + let is_int ( x : Expr.expr ) = + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) (** Indicates whether the term is an arithmetic numeral. *) - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + let is_arithmetic_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) (** Indicates whether the term is a less-than-or-equal *) - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + let is_le ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) (** Indicates whether the term is a greater-than-or-equal *) - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + let is_ge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) (** Indicates whether the term is a less-than *) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) (** Indicates whether the term is a greater-than *) - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + let is_gt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) (** Indicates whether the term is addition (binary) *) - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + let is_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) (** Indicates whether the term is subtraction (binary) *) - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + let is_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) (** Indicates whether the term is a unary minus *) - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + let is_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) (** Indicates whether the term is multiplication (binary) *) - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + let is_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) (** Indicates whether the term is division (binary) *) - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + let is_div ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) (** Indicates whether the term is integer division (binary) *) - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + let is_idiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) (** Indicates whether the term is remainder (binary) *) - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + let is_remainder ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) (** Indicates whether the term is modulus (binary) *) - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + let is_modulus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) (** Indicates whether the term is a coercion of integer to real (unary) *) - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_inttoreal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) (** Indicates whether the term is a coercion of real to integer (unary) *) - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + let is_real_is_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) (** Indicates whether the term is of sort real. *) - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == REAL_SORT) + let is_real ( x : Expr.expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) (** Indicates whether the term is an integer numeral. *) - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + let is_int_numeral ( x : Expr.expr ) = (Expr.is_numeral x) && (is_int x) (** Indicates whether the term is a real numeral. *) - let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) + let is_rat_num ( x : Expr.expr ) = (Expr.is_numeral x) && (is_real x) (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number x#gnc x#gno - - (** Retrieve the int value. *) - let get_int ( x : int_num ) = - let (r, v) = Z3native.get_numeral_int x#gnc x#gno in - if r then v - else raise (Z3native.Exception "Conversion failed.") - - (** Returns a string representation of the numeral. *) - let to_string ( x : int_num ) = Z3native.get_numeral_string x#gnc x#gno - - (** The numerator of a rational numeral. *) - let get_numerator ( x : rat_num ) = - (new int_num x#gc)#create_obj (Z3native.get_numerator x#gnc x#gno) - - (** The denominator of a rational numeral. *) - let get_denominator ( x : rat_num ) = - (new int_num x#gc)#create_obj (Z3native.get_denominator x#gnc x#gno) - - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : rat_num ) (precision : int) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision - - (** Returns a string representation of the numeral. *) - let to_string ( x : rat_num ) = Z3native.get_numeral_string x#gnc x#gno - - (** - Creates an integer constant. - *) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = - ((Expr.mk_const ctx name (mk_int_sort ctx)) :> int_expr) - - (** - Creates an integer constant. - *) - let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx (Symbol.mk_string ctx name) - - (** - Creates a real constant. - *) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = - ((Expr.mk_const ctx name (mk_real_sort ctx)) :> real_expr) - - (** - Creates a real constant. - *) - let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx (Symbol.mk_string ctx name) + let is_algebraic_number ( x : Expr.expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) (** Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) + Arithmetic.create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Arithmetic.aton t)) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) + Arithmetic.create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Arithmetic.aton t)) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - (create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (AST.aton t)) :> arith_expr) + Arithmetic.create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Arithmetic.aton t)) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - ArithExpr(create ctx (Z3native.mk_unary_minus (context_gno ctx) - (gno (match t with ArithExpr(b) -> b)))) + Arithmetic.create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t)) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - ArithExpr(create ctx (Z3native.mk_div (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Create an expression representing t1 mod t2. - The arguments must have int type. - *) - let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - IntExpr(create ctx (Z3native.mk_mod (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Create an expression representing t1 rem t2. - The arguments must have int type. - *) - let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - IntExpr(create ctx (Z3native.mk_rem (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Arithmetic.create_expr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 ^ t2. *) - let mk_power ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - ArithExpr(create_expr ctx (Z3native.mk_power (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Arithmetic.create_expr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 < t2 *) - let mk_lt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_lt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 <= t2 *) - let mk_le ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_le (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 > t2 *) - let mk_gt ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_gt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 >= t2 *) - let mk_ge ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - BoolExpr(create ctx (Z3native.mk_ge (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. - *) - let mk_int2real ( ctx : context ) ( t : int_expr ) = - RealExpr(create (Z3native.mk_int2real (context_gno ctx) - (gno (match t with BoolExpr(b) -> b)))) - - (** - Coerce a real to an integer. - - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. - *) - let mk_real2int ( ctx : context ) ( t : real_expr ) = - (new int_expr ctx)#create_obj (Z3native.mk_real2int (context_gno ctx) t#gno) - - (** - Creates an expression that checks whether a real number is an integer. - *) - let mk_is_integer ( ctx : context ) ( t : real_expr ) = - BoolExpr(create ctx (Z3native.mk_is_int (context_gno ctx) - (gno (match t with BoolExpr(b) -> b)))) - (** - Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) - let to_upper ( x : algebraic_num ) ( precision : int ) = - (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_upper x#gnc x#gno precision) - - (** - Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) - let to_lower ( x : algebraic_num ) precision = - (new rat_num x#gc)#create_obj (Z3native.get_algebraic_number_lower x#gnc x#gno precision) - - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string x#gnc x#gno precision - - (** - Create a real from a fraction. - - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - *) - let mk_real_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = - if (den == 0) then - raise (Z3native.Exception "Denominator is zero") - else - - (new rat_num ctx)#create_obj (Z3native.mk_real (context_gno ctx) num den) - - (** - Create a real numeral. - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - *) - let mk_real_numeral_s ( ctx : context ) ( v : string ) = - (new rat_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_real_sort ctx)#gno) - - (** - Create a real numeral. - - @param v value of the numeral. - @return A Term with value and sort Real - *) - let mk_real_numeral_i ( ctx : context ) ( v : int ) = - (new rat_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_real_sort ctx)#gno) - - (** - Create an integer numeral. - @param v A string representing the Term value in decimal notation. - *) - let mk_int_numeral_s ( ctx : context ) ( v : string ) = - (new int_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_int_sort ctx)#gno) - - (** - Create an integer numeral. - @param v value of the numeral. - @return A Term with value and sort Integer - *) - let mk_int_numeral_i ( ctx : context ) ( v : int ) = - (new int_num ctx)#create_obj (Z3native.mk_int (context_gno ctx) v (mk_int_sort ctx)#gno) - - (** Returns a string representation of the numeral. *) - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string x#gnc x#gno + let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Booleans.create_expr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2)) end From 9845c8ee269bf2c8e0c3b32bfcfb3d735e537a8c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 5 Feb 2013 00:19:06 +0000 Subject: [PATCH 392/507] ML API: No more objects; type hierarchy exposed; clean separation into modules. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 691 ++++++++++++++++++++++++----------------------- 1 file changed, 357 insertions(+), 334 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 58c319d4d..4cf41f420 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -334,6 +334,13 @@ sig val create : context -> Z3native.ptr -> ast val aton : ast array -> Z3native.ptr array + module ASTVectors : sig + type ast_vector + val create : context -> Z3native.ptr -> ast_vector + val get_size : ast_vector -> int + val get : ast_vector -> int -> ast + end + val is_expr : ast -> bool val is_var : ast -> bool end = struct @@ -354,7 +361,7 @@ end = struct (** Vectors of ASTs *) - module ASTVector = + module ASTVectors = struct type ast_vector = z3_native_object @@ -401,7 +408,7 @@ end = struct (** Translates all ASTs in the vector to . @param to_ctx A context - @return A new ASTVector + @return A new ASTVectors *) let translate ( x : ast_vector ) ( to_ctx : context ) = create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) @@ -466,7 +473,7 @@ end = struct (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVectors.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = @@ -613,16 +620,15 @@ end and Sort : sig type sort = Sort of AST.ast - type bitvec_sort = BitvecSort of sort type uninterpreted_sort = UninterpretedSort of sort val create : context -> Z3native.ptr -> sort - val gno : sort -> Z3native.ptr + val gc : sort -> context val gnc : sort -> Z3native.ptr + val gno : sort -> Z3native.ptr val aton : sort array -> Z3native.ptr array end = struct type sort = Sort of AST.ast - type bitvec_sort = BitvecSort of sort type uninterpreted_sort = UninterpretedSort of sort let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) @@ -713,11 +719,14 @@ sig type func_decl = FuncDecl of AST.ast val create : context -> Z3native.ptr -> func_decl + val gc : func_decl -> context val gno : func_decl -> Z3native.ptr val gnc : func_decl -> Z3native.ptr + val aton : func_decl array -> Z3native.ptr array val get_domain_size : func_decl -> int val get_decl_kind : func_decl -> Z3enums.decl_kind + val get_arity : func_decl -> int end = struct open Sort @@ -1098,6 +1107,7 @@ sig val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val get_func_decl : expr -> FuncDecl.func_decl val is_numeral : expr -> bool + val to_string : expr -> string end = struct type expr = Expr of AST.ast @@ -1108,20 +1118,20 @@ end = struct let s = Z3native.get_sort (context_gno ctx) obj in let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.Expr(e)) -> e) + (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.ArithExpr(e)) -> e) else if (Z3native.is_numeral_ast (context_gno ctx) obj) && (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then match sk with - | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.Expr(e))) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.Expr(e))) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e))) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e))) -> e) | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) | _ -> raise (Z3native.Exception "Unsupported numeral object") else match sk with | BOOL_SORT -> (match (Booleans.create_expr ctx obj) with Booleans.BoolExpr(e) -> e) - | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.Expr(e)) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.Expr(e)) -> e) + | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e)) -> e) + | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e)) -> e) | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) @@ -1409,6 +1419,9 @@ sig val create_expr : context -> Z3native.ptr -> bool_expr val create_sort : context -> Z3native.ptr -> bool_sort + val gc : bool_expr -> context + val gnc : bool_expr -> Z3native.ptr + val gno : bool_expr -> Z3native.ptr val aton : bool_expr array -> Z3native.ptr array end = struct type bool_expr = BoolExpr of Expr.expr @@ -2648,9 +2661,10 @@ end and Arithmetic : sig type arith_sort = ArithSort of Sort.sort - type arith_expr = Expr of Expr.expr + type arith_expr = ArithExpr of Expr.expr val create_expr : context -> Z3native.ptr -> arith_expr + val create_sort : context -> Z3native.ptr -> arith_sort val aton : arith_expr array -> Z3native.ptr array module Integers : sig @@ -2679,14 +2693,53 @@ sig val create_num : context -> Z3native.ptr -> algebraic_num end + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool + val mk_add : context -> arith_expr array -> Arithmetic.arith_expr + val mk_mul : context -> arith_expr array -> Arithmetic.arith_expr + val mk_sub : context -> arith_expr array -> Arithmetic.arith_expr + val mk_unary_minus : + context -> arith_expr -> Arithmetic.arith_expr + val mk_div : + context -> arith_expr -> arith_expr -> Arithmetic.arith_expr + val mk_power : + context -> arith_expr -> arith_expr -> Arithmetic.arith_expr + val mk_lt : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + val mk_le : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + val mk_gt : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + val mk_ge : + context -> arith_expr -> arith_expr -> Booleans.bool_expr + end = struct type arith_sort = ArithSort of Sort.sort type arith_expr = ArithExpr of Expr.expr - let create_arith_expr ( ctx : context ) ( no : Z3native.ptr ) = + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = ArithExpr(Expr.create ctx no) - let create_arith_sort ( ctx : context ) ( no : Z3native.ptr ) = + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = ArithSort(Sort.create ctx no) let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gc s) @@ -2712,10 +2765,10 @@ end = struct type int_num = IntNum of int_expr let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - IntSort(create_arith_sort ctx no) + IntSort(Arithmetic.create_sort ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - IntExpr(create_arith_expr ctx no) + IntExpr(Arithmetic.create_expr ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = IntNum(create_expr ctx no) @@ -2796,6 +2849,19 @@ end = struct *) let mk_int2real ( ctx : context ) ( t : int_expr ) = Reals.create_expr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)) + + (** + Create an bit bit-vector from the integer argument . + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. + *) + let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = + BitVectors.create_expr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t)) end and Reals : @@ -2813,10 +2879,10 @@ end = struct type rat_num = RatNum of real_expr let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - RealSort(create_arith_sort ctx no) + RealSort(Arithmetic.create_sort ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - RealExpr(create_arith_expr ctx no) + RealExpr(Arithmetic.create_expr ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = RatNum(create_expr ctx no) @@ -2914,7 +2980,7 @@ end = struct type algebraic_num = AlgebraicNum of arith_expr let create_num ( ctx : context ) ( no : Z3native.ptr ) = - AlgebraicNum(create_arith_expr ctx no) + AlgebraicNum(Arithmetic.create_expr ctx no) let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) @@ -3126,316 +3192,330 @@ end (** Functions to manipulate bit-vector expressions *) and BitVectors : sig + type bitvec_sort = BitVecSort of Sort.sort type bitvec_expr = BitVecExpr of Expr.expr type bitvec_num = BitVecNum of bitvec_expr + val create_sort : context -> Z3native.ptr -> bitvec_sort val create_expr : context -> Z3native.ptr -> bitvec_expr val create_num : context -> Z3native.ptr -> bitvec_num end = struct - type bitvec_expr = Expr of Expr.expr - type bitvec_num = BitVecExpr of bitvec_expr + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + BitVecSort(Sort.create ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (Expr.create ctx no) in - BitVecExpr(e) + BitVecExpr(Expr.create ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = - let e = (create_expr ctx no) in - BitVecNum(e) + BitVecNum(create_expr ctx no) + + let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) + let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) + let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) + let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) + let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) + let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) + let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) + let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) + let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) (** Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - (new bitvec_sort ctx)#create_obj (Z3native.mk_bv_sort (context_gno ctx) size) + create_sort ctx (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. *) - let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind x#gnc (Z3native.get_sort x#gnc x#gno))) == BV_SORT) + let is_bv ( x : Expr.expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) (** Indicates whether the term is a bit-vector numeral *) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) (** Indicates whether the term is a one-bit bit-vector with value one *) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit1 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) (** Indicates whether the term is a one-bit bit-vector with value zero *) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_bit0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) (** Indicates whether the term is a bit-vector unary minus *) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) (** Indicates whether the term is a bit-vector addition (binary) *) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) (** Indicates whether the term is a bit-vector subtraction (binary) *) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) (** Indicates whether the term is a bit-vector multiplication (binary) *) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) (** Indicates whether the term is a bit-vector signed division (binary) *) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_sdiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) (** Indicates whether the term is a bit-vector unsigned division (binary) *) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_udiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) (** Indicates whether the term is a bit-vector signed remainder (binary) *) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_SRem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_urem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) (** Indicates whether the term is a bit-vector signed modulus *) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_smod ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) (** Indicates whether the term is a bit-vector signed division by zero *) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_sdiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) (** Indicates whether the term is a bit-vector unsigned division by zero *) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_udiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) (** Indicates whether the term is a bit-vector signed remainder by zero *) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_srem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_urem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) (** Indicates whether the term is a bit-vector signed modulus by zero *) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_smod0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_ule ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_sle ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_uge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_sge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) (** Indicates whether the term is an unsigned bit-vector less-than *) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_ult ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) (** Indicates whether the term is a signed bit-vector less-than *) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_slt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) (** Indicates whether the term is an unsigned bit-vector greater-than *) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_ugt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) (** Indicates whether the term is a signed bit-vector greater-than *) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_sgt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) (** Indicates whether the term is a bit-wise AND *) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_and ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) (** Indicates whether the term is a bit-wise OR *) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_or ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) (** Indicates whether the term is a bit-wise NOT *) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_not ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) (** Indicates whether the term is a bit-wise XOR *) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_xor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) (** Indicates whether the term is a bit-wise NAND *) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) (** Indicates whether the term is a bit-wise NOR *) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_nor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) (** Indicates whether the term is a bit-wise XNOR *) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_xnor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) (** Indicates whether the term is a bit-vector concatenation (binary) *) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_concat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) (** Indicates whether the term is a bit-vector sign extension *) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_signextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) (** Indicates whether the term is a bit-vector zero extension *) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_zeroextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) (** Indicates whether the term is a bit-vector extraction *) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_extract ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) (** Indicates whether the term is a bit-vector repetition *) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_repeat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) (** Indicates whether the term is a bit-vector reduce OR *) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) (** Indicates whether the term is a bit-vector reduce AND *) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_reduceand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) (** Indicates whether the term is a bit-vector comparison *) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_comp ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) (** Indicates whether the term is a bit-vector shift left *) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) (** Indicates whether the term is a bit-vector logical shift right *) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightlogical ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) (** Indicates whether the term is a bit-vector arithmetic shift left *) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_shiftrightarithmetic ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) (** Indicates whether the term is a bit-vector rotate left *) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right *) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateright ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) (** Indicates whether the term is a bit-vector rotate left (extended) Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotateleftextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right (extended) Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_bv_rotaterightextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_int_to_bv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_carry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) (** Indicates whether the term is a bit-vector ternary XOR The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let is_bv_xor3 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) (** The size of a bit-vector sort. *) - let get_size (x : bitvec_sort) = Z3native.get_bv_sort_size x#gnc x#gno + let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = - let (r, v) = Z3native.get_numeral_int x#gnc x#gno in + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in if r then v else raise (Z3native.Exception "Conversion failed.") (** Returns a string representation of the numeral. *) - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string x#gnc x#gno + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) (** Creates a bit-vector constant. *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - ((Expr.mk_const ctx name (mk_sort ctx size)) :> bitvec_expr) + BitVecExpr(Expr.mk_const ctx name (match (mk_sort ctx size) with BitVecSort(s) -> s)) (** Creates a bit-vector constant. @@ -3448,91 +3528,91 @@ end = struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnot (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredand (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvredor (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvand (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnand (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvnor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvxnor (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvneg (context_gno ctx) t#gno) + create_expr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvadd (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsub (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvmul (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) (** Unsigned division. @@ -3544,7 +3624,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvudiv (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) (** Signed division. @@ -3559,7 +3639,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsdiv (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) (** Unsigned remainder. @@ -3569,7 +3649,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvurem (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) (** Signed remainder. @@ -3581,7 +3661,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsrem (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed remainder (sign follows divisor). @@ -3590,7 +3670,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_bvsmod (context_gno ctx) t1#gno t2#gno) + create_expr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than @@ -3598,9 +3678,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvult (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed less-than @@ -3608,9 +3686,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvslt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than or equal to. @@ -3618,9 +3694,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvule (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed less-than or equal to. @@ -3628,9 +3702,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsle (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2)) (** Unsigned greater than or equal to. @@ -3638,19 +3710,15 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvuge (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed greater than or equal to. The arguments must have the same bit-vector sort. *) - let mk_SGE ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsge (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Booleans.create_expr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2)) (** Unsigned greater-than. @@ -3658,9 +3726,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvugt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed greater-than. @@ -3668,9 +3734,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsgt (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector concatenation. @@ -3681,9 +3745,7 @@ end = struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVectors.BitVecExpr(create ctx (Z3native.mk_concat (context_gno ctx) - (gno (match t1 with BitVecExpr(b) -> b)) - (gno (match t2 with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector extraction. @@ -3694,7 +3756,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - (new bitvec_expr ctx)#create_obj (Z3native.mk_extract (context_gno ctx) high low t#gno) + create_expr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) (** Bit-vector sign extension. @@ -3704,7 +3766,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_sign_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) (** Bit-vector zero extension. @@ -3715,7 +3777,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_zero_ext (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) (** Bit-vector repetition. @@ -3723,7 +3785,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_repeat (context_gno ctx) i (gno (match t with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) (** Shift left. @@ -3738,9 +3800,8 @@ end = struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_bvshl (context_gno ctx) - (gno (match t1 with BitVecExpr(b) -> b)) - (gno (match t2 with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + (** Logical shift right @@ -3754,9 +3815,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_bvlshr (context_gno ctx) - (gno (match t1 with BitVecExpr(b) -> b)) - (gno (match t2 with BitVecExpr(b) -> b)))) + create_expr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) (** Arithmetic shift right @@ -3772,9 +3831,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_bvashr (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) (** Rotate Left. @@ -3783,7 +3840,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_rotate_left (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) (** Rotate Right. @@ -3792,7 +3849,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_rotate_right (context_gno ctx) i (gno (match t with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) (** Rotate Left. @@ -3801,9 +3858,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_ext_rotate_left (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + create_expr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) (** Rotate Right. @@ -3813,22 +3868,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BitVecExpr(create ctx (Z3native.mk_ext_rotate_right (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - - (** - Create an bit bit-vector from the integer argument . - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. - *) - let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVecExpr(create ctx (Z3native.mk_int2bv (context_gno ctx) n (gno (match t with IntExpr(b) -> b)))) + create_expr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) (** Create an integer from the bit-vector argument . @@ -3845,8 +3885,8 @@ end = struct The argument must be of bit-vector sort. *) - let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool) = - (new int_expr ctx)#create_obj (Z3native.mk_bv2int (context_gno ctx) t#gno signed) + let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = + Arithmetic.Integers.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3854,10 +3894,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - BoolExpr(create ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)) - signed)) + Booleans.create_expr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3865,19 +3902,15 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) - + Booleans.create_expr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2)) + (** Create a predicate that checks that the bit-wise subtraction does not overflow. The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2)) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3885,10 +3918,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - BoolExpr(create ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)) - signed)) + Booleans.create_expr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3896,17 +3926,15 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2)) (** Create a predicate that checks that the bit-wise negation does not overflow. The arguments must be of bit-vector sort. *) - let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr) = - BoolExpr(create ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (gno (match t with BitVecExpr(b) -> b)))) + let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = + Booleans.create_expr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t)) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3914,10 +3942,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - BoolExpr(create ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)) - signed)) + Booleans.create_expr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3925,9 +3950,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - BoolExpr(create ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) - (gno (match t1 with BoolExpr(b) -> b)) - (gno (match t2 with BoolExpr(b) -> b)))) + Booleans.create_expr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2)) (** Create a bit-vector numeral. @@ -3936,7 +3959,7 @@ end = struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = - (new bitvec_num ctx)#create_obj (Z3native.mk_numeral (context_gno ctx) v (mk_sort ctx size)#gno) + create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx size))) end (** Functions to manipulate proof expressions *) @@ -3946,17 +3969,17 @@ end = struct (** Indicates whether the term is a Proof for the expression 'true'. *) - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) (** Indicates whether the term is a proof for a fact asserted by the user. *) - let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_asserted ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_goal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) (** Indicates whether the term is proof via modus ponens @@ -3967,7 +3990,7 @@ end = struct [mp T1 T2]: q The second antecedents may also be a proof for (iff p q). *) - let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_modus_ponens ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. @@ -3976,7 +3999,7 @@ end = struct equivalence modulo namings, equality and equivalence. That is, R is either '~', '=' or 'iff'. *) - let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_reflexivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) (** Indicates whether the term is proof by symmetricity of a relation @@ -3986,7 +4009,7 @@ end = struct [symmetry T1]: (R s t) T1 is the antecedent of this proof object. *) - let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_symmetry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) (** Indicates whether the term is a proof by transitivity of a relation @@ -3997,7 +4020,7 @@ end = struct T2: (R s u) [trans T1 T2]: (R t u) *) - let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_transitivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) (** Indicates whether the term is a proof by condensed transitivity of a relation @@ -4017,7 +4040,7 @@ end = struct if there is a path from s to t, if we view every antecedent (R a b) as an edge between a and b. *) - let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_Transitivity_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) (** @@ -4030,7 +4053,7 @@ end = struct Remark: if t_i == s_i, then the antecedent Ti is suppressed. That is, reflexivity proofs are supressed to save space. *) - let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_monotonicity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) (** Indicates whether the term is a quant-intro proof @@ -4039,7 +4062,7 @@ end = struct T1: (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_quant_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) (** Indicates whether the term is a distributivity proof object. @@ -4056,7 +4079,7 @@ end = struct Remark. This rule is used by the CNF conversion pass and instantiated by f = or, and g = and. *) - let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_distributivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) (** Indicates whether the term is a proof by elimination of AND @@ -4065,7 +4088,7 @@ end = struct T1: (and l_1 ... l_n) [and-elim T1]: l_i *) - let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_and_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) (** Indicates whether the term is a proof by eliminiation of not-or @@ -4074,7 +4097,7 @@ end = struct T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) *) - let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_or_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) (** Indicates whether the term is a proof by rewriting @@ -4088,11 +4111,11 @@ end = struct Remark: if f is bool, then = is iff. Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) + (= (+ ( x : Expr.expr ) 0) x) + (= (+ ( x : Expr.expr ) 1 2) (+ 3 x)) + (iff (or ( x : Expr.expr ) false) x) *) - let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) (** Indicates whether the term is a proof by rewriting @@ -4107,14 +4130,14 @@ end = struct - When converting bit-vectors to Booleans (BIT2BOOL=true) - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_rewrite_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) (** Indicates whether the term is a proof for pulling quantifiers out. A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) (** Indicates whether the term is a proof for pulling quantifiers out. @@ -4123,7 +4146,7 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object has no antecedents *) - let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_pull_quant_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) (** Indicates whether the term is a proof for pushing quantifiers in. @@ -4136,7 +4159,7 @@ end = struct This proof object has no antecedents *) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_push_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) (** Indicates whether the term is a proof for elimination of unused variables. @@ -4148,34 +4171,34 @@ end = struct This proof object has no antecedents. *) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_elim_unused_vars ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) (** Indicates whether the term is a proof for destructive equality resolution A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. + (iff (forall (x) (or (not (= ( x : Expr.expr ) t)) P[x])) P[t]) + if ( x : Expr.expr ) does not occur in t. This proof object has no antecedents. Several variables can be eliminated simultaneously. *) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_der ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) (** Indicates whether the term is a proof for quantifier instantiation A proof of (or (not (forall (x) (P x))) (P a)) *) - let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_quant_inst ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) (** Indicates whether the term is a hypthesis marker. Mark a hypothesis in a natural deduction style proof. *) - let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_hypothesis ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) (** Indicates whether the term is a proof by lemma @@ -4187,7 +4210,7 @@ end = struct It converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 contains the hypotheses: l_1, ..., l_n. *) - let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) (** Indicates whether the term is a proof by unit resolution @@ -4198,7 +4221,7 @@ end = struct T(n+1): (not l_n) [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_unit_resolution ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) (** Indicates whether the term is a proof by iff-true @@ -4206,7 +4229,7 @@ end = struct T1: p [iff-true T1]: (iff p true) *) - let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) (** Indicates whether the term is a proof by iff-false @@ -4214,7 +4237,7 @@ end = struct T1: (not p) [iff-false T1]: (iff p false) *) - let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_iff_false ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) (** Indicates whether the term is a proof by commutativity @@ -4226,7 +4249,7 @@ end = struct This proof object has no antecedents. Remark: if f is bool, then = is iff. *) - let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_commutativity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) (** Indicates whether the term is a proof for Tseitin-like axioms @@ -4261,7 +4284,7 @@ end = struct unfolding the Boolean connectives in the axioms a small bounded number of steps (=3). *) - let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_axiom ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) (** Indicates whether the term is a proof for introduction of a name @@ -4283,7 +4306,7 @@ end = struct Otherwise: [def-intro]: (= n e) *) - let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_def_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) (** Indicates whether the term is a proof for application of a definition @@ -4292,7 +4315,7 @@ end = struct F is 'equivalent' to n, given that T1 is a proof that n is a name for F. *) - let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_apply_def ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) (** Indicates whether the term is a proof iff-oeq @@ -4300,7 +4323,7 @@ end = struct T1: (iff p q) [iff~ T1]: (~ p q) *) - let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_iff_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) (** Indicates whether the term is a proof for a positive NNF step @@ -4327,7 +4350,7 @@ end = struct NNF_NEG furthermore handles the case where negation is pushed over Boolean connectives 'and' and 'or'. *) - let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_pos ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) (** Indicates whether the term is a proof for a negative NNF step @@ -4351,7 +4374,7 @@ end = struct [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 r_2) (or r_1' r_2'))) *) - let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_neg ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. @@ -4362,7 +4385,7 @@ end = struct This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_nnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. @@ -4371,19 +4394,19 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_cnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) (** Indicates whether the term is a proof for a Skolemization step Proof for: - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + [sk]: (~ (not (forall ( x : Expr.expr ) (p ( x : Expr.expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : Expr.expr ) (p ( x : Expr.expr ) y)) (p (sk y) y)) This proof object has no antecedents. *) - let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_skolemize ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. @@ -4393,7 +4416,7 @@ end = struct T2: (~ p q) [mp~ T1 T2]: q *) - let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_modus_ponens_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) (** Indicates whether the term is a proof for theory lemma @@ -4411,7 +4434,7 @@ end = struct (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) + let is_theory_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end @@ -4462,8 +4485,8 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) - let assert_ ( x : goal ) ( constraints : bool_expr array ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) e#gno in + let assert_ ( x : goal ) ( constraints : Booleans.bool_expr array ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) in ignore (Array.map f constraints) ; () @@ -4484,7 +4507,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (new bool_expr (z3obj_gc x))#create_obj (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in + let f i = Booleans.create_expr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) @@ -4599,7 +4622,7 @@ struct Return the (symbolic) value of this entry. *) let get_value ( x : func_entry ) = - create_expr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) + Expr.create (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) (** The number of arguments of the entry. @@ -4611,7 +4634,7 @@ struct *) let get_args ( x : func_entry ) = let n = (get_num_args x) in - let f i = (create_expr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (Expr.create (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4639,7 +4662,7 @@ struct (** The (symbolic) `else' value of the function interpretation. *) - let get_else ( x : func_interp ) = create_expr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) + let get_else ( x : func_interp ) = Expr.create (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) (** The arity of the function interpretation @@ -4666,31 +4689,31 @@ struct (** Retrieves the interpretation (the assignment) of in the model. A function declaration of zero arity An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : func_decl ) = + let get_const_interp ( x : model ) ( f : FuncDecl.func_decl ) = if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind f#gnc (Z3native.get_range f#gnc f#gno))) == ARRAY_SORT then + (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") else - let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in if (Z3native.is_null np) then None else - Some (create_expr (z3obj_gc x) np) + Some (Expr.create (z3obj_gc x) np) (** Retrieves the interpretation (the assignment) of in the model. A Constant An expression if the constant has an interpretation in the model, null otherwise. *) - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + let get_const_interp_e ( x : model ) ( a : Expr.expr ) = get_const_interp x (Expr.get_func_decl a) (** Retrieves the interpretation (the assignment) of a non-constant in the model. A function declaration of non-zero arity A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range f#gnc f#gno))) in + let rec get_func_interp ( x : model ) ( f : FuncDecl.func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) f#gno in + let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in if (Z3native.is_null n) then None else @@ -4700,10 +4723,10 @@ struct raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x ((new func_decl f#gc)#create_obj fd) + get_func_interp x (FuncDecl.create (z3obj_gc x) fd) | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else - let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) f#gno) in + let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) (** The number of constants that have an interpretation in the model. *) @@ -4712,7 +4735,7 @@ struct (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f @@ -4722,15 +4745,15 @@ struct (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in - let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in - let f i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = (new func_decl (z3obj_gc x))#create_obj (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) @@ -4751,15 +4774,15 @@ struct The evaluation of in the model. *) - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) t#gno completion) in + let eval ( x : model ) ( t : Expr.expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then raise (ModelEvaluationFailedException "evaluation failed") else - create_expr (z3obj_gc x) v + Expr.create (z3obj_gc x) v (** Alias for eval. *) - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + let evaluate ( x : model ) ( t : Expr.expr ) ( completion : bool ) = eval x t completion (** The number of uninterpreted sorts that the model has an interpretation for. *) @@ -4775,7 +4798,7 @@ struct *) let get_sorts ( x : model ) = let n = (get_num_sorts x) in - let f i = (create_sort (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (Sort.create (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f @@ -4784,10 +4807,10 @@ struct An uninterpreted sort An array of expressions, where each is an element of the universe of *) - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) s#gno) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in + let sort_universe ( x : model ) ( s : Sort.sort ) = + let n_univ = AST.ASTVectors.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n = (AST.ASTVectors.get_size n_univ) in + let f i = (AST.ASTVectors.get n_univ i) in Array.init n f (** Conversion of models to strings. @@ -5323,8 +5346,8 @@ struct (** Assert a constraint (or multiple) into the solver. *) - let assert_ ( x : solver ) ( constraints : bool_expr array ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in + let assert_ ( x : solver ) ( constraints : Booleans.bool_expr array ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in ignore (Array.map f constraints) (** @@ -5340,11 +5363,11 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = + let assert_and_track ( x : solver ) ( cs : Booleans.bool_expr array ) ( ps : Booleans.bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) e#gno (Array.get ps i)#gno) in + let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) (Booleans.gno (Array.get ps i))) in ignore (Array.iteri f cs) (** @@ -5359,24 +5382,24 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) c#gno p#gno + let assert_and_track ( x : solver ) ( c : Booleans.bool_expr ) ( p : Booleans.bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno c) (Booleans.gno p) (** The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVector.get_size a) + let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + (AST.ASTVectors.get_size a) (** The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size a) in - let f i = ((new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get a i)#gno) in + let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVectors.get_size a) in + let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get a i)) in Array.init n f (** @@ -5386,12 +5409,12 @@ struct *) - let check ( x : solver ) ( assumptions : bool_expr array) = + let check ( x : solver ) ( assumptions : Booleans.bool_expr array) = let r = if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (AST.aton assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Booleans.aton assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -5422,7 +5445,7 @@ struct if (Z3native.is_null q) then None else - Some (create_expr (z3obj_gc x) q) + Some (Expr.create (z3obj_gc x) q) (** The unsat core of the last Check. @@ -5432,9 +5455,9 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size cn) in - let f i = (AST.ASTVector.get cn i) in + let cn = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVectors.get_size cn) in + let f i = (AST.ASTVectors.get cn i) in Array.init n f (** @@ -5527,30 +5550,30 @@ struct (** Assert a constraints into the fixedpoint solver. *) - let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) e#gno) in + let assert_ ( x : fixedpoint ) ( constraints : Booleans.bool_expr array ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in ignore (Array.map f constraints) ; () (** Register predicate as recursive relation. *) - let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) f#gno + let register_relation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) = + Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno y) + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno y) (** Add table fact to the fixedpoint solver. *) - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) pred#gno (Array.length args) args + let add_fact ( x : fixedpoint ) ( pred : FuncDecl.func_decl ) ( args : int array ) = + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args (** Query the fixedpoint solver. @@ -5558,8 +5581,8 @@ struct The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - let query ( x : fixedpoint ) ( query : bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) query#gno)) with + let query ( x : fixedpoint ) ( query : Booleans.bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Booleans.gno query))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5570,8 +5593,8 @@ struct The query is satisfiable if there is an instance of some relation that is non-empty. The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - let query_r ( x : fixedpoint ) ( relations : func_decl array ) = - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (func_declaton relations))) with + let query_r ( x : fixedpoint ) ( relations : FuncDecl.func_decl array ) = + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (FuncDecl.aton relations))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -5595,8 +5618,8 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) rule#gno (Symbol.gno name) + let update_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno name) (** Retrieve satisfying instance or instances of solver, @@ -5607,7 +5630,7 @@ struct if (Z3native.is_null q) then None else - Some (create_expr (z3obj_gc x) q) + Some (Expr.create (z3obj_gc x) q) (** Retrieve explanation why fixedpoint engine returned status Unknown. @@ -5618,25 +5641,25 @@ struct (** Retrieve the number of levels explored for a given predicate. *) - let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) predicate#gno + let get_num_levels ( x : fixedpoint ) ( predicate : FuncDecl.func_decl ) = + Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) (** Retrieve the cover of a predicate. *) - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level predicate#gno) in + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) = + let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in if (Z3native.is_null q) then None else - Some (create_expr (z3obj_gc x) q) + Some (Expr.create (z3obj_gc x) q) (** Add property about the predicate. The property is added at level. *) - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level predicate#gno property#gno + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) ( property : Expr.expr ) = + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) (** Retrieve internal string representation of fixedpoint object. @@ -5646,31 +5669,31 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) f#gno (Array.length kinds) (Symbol.aton kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) ( kinds : Symbol.symbol array ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Symbol.aton kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) - let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (AST.aton queries) + let to_string_q ( x : fixedpoint ) ( queries : Booleans.bool_expr array ) = + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Booleans.aton queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in + let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVectors.get_size v) in + let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = (new bool_expr (z3obj_gc x))#create_obj (AST.ASTVector.get v i)#gno in + let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVectors.get_size v) in + let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in Array.init n f (** @@ -5754,10 +5777,10 @@ struct @param formula Formula to be checked for consistency in conjunction with assumptions. @return A string representation of the benchmark. *) - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Booleans.bool_expr array ) ( formula : Booleans.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (AST.aton assumptions) - formula#gno + (Array.length assumptions) (Booleans.aton assumptions) + (Booleans.gno formula) (** Parse the given string using the SMT-LIB parser. @@ -5768,7 +5791,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5779,16 +5802,16 @@ struct Z3native.parse_smtlib_string (context_gno ctx) str cs (Symbol.aton sort_names) - (AST.aton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5799,10 +5822,10 @@ struct Z3native.parse_smtlib_file (context_gno ctx) file_name cs (Symbol.aton sort_names) - (AST.aton sorts) + (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. @@ -5814,7 +5837,7 @@ struct *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) :> bool_expr) in + let f i = Booleans.create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i) in Array.init n f @@ -5828,7 +5851,7 @@ struct *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = ((create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) :> bool_expr ) in + let f i = Booleans.create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i) in Array.init n f (** @@ -5841,7 +5864,7 @@ struct *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = (new func_decl ctx)#create_obj (Z3native.get_smtlib_decl (context_gno ctx) i) in + let f i = FuncDecl.create ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** @@ -5854,7 +5877,7 @@ struct *) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in - let f i = (create_sort ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in + let f i = (Sort.create ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f (** @@ -5863,7 +5886,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5877,13 +5900,13 @@ struct (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5897,7 +5920,7 @@ struct (Sort.aton sorts) cd (Symbol.aton decl_names) - (func_declaton decls) + (FuncDecl.aton decls) end From 7eedf1556189b437eb67533bfa1ea11ef62333f5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 5 Feb 2013 00:51:20 +0000 Subject: [PATCH 393/507] ML API: documentation fixes. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 246 +++++++++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 105 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 4cf41f420..aeb9c0d03 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -331,8 +331,10 @@ module rec AST : sig type ast = z3_native_object +(**/**) val create : context -> Z3native.ptr -> ast val aton : ast array -> Z3native.ptr array +(**/**) module ASTVectors : sig type ast_vector @@ -346,6 +348,7 @@ sig end = struct type ast = z3_native_object + (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let res : z3_native_object = { m_ctx = ctx ; m_n_obj = null ; @@ -358,7 +361,7 @@ end = struct let aton (a : ast array) = let f (e : ast) = (z3obj_gno e) in Array.map f a - + (**/**) (** Vectors of ASTs *) module ASTVectors = @@ -615,7 +618,6 @@ end = struct (**/**) end - (** The Sort module implements type information for ASTs *) and Sort : sig @@ -631,6 +633,7 @@ end = struct type sort = Sort of AST.ast type uninterpreted_sort = UninterpretedSort of sort + (**/**) let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) @@ -657,6 +660,7 @@ end = struct | FINITE_DOMAIN_SORT | RELATION_SORT -> Sort(q) | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + (**/**) (** @@ -728,10 +732,9 @@ sig val get_decl_kind : func_decl -> Z3enums.decl_kind val get_arity : func_decl -> int end = struct - open Sort - type func_decl = FuncDecl of AST.ast + (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let res = { m_ctx = ctx ; m_n_obj = null ; @@ -741,7 +744,7 @@ end = struct (z3obj_create res) ; FuncDecl(res) - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -750,7 +753,7 @@ end = struct (z3obj_create res) ; FuncDecl(res) - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let create_pdr ( ctx : context) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -766,7 +769,8 @@ end = struct let aton (a : func_decl array) = let f (e : func_decl) = (gno e) in Array.map f a - + (**/**) + (** Parameters of Func_Decls *) module Parameter = struct @@ -833,18 +837,16 @@ end = struct | _ -> raise (Z3native.Exception "parameter is not a rational string") end - open Parameter - (** Creates a new function declaration. *) - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = create_ndr ctx name domain range (** Creates a new function declaration. *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range (** @@ -852,19 +854,19 @@ end = struct *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = create_pdr ctx prefix domain range (** Creates a new constant function declaration. *) - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = create_ndr ctx name [||] range (** Creates a new constant function declaration. *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = create_ndr ctx (Symbol.mk_string ctx name) [||] range (** @@ -872,7 +874,7 @@ end = struct *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = create_pdr ctx prefix [||] range @@ -945,13 +947,13 @@ end = struct let get_parameters ( x : func_decl ) = let n = (get_num_parameters x) in let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> Parameter.P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> Parameter.P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) ) in mk_list f n @@ -977,6 +979,7 @@ sig type param_descrs = z3_native_object val create : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit end end = struct type params = z3_native_object @@ -998,6 +1001,7 @@ end = struct type param_descrs = z3_native_object val create : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit end = struct type param_descrs = z3_native_object @@ -1025,7 +1029,7 @@ end = struct let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - + (** The size of the ParamDescrs. *) let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) @@ -1092,7 +1096,7 @@ end = struct let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) end -(** General expressions (terms), including Boolean logic *) +(** General expressions (terms) *) and Expr : sig type expr = Expr of AST.ast @@ -1111,6 +1115,7 @@ sig end = struct type expr = Expr of AST.ast + (**/**) let create ( ctx : context ) ( obj : Z3native.ptr ) = if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then (match (Quantifiers.create ctx obj) with Quantifiers.Quantifier(e) -> e) @@ -1148,7 +1153,12 @@ end = struct let gc ( x : expr ) = match x with Expr(a) -> (z3obj_gc a) let gnc ( x : expr ) = match x with Expr(a) -> (z3obj_gnc a) let gno ( x : expr ) = match x with Expr(a) -> (z3obj_gno a) - + + let aton (a : expr array) = + let f (e : expr) = (gno e) in + Array.map f a + (**/**) + (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier @@ -1405,10 +1415,6 @@ end = struct *) let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : Sort.sort ) = create ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) - - let aton (a : expr array) = - let f (e : expr) = (gno e) in - Array.map f a end (** Boolean expressions *) @@ -1427,6 +1433,7 @@ end = struct type bool_expr = BoolExpr of Expr.expr type bool_sort = BoolSort of Sort.sort + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let a = (AST.create ctx no) in BoolExpr(Expr.Expr(a)) @@ -1441,6 +1448,7 @@ end = struct let aton ( a : bool_expr array ) = let f (e : bool_expr) = (gno e) in Array.map f a + (**/**) let mk_sort ( ctx : context ) = BoolSort(Sort.create ctx (Z3native.mk_bool_sort (context_gno ctx))) @@ -1542,6 +1550,7 @@ sig end = struct type quantifier = Quantifier of Expr.expr + (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let a = (AST.create ctx no) in Quantifier(Expr.Expr(a)) @@ -1549,7 +1558,61 @@ end = struct let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - + (**/**) + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. + *) + module Patterns : + sig + type pattern = Pattern of AST.ast + + val create : context -> Z3native.ptr -> pattern + val aton : pattern array -> Z3native.ptr array + end = struct + type pattern = Pattern of AST.ast + + (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + Pattern(res) + + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) + let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) + let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) + + let aton (a : pattern array) = + let f (e : pattern) = (gno e) in + Array.map f a + (**/**) + + (** + The number of terms in the pattern. + *) + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms (gnc x) (gno x) + + (** + The terms in the pattern. + *) + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in + Array.init n f + + (** + A string representation of the pattern. + *) + let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) + end (** The de-Burijn index of a bound variable. @@ -1575,58 +1638,6 @@ end = struct else Z3native.get_index_value (Expr.gnc x) (Expr.gno x) - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. - *) - module Patterns : - sig - type pattern = Pattern of AST.ast - - val create : context -> Z3native.ptr -> pattern - val aton : pattern array -> Z3native.ptr array - end = struct - type pattern = Pattern of AST.ast - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - Pattern(res) - - let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) - let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) - let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - - (** - The number of terms in the pattern. - *) - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - - (** - The terms in the pattern. - *) - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - Array.init n f - - (** - A string representation of the pattern. - *) - let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) - - let aton (a : pattern array) = - let f (e : pattern) = (gno e) in - Array.map f a - end - (** Indicates whether the quantifier is universal. *) @@ -1849,6 +1860,7 @@ end = struct type array_expr = ArrayExpr of Expr.expr type array_sort = ArraySort of Sort.sort + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let e = (Expr.create ctx no) in ArrayExpr(e) @@ -1868,7 +1880,7 @@ end = struct let aton (a : array_expr array) = let f (e : array_expr) = (egno e) in Array.map f a - + (**/**) (** Create a new array sort. @@ -2120,6 +2132,7 @@ sig end = struct type finite_domain_sort = FiniteDomainSort of Sort.sort + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = let s = (Sort.create ctx no) in FiniteDomainSort(s) @@ -2127,7 +2140,8 @@ end = struct let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gc s) let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gnc s) let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s))-> (z3obj_gno s) - + (**/**) + (** Create a new finite domain sort. *) @@ -2168,6 +2182,7 @@ sig end = struct type relation_sort = RelationSort of Sort.sort + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = let s = (Sort.create ctx no) in RelationSort(s) @@ -2175,7 +2190,8 @@ end = struct let gc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gc s) let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gnc s) let gno ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s))-> (z3obj_gno s) - + (**/**) + (** Indicates whether the term is of a relation sort. *) @@ -2306,6 +2322,7 @@ end = struct type datatype_expr = DatatypeExpr of Expr.expr type datatype_sort = DatatypeSort of Sort.sort + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = let e = (Expr.create ctx no) in DatatypeExpr(e) @@ -2317,19 +2334,24 @@ end = struct let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gc s) let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gnc s) let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s))-> (z3obj_gno s) - + (**/**) (** Constructors *) - module Constructor = - struct + module Constructor : sig + type constructor + val create : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> constructor + val aton : constructor array -> Z3native.ptr array + end = struct type constructor_extra = { m_n : int; mutable m_tester_decl : FuncDecl.func_decl option; mutable m_constructor_decl : FuncDecl.func_decl option ; mutable m_accessor_decls : FuncDecl.func_decl array option} + type constructor = Constructor of (z3_native_object * constructor_extra) - let create_ssssi ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + (**/**) + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -2356,6 +2378,10 @@ end = struct let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; Constructor(no, ex) + + let aton ( a : constructor array ) = + let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in + Array.map f a let init_extra ( x : constructor ) = match x with Constructor(no, ex) -> @@ -2367,7 +2393,8 @@ end = struct ex.m_accessor_decls <- Some (let f e = (FuncDecl.create (z3obj_gc no) e) in Array.map f c) ; () | _ -> () - + (**/**) + let get_n ( x : constructor ) = match x with Constructor(no, ex) -> ex.m_n @@ -2389,12 +2416,7 @@ end = struct match ex.m_accessor_decls with | Some(s) -> s | None -> init_extra x ; accessor_decls x - - let aton ( a : constructor array ) = - let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in - Array.map f a - - + (** The number of fields of the constructor. *) let get_num_fields ( x : constructor ) = get_n x @@ -2413,6 +2435,7 @@ end = struct struct type constructor_list = z3_native_object + (**/**) let create ( ctx : context )( c : Constructor.constructor array ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; @@ -2427,6 +2450,7 @@ end = struct let aton (a : constructor_list array) = let f (e : constructor_list) = (z3obj_gno e) in Array.map f a + (**/**) end (* DATATYPES *) @@ -2441,7 +2465,7 @@ end = struct referring to one of the recursive datatypes that is declared. *) let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array) = - Constructor.create_ssssi ctx name recognizer field_names sorts sort_refs + Constructor.create ctx name recognizer field_names sorts sort_refs (** @@ -2530,6 +2554,7 @@ end = struct mutable _testerdecls : FuncDecl.func_decl array } type enum_sort = EnumSort of (Sort.sort * enum_sort_data) + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = let s = (Sort.create ctx no) in let e = { _constdecls = (let f e = FuncDecl.create ctx e in (Array.map f cdecls)) ; @@ -2539,7 +2564,7 @@ end = struct let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gc s) let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_)-> (z3obj_gno s) - + (**/**) (** Create a new enumeration sort. @@ -2576,6 +2601,7 @@ end = struct _taildecl : FuncDecl.func_decl } type list_sort = ListSort of (Sort.sort * list_sort_data) + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = let s = (Sort.create ctx no) in let e = {_nildecl = FuncDecl.create ctx nildecl; @@ -2589,7 +2615,7 @@ end = struct let sgc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gc s) let sgnc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gnc s) let sgno ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_)-> (z3obj_gno s) - + (**/**) (** Create a new list sort. *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : Sort.sort ) = @@ -2629,6 +2655,7 @@ sig end = struct type tuple_sort = TupleSort of Sort.sort + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = let s = (Sort.create ctx no) in TupleSort(s) @@ -2636,6 +2663,7 @@ end = struct let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gc s) let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s))-> (z3obj_gno s) + (**/**) (** Create a new tuple sort. *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : Sort.sort array ) = @@ -2736,6 +2764,7 @@ end = struct type arith_sort = ArithSort of Sort.sort type arith_expr = ArithExpr of Expr.expr + (**/**) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = ArithExpr(Expr.create ctx no) @@ -2749,6 +2778,10 @@ end = struct let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) + let aton (a : arith_expr array) = + let f (e : arith_expr) = (egno e) in + Array.map f a + (**/**) module rec Integers : sig @@ -2764,6 +2797,7 @@ end = struct type int_expr = IntExpr of arith_expr type int_num = IntNum of int_expr + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = IntSort(Arithmetic.create_sort ctx no) @@ -2782,6 +2816,7 @@ end = struct let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) + (**/**) (** Create a new integer sort. *) let mk_sort ( ctx : context ) = @@ -2878,6 +2913,7 @@ end = struct type real_expr = RealExpr of arith_expr type rat_num = RatNum of real_expr + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = RealSort(Arithmetic.create_sort ctx no) @@ -2896,7 +2932,8 @@ end = struct let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - + (**/**) + (** Create a real sort. *) let mk_sort ( ctx : context ) = create_sort ctx (Z3native.mk_real_sort (context_gno ctx)) @@ -2979,12 +3016,14 @@ end = struct end = struct type algebraic_num = AlgebraicNum of arith_expr + (**/**) let create_num ( ctx : context ) ( no : Z3native.ptr ) = AlgebraicNum(Arithmetic.create_expr ctx no) let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) + (**/**) (** Return a upper bound for a given real algebraic number. @@ -3015,10 +3054,6 @@ end = struct let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) end - let aton (a : arith_expr array) = - let f (e : arith_expr) = (egno e) in - Array.map f a - (** Indicates whether the term is of integer sort. *) @@ -3188,7 +3223,6 @@ end = struct Booleans.create_expr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2)) end - (** Functions to manipulate bit-vector expressions *) and BitVectors : sig @@ -3204,6 +3238,7 @@ end = struct type bitvec_expr = BitVecExpr of Expr.expr type bitvec_num = BitVecNum of bitvec_expr + (**/**) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = BitVecSort(Sort.create ctx no) @@ -3222,6 +3257,7 @@ end = struct let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) + (**/**) (** Create a new bit-vector sort. From 7ec027dadb4ae56497ce8b9aaadfe2000d701ef8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 19:49:27 +0000 Subject: [PATCH 394/507] ML API: basic structure and interface Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 81 +- scripts/update_api.py | 30 +- src/api/ml/Makefile | 2 +- src/api/ml/z3.ml | 2714 +++++++++++++++++++---------------------- 4 files changed, 1380 insertions(+), 1447 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 1d3412c30..cfea8d0f1 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1350,10 +1350,17 @@ class MLComponent(Component): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + cmis = '%s/z3enums.cmi %s/z3native.cmi %s/z3.cmi' % (src_dir,src_dir,src_dir) + out.write('%s/z3enums.cmi: %s/z3enums.mli\n' % (src_dir,src_dir)) + out.write('\t%s -I %s -c %s/z3enums.mli\n' % (OCAMLC,src_dir,src_dir)) + out.write('%s/z3native.cmi: %s/z3native.mli\n' % (src_dir,src_dir)) + out.write('\t%s -I %s -c %s/z3native.mli\n' % (OCAMLC,src_dir,src_dir)) + out.write('%s/z3.cmi: %s/z3.mli\n' % (src_dir,src_dir)) + out.write('\t%s -I %s -c %s/z3.mli\n' % (OCAMLC,src_dir,src_dir)) out.write('api/ml/libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, src_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') - out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(src_dir, mlfile)) out.write('\n') @@ -1361,7 +1368,7 @@ class MLComponent(Component): if DEBUG_MODE: out.write('-g ') out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) - out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT)' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) out.write('\n') @@ -2732,6 +2739,76 @@ def mk_z3consts_ml(api_files): efile.write('end\n') if VERBOSE: print "Generated '%s/z3enums.ml'" % ('%s' % gendir) + efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') + efile.write('(* Automatically generated file *)\n\n') + efile.write('(** The enumeration types of Z3. *)\n\n') + for api_file in api_files: + api_file_c = ml.find_file(api_file, ml.name) + api_file = os.path.join(api_file_c.src_dir, api_file) + + api = open(api_file, 'r') + + SEARCHING = 0 + FOUND_ENUM = 1 + IN_ENUM = 2 + + mode = SEARCHING + decls = {} + idx = 0 + + linenum = 1 + for line in api: + m1 = blank_pat.match(line) + m2 = comment_pat.match(line) + if m1 or m2: + # skip blank lines and comments + linenum = linenum + 1 + elif mode == SEARCHING: + m = typedef_pat.match(line) + if m: + mode = FOUND_ENUM + m = typedef2_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + elif mode == FOUND_ENUM: + m = openbrace_pat.match(line) + if m: + mode = IN_ENUM + decls = {} + idx = 0 + else: + assert False, "Invalid %s, line: %s" % (api_file, linenum) + else: + assert mode == IN_ENUM + words = re.split('[^\-a-zA-Z0-9_]+', line) + m = closebrace_pat.match(line) + if m: + name = words[1] + if name not in DeprecatedEnums: + efile.write('(** %s *)\n' % name[3:]) + efile.write('type %s =\n' % name[3:]) # strip Z3_ + for k, i in decls.iteritems(): + efile.write(' | %s \n' % k[3:]) # strip Z3_ + efile.write('\n') + efile.write('(** Convert %s to int*)\n' % name[3:]) + efile.write('val int_of_%s : %s -> int\n' % (name[3:], name[3:])) # strip Z3_ + efile.write('(** Convert int to %s*)\n' % name[3:]) + efile.write('val %s_of_int : int -> %s\n' % (name[3:],name[3:])) # strip Z3_ + efile.write('\n') + mode = SEARCHING + else: + if words[2] != '': + if len(words[2]) > 1 and words[2][1] == 'x': + idx = int(words[2], 16) + else: + idx = int(words[2]) + decls[words[1]] = idx + idx = idx + 1 + linenum = linenum + 1 + if VERBOSE: + print "Generated '%s/z3enums.mli'" % ('%s' % gendir) def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index c730a325e..6e9c14355 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1147,49 +1147,66 @@ def mk_ml(): return ml_dir = get_component('ml').src_dir ml_nativef = os.path.join(ml_dir, 'z3native.ml') + ml_nativefi = os.path.join(ml_dir, 'z3native.mli') ml_wrapperf = os.path.join(ml_dir, 'z3native.c') ml_native = open(ml_nativef, 'w') + ml_i = open(ml_nativefi, 'w') ml_native.write('(* Automatically generated file *)\n\n') ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') + ml_i.write('(* Automatically generated file *)\n\n') + ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_native.write('open Z3enums\n\n') ml_native.write('(**/**)\n') ml_native.write('type ptr\n') + ml_i.write('type ptr\n') ml_native.write('and z3_symbol = ptr\n') + ml_i.write('and z3_symbol = ptr\n') for k, v in Type2Str.iteritems(): if is_obj(k): ml_native.write('and %s = ptr\n' % v.lower()) + ml_i.write('and %s = ptr\n' % v.lower()) ml_native.write('\n') - ml_native.write('external is_null : ptr -> bool\n') - ml_native.write(' = "n_is_null"\n\n') - ml_native.write('external mk_null : unit -> ptr\n') - ml_native.write(' = "n_mk_null"\n\n') + ml_i.write('\n') + ml_native.write('external is_null : ptr -> bool\n = "n_is_null"\n\n') + ml_native.write('external mk_null : unit -> ptr\n = "n_mk_null"\n\n') ml_native.write('exception Exception of string\n\n') + ml_i.write('val is_null : ptr -> bool\n') + ml_i.write('val mk_null : unit -> ptr\n') + ml_i.write('exception Exception of string\n\n') # ML declarations - ml_native.write(' module ML2C = struct\n\n') + ml_native.write('module ML2C = struct\n\n') for name, result, params in _dotnet_decls: ml_native.write(' external n_%s : ' % ml_method_name(name)) + ml_i.write('val %s : ' % ml_method_name(name)) ip = inparams(params) op = outparams(params) if len(ip) == 0: - ml_native.write(' unit -> ') + ml_native.write(' unit -> ') for p in ip: ml_native.write('%s -> ' % param2ml(p)) + ml_i.write('%s -> ' % param2ml(p)) if len(op) > 0: ml_native.write('(') + ml_i.write('(') first = True if result != VOID or len(op) == 0: ml_native.write('%s' % type2ml(result)) + ml_i.write('%s' % type2ml(result)) first = False for p in op: if first: first = False else: ml_native.write(' * ') + ml_i.write(' * ') ml_native.write('%s' % param2ml(p)) + ml_i.write('%s' % param2ml(p)) if len(op) > 0: ml_native.write(')') + ml_i.write(')') ml_native.write('\n') + ml_i.write('\n') ml_native.write(' = "n_%s"\n' % ml_method_name(name)) if len(ip) > 5: ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) @@ -1201,6 +1218,7 @@ def mk_ml(): ip = inparams(params) op = outparams(params) ml_native.write(' let %s ' % ml_method_name(name)) + first = True i = 0; for p in params: diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index ad5442327..abcefa4af 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -7,4 +7,4 @@ all: doc: *.ml mkdir -p doc - ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.ml -hide Z3 + ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.mli -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index aeb9c0d03..ea8c9576e 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,8 +7,479 @@ open Z3enums -(** Interaction logging for Z3 +(* Some helpers. *) +let null = Z3native.mk_null() +let is_null o = (Z3native.is_null o) + +(* Internal types *) +type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +type context = z3_native_context + + + +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } + + +(* Symbol types *) +type int_symbol = z3_native_object +type string_symbol = z3_native_object + +type symbol = + | S_Int of int_symbol + | S_Str of string_symbol + +(* AST types *) +type ast = z3_native_object +type ast_vector = z3_native_object +type ast_map = z3_native_object + +(* FuncDecl types *) +type func_decl = FuncDecl of ast + +(* Sort types *) +type sort = Sort of ast +type uninterpreted_sort = UninterpretedSort of sort +type bool_sort = BoolSort of sort +type array_sort = ArraySort of sort +type set_sort = SetSort of sort +type datatype_sort = DatatypeSort of sort +type relation_sort = RelationSort of sort +type finite_domain_sort = FiniteDomainSort of sort +type enum_sort = EnumSort of sort +type list_sort = ListSort of sort +type tuple_sort = TupleSort of sort +type arith_sort = ArithSort of sort +type bitvec_sort = BitVecSort of sort + +type int_sort = IntSort of arith_sort +type real_sort = RealSort of arith_sort + +(* FuncDecl parameters *) +type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of symbol + | P_Srt of sort + | P_Ast of ast + | P_Fdl of func_decl + | P_Rat of string +type params = z3_native_object +type param_descrs = z3_native_object + +(* Expr types *) +type expr = Expr of ast + +type bool_expr = BoolExpr of expr +type arith_expr = ArithExpr of expr +type int_expr = IntExpr of arith_expr +type real_expr = RealExpr of arith_expr +type bitvec_expr = BitVecExpr of expr +type array_expr = ArrayExpr of expr +type datatype_expr = DatatypeExpr of expr + +(* Numerals *) +type int_num = IntNum of int_expr +type rat_num = RatNum of real_expr +type algebraic_num = AlgebraicNum of arith_expr +type bitvec_num = BitVecNum of bitvec_expr + +(* Quantifier stuff *) +type quantifier = Quantifier of expr +type pattern = Pattern of ast + +(* Datatype stuff *) +type constructor_extra = { + m_n : int; + mutable m_tester_decl : func_decl option; + mutable m_constructor_decl : func_decl option ; + mutable m_accessor_decls : func_decl array option} + +type constructor = Constructor of (z3_native_object * constructor_extra) +type constructor_list = z3_native_object + +(* Tactical interface *) +type goal = z3_native_object +type model = z3_native_object +type func_interp = z3_native_object +type func_entry = z3_native_object +type probe = z3_native_object +type tactic = z3_native_object +type apply_result = z3_native_object +type solver = z3_native_object +type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE +type statistics = z3_native_object +type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } +type fixedpoint = z3_native_object + + +(** Internal stuff *) +module Internal = +struct + let dispose_context ctx = + if ctx.m_n_obj_cnt == 0 then ( + (* Printf.printf "Disposing context \n" ; *) + (Z3native.del_context ctx.m_n_ctx) + ) else ( + Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; + (* re-queue for finalization? *) + ) + + let create_context settings = + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + (* Printf.printf "Installing finalizer on context \n" ; *) + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> dispose_context o in + Gc.finalise f res; + res + (* CMW: Install error handler here! + m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. + Z3native.set_error_handler(m_ctx, m_n_err_handler); + GC.SuppressFinalize(this); + *) + + let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) + let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) + let context_gno ctx = ctx.m_n_ctx + + + let z3obj_gc o = o.m_ctx + let z3obj_gnc o = (context_gno o.m_ctx) + + let z3obj_gno o = o.m_n_obj + let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + + let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + + let z3obj_create o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o + + let z3obj_nil_ref x y = () + + let array_to_native a = + let f e = (z3obj_gno e) in + Array.map f a + + (* Internal coercions *) + let context_of_ast ( x : ast ) = (z3obj_gc x) + let nc_of_ast ( x : ast ) = (z3obj_gnc x) + let ptr_of_ast ( x : ast ) = (z3obj_gno x) + + let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) + let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) + let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + + + let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> + let res : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> + let q = (z3_native_object_of_ast_ptr ctx no) in + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then + raise (Z3native.Exception "Invalid coercion") + else + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + FuncDecl(z3_native_object_of_ast_ptr ctx no) + + let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST + | SORT_AST + | QUANTIFIER_AST + | APP_AST + | NUMERAL_AST + | VAR_AST -> z3_native_object_of_ast_ptr ctx no + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") + + and expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then + Expr(z3_native_object_of_ast_ptr ctx no) + else + let s = Z3native.get_sort (context_gno ctx) no in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) no) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + if (Z3native.is_numeral_ast (context_gno ctx) no) then + if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + raise (Z3native.Exception "Unsupported numeral object") + else + Expr(z3_native_object_of_ast_ptr ctx no) + + let expr_aton ( a : expr array ) = + let f ( e : expr ) = match e with Expr(a) -> (ptr_of_ast a) in + Array.map f a + + let expr_of_func_app : context -> func_decl -> expr array -> expr = fun ctx f args -> + match f with FuncDecl(fa) -> + let o = Z3native.mk_app (context_gno ctx) (ptr_of_ast fa) (Array.length args) (expr_aton args) in + expr_of_ptr ctx o +end + + +open Internal + + + +(* Sort coercions *) +let ast_of_sort s = match s with Sort(x) -> x +let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x +let sort_of_bool_sort s = match s with BoolSort(x) -> x +let sort_of_array_sort s = match s with ArraySort(x) -> x +let sort_of_set_sort s = match s with SetSort(x) -> x +let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x +let sort_of_relation_sort s = match s with RelationSort(x) -> x +let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x +let sort_of_enum_sort s = match s with EnumSort(x) -> x +let sort_of_list_sort s = match s with ListSort(x) -> x +let sort_of_tuple_sort s = match s with TupleSort(x) -> x +let sort_of_arith_sort s = match s with ArithSort(x) -> x +let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x +let arith_sort_of_int_sort s = match s with IntSort(x) -> x +let arith_sort_of_real_sort s = match s with RealSort(x) -> x + +let uninterpreted_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + UninterpretedSort(s) + +let bool_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolSort(s) + +let array_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArraySort(s) + +let datatype_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeSort(s) + +let relation_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RelationSort(s) + +let finite_domain_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + FiniteDomainSort(s) + +let arith_sort_of_sort s = match s with Sort(a) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithSort(s) + +let bitvec_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecSort(s) + +let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntSort(s) + +let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealSort(s) + +(* FuncDecl coercions *) +let ast_of_func_decl f = match f with FuncDecl(x) -> x + +(* Expr coercions *) +let ast_of_expr e = match e with Expr(a) -> a +let expr_of_bool_expr e = match e with BoolExpr(x) -> x +let expr_of_arith_expr e = match e with ArithExpr(x) -> x +let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x +let expr_of_array_expr e = match e with ArrayExpr(x) -> x +let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x + +let arith_expr_of_int_expr e = match e with IntExpr(x) -> x +let arith_expr_of_real_expr e = match e with RealExpr(x) -> x + +let int_expr_of_int_num e = match e with IntNum(x) -> x +let real_expr_of_rat_num e = match e with RatNum(x) -> x +let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x +let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x + +let expr_of_quantifier e = match e with Quantifier(x) -> x +let ast_of_pattern e = match e with Pattern(x) -> x + + +let expr_of_ast a = + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Expr(a) + +let bool_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolExpr(e) + +let arith_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithExpr(e) + +let bitvec_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecExpr(e) + +let array_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArrayExpr(e) + +let datatype_expr_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeExpr(e) + +let int_expr_of_arith_expr e = + match e with ArithExpr(Expr(no)) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntExpr(e) + +let real_expr_of_arith_expr e = + match e with ArithExpr(Expr(no)) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealExpr(e) + +let int_num_of_int_expr e = + match e with IntExpr(ArithExpr(Expr(no))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + IntNum(e) + +let rat_num_of_real_expr e = + match e with RealExpr(ArithExpr(Expr(no))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + RatNum(e) + +let algebraic_num_of_arith_expr e = + match e with ArithExpr(Expr(no)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + AlgebraicNum(e) + +let bitvec_num_of_bitvec_expr e = + match e with BitVecExpr(Expr(no)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecNum(e) + +let quantifier_of_expr e = + match e with Expr(no) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc no) (z3obj_gno no))) in + if (q != Z3enums.QUANTIFIER_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Quantifier(e) + +let pattern_of_ast a = + (* CMW: Unchecked ok? *) + Pattern(a) + + + +(** Interaction logging for Z3 Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) module Log = @@ -28,6 +499,7 @@ struct let append s = Z3native.append_log s end + (** Version information *) module Version = struct @@ -52,11 +524,6 @@ struct string_of_int rev ^ "." end -(**/**) -(* Some helpers. *) - -let null = Z3native.mk_null() -let is_null o = (Z3native.is_null o) let mk_list ( f : int -> 'a ) ( n : int ) = let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = @@ -66,49 +533,8 @@ let mk_list ( f : int -> 'a ) ( n : int ) = (mk_list' f (i+1) n ((f i) :: tail)) in mk_list' f 0 n [] -(**/**) -(**/**) -type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } -(**/**) -type context = z3_native_context - -(**/**) - -let context_dispose ctx = - if ctx.m_n_obj_cnt == 0 then ( - (* Printf.printf "Disposing context \n" ; *) - (Z3native.del_context ctx.m_n_ctx) - ) else ( - Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; - (* re-queue for finalization? *) - ) - -let context_create settings = - let cfg = Z3native.mk_config in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - (* Printf.printf "Installing finalizer on context \n" ; *) - let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in - let f = fun o -> context_dispose o in - Gc.finalise f res; - res -(* CMW: Install error handler here! - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); -*) - -let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) -let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) -let context_gno ctx = ctx.m_n_ctx - -(**/**) - (** Create a context object. Most interactions with Z3 are interpreted in some context; many users will only @@ -130,113 +556,14 @@ let context_gno ctx = ctx.m_n_ctx *) let mk_context ( cfg : ( string * string ) list ) = - context_create cfg + create_context cfg -(**/**) -class virtual z3object ctx_init obj_init = -object (self) - val mutable m_ctx : context = ctx_init - val mutable m_n_obj : Z3native.ptr option = obj_init - - initializer - (match m_n_obj with - | Some (x) -> self#incref (context_gno m_ctx) x; - (context_add1 m_ctx) - | None -> () - ); - (* Printf.printf "Installing finalizer on z3object %d \n" (Oo.id self) ; *) - let f = fun o -> o#dispose in - let v = self in - Gc.finalise f v - - method virtual incref : Z3native.ptr -> Z3native.ptr -> unit - method virtual decref : Z3native.ptr -> Z3native.ptr -> unit - - method dispose = - (* Printf.printf "Disposing z3object %d \n" (Oo.id self) ; *) - (match m_n_obj with - | Some (x) -> - self#decref (context_gno m_ctx) x; - (context_sub1 m_ctx) ; - m_n_obj <- None; - | None -> () - ); - - method gno = match m_n_obj with - | Some(x) -> x - | None -> raise (Z3native.Exception "Z3 object lost") - - method sno (ctx : context) o = - (context_add1 m_ctx) ; - self#incref (context_gno ctx) o ; - (match m_n_obj with - | Some(x) -> self#decref (context_gno ctx) x ; (context_sub1 m_ctx) - | None -> () - ); - m_n_obj <- Some o - - method gc = m_ctx - method gnc = (context_gno m_ctx) -end - - - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - -let z3obj_gc o = o.m_ctx -let z3obj_gnc o = (context_gno o.m_ctx) - -let z3obj_gno o = o.m_n_obj -let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - -let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - -let z3obj_create o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - -let z3obj_nil_ref x y = () - -let array_to_native a = - let f e = (z3obj_gno e) in - Array.map f a -(**/**) (** Symbols are used to name several term and type constructors *) module Symbol = -struct - (** Int symbol objects *) - type int_symbol = z3_native_object - - (** String symbol objects *) - type string_symbol = z3_native_object - - (** Symbol Objects *) - type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - - (**/**) +struct let create_i ( ctx : context ) ( no : Z3native.ptr ) = let res : int_symbol = { m_ctx = ctx ; m_n_obj = null ; @@ -255,6 +582,11 @@ struct (z3obj_create res) ; res + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with + | INT_SYMBOL -> S_Int (create_i ctx no) + | STRING_SYMBOL -> S_Str (create_s ctx no) + let gc ( x : symbol ) = match x with | S_Int(n) -> (z3obj_gc n) @@ -269,17 +601,7 @@ struct match x with | S_Int(n) -> (z3obj_gno n) | S_Str(n) -> (z3obj_gno n) - - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> S_Int (create_i ctx no) - | STRING_SYMBOL -> S_Str (create_s ctx no) - - let aton a = - let f e = (gno e) in - Array.map f a - (**/**) - + (** The kind of the symbol (int or string) *) let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) @@ -327,48 +649,11 @@ end (** The abstract syntax tree (AST) module *) -module rec AST : -sig - type ast = z3_native_object - -(**/**) - val create : context -> Z3native.ptr -> ast - val aton : ast array -> Z3native.ptr array -(**/**) - - module ASTVectors : sig - type ast_vector - val create : context -> Z3native.ptr -> ast_vector - val get_size : ast_vector -> int - val get : ast_vector -> int -> ast - end - - val is_expr : ast -> bool - val is_var : ast -> bool -end = struct - type ast = z3_native_object - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let aton (a : ast array) = - let f (e : ast) = (z3obj_gno e) in - Array.map f a - (**/**) - +module AST = +struct (** Vectors of ASTs *) - module ASTVectors = + module ASTVector = struct - type ast_vector = z3_native_object - - (**/**) let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; @@ -377,7 +662,7 @@ end = struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** The size of the vector *) let get_size ( x : ast_vector ) = @@ -411,7 +696,7 @@ end = struct (** Translates all ASTs in the vector to . @param to_ctx A context - @return A new ASTVectors + @return A new ASTVector *) let translate ( x : ast_vector ) ( to_ctx : context ) = create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) @@ -423,10 +708,8 @@ end = struct (** Map from AST to AST *) module ASTMap = - struct - type ast_map = z3_native_object - - (**/**) + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; @@ -435,7 +718,7 @@ end = struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Checks whether the map contains the key . @param k An AST @@ -476,7 +759,7 @@ end = struct (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVectors.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = @@ -576,7 +859,7 @@ end = struct if (z3obj_gnc x) == (context_gno to_ctx) then x else - create to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Wraps an AST. @@ -590,7 +873,7 @@ end = struct @param nativeObject The native pointer to wrap. *) let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - create ctx ptr + ast_of_ptr ctx ptr (** Unwraps an AST. @@ -603,66 +886,17 @@ end = struct @param a The AST to unwrap. *) - let unwrap_ast ( x : ast ) = (z3obj_gno x) - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST -> (match (FuncDecl.create ctx no) with FuncDecl.FuncDecl(x) -> x) - | SORT_AST -> (match (Sort.create ctx no) with Sort.Sort(x) -> x) - | QUANTIFIER_AST -> (match (Quantifiers.create ctx no) with Quantifiers.Quantifier(Expr.Expr(x)) -> x) - | APP_AST - | NUMERAL_AST - | VAR_AST -> (match (Expr.create ctx no) with Expr.Expr(x) -> x) - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") -(**/**) + let unwrap_ast ( x : ast ) = (z3obj_gno x) end (** The Sort module implements type information for ASTs *) -and Sort : -sig - type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort - - val create : context -> Z3native.ptr -> sort - val gc : sort -> context - val gnc : sort -> Z3native.ptr - val gno : sort -> Z3native.ptr - val aton : sort array -> Z3native.ptr array -end = struct - type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort - - (**/**) +module Sort = +struct + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - let aton : sort array -> Z3native.ptr array = fun a -> - let f e = (gno e) in - Array.map f a - - let create : context -> Z3native.ptr -> sort = fun ctx no -> - let q : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno q ctx no) ; - (z3obj_create q) ; - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - (**/**) - - (** Comparison operator. @param a A sort @@ -700,7 +934,7 @@ end = struct (** Create a new uninterpreted sort. *) - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = + let mk_uninterpreted ( ctx : context ) ( s : symbol ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -718,71 +952,37 @@ end (** Function declarations *) -and FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - - val create : context -> Z3native.ptr -> func_decl - val gc : func_decl -> context - val gno : func_decl -> Z3native.ptr - val gnc : func_decl -> Z3native.ptr - val aton : func_decl array -> Z3native.ptr array - - val get_domain_size : func_decl -> int - val get_decl_kind : func_decl -> Z3enums.decl_kind - val get_arity : func_decl -> int -end = struct - type func_decl = FuncDecl of AST.ast - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - FuncDecl(res) - - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = +module FuncDecl = +struct + (**/**) + let create_ndr ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + let f x = (ptr_of_ast (ast_of_sort x)) in + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) - let create_pdr ( ctx : context) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Sort.aton domain) (Sort.gno range))) ; + let f x = (ptr_of_ast (ast_of_sort x)) in + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - - let aton (a : func_decl array) = - let f (e : func_decl) = (gno e) in - Array.map f a - (**/**) + (**/**) (** Parameters of Func_Decls *) module Parameter = - struct - type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - + struct (** The kind of the parameter. *) let get_kind ( x : parameter ) = (match x with @@ -840,13 +1040,13 @@ end = struct (** Creates a new function declaration. *) - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = create_ndr ctx name domain range (** Creates a new function declaration. *) - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range (** @@ -854,19 +1054,19 @@ end = struct *) - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : Sort.sort array ) ( range : Sort.sort ) = + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = create_pdr ctx prefix domain range (** Creates a new constant function declaration. *) - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = + let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort ) = create_ndr ctx name [||] range (** Creates a new constant function declaration. *) - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = create_ndr ctx (Symbol.mk_string ctx name) [||] range (** @@ -874,7 +1074,7 @@ end = struct *) - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = create_pdr ctx prefix [||] range @@ -917,14 +1117,14 @@ end = struct *) let get_domain ( x : func_decl ) = let n = (get_domain_size x) in - let f i = Sort.create (gc x) (Z3native.get_domain (gnc x) (gno x) i) in + let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in Array.init n f (** The range of the function declaration *) let get_range ( x : func_decl ) = - Sort.create (gc x) (Z3native.get_range (gnc x) (gno x)) + sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) (** The kind of the function declaration. @@ -947,13 +1147,13 @@ end = struct let get_parameters ( x : func_decl ) = let n = (get_num_parameters x) in let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> Parameter.P_Srt (Sort.create (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> Parameter.P_Ast (AST.create (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (create (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> P_Ast (ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) ) in mk_list f n @@ -961,7 +1161,7 @@ end = struct Create expression that applies function to arguments. @param args The arguments *) - let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.create_fa (gc x) x args + let apply ( x : func_decl ) ( args : expr array ) = expr_of_func_app (gc x) x args end (** @@ -969,43 +1169,12 @@ end A Params objects represents a configuration in the form of symbol/value pairs. *) -and Params : -sig - type params = z3_native_object - - val create : context -> Z3native.ptr -> params - - module ParamDescrs : sig - type param_descrs = z3_native_object - - val create : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - end -end = struct - type params = z3_native_object - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : params = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.params_inc_ref ; - dec_ref = Z3native.params_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - (**/**) - +module Params = +struct (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs : - sig - type param_descrs = z3_native_object - - val create : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - end = struct - type param_descrs = z3_native_object - - (**/**) + module ParamDescrs = + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : param_descrs = { m_ctx = ctx ; m_n_obj = null ; @@ -1014,14 +1183,14 @@ end = struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Validate a set of parameters. *) let validate ( x : param_descrs ) ( p : params ) = Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = + let get_kind ( x : param_descrs ) ( name : symbol ) = (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) (** Retrieve all names of parameters. *) @@ -1040,25 +1209,25 @@ end = struct (** Adds a parameter setting. *) - let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = + let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = + let add_int ( x : params ) (name : symbol ) ( value : int ) = Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + let add_double ( x : params ) ( name : symbol ) ( value : float ) = Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value (** Adds a parameter setting. *) - let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = + let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) (** @@ -1081,14 +1250,20 @@ end = struct (** Adds a parameter setting. *) - let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = + let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = add_symbol x (Symbol.mk_string (z3obj_gc x) name) value (** Creates a new parameter set *) let mk_params ( ctx : context ) = - create ctx (Z3native.mk_params (context_gno ctx)) + let res : params = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.params_inc_ref ; + dec_ref = Z3native.params_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; + (z3obj_create res) ; + res (** A string representation of the parameter set. @@ -1097,76 +1272,16 @@ end = struct end (** General expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - - val create : context -> Z3native.ptr -> expr - val create_fa : context -> FuncDecl.func_decl -> expr array -> expr - val gc : expr -> context - val gno : expr -> Z3native.ptr - val gnc : expr -> Z3native.ptr - val aton : expr array -> Z3native.ptr array - - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - val get_func_decl : expr -> FuncDecl.func_decl - val is_numeral : expr -> bool - val to_string : expr -> string -end = struct - type expr = Expr of AST.ast - - (**/**) - let create ( ctx : context ) ( obj : Z3native.ptr ) = - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) obj) == QUANTIFIER_AST then - (match (Quantifiers.create ctx obj) with Quantifiers.Quantifier(e) -> e) - else - let s = Z3native.get_sort (context_gno ctx) obj in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) obj) then - (match (Arithmetic.AlgebraicNumbers.create_num ctx obj) with Arithmetic.AlgebraicNumbers.AlgebraicNum(Arithmetic.ArithExpr(e)) -> e) - else - if (Z3native.is_numeral_ast (context_gno ctx) obj) && - (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - match sk with - | INT_SORT -> (match (Arithmetic.Integers.create_num ctx obj) with Arithmetic.Integers.IntNum(Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e))) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_num ctx obj) with Arithmetic.Reals.RatNum(Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e))) -> e) - | BV_SORT -> (match (BitVectors.create_num ctx obj) with BitVectors.BitVecNum(BitVectors.BitVecExpr(e)) -> e) - | _ -> raise (Z3native.Exception "Unsupported numeral object") - else - match sk with - | BOOL_SORT -> (match (Booleans.create_expr ctx obj) with Booleans.BoolExpr(e) -> e) - | INT_SORT -> (match (Arithmetic.Integers.create_expr ctx obj) with Arithmetic.Integers.IntExpr(Arithmetic.ArithExpr(e)) -> e) - | REAL_SORT -> (match (Arithmetic.Reals.create_expr ctx obj) with Arithmetic.Reals.RealExpr(Arithmetic.ArithExpr(e)) -> e) - | BV_SORT -> (match (BitVectors.create_expr ctx obj) with BitVectors.BitVecExpr(e) -> e) - | ARRAY_SORT -> (match (Arrays.create_expr ctx obj) with Arrays.ArrayExpr(e) -> e) - | DATATYPE_SORT -> (match (Datatypes.create_expr ctx obj) with Datatypes.DatatypeExpr(e) -> e) - | _ -> Expr(AST.create ctx obj) - - let aton ( a : expr array ) = - let f ( e : expr ) = match e with Expr(a) -> (z3obj_gno a) in - Array.map f a - - let create_fa ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = - let o = Z3native.mk_app (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args) in - Expr.create ctx o - - let gc ( x : expr ) = match x with Expr(a) -> (z3obj_gc a) - let gnc ( x : expr ) = match x with Expr(a) -> (z3obj_gnc a) - let gno ( x : expr ) = match x with Expr(a) -> (z3obj_gno a) - - let aton (a : expr array) = - let f (e : expr) = (gno e) in - Array.map f a - (**/**) - +module Expr = +struct (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier *) - let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> Expr.create (gc x) (Z3native.simplify (gnc x) (gno x)) - | Some pp -> Expr.create (gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) + let simplify ( x : expr ) ( p : params option ) = match p with + | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) + | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) (** a string describing all available parameters to Expr.Simplify. @@ -1183,24 +1298,24 @@ end = struct (** The function declaration of the function that is applied in this expression. *) - let get_func_decl ( x : expr ) = FuncDecl.create (gc x) (Z3native.get_app_decl (gnc x) (gno x)) + let get_func_decl ( x : expr ) = func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the expression is the true or false expression or something else (L_UNDEF). *) - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (nc_of_expr x) (ptr_of_expr x)) (** The number of arguments of the expression. *) - let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) + let get_num_args ( x : expr ) = Z3native.get_app_num_args (nc_of_expr x) (ptr_of_expr x) (** The arguments of the expression. *) let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = create (gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in + let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in Array.init n f (** @@ -1211,7 +1326,7 @@ end = struct if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - create (gc x) (Z3native.update_term (gnc x) (gno x) (Array.length args) (aton args)) + expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (Array.length args) (expr_aton args)) (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. @@ -1224,7 +1339,7 @@ end = struct if (Array.length from) <> (Array.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - create (gc x) (Z3native.substitute (gnc x) (gno x) (Array.length from) (aton from) (aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (Array.length from) (expr_aton from) (expr_aton to_)) (** Substitute every occurrence of from in the expression with to. @@ -1239,48 +1354,47 @@ end = struct For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) let substitute_vars ( x : expr ) to_ = - create (gc x) (Z3native.substitute_vars (gnc x) (gno x) (Array.length to_) (aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (Array.length to_) (expr_aton to_)) - (** Translates (copies) the term to the Context . @param ctx A context @return A copy of the term which is associated with *) let translate ( x : expr ) to_ctx = - if (gc x) == to_ctx then + if (c_of_expr x) == to_ctx then x else - create to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) + expr_of_ptr to_ctx (Z3native.translate (nc_of_expr x) (ptr_of_expr x) (context_gno to_ctx)) (** Returns a string representation of the expression. *) - let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) + let to_string ( x : expr ) = Z3native.ast_to_string (nc_of_expr x) (ptr_of_expr x) (** Indicates whether the term is a numeral *) - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the term is well-sorted. @return True if the term is well-sorted, false otherwise. *) - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (nc_of_expr x) (ptr_of_expr x) (** The Sort of the term. *) - let get_sort ( x : expr ) = Sort.create (gc x) (Z3native.get_sort (gnc x) (gno x)) + let get_sort ( x : expr ) = sort_of_ptr (c_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the term has Boolean sort. *) let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (gnc x) - (Z3native.mk_bool_sort (gnc x)) - (Z3native.get_sort (gnc x) (gno x))) + (Z3native.is_eq_sort (nc_of_expr x) + (Z3native.mk_bool_sort (nc_of_expr x)) + (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x))) (** Indicates whether the term represents a constant. @@ -1366,14 +1480,14 @@ end = struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : Sort.sort ) = - create ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) + let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) (** Creates a new Constant of sort and named . *) - let mk_const_s ( ctx : context ) ( name : string ) ( range : Sort.sort ) = + let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) range @@ -1381,21 +1495,21 @@ end = struct Creates a constant from the func_decl . @param f An expression of a 0-arity function *) - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = - create_fa ctx f [||] + let mk_const_f ( ctx : context ) ( f : func_decl ) = + expr_of_func_app ctx f [||] (** Creates a fresh constant of sort and a name prefixed with . *) - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : Sort.sort ) = - create ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) (** Create a new function application. *) - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = - create_fa ctx f args + let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = + expr_of_func_app ctx f args (** Create a numeral of a given sort. @@ -1403,8 +1517,8 @@ end = struct @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. @return A Term with value and sort *) - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : Sort.sort ) = - create ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. @@ -1413,50 +1527,31 @@ end = struct @param ty Sort of the numeral @return A Term with value and type *) - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : Sort.sort ) = - create ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) end (** Boolean expressions *) -and Booleans : -sig - type bool_expr = BoolExpr of Expr.expr - type bool_sort = BoolSort of Sort.sort +module Boolean = +struct + let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let a = (ast_of_ptr ctx no) in + BoolExpr(Expr(a)) - val create_expr : context -> Z3native.ptr -> bool_expr - val create_sort : context -> Z3native.ptr -> bool_sort - val gc : bool_expr -> context - val gnc : bool_expr -> Z3native.ptr - val gno : bool_expr -> Z3native.ptr - val aton : bool_expr array -> Z3native.ptr array -end = struct - type bool_expr = BoolExpr of Expr.expr - type bool_sort = BoolSort of Sort.sort - - (**/**) - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.create ctx no) in - BoolExpr(Expr.Expr(a)) + let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + BoolSort(sort_of_ptr ctx no) - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - BoolSort(Sort.create ctx no) - - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gc e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gnc e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.gno e) - - let aton ( a : bool_expr array ) = - let f (e : bool_expr) = (gno e) in - Array.map f a - (**/**) + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (c_of_expr e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (nc_of_expr e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (ptr_of_expr e) let mk_sort ( ctx : context ) = - BoolSort(Sort.create ctx (Z3native.mk_bool_sort (context_gno ctx))) + BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) (** Create a Boolean constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : symbol ) = let s = (match (mk_sort ctx) with BoolSort(q) -> q) in BoolExpr(Expr.mk_const ctx name s) @@ -1470,13 +1565,13 @@ end = struct The true Term. *) let mk_true ( ctx : context ) = - create_expr ctx (Z3native.mk_true (context_gno ctx)) + bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) (** The false Term. *) let mk_false ( ctx : context ) = - create_expr ctx (Z3native.mk_false (context_gno ctx)) + bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) (** Creates a Boolean value. @@ -1487,20 +1582,20 @@ end = struct (** Creates the equality = . *) - let mk_eq ( ctx : context ) ( x : Expr.expr ) ( y : Expr.expr ) = - create_expr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) (** Creates a distinct term. *) - let mk_distinct ( ctx : context ) ( args : Expr.expr array ) = - create_expr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (Expr.aton args)) + let mk_distinct ( ctx : context ) ( args : expr array ) = + bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (expr_aton args)) (** Mk an expression representing not(a). *) let mk_not ( ctx : context ) ( a : bool_expr ) = - create_expr ctx (Z3native.mk_not (context_gno ctx) (gno a)) + bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) (** Create an expression representing an if-then-else: ite(t1, t2, t3). @@ -1509,103 +1604,70 @@ end = struct @param t3 An expression with the same sort as *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - create_expr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) (** Create an expression representing t1 iff t2. *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create_expr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 -> t2. *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create_expr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing t1 xor t2. *) let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - create_expr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) (** Create an expression representing the AND of args *) let mk_and ( ctx : context ) ( args : bool_expr array ) = - create_expr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (aton args)) + let f x = (ptr_of_expr (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (Array.map f args)) (** Create an expression representing the OR of args *) let mk_or ( ctx : context ) ( args : bool_expr array ) = - create_expr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (aton args)) + let f x = (ptr_of_expr (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (Array.map f args)) end (** Quantifier expressions *) -and Quantifiers : -sig - type quantifier = Quantifier of Expr.expr - - val create : context -> Z3native.ptr -> quantifier -end = struct - type quantifier = Quantifier of Expr.expr - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.create ctx no) in - Quantifier(Expr.Expr(a)) - - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - (**/**) - +module Quantifier = +struct + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (c_of_expr e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) + (** Quantifier patterns Patterns comprise a list of terms. The list should be non-empty. If the list comprises of more than one term, it is also called a multi-pattern. *) - module Patterns : - sig - type pattern = Pattern of AST.ast - - val create : context -> Z3native.ptr -> pattern - val aton : pattern array -> Z3native.ptr array - end = struct - type pattern = Pattern of AST.ast - - (**/**) - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - Pattern(res) - + module Pattern = struct let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - let aton (a : pattern array) = - let f (e : pattern) = (gno e) in - Array.map f a - (**/**) - (** The number of terms in the pattern. *) let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - + Z3native.get_pattern_num_terms (gnc x) (gno x) + (** The terms in the pattern. *) let get_terms ( x : pattern ) = let n = (get_num_terms x) in - let f i = (Expr.create (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in + let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in Array.init n f (** @@ -1632,11 +1694,11 @@ end = struct on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its index. *) - let get_index ( x : Expr.expr ) = - if not (AST.is_var (match x with Expr.Expr(a) -> a)) then + let get_index ( x : expr ) = + if not (AST.is_var (match x with Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else - Z3native.get_index_value (Expr.gnc x) (Expr.gno x) + Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) (** Indicates whether the quantifier is universal. @@ -1664,7 +1726,7 @@ end = struct *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = (Patterns.create (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1677,7 +1739,7 @@ end = struct *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = (Patterns.create (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1698,31 +1760,31 @@ end = struct *) let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in - let f i = (Sort.create (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in + let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in Array.init n f (** The body of the quantifier. *) let get_body ( x : quantifier ) = - Booleans.create_expr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) (** Creates a new bound variable. @param index The de-Bruijn index of the variable @param ty The sort of the variable *) - let mk_bound ( ctx : context ) ( index : int ) ( ty : Sort.sort ) = - Expr.create ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) (** Create a quantifier pattern. *) - let mk_pattern ( ctx : context ) ( terms : Expr.expr array ) = + let mk_pattern ( ctx : context ) ( terms : expr array ) = if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - Patterns.create ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (Expr.aton terms)) + Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) (** Create a universal Quantifier. @@ -1743,96 +1805,96 @@ end = struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (Patterns.aton patterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) - + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) + (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (ptr_of_expr body))) (** Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (Patterns.aton patterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Array.length sorts) (Sort.aton sorts) - (Symbol.aton names) - (Expr.gno body)) - + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (let f x = (Symbol.gno x) in (Array.map f names)) + (ptr_of_expr body))) + (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - create ctx (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (ptr_of_expr body))) else - create ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (Expr.aton bound_constants) - (Array.length patterns) (Patterns.aton patterns) - (Array.length nopatterns) (Expr.aton nopatterns) - (Expr.gno body)) + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (Array.length bound_constants) (expr_aton bound_constants) + (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length nopatterns) (expr_aton nopatterns) + (ptr_of_expr body))) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : Sort.sort array ) ( names : Symbol.symbol array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -1842,7 +1904,7 @@ end = struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : Expr.expr array ) ( body : Expr.expr ) ( weight : int option ) ( patterns : Patterns.pattern array ) ( nopatterns : Expr.expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -1850,42 +1912,29 @@ end = struct end (** Functions to manipulate Array expressions *) -and Arrays : -sig - type array_expr = ArrayExpr of Expr.expr - type array_sort = ArraySort of Sort.sort - - val create_expr : context -> Z3native.ptr -> array_expr -end = struct - type array_expr = ArrayExpr of Expr.expr - type array_sort = ArraySort of Sort.sort - - (**/**) +module Array_ = +struct + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (Expr.create ctx no) in + let e = (expr_of_ptr ctx no) in ArrayExpr(e) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in ArraySort(s) - let sgc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : array_sort ) = match (x) with ArraySort(Sort.Sort(s)) -> (z3obj_gno s) + let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) - let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gc e) - let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gnc e) - let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr.Expr(e)) -> (z3obj_gno e) + let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) + let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) + let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - let aton (a : array_expr array) = - let f (e : array_expr) = (egno e) in - Array.map f a - (**/**) - (** Create a new array sort. *) - let mk_sort ( ctx : context ) ( domain : Sort.sort ) ( range : Sort.sort ) = + let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = create_sort ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) (** @@ -1893,62 +1942,62 @@ end = struct It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). Array store takes at least 3 arguments. *) - let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) (** Indicates whether the term is an array select. *) - let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) (** Indicates whether the term is a constant array. For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - let is_constant_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) (** Indicates whether the term is a default array. For example default(const(v)) = v. The function is unary. *) - let is_default_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) (** Indicates whether the term is an array map. It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - let is_array_map ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) (** Indicates whether the term is an as-array term. An as-array term is n array value that behaves as the function graph of the function passed as parameter. *) - let is_as_array ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) (** Indicates whether the term is of an array sort. *) - let is_array ( x : Expr.expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) + let is_array ( x : expr ) = + (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) (** The domain of the array sort. *) - let get_domain ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) + let get_domain ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) (** The range of the array sort. *) - let get_range ( x : array_sort ) = Sort.create (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) + let get_range ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : Sort.sort ) ( range : Sort.sort ) = + let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) (** Create an array constant. *) - let mk_const_s ( ctx : context ) ( name : string ) ( domain : Sort.sort ) ( range : Sort.sort ) = + let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range (** @@ -1963,8 +2012,8 @@ end = struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) = - create_expr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = + expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) (** Array update. @@ -1982,8 +2031,8 @@ end = struct *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : Expr.expr ) ( v : Expr.expr ) = - create_expr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = + expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) (** Create a constant array. @@ -1993,8 +2042,8 @@ end = struct *) - let mk_const_array ( ctx : context ) ( domain : Sort.sort ) ( v : Expr.expr ) = - create_expr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) + let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = + expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) (** Maps f on the argument arrays. @@ -2006,8 +2055,9 @@ end = struct *) - let mk_map ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : array_expr array ) = - create_expr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (aton args)) + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = + let m x = (ptr_of_expr (expr_of_array_expr x)) in + expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) (** Access the array default value. @@ -2016,137 +2066,122 @@ end = struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - create_expr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) + expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end (** Functions to manipulate Set expressions *) -and Sets : -sig - type set_sort = SetSort of Sort.sort - -end = struct - type set_sort = SetSort of Sort.sort - +module Set = +struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in SetSort(s) (** Indicates whether the term is set union *) - let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) (** Indicates whether the term is set intersection *) - let is_intersect ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) (** Indicates whether the term is set difference *) - let is_difference ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) (** Indicates whether the term is set complement *) - let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) (** Indicates whether the term is set subset *) - let is_subset ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) (** Create a set type. *) - let mk_sort ( ctx : context ) ( ty : Sort.sort ) = + let mk_sort ( ctx : context ) ( ty : sort ) = create_sort ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) (** Create an empty set. *) - let mk_empty ( ctx : context ) ( domain : Sort.sort ) = - (Expr.create ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) + let mk_empty ( ctx : context ) ( domain : sort ) = + (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) (** Create the full set. *) - let mk_full ( ctx : context ) ( domain : Sort.sort ) = - Expr.create ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) + let mk_full ( ctx : context ) ( domain : sort ) = + expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) (** Add an element to the set. *) - let mk_set_add ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) + let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) (** Remove an element from a set. *) - let mk_del ( ctx : context ) ( set : Expr.expr ) ( element : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) + let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) (** Take the union of a list of sets. *) - let mk_union ( ctx : context ) ( args : Expr.expr array ) = - Expr.create ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (Expr.aton args)) + let mk_union ( ctx : context ) ( args : expr array ) = + expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (expr_aton args)) (** Take the intersection of a list of sets. *) - let mk_intersection ( ctx : context ) ( args : Expr.expr array ) = - Expr.create ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (Expr.aton args)) + let mk_intersection ( ctx : context ) ( args : expr array ) = + expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (expr_aton args)) (** Take the difference between two sets. *) - let mk_difference ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) (** Take the complement of a set. *) - let mk_complement ( ctx : context ) ( arg : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) + let mk_complement ( ctx : context ) ( arg : expr ) = + expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (ptr_of_expr arg)) (** Check for set membership. *) - let mk_membership ( ctx : context ) ( elem : Expr.expr ) ( set : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) + let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (ptr_of_expr elem) (ptr_of_expr set)) (** Check for subsetness of sets. *) - let mk_subset ( ctx : context ) ( arg1 : Expr.expr ) ( arg2 : Expr.expr ) = - Expr.create ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) end (** Functions to manipulate Finite Domain expressions *) -and FiniteDomains : -sig - type finite_domain_sort = FiniteDomainSort of Sort.sort - -end = struct - type finite_domain_sort = FiniteDomainSort of Sort.sort - - (**/**) - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in - FiniteDomainSort(s) - - let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gc s) - let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s)) -> (z3obj_gnc s) - let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) - +module FiniteDomain = +struct + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) + (** Create a new finite domain sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - create_sort ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size) + let mk_sort ( ctx : context ) ( name : symbol ) ( size : int ) = + let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in + FiniteDomainSort(s) (** Create a new finite domain sort. @@ -2158,14 +2193,15 @@ end = struct (** Indicates whether the term is of an array sort. *) - let is_finite_domain ( x : Expr.expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == FINITE_DOMAIN_SORT) + let is_finite_domain ( x : expr ) = + let nc = (nc_of_expr x) in + (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == FINITE_DOMAIN_SORT) (** Indicates whether the term is a less than predicate over a finite domain. *) - let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) (** The size of the finite domain sort. *) let get_size ( x : finite_domain_sort ) = @@ -2175,29 +2211,25 @@ end = struct end (** Functions to manipulate Relation expressions *) -and Relations : -sig - type relation_sort = RelationSort of Sort.sort - -end = struct - type relation_sort = RelationSort of Sort.sort - - (**/**) +module Relation = +struct + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in RelationSort(s) - let gc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gc s) - let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s)) -> (z3obj_gnc s) - let gno ( x : relation_sort ) = match (x) with RelationSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) + (** Indicates whether the term is of a relation sort. *) - let is_relation ( x : Expr.expr ) = - ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) == RELATION_SORT)) + let is_relation ( x : expr ) = + let nc = (nc_of_expr x) in + ((Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == RELATION_SORT)) (** Indicates whether the term is an relation store @@ -2206,40 +2238,40 @@ end = struct The function takes n+1 arguments, where the first argument is the relation and the remaining n elements correspond to the n columns of the relation. *) - let is_store ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) (** Indicates whether the term is an empty relation *) - let is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) (** Indicates whether the term is a test for the emptiness of a relation *) - let is_is_empty ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) (** Indicates whether the term is a relational join *) - let is_join ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) (** Indicates whether the term is the union or convex hull of two relations. The function takes two arguments. *) - let is_union ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) (** Indicates whether the term is the widening of two relations The function takes two arguments. *) - let is_widen ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). The function takes one argument. *) - let is_project ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) (** Indicates whether the term is a relation filter @@ -2250,7 +2282,7 @@ end = struct corresponding to the columns of the relation. So the first column in the relation has index 0. *) - let is_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) (** Indicates whether the term is an intersection of a relation with the negation of another. @@ -2265,7 +2297,7 @@ end = struct target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with ( x : expr ) on the columns c1, d1, .., cN, dN. *) - let is_negation_filter ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) (** Indicates whether the term is the renaming of a column in a relation @@ -2273,12 +2305,12 @@ end = struct The function takes one argument. The parameters contain the renaming as a cycle. *) - let is_rename ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) (** Indicates whether the term is the complement of a relation *) - let is_complement ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) (** Indicates whether the term is a relational select @@ -2287,7 +2319,7 @@ end = struct The function takes n+1 arguments, where the first argument is a relation, and the remaining n arguments correspond to a record. *) - let is_select ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) (** Indicates whether the term is a relational clone (copy) @@ -2298,7 +2330,7 @@ end = struct for terms of kind to perform destructive updates to the first argument. *) - let is_clone ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) (** The arity of the relation sort. *) let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) @@ -2312,46 +2344,22 @@ end = struct end (** Functions to manipulate Datatype expressions *) -and Datatypes : -sig - type datatype_expr = DatatypeExpr of Expr.expr - type datatype_sort = DatatypeSort of Sort.sort - - val create_expr : context -> Z3native.ptr -> datatype_expr -end = struct - type datatype_expr = DatatypeExpr of Expr.expr - type datatype_sort = DatatypeSort of Sort.sort - - (**/**) - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (Expr.create ctx no) in - DatatypeExpr(e) - +module Datatype = +struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in DatatypeSort(s) - let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) + (** Constructors *) - module Constructor : sig - type constructor - val create : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> constructor - val aton : constructor array -> Z3native.ptr array - end = struct - type constructor_extra = { - m_n : int; - mutable m_tester_decl : FuncDecl.func_decl option; - mutable m_constructor_decl : FuncDecl.func_decl option ; - mutable m_accessor_decls : FuncDecl.func_decl array option} - - type constructor = Constructor of (z3_native_object * constructor_extra) - - (**/**) - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + module Constructor = + struct + + let create ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -2362,8 +2370,8 @@ end = struct let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) n - (Symbol.aton field_names) - (Sort.aton sorts) + (let f x = (Symbol.gno x) in (Array.map f field_names)) + (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) sort_refs) in let no : z3_native_object = { m_ctx = ctx ; m_n_obj = null ; @@ -2379,21 +2387,17 @@ end = struct Gc.finalise f no ; Constructor(no, ex) - let aton ( a : constructor array ) = - let f (e : constructor) = match e with Constructor(no, ex) -> (z3obj_gno no)in - Array.map f a - let init_extra ( x : constructor ) = match x with Constructor(no, ex) -> match ex.m_tester_decl with | None -> let (a, b, c) = (Z3native.query_constructor (z3obj_gnc no) (z3obj_gno no) ex.m_n) in - ex.m_constructor_decl <- Some (FuncDecl.create (z3obj_gc no) a) ; - ex.m_tester_decl <- Some (FuncDecl.create (z3obj_gc no) b) ; - ex.m_accessor_decls <- Some (let f e = (FuncDecl.create (z3obj_gc no) e) in Array.map f c) ; + ex.m_constructor_decl <- Some (func_decl_of_ptr (z3obj_gc no) a) ; + ex.m_tester_decl <- Some (func_decl_of_ptr (z3obj_gc no) b) ; + ex.m_accessor_decls <- Some (let f e = (func_decl_of_ptr (z3obj_gc no) e) in Array.map f c) ; () | _ -> () - (**/**) + let get_n ( x : constructor ) = match x with Constructor(no, ex) -> @@ -2433,24 +2437,18 @@ end = struct (** Constructor list objects *) module ConstructorList = struct - type constructor_list = z3_native_object - - (**/**) - let create ( ctx : context )( c : Constructor.constructor array ) = + + let create ( ctx : context ) ( c : constructor array ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Constructor.aton c))) ; + let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Array.map f c))) ; (z3obj_create res) ; let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f res; res - - let aton (a : constructor_list array) = - let f (e : constructor_list) = (z3obj_gno e) in - Array.map f a - (**/**) end (* DATATYPES *) @@ -2464,7 +2462,7 @@ end = struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array) = + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = Constructor.create ctx name recognizer field_names sorts sort_refs @@ -2478,21 +2476,22 @@ end = struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array) = - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Constructor.aton constructors)) in + let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = + let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in create_sort ctx x (** Create a new datatype sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors (** @@ -2500,16 +2499,17 @@ end = struct @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = + let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = let n = (Array.length names) in - let f e = (ConstructorList.create ctx e) in + let f e = (ptr_of_ast (ConstructorList.create ctx e)) in let cla = (Array.map f c) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.aton names) (ConstructorList.aton cla)) in + let f2 x = (Symbol.gno x) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Array.map f2 names) cla) in let g e = (create_sort ctx e) in (Array.map g r) (** Create mutually recursive data-types. *) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in @@ -2523,54 +2523,50 @@ end = struct (** The range of the array sort. *) let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in Array.init n f (** The recognizers. *) let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in - let f i = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in Array.init n f (** The constructor accessors. *) let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = ( - let fd = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = FuncDecl.create (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in + let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in Array.init ds g ) in Array.init n f end (** Functions to manipulate Enumeration expressions *) -and Enumerations : -sig - type enum_sort_data - type enum_sort = EnumSort of (Sort.sort * enum_sort_data) -end = struct - type enum_sort_data = { mutable _constdecls : FuncDecl.func_decl array ; - mutable _testerdecls : FuncDecl.func_decl array } - type enum_sort = EnumSort of (Sort.sort * enum_sort_data) - - (**/**) +module Enumeration = +struct + let _constdecls = Hashtbl.create 0 + let _testerdecls = Hashtbl.create 0 + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = - let s = (Sort.create ctx no) in - let e = { _constdecls = (let f e = FuncDecl.create ctx e in (Array.map f cdecls)) ; - _testerdecls = (let f e = FuncDecl.create ctx e in (Array.map f tdecls)) } in - EnumSort(s, e) + let s = (sort_of_ptr ctx no) in + let res = EnumSort(s) in + Hashtbl.add _constdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f cdecls)) ; + Hashtbl.add _testerdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f tdecls)) ; + res - let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gc s) - let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_) -> (z3obj_gnc s) - let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort.Sort(s),_)-> (z3obj_gno s) - (**/**) + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) (** Create a new enumeration sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Symbol.aton enum_names)) in + let mk_sort ( ctx : context ) ( name : symbol ) ( enum_names : symbol array ) = + let f x = Symbol.gno x in + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in create_sort ctx a b c (** @@ -2580,45 +2576,40 @@ end = struct mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) - let get_const_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._constdecls + let get_const_decls ( x : enum_sort ) = Hashtbl.find _constdecls x (** The test predicates for the constants in the enumeration. *) - let get_tester_decls ( x : enum_sort ) = match x with EnumSort(_,ex) -> ex._testerdecls + let get_tester_decls ( x : enum_sort ) = Hashtbl.find _testerdecls x end (** Functions to manipulate List expressions *) -and Lists : -sig - type list_sort_data - type list_sort = ListSort of (Sort.sort * list_sort_data) - -end = struct - type list_sort_data = { _nildecl : FuncDecl.func_decl ; - _is_nildecl : FuncDecl.func_decl ; - _consdecl : FuncDecl.func_decl ; - _is_consdecl : FuncDecl.func_decl ; - _headdecl : FuncDecl.func_decl ; - _taildecl : FuncDecl.func_decl } - type list_sort = ListSort of (Sort.sort * list_sort_data) - - (**/**) +module List_ = +struct + let _nildecls = Hashtbl.create 0 + let _is_nildecls = Hashtbl.create 0 + let _consdecls = Hashtbl.create 0 + let _is_consdecls = Hashtbl.create 0 + let _headdecls = Hashtbl.create 0 + let _taildecls = Hashtbl.create 0 + let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = - let s = (Sort.create ctx no) in - let e = {_nildecl = FuncDecl.create ctx nildecl; - _is_nildecl = FuncDecl.create ctx is_nildecl; - _consdecl = FuncDecl.create ctx consdecl; - _is_consdecl = FuncDecl.create ctx is_consdecl; - _headdecl = FuncDecl.create ctx headdecl; - _taildecl = FuncDecl.create ctx taildecl} in - ListSort(s, e) + let s = (sort_of_ptr ctx no) in + let res = ListSort(s) in + Hashtbl.add _nildecls res (func_decl_of_ptr ctx nildecl) ; + Hashtbl.add _is_nildecls res (func_decl_of_ptr ctx is_nildecl) ; + Hashtbl.add _consdecls res (func_decl_of_ptr ctx consdecl) ; + Hashtbl.add _is_consdecls res (func_decl_of_ptr ctx is_consdecl) ; + Hashtbl.add _headdecls res (func_decl_of_ptr ctx headdecl) ; + Hashtbl.add _taildecls res (func_decl_of_ptr ctx taildecl) ; + res - let sgc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gc s) - let sgnc ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_) -> (z3obj_gnc s) - let sgno ( x : list_sort ) = match (x) with ListSort(Sort.Sort(s),_)-> (z3obj_gno s) - (**/**) + let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) + (** Create a new list sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : Sort.sort ) = + let mk_sort ( ctx : context ) ( name : symbol ) ( elem_sort : sort ) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in create_sort ctx r a b c d e f @@ -2627,53 +2618,51 @@ end = struct mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) - let get_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._nildecl + let get_nil_decl ( x : list_sort ) = (Hashtbl.find _nildecls x) (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_nildecl + let get_is_nil_decl ( x : list_sort ) = (Hashtbl.find _is_nildecls x) (** The declaration of the cons function of this list sort. *) - let get_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._consdecl + let get_cons_decl ( x : list_sort ) = (Hashtbl.find _consdecls x) (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._is_consdecl + let get_is_cons_decl ( x : list_sort ) = (Hashtbl.find _is_consdecls x) (** The declaration of the head function of this list sort. *) - let get_head_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._headdecl + let get_head_decl ( x : list_sort ) = (Hashtbl.find _headdecls x) (** The declaration of the tail function of this list sort. *) - let get_tail_decl ( x : list_sort ) = match x with ListSort(no, ex) -> ex._taildecl + let get_tail_decl ( x : list_sort ) = (Hashtbl.find _taildecls x) (** The empty list. *) - let nil ( x : list_sort ) = Expr.create_fa (sgc x) (get_nil_decl x) [||] + let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] end (** Functions to manipulate Tuple expressions *) -and Tuples : -sig - type tuple_sort = TupleSort of Sort.sort -end = struct - type tuple_sort = TupleSort of Sort.sort - - (**/**) +module Tuple = +struct + let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - let s = (Sort.create ctx no) in + let s = (sort_of_ptr ctx no) in TupleSort(s) - let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort.Sort(s))-> (z3obj_gno s) - (**/**) + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) + (** Create a new tuple sort. *) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : Sort.sort array ) = - let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Symbol.aton field_names) (Sort.aton field_sorts)) in + let mk_sort ( ctx : context ) ( name : symbol ) ( field_names : symbol array ) ( field_sorts : sort array ) = + let f x = Symbol.gno x in + let f2 x = ptr_of_ast (ast_of_sort x) in + let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in (* CMW: leaks a,b? *) create_sort ctx r (** The constructor function of the tuple. *) let get_mk_decl ( x : tuple_sort ) = - FuncDecl.create (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) + func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) (** The number of fields in the tuple. *) let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) @@ -2681,131 +2670,37 @@ end = struct (** The field declarations. *) let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in - let f i = FuncDecl.create (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in Array.init n f end (** Functions to manipulate arithmetic expressions *) -and Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val create_expr : context -> Z3native.ptr -> arith_expr - val create_sort : context -> Z3native.ptr -> arith_sort - val aton : arith_expr array -> Z3native.ptr array - - module Integers : sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val create_sort : context -> Z3native.ptr -> int_sort - val create_expr : context -> Z3native.ptr -> int_expr - val create_num : context -> Z3native.ptr -> int_num - end - - module Reals : sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val create_sort : context -> Z3native.ptr -> real_sort - val create_expr : context -> Z3native.ptr -> real_expr - val create_num : context -> Z3native.ptr -> rat_num - end - - module AlgebraicNumbers : sig - type algebraic_num = AlgebraicNum of arith_expr - - val create_num : context -> Z3native.ptr -> algebraic_num - end - - val is_int : Expr.expr -> bool - val is_arithmetic_numeral : Expr.expr -> bool - val is_le : Expr.expr -> bool - val is_ge : Expr.expr -> bool - val is_lt : Expr.expr -> bool - val is_gt : Expr.expr -> bool - val is_add : Expr.expr -> bool - val is_sub : Expr.expr -> bool - val is_uminus : Expr.expr -> bool - val is_mul : Expr.expr -> bool - val is_div : Expr.expr -> bool - val is_idiv : Expr.expr -> bool - val is_remainder : Expr.expr -> bool - val is_modulus : Expr.expr -> bool - val is_inttoreal : Expr.expr -> bool - val is_real_to_int : Expr.expr -> bool - val is_real_is_int : Expr.expr -> bool - val is_real : Expr.expr -> bool - val is_int_numeral : Expr.expr -> bool - val is_rat_num : Expr.expr -> bool - val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr array -> Arithmetic.arith_expr - val mk_mul : context -> arith_expr array -> Arithmetic.arith_expr - val mk_sub : context -> arith_expr array -> Arithmetic.arith_expr - val mk_unary_minus : - context -> arith_expr -> Arithmetic.arith_expr - val mk_div : - context -> arith_expr -> arith_expr -> Arithmetic.arith_expr - val mk_power : - context -> arith_expr -> arith_expr -> Arithmetic.arith_expr - val mk_lt : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - val mk_le : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - val mk_gt : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - val mk_ge : - context -> arith_expr -> arith_expr -> Booleans.bool_expr - -end = struct - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - (**/**) +module Arithmetic = +struct + let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - ArithExpr(Expr.create ctx no) + arith_expr_of_expr (expr_of_ptr ctx no) let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - ArithSort(Sort.create ctx no) + arith_sort_of_sort (sort_of_ptr ctx no) - let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gc s) - let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gnc s) - let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort.Sort(s)) -> (z3obj_gno s) - let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) - let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) - let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) + let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) + let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (c_of_expr e) + let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (nc_of_expr e) + let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (ptr_of_expr e) - let aton (a : arith_expr array) = - let f (e : arith_expr) = (egno e) in - Array.map f a - (**/**) - - module rec Integers : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val create_sort : context -> Z3native.ptr -> int_sort - val create_expr : context -> Z3native.ptr -> int_expr - val create_num : context -> Z3native.ptr -> int_num - end = struct - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - (**/**) + module Integer = + struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - IntSort(Arithmetic.create_sort ctx no) + int_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - IntExpr(Arithmetic.create_expr ctx no) + int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) let create_num ( ctx : context ) ( no : Z3native.ptr ) = - IntNum(create_expr ctx no) + int_num_of_int_expr (create_expr ctx no) let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) @@ -2816,7 +2711,7 @@ end = struct let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - (**/**) + (** Create a new integer sort. *) let mk_sort ( ctx : context ) = @@ -2834,7 +2729,7 @@ end = struct (** Creates an integer constant. *) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_int_const ( ctx : context ) ( name : symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) (** @@ -2848,14 +2743,14 @@ end = struct The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - create_expr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - create_expr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) (** Create an integer numeral. @@ -2883,7 +2778,7 @@ end = struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - Reals.create_expr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)) + real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) (** Create an bit bit-vector from the integer argument . @@ -2896,32 +2791,19 @@ end = struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVectors.create_expr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t)) + bitvec_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) end - and Reals : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val create_sort : context -> Z3native.ptr -> real_sort - val create_expr : context -> Z3native.ptr -> real_expr - val create_num : context -> Z3native.ptr -> rat_num - end = struct - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - (**/**) + module Real = + struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - RealSort(Arithmetic.create_sort ctx no) + real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - RealExpr(Arithmetic.create_expr ctx no) - + real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + let create_num ( ctx : context ) ( no : Z3native.ptr ) = - RatNum(create_expr ctx no) + rat_num_of_real_expr (create_expr ctx no) let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) @@ -2932,7 +2814,7 @@ end = struct let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - (**/**) + (** Create a real sort. *) let mk_sort ( ctx : context ) = @@ -2940,11 +2822,11 @@ end = struct (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = - Integers.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + Integer.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = - Integers.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + Integer.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2955,7 +2837,7 @@ end = struct let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) (** Creates a real constant. *) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_real_const ( ctx : context ) ( name : symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) (** Creates a real constant. *) @@ -2995,7 +2877,7 @@ end = struct (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - Booleans.create_expr ctx (Z3native.mk_is_int (context_gno ctx) (egno t)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) (** Coerce a real to an integer. @@ -3005,25 +2887,18 @@ end = struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - Integers.create_expr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)) + int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) end - and AlgebraicNumbers : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val create_num : context -> Z3native.ptr -> algebraic_num - end = struct - type algebraic_num = AlgebraicNum of arith_expr - - (**/**) + module AlgebraicNumber = + struct let create_num ( ctx : context ) ( no : Z3native.ptr ) = - AlgebraicNum(Arithmetic.create_expr ctx no) + algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - (**/**) + (** Return a upper bound for a given real algebraic number. @@ -3033,7 +2908,7 @@ end = struct @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = - Reals.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + Real.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) (** Return a lower bound for the given real algebraic number. @@ -3043,7 +2918,7 @@ end = struct @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = - Reals.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + Real.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -3057,207 +2932,197 @@ end = struct (** Indicates whether the term is of integer sort. *) - let is_int ( x : Expr.expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) + let is_int ( x : expr ) = + (Z3native.is_numeral_ast (nc_of_expr x) (nc_of_expr x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == INT_SORT) (** Indicates whether the term is an arithmetic numeral. *) - let is_arithmetic_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) (** Indicates whether the term is a less-than-or-equal *) - let is_le ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) (** Indicates whether the term is a greater-than-or-equal *) - let is_ge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) (** Indicates whether the term is a less-than *) - let is_lt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) (** Indicates whether the term is a greater-than *) - let is_gt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) (** Indicates whether the term is addition (binary) *) - let is_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) (** Indicates whether the term is subtraction (binary) *) - let is_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) (** Indicates whether the term is a unary minus *) - let is_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) (** Indicates whether the term is multiplication (binary) *) - let is_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) (** Indicates whether the term is division (binary) *) - let is_div ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) (** Indicates whether the term is integer division (binary) *) - let is_idiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) (** Indicates whether the term is remainder (binary) *) - let is_remainder ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) (** Indicates whether the term is modulus (binary) *) - let is_modulus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) (** Indicates whether the term is a coercion of integer to real (unary) *) - let is_inttoreal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) (** Indicates whether the term is a coercion of real to integer (unary) *) - let is_real_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - let is_real_is_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) (** Indicates whether the term is of sort real. *) - let is_real ( x : Expr.expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == REAL_SORT) (** Indicates whether the term is an integer numeral. *) - let is_int_numeral ( x : Expr.expr ) = (Expr.is_numeral x) && (is_int x) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) (** Indicates whether the term is a real numeral. *) - let is_rat_num ( x : Expr.expr ) = (Expr.is_numeral x) && (is_real x) + let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) (** Indicates whether the term is an algebraic number *) - let is_algebraic_number ( x : Expr.expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) (** Create an expression representing t[0] + t[1] + .... *) let mk_add ( ctx : context ) ( t : arith_expr array ) = - Arithmetic.create_expr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Arithmetic.aton t)) + let f x = (ptr_of_expr (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Array.map f t))) (** Create an expression representing t[0] * t[1] * .... *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = - Arithmetic.create_expr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Arithmetic.aton t)) + let f x = (ptr_of_expr (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Array.map f t))) (** Create an expression representing t[0] - t[1] - .... *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = - Arithmetic.create_expr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Arithmetic.aton t)) + let f x = (ptr_of_expr (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Array.map f t))) (** Create an expression representing -t. *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - Arithmetic.create_expr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t)) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) (** Create an expression representing t1 / t2. *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Arithmetic.create_expr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2)) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 ^ t2. *) let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Arithmetic.create_expr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2)) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Booleans.create_expr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) end (** Functions to manipulate bit-vector expressions *) -and BitVectors : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val create_sort : context -> Z3native.ptr -> bitvec_sort - val create_expr : context -> Z3native.ptr -> bitvec_expr - val create_num : context -> Z3native.ptr -> bitvec_num -end = struct - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - (**/**) +module BitVector = +struct let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - BitVecSort(Sort.create ctx no) + bitvec_sort_of_sort (sort_of_ptr ctx no) let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - BitVecExpr(Expr.create ctx no) + bitvec_expr_of_expr (expr_of_ptr ctx no) let create_num ( ctx : context ) ( no : Z3native.ptr ) = - BitVecNum(create_expr ctx no) + bitvec_num_of_bitvec_expr (create_expr ctx no) let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) - let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) - let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) - let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) + let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (c_of_expr e) + let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (nc_of_expr e) + let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (ptr_of_expr e) let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - (**/**) + (** Create a new bit-vector sort. @@ -3268,272 +3133,272 @@ end = struct (** Indicates whether the terms is of bit-vector sort. *) - let is_bv ( x : Expr.expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) + let is_bv ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == BV_SORT) (** Indicates whether the term is a bit-vector numeral *) - let is_bv_numeral ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) (** Indicates whether the term is a one-bit bit-vector with value one *) - let is_bv_bit1 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) (** Indicates whether the term is a one-bit bit-vector with value zero *) - let is_bv_bit0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) (** Indicates whether the term is a bit-vector unary minus *) - let is_bv_uminus ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) (** Indicates whether the term is a bit-vector addition (binary) *) - let is_bv_add ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) (** Indicates whether the term is a bit-vector subtraction (binary) *) - let is_bv_sub ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) (** Indicates whether the term is a bit-vector multiplication (binary) *) - let is_bv_mul ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) (** Indicates whether the term is a bit-vector signed division (binary) *) - let is_bv_sdiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) (** Indicates whether the term is a bit-vector unsigned division (binary) *) - let is_bv_udiv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) (** Indicates whether the term is a bit-vector signed remainder (binary) *) - let is_bv_SRem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - let is_bv_urem ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) (** Indicates whether the term is a bit-vector signed modulus *) - let is_bv_smod ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) (** Indicates whether the term is a bit-vector signed division by zero *) - let is_bv_sdiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) (** Indicates whether the term is a bit-vector unsigned division by zero *) - let is_bv_udiv0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) (** Indicates whether the term is a bit-vector signed remainder by zero *) - let is_bv_srem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - let is_bv_urem0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) (** Indicates whether the term is a bit-vector signed modulus by zero *) - let is_bv_smod0 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - let is_bv_ule ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - let is_bv_sle ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - let is_bv_uge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - let is_bv_sge ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) (** Indicates whether the term is an unsigned bit-vector less-than *) - let is_bv_ult ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) (** Indicates whether the term is a signed bit-vector less-than *) - let is_bv_slt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) (** Indicates whether the term is an unsigned bit-vector greater-than *) - let is_bv_ugt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) (** Indicates whether the term is a signed bit-vector greater-than *) - let is_bv_sgt ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) (** Indicates whether the term is a bit-wise AND *) - let is_bv_and ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) (** Indicates whether the term is a bit-wise OR *) - let is_bv_or ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) (** Indicates whether the term is a bit-wise NOT *) - let is_bv_not ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) (** Indicates whether the term is a bit-wise XOR *) - let is_bv_xor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) (** Indicates whether the term is a bit-wise NAND *) - let is_bv_nand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) (** Indicates whether the term is a bit-wise NOR *) - let is_bv_nor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) (** Indicates whether the term is a bit-wise XNOR *) - let is_bv_xnor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) (** Indicates whether the term is a bit-vector concatenation (binary) *) - let is_bv_concat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) (** Indicates whether the term is a bit-vector sign extension *) - let is_bv_signextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) (** Indicates whether the term is a bit-vector zero extension *) - let is_bv_zeroextension ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) (** Indicates whether the term is a bit-vector extraction *) - let is_bv_extract ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) (** Indicates whether the term is a bit-vector repetition *) - let is_bv_repeat ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) (** Indicates whether the term is a bit-vector reduce OR *) - let is_bv_reduceor ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) (** Indicates whether the term is a bit-vector reduce AND *) - let is_bv_reduceand ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) (** Indicates whether the term is a bit-vector comparison *) - let is_bv_comp ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) (** Indicates whether the term is a bit-vector shift left *) - let is_bv_shiftleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) (** Indicates whether the term is a bit-vector logical shift right *) - let is_bv_shiftrightlogical ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) (** Indicates whether the term is a bit-vector arithmetic shift left *) - let is_bv_shiftrightarithmetic ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) (** Indicates whether the term is a bit-vector rotate left *) - let is_bv_rotateleft ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right *) - let is_bv_rotateright ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) (** Indicates whether the term is a bit-vector rotate left (extended) Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotateleftextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) (** Indicates whether the term is a bit-vector rotate right (extended) Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - let is_bv_rotaterightextended ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_int_to_bv ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - let is_bv_to_int ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - let is_bv_carry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) (** Indicates whether the term is a bit-vector ternary XOR The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - let is_bv_xor3 ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) (** The size of a bit-vector sort. *) let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) @@ -3550,7 +3415,7 @@ end = struct (** Creates a bit-vector constant. *) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = BitVecExpr(Expr.mk_const ctx name (match (mk_sort ctx size) with BitVecSort(s) -> s)) (** @@ -3564,91 +3429,91 @@ end = struct The argument must have a bit-vector sort. *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = - create_expr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = - create_expr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) (** Bitwise conjunction. The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - create_expr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) + expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) (** Unsigned division. @@ -3660,7 +3525,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) (** Signed division. @@ -3675,7 +3540,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) (** Unsigned remainder. @@ -3685,7 +3550,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) (** Signed remainder. @@ -3697,7 +3562,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed remainder (sign follows divisor). @@ -3706,7 +3571,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than @@ -3714,7 +3579,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than @@ -3722,7 +3587,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) (** Unsigned less-than or equal to. @@ -3730,7 +3595,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than or equal to. @@ -3738,7 +3603,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater than or equal to. @@ -3746,7 +3611,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater than or equal to. @@ -3754,7 +3619,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater-than. @@ -3762,7 +3627,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater-than. @@ -3770,7 +3635,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) (** Bit-vector concatenation. @@ -3781,7 +3646,7 @@ end = struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector extraction. @@ -3792,7 +3657,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) + expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) (** Bit-vector sign extension. @@ -3802,7 +3667,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) (** Bit-vector zero extension. @@ -3813,7 +3678,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) (** Bit-vector repetition. @@ -3821,7 +3686,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) (** Shift left. @@ -3836,7 +3701,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) (** @@ -3851,7 +3716,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) (** Arithmetic shift right @@ -3867,7 +3732,7 @@ end = struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) (** Rotate Left. @@ -3876,7 +3741,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) (** Rotate Right. @@ -3885,7 +3750,7 @@ end = struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - create_expr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) + expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) (** Rotate Left. @@ -3894,7 +3759,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) (** Rotate Right. @@ -3904,7 +3769,7 @@ end = struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - create_expr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) + expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) (** Create an integer from the bit-vector argument . @@ -3922,7 +3787,7 @@ end = struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integers.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) + Arithmetic.Integer.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3930,7 +3795,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Booleans.create_expr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3938,7 +3803,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not overflow. @@ -3946,7 +3811,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3954,7 +3819,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Booleans.create_expr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3962,7 +3827,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3970,7 +3835,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3978,7 +3843,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Booleans.create_expr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3986,7 +3851,7 @@ end = struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Booleans.create_expr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2)) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a bit-vector numeral. @@ -3994,28 +3859,27 @@ end = struct @param v A string representing the value in decimal notation. @param size the size of the bit-vector *) - let mk_numeral ( ctx : context ) ( ctx : context ) ( v : string ) ( size : int) = + let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx size))) end (** Functions to manipulate proof expressions *) -and Proofs : -sig -end = struct +module Proof = +struct (** Indicates whether the term is a Proof for the expression 'true'. *) - let is_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) (** Indicates whether the term is a proof for a fact asserted by the user. *) - let is_asserted ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - let is_goal ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) (** Indicates whether the term is proof via modus ponens @@ -4026,7 +3890,7 @@ end = struct [mp T1 T2]: q The second antecedents may also be a proof for (iff p q). *) - let is_modus_ponens ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. @@ -4035,7 +3899,7 @@ end = struct equivalence modulo namings, equality and equivalence. That is, R is either '~', '=' or 'iff'. *) - let is_reflexivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) (** Indicates whether the term is proof by symmetricity of a relation @@ -4045,7 +3909,7 @@ end = struct [symmetry T1]: (R s t) T1 is the antecedent of this proof object. *) - let is_symmetry ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) (** Indicates whether the term is a proof by transitivity of a relation @@ -4056,7 +3920,7 @@ end = struct T2: (R s u) [trans T1 T2]: (R t u) *) - let is_transitivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) (** Indicates whether the term is a proof by condensed transitivity of a relation @@ -4076,7 +3940,7 @@ end = struct if there is a path from s to t, if we view every antecedent (R a b) as an edge between a and b. *) - let is_Transitivity_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) (** @@ -4089,7 +3953,7 @@ end = struct Remark: if t_i == s_i, then the antecedent Ti is suppressed. That is, reflexivity proofs are supressed to save space. *) - let is_monotonicity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) (** Indicates whether the term is a quant-intro proof @@ -4098,7 +3962,7 @@ end = struct T1: (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - let is_quant_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) (** Indicates whether the term is a distributivity proof object. @@ -4115,7 +3979,7 @@ end = struct Remark. This rule is used by the CNF conversion pass and instantiated by f = or, and g = and. *) - let is_distributivity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) (** Indicates whether the term is a proof by elimination of AND @@ -4124,7 +3988,7 @@ end = struct T1: (and l_1 ... l_n) [and-elim T1]: l_i *) - let is_and_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) (** Indicates whether the term is a proof by eliminiation of not-or @@ -4133,7 +3997,7 @@ end = struct T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) *) - let is_or_elimination ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) (** Indicates whether the term is a proof by rewriting @@ -4147,11 +4011,11 @@ end = struct Remark: if f is bool, then = is iff. Examples: - (= (+ ( x : Expr.expr ) 0) x) - (= (+ ( x : Expr.expr ) 1 2) (+ 3 x)) - (iff (or ( x : Expr.expr ) false) x) + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) - let is_rewrite ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) (** Indicates whether the term is a proof by rewriting @@ -4166,14 +4030,14 @@ end = struct - When converting bit-vectors to Booleans (BIT2BOOL=true) - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - let is_rewrite_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) (** Indicates whether the term is a proof for pulling quantifiers out. A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - let is_pull_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) (** Indicates whether the term is a proof for pulling quantifiers out. @@ -4182,7 +4046,7 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object has no antecedents *) - let is_pull_quant_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) (** Indicates whether the term is a proof for pushing quantifiers in. @@ -4195,7 +4059,7 @@ end = struct This proof object has no antecedents *) - let is_push_quant ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) (** Indicates whether the term is a proof for elimination of unused variables. @@ -4207,34 +4071,34 @@ end = struct This proof object has no antecedents. *) - let is_elim_unused_vars ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) (** Indicates whether the term is a proof for destructive equality resolution A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : Expr.expr ) t)) P[x])) P[t]) - if ( x : Expr.expr ) does not occur in t. + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. This proof object has no antecedents. Several variables can be eliminated simultaneously. *) - let is_der ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) (** Indicates whether the term is a proof for quantifier instantiation A proof of (or (not (forall (x) (P x))) (P a)) *) - let is_quant_inst ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) (** Indicates whether the term is a hypthesis marker. Mark a hypothesis in a natural deduction style proof. *) - let is_hypothesis ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) (** Indicates whether the term is a proof by lemma @@ -4246,7 +4110,7 @@ end = struct It converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 contains the hypotheses: l_1, ..., l_n. *) - let is_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) (** Indicates whether the term is a proof by unit resolution @@ -4257,7 +4121,7 @@ end = struct T(n+1): (not l_n) [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - let is_unit_resolution ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) (** Indicates whether the term is a proof by iff-true @@ -4265,7 +4129,7 @@ end = struct T1: p [iff-true T1]: (iff p true) *) - let is_iff_true ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) (** Indicates whether the term is a proof by iff-false @@ -4273,7 +4137,7 @@ end = struct T1: (not p) [iff-false T1]: (iff p false) *) - let is_iff_false ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) (** Indicates whether the term is a proof by commutativity @@ -4285,7 +4149,7 @@ end = struct This proof object has no antecedents. Remark: if f is bool, then = is iff. *) - let is_commutativity ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) (** Indicates whether the term is a proof for Tseitin-like axioms @@ -4320,7 +4184,7 @@ end = struct unfolding the Boolean connectives in the axioms a small bounded number of steps (=3). *) - let is_def_axiom ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) (** Indicates whether the term is a proof for introduction of a name @@ -4342,7 +4206,7 @@ end = struct Otherwise: [def-intro]: (= n e) *) - let is_def_intro ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) (** Indicates whether the term is a proof for application of a definition @@ -4351,7 +4215,7 @@ end = struct F is 'equivalent' to n, given that T1 is a proof that n is a name for F. *) - let is_apply_def ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) (** Indicates whether the term is a proof iff-oeq @@ -4359,7 +4223,7 @@ end = struct T1: (iff p q) [iff~ T1]: (~ p q) *) - let is_iff_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) (** Indicates whether the term is a proof for a positive NNF step @@ -4386,7 +4250,7 @@ end = struct NNF_NEG furthermore handles the case where negation is pushed over Boolean connectives 'and' and 'or'. *) - let is_nnf_pos ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) (** Indicates whether the term is a proof for a negative NNF step @@ -4410,7 +4274,7 @@ end = struct [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 r_2) (or r_1' r_2'))) *) - let is_nnf_neg ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. @@ -4421,7 +4285,7 @@ end = struct This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_nnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. @@ -4430,19 +4294,19 @@ end = struct This proof object is only used if the parameter PROOF_MODE is 1. This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - let is_cnf_star ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) (** Indicates whether the term is a proof for a Skolemization step Proof for: - [sk]: (~ (not (forall ( x : Expr.expr ) (p ( x : Expr.expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : Expr.expr ) (p ( x : Expr.expr ) y)) (p (sk y) y)) + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) This proof object has no antecedents. *) - let is_skolemize ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. @@ -4452,7 +4316,7 @@ end = struct T2: (~ p q) [mp~ T1 T2]: q *) - let is_modus_ponens_oeq ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) (** Indicates whether the term is a proof for theory lemma @@ -4470,7 +4334,7 @@ end = struct (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - let is_theory_lemma ( x : Expr.expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) + let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end @@ -4480,10 +4344,8 @@ end of formulas, that can be solved and/or transformed using tactics and solvers. *) module Goal = -struct - type goal = z3_native_object - - (**/**) +struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : goal = { m_ctx = ctx ; m_n_obj = null ; @@ -4492,7 +4354,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** The precision of the goal. @@ -4521,8 +4383,8 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) - let assert_ ( x : goal ) ( constraints : Booleans.bool_expr array ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) in + let assert_ ( x : goal ) ( constraints : bool_expr array ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in ignore (Array.map f constraints) ; () @@ -4543,7 +4405,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = Booleans.create_expr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) @@ -4562,7 +4424,7 @@ struct create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - let simplify ( x : goal ) ( p : Params.params option ) = + let simplify ( x : goal ) ( p : params option ) = let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in Z3native.tactic_inc_ref (z3obj_gnc x) tn ; let arn = match p with @@ -4602,9 +4464,7 @@ end A Model contains interpretations (assignments) of constants and functions. *) module Model = struct - type model = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; m_n_obj = null ; @@ -4613,7 +4473,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Function interpretations @@ -4622,9 +4482,7 @@ struct *) module FuncInterp = struct - type func_interp = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_interp = { m_ctx = ctx ; m_n_obj = null ; @@ -4633,17 +4491,15 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Function interpretations entries An Entry object represents an element in the finite map used to a function interpretation. *) module FuncEntry = - struct - type func_entry = z3_native_object - - (**/**) + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; m_n_obj = null ; @@ -4652,13 +4508,13 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Return the (symbolic) value of this entry. *) let get_value ( x : func_entry ) = - Expr.create (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) + expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) (** The number of arguments of the entry. @@ -4670,7 +4526,7 @@ struct *) let get_args ( x : func_entry ) = let n = (get_num_args x) in - let f i = (Expr.create (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f (** @@ -4698,7 +4554,7 @@ struct (** The (symbolic) `else' value of the function interpretation. *) - let get_else ( x : func_interp ) = Expr.create (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) + let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) (** The arity of the function interpretation @@ -4725,7 +4581,7 @@ struct (** Retrieves the interpretation (the assignment) of in the model. A function declaration of zero arity An expression if the function has an interpretation in the model, null otherwise. *) - let get_const_interp ( x : model ) ( f : FuncDecl.func_decl ) = + let get_const_interp ( x : model ) ( f : func_decl ) = if (FuncDecl.get_arity f) != 0 || (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") @@ -4734,19 +4590,19 @@ struct if (Z3native.is_null np) then None else - Some (Expr.create (z3obj_gc x) np) + Some (expr_of_ptr (z3obj_gc x) np) (** Retrieves the interpretation (the assignment) of in the model. A Constant An expression if the constant has an interpretation in the model, null otherwise. *) - let get_const_interp_e ( x : model ) ( a : Expr.expr ) = get_const_interp x (Expr.get_func_decl a) + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) (** Retrieves the interpretation (the assignment) of a non-constant in the model. A function declaration of non-zero arity A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - let rec get_func_interp ( x : model ) ( f : FuncDecl.func_decl ) = + let rec get_func_interp ( x : model ) ( f : func_decl ) = let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in if (FuncDecl.get_arity f) == 0 then let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in @@ -4759,7 +4615,7 @@ struct raise (Z3native.Exception "Argument was not an array constant") else let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x (FuncDecl.create (z3obj_gc x) fd) + get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); else let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in @@ -4771,7 +4627,7 @@ struct (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in - let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f @@ -4781,15 +4637,15 @@ struct (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in - let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in - let f i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = FuncDecl.create (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) @@ -4810,15 +4666,15 @@ struct The evaluation of in the model. *) - let eval ( x : model ) ( t : Expr.expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (ptr_of_expr t) completion) in if not r then raise (ModelEvaluationFailedException "evaluation failed") else - Expr.create (z3obj_gc x) v + expr_of_ptr (z3obj_gc x) v (** Alias for eval. *) - let evaluate ( x : model ) ( t : Expr.expr ) ( completion : bool ) = + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = eval x t completion (** The number of uninterpreted sorts that the model has an interpretation for. *) @@ -4834,7 +4690,7 @@ struct *) let get_sorts ( x : model ) = let n = (get_num_sorts x) in - let f i = (Sort.create (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f @@ -4843,10 +4699,10 @@ struct An uninterpreted sort An array of expressions, where each is an element of the universe of *) - let sort_universe ( x : model ) ( s : Sort.sort ) = - let n_univ = AST.ASTVectors.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in - let n = (AST.ASTVectors.get_size n_univ) in - let f i = (AST.ASTVectors.get n_univ i) in + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in Array.init n f (** Conversion of models to strings. @@ -4866,9 +4722,7 @@ end *) module Probe = struct - type probe = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : probe = { m_ctx = ctx ; m_n_obj = null ; @@ -4877,14 +4731,14 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Execute the probe over the goal. A probe always produce a double value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let apply ( x : probe ) (g : Goal.goal) = + let apply ( x : probe ) (g : goal) = Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (** @@ -4988,10 +4842,8 @@ end It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. *) module Tactic = -struct - type tactic = z3_native_object - - (**/**) +struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : tactic = { m_ctx = ctx ; m_n_obj = null ; @@ -5000,7 +4852,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Tactic application results @@ -5008,9 +4860,7 @@ struct tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult = struct - type apply_result = z3_native_object - - (**/**) + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : apply_result = { m_ctx = ctx ; m_n_obj = null ; @@ -5019,7 +4869,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** The number of Subgoals. *) let get_num_subgoals ( x : apply_result ) = @@ -5039,7 +4889,7 @@ struct goal g, that the ApplyResult was obtained from. #return A model for g *) - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) (** A string representation of the ApplyResult. *) @@ -5054,7 +4904,7 @@ struct Params.ParamDescrs.create (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) - let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = + let apply ( x : tactic ) ( g : goal ) ( p : params option ) = match p with | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) @@ -5122,14 +4972,14 @@ struct If evaluates to false, then the new tactic behaves like the skip tactic. *) (* CMW: when is a keyword *) - let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = + let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) - let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = + let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** @@ -5154,7 +5004,7 @@ struct (** Create a tactic that fails if the probe evaluates to false. *) - let fail_if ( ctx : context ) ( p : Probe.probe ) = + let fail_if ( ctx : context ) ( p : probe ) = create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** @@ -5167,14 +5017,14 @@ struct (** Create a tactic that applies using the given set of parameters . *) - let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . Alias for UsingParams*) (* CMW: with is a keyword *) - let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = using_params ctx t p (** @@ -5201,10 +5051,8 @@ end (** Solvers *) module Solver = -struct - type solver = z3_native_object - - (**/**) +struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; @@ -5213,9 +5061,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) - - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + let string_of_status ( s : status) = match s with | UNSATISFIABLE -> "unsatisfiable" @@ -5224,10 +5070,8 @@ struct (** Objects that track statistical information about solvers. *) module Statistics = - struct - type statistics = z3_native_object - - (**/**) + struct + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; @@ -5236,7 +5080,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - (**/**) + (** Statistical data is organized into pairs of \[Key, Entry\], where every @@ -5245,14 +5089,7 @@ struct *) module Entry = struct - type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } - - (**/**) + let create_si k v = let res : statistics_entry = { m_key = k ; @@ -5272,7 +5109,7 @@ struct m_float = v } in res - (**/**) + (** The key of the entry. *) let get_key (x : statistics_entry) = x.m_key @@ -5344,7 +5181,7 @@ struct (** Sets the solver parameters. *) - let set_parameters ( x : solver ) ( p : Params.params )= + let set_parameters ( x : solver ) ( p : params )= Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** @@ -5382,8 +5219,8 @@ struct (** Assert a constraint (or multiple) into the solver. *) - let assert_ ( x : solver ) ( constraints : Booleans.bool_expr array ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in + let assert_ ( x : solver ) ( constraints : bool_expr array ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) (** @@ -5399,11 +5236,11 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( cs : Booleans.bool_expr array ) ( ps : Booleans.bool_expr array ) = + let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e) (Booleans.gno (Array.get ps i))) in + let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) (Boolean.gno (Array.get ps i))) in ignore (Array.iteri f cs) (** @@ -5418,24 +5255,24 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( c : Booleans.bool_expr ) ( p : Booleans.bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Booleans.gno c) (Booleans.gno p) + let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) (** The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVectors.get_size a) + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + (AST.ASTVector.get_size a) (** The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVectors.get_size a) in - let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get a i)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size a) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in Array.init n f (** @@ -5445,12 +5282,13 @@ struct *) - let check ( x : solver ) ( assumptions : Booleans.bool_expr array) = + let check ( x : solver ) ( assumptions : bool_expr array) = let r = if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Booleans.aton assumptions)) + let f x = (ptr_of_expr (expr_of_bool_expr x)) in + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Array.map f assumptions)) in match r with | L_TRUE -> SATISFIABLE @@ -5481,7 +5319,7 @@ struct if (Z3native.is_null q) then None else - Some (Expr.create (z3obj_gc x) q) + Some (expr_of_ptr (z3obj_gc x) q) (** The unsat core of the last Check. @@ -5491,9 +5329,9 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVectors.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVectors.get_size cn) in - let f i = (AST.ASTVectors.get cn i) in + let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size cn) in + let f i = (AST.ASTVector.get cn i) in Array.init n f (** @@ -5515,7 +5353,7 @@ struct check-sat command, and check-sat commands that take more than a given number of milliseconds to be solved. *) - let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = + let mk_solver ( ctx : context ) ( logic : symbol option ) = match logic with | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) @@ -5539,7 +5377,7 @@ struct The solver supports the commands Push and Pop, but it will always solve each check from scratch. *) - let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = + let mk_solver_t ( ctx : context ) ( t : tactic ) = (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** @@ -5551,10 +5389,7 @@ end (** Fixedpoint solving *) module Fixedpoint = -struct - type fixedpoint = z3_native_object - - (**/**) +struct let create ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; @@ -5563,7 +5398,7 @@ struct (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; (z3obj_create res) ; res - (**/**) + (** A string that describes all available fixedpoint solver parameters. @@ -5574,7 +5409,7 @@ struct (** Sets the fixedpoint solver parameters. *) - let set_params ( x : fixedpoint ) ( p : Params.params )= + let set_params ( x : fixedpoint ) ( p : params )= Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** @@ -5586,29 +5421,29 @@ struct (** Assert a constraints into the fixedpoint solver. *) - let assert_ ( x : fixedpoint ) ( constraints : Booleans.bool_expr array ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Booleans.gno e)) in + let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) ; () (** Register predicate as recursive relation. *) - let register_relation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) = + let register_relation ( x : fixedpoint ) ( f : func_decl ) = Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno y) + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) (** Add table fact to the fixedpoint solver. *) - let add_fact ( x : fixedpoint ) ( pred : FuncDecl.func_decl ) ( args : int array ) = + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args (** @@ -5617,11 +5452,11 @@ struct The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - let query ( x : fixedpoint ) ( query : Booleans.bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Booleans.gno query))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN + let query ( x : fixedpoint ) ( query : bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN (** Query the fixedpoint solver. @@ -5629,11 +5464,12 @@ struct The query is satisfiable if there is an instance of some relation that is non-empty. The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - let query_r ( x : fixedpoint ) ( relations : FuncDecl.func_decl array ) = - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (FuncDecl.aton relations))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN + let query_r ( x : fixedpoint ) ( relations : func_decl array ) = + let f x = ptr_of_ast (ast_of_func_decl x) in + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN (** Creates a backtracking point. @@ -5654,8 +5490,8 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : Booleans.bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Booleans.gno rule) (Symbol.gno name) + let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) (** Retrieve satisfying instance or instances of solver, @@ -5666,7 +5502,7 @@ struct if (Z3native.is_null q) then None else - Some (Expr.create (z3obj_gc x) q) + Some (expr_of_ptr (z3obj_gc x) q) (** Retrieve explanation why fixedpoint engine returned status Unknown. @@ -5677,25 +5513,25 @@ struct (** Retrieve the number of levels explored for a given predicate. *) - let get_num_levels ( x : fixedpoint ) ( predicate : FuncDecl.func_decl ) = + let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) (** Retrieve the cover of a predicate. *) - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) = + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in if (Z3native.is_null q) then None else - Some (Expr.create (z3obj_gc x) q) + Some (expr_of_ptr (z3obj_gc x) q) (** Add property about the predicate. The property is added at level. *) - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : FuncDecl.func_decl ) ( property : Expr.expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (ptr_of_expr property) (** Retrieve internal string representation of fixedpoint object. @@ -5705,31 +5541,33 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : FuncDecl.func_decl ) ( kinds : Symbol.symbol array ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Symbol.aton kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = + let f2 x = (Symbol.gno x) in + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) - let to_string_q ( x : fixedpoint ) ( queries : Booleans.bool_expr array ) = - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Booleans.aton queries) + let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = + let f x = ptr_of_expr (expr_of_bool_expr x) in + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVectors.get_size v) in - let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVectors.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVectors.get_size v) in - let f i = Booleans.create_expr (z3obj_gc x) (z3obj_gno (AST.ASTVectors.get v i)) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** @@ -5813,10 +5651,10 @@ struct @param formula Formula to be checked for consistency in conjunction with assumptions. @return A string representation of the benchmark. *) - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Booleans.bool_expr array ) ( formula : Booleans.bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (Booleans.aton assumptions) - (Booleans.gno formula) + (Array.length assumptions) (let f x = ptr_of_expr (expr_of_bool_expr x) in (Array.map f assumptions)) + (Boolean.gno formula) (** Parse the given string using the SMT-LIB parser. @@ -5827,7 +5665,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5837,17 +5675,17 @@ struct else Z3native.parse_smtlib_string (context_gno ctx) str cs - (Symbol.aton sort_names) - (Sort.aton sorts) + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)) (** Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5857,11 +5695,11 @@ struct else Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (Symbol.aton sort_names) - (Sort.aton sorts) + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)) (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. @@ -5873,7 +5711,7 @@ struct *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = Booleans.create_expr ctx (Z3native.get_smtlib_formula (context_gno ctx) i) in + let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in Array.init n f @@ -5887,7 +5725,7 @@ struct *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = Booleans.create_expr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i) in + let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in Array.init n f (** @@ -5900,7 +5738,7 @@ struct *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in - let f i = FuncDecl.create ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in + let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f (** @@ -5913,7 +5751,7 @@ struct *) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in - let f i = (Sort.create ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in + let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f (** @@ -5922,7 +5760,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5930,19 +5768,19 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.aton sort_names) - (Sort.aton sorts) - cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) + cd + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : Sort.sort array ) ( decl_names : Symbol.symbol array ) ( decls : FuncDecl.func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5950,13 +5788,13 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Z3native.parse_smtlib2_string (context_gno ctx) file_name + bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (Symbol.aton sort_names) - (Sort.aton sorts) + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) cd - (Symbol.aton decl_names) - (FuncDecl.aton decls) + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) end From 4e8d05dcf6bcdd69c85d763dda6730be87783b4d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 19:51:09 +0000 Subject: [PATCH 395/507] ML API: formatting. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.mli | 3331 +++++++++------------------------------------ 1 file changed, 654 insertions(+), 2677 deletions(-) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index b2f0939d0..f82492e8a 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1,3001 +1,978 @@ (** - The Z3 ML/OCaml Interface. + The Z3 ML/Ocaml Interface. Copyright (C) 2012 Microsoft Corporation @author CM Wintersteiger (cwinter) 2012-12-17 *) -(** General Z3 exceptions - - Many functions in this API may throw an exception; if they do, it is this one.*) -exception Error of string - -(** Context objects. - - Most interactions with Z3 are interpreted in some context; many users will only - require one such object, but power users may require more than one. To start using - Z3, do - - - let ctx = (mk_context []) in - (...) - - - where a list of pairs of strings may be passed to set options on - the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (mk_context cfg) in - (...) - -*) type context -(** Create a context object - The following parameters can be set: - - - proof (Boolean) Enable proof generation - - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting - - trace (Boolean) Tracing support for VCC - - trace_file_name (String) Trace out file for VCC traces - - timeout (unsigned) default timeout (in milliseconds) used for solvers - - well_sorted_check type checker - - auto_config use heuristics to automatically select solver and configure it - - model model generation for solvers, this parameter can be overwritten when creating a solver - - model_validate validate models produced by solvers - - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver -*) -val mk_context : (string * string) list -> context +type int_symbol +type string_symbol +type symbol = S_Int of int_symbol | S_Str of string_symbol + +type ast +type ast_vector +type ast_map + +type sort = Sort of ast + +type uninterpreted_sort = UninterpretedSort of sort +type bool_sort = BoolSort of sort +type array_sort = ArraySort of sort +type set_sort = SetSort of sort +type datatype_sort = DatatypeSort of sort +type relation_sort = RelationSort of sort +type finite_domain_sort = FiniteDomainSort of sort +type enum_sort = EnumSort of sort +type list_sort = ListSort of sort +type tuple_sort = TupleSort of sort +type arith_sort = ArithSort of sort +type bitvec_sort = BitVecSort of sort +type int_sort = IntSort of arith_sort +type real_sort = RealSort of arith_sort + +type func_decl = FuncDecl of ast + +type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of symbol + | P_Srt of sort + | P_Ast of ast + | P_Fdl of func_decl + | P_Rat of string + +type params +type param_descrs + +type expr = Expr of ast +type bool_expr = BoolExpr of expr +type arith_expr = ArithExpr of expr +type int_expr = IntExpr of arith_expr +type real_expr = RealExpr of arith_expr +type bitvec_expr = BitVecExpr of expr +type array_expr = ArrayExpr of expr +type datatype_expr = DatatypeExpr of expr +type int_num = IntNum of int_expr +type rat_num = RatNum of real_expr +type algebraic_num = AlgebraicNum of arith_expr +type bitvec_num = BitVecNum of bitvec_expr +type quantifier = Quantifier of expr +type pattern = Pattern of ast + +type constructor + +type goal + +type model +type func_interp +type func_entry + +type probe + +type tactic +type apply_result + +type solver +type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + +type statistics +type statistics_entry + +type fixedpoint + +val ast_of_sort : sort -> ast +val sort_of_uninterpreted_sort : uninterpreted_sort -> sort +val sort_of_bool_sort : bool_sort -> sort +val sort_of_array_sort : array_sort -> sort +val sort_of_set_sort : set_sort -> sort +val sort_of_datatype_sort : datatype_sort -> sort +val sort_of_relation_sort : relation_sort -> sort +val sort_of_finite_domain_sort : finite_domain_sort -> sort +val sort_of_enum_sort : enum_sort -> sort +val sort_of_list_sort : list_sort -> sort +val sort_of_tuple_sort : tuple_sort -> sort +val sort_of_arith_sort : arith_sort -> sort +val sort_of_bitvec_sort : bitvec_sort -> sort +val arith_sort_of_int_sort : int_sort -> arith_sort +val arith_sort_of_real_sort : real_sort -> arith_sort +val uninterpreted_sort_of_sort : sort -> uninterpreted_sort +val bool_sort_of_sort : sort -> bool_sort +val array_sort_of_sort : sort -> array_sort +val datatype_sort_of_sort : sort -> datatype_sort +val relation_sort_of_sort : sort -> relation_sort +val finite_domain_sort_of_sort : sort -> finite_domain_sort +val arith_sort_of_sort : sort -> arith_sort +val bitvec_sort_of_sort : sort -> bitvec_sort +val int_sort_of_arith_sort : arith_sort -> int_sort +val real_sort_of_arith_sort : arith_sort -> real_sort +val ast_of_func_decl : func_decl -> ast +val ast_of_expr : expr -> ast +val expr_of_bool_expr : bool_expr -> expr +val expr_of_arith_expr : arith_expr -> expr +val expr_of_bitvec_expr : bitvec_expr -> expr +val expr_of_array_expr : array_expr -> expr +val expr_of_datatype_expr : datatype_expr -> expr +val arith_expr_of_int_expr : int_expr -> arith_expr +val arith_expr_of_real_expr : real_expr -> arith_expr +val int_expr_of_int_num : int_num -> int_expr +val real_expr_of_rat_num : rat_num -> real_expr +val arith_expr_of_algebraic_num : algebraic_num -> arith_expr +val bitvec_expr_of_bitvec_num : bitvec_num -> bitvec_expr +val expr_of_quantifier : quantifier -> expr +val ast_of_pattern : pattern -> ast +val expr_of_ast : ast -> expr +val bool_expr_of_expr : expr -> bool_expr +val arith_expr_of_expr : expr -> arith_expr +val bitvec_expr_of_expr : expr -> bitvec_expr +val array_expr_of_expr : expr -> array_expr +val datatype_expr_of_expr : expr -> datatype_expr +val int_expr_of_arith_expr : arith_expr -> int_expr +val real_expr_of_arith_expr : arith_expr -> real_expr +val int_num_of_int_expr : int_expr -> int_num +val rat_num_of_real_expr : real_expr -> rat_num +val algebraic_num_of_arith_expr : arith_expr -> algebraic_num +val bitvec_num_of_bitvec_expr : bitvec_expr -> bitvec_num +val quantifier_of_expr : expr -> quantifier +val pattern_of_ast : ast -> pattern -(** Interaction logging for Z3 - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) module Log : sig - (** Open an interaction log file. - @return True if opening the log file succeeds, false otherwise. *) - (* CMW: "open" is a reserved keyword. *) val open_ : string -> bool - - (** Closes the interaction log. *) - val close : unit -> unit - - (** Appends a user-provided string to the interaction log. *) + val close : unit val append : string -> unit end -(** Version information *) module Version : sig - (** The major version. *) val major : int - - (** The minor version. *) val minor : int - - (** The build version. *) val build : int - - (** The revision. *) val revision : int - - (** A string representation of the version information. *) val to_string : string end -(** Symbols are used to name several term and type constructors *) +val mk_context : (string * string) list -> context + module Symbol : sig - type symbol - - (** The kind of the symbol (int or string) *) val kind : symbol -> Z3enums.symbol_kind - - (** Indicates whether the symbol is of Int kind *) val is_int_symbol : symbol -> bool - - (** Indicates whether the symbol is of string kind. *) val is_string_symbol : symbol -> bool - - (** The int value of the symbol. *) - val get_int : symbol -> int - - (** The string value of the symbol. *) - val get_string : symbol -> string - - (** A string representation of the symbol. *) + val get_int : int_symbol -> int + val get_string : string_symbol -> string val to_string : symbol -> string - - (** Creates a new symbol using an integer. - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. *) val mk_int : context -> int -> symbol - - (** Creates a new symbol using a string. *) val mk_string : context -> string -> symbol - - (** Create a list of symbols. *) - val mk_ints : context -> int list -> symbol list - - (** Create a list of symbols. *) - val mk_strings : context -> string list -> symbol list + val mk_ints : context -> int array -> symbol array + val mk_strings : context -> string array -> symbol array end -(** The abstract syntax tree (AST) module *) module AST : sig - type ast - (** Vectors of ASTs *) module ASTVector : sig - type ast_vector - - (** Create an empty AST vector *) - val mk_ast_vector : context -> ast_vector - - (** The size of the vector *) val get_size : ast_vector -> int - - (** Retrieves the i-th object in the vector. - @return An AST *) - val get : ast_vector -> int -> ast - - (** Sets the i-th object in the vector. *) + val get : ast_vector -> int -> ast_vector val set : ast_vector -> int -> ast -> unit - - (** Resize the vector to a new size. *) val resize : ast_vector -> int -> unit - - (** Add an ast to the back of the vector. The size - is increased by 1. *) val push : ast_vector -> ast -> unit - - (** Translates all ASTs in the vector to another context. - @return A new ASTVector *) val translate : ast_vector -> context -> ast_vector - - (** Retrieves a string representation of the vector. *) val to_string : ast_vector -> string end - (** Map from AST to AST *) module ASTMap : sig - type ast_map - - (** Create an empty mapping from AST to AST *) - val mk_ast_map : context -> ast_map - - (** Checks whether the map contains a key. - @return True if the key in the map, false otherwise. *) val contains : ast_map -> ast -> bool - - (** Finds the value associated with the key. - This function signs an error when the key is not a key in the map. *) - val find : ast_map -> ast -> ast - - (** Stores or replaces a new key/value pair in the map. *) + val find : ast_map -> ast -> ast_map val insert : ast_map -> ast -> ast -> unit - - (** Erases the key from the map.*) val erase : ast_map -> ast -> unit - - (** Removes all keys from the map. *) val reset : ast_map -> unit - - (** The size of the map *) val get_size : ast_map -> int - - (** The keys stored in the map. *) - val get_keys : ast_map -> ast list - - (** Retrieves a string representation of the map.*) + val get_keys : ast_map -> ast_vector val to_string : ast_map -> string end - (** The AST's hash code. - @return A hash code *) - val hash : ast -> int - - (** A unique identifier for the AST (unique among all ASTs). *) + val get_hash_code : ast -> int val get_id : ast -> int - - (** The kind of the AST. *) val get_ast_kind : ast -> Z3enums.ast_kind - - (** Indicates whether the AST is an Expr *) val is_expr : ast -> bool - - (** Indicates whether the AST is a bound variable*) val is_var : ast -> bool - - (** Indicates whether the AST is a Quantifier *) val is_quantifier : ast -> bool - - (** Indicates whether the AST is a Sort *) val is_sort : ast -> bool - - (** Indicates whether the AST is a func_decl *) val is_func_decl : ast -> bool - - (** A string representation of the AST. *) val to_string : ast -> string - - (** A string representation of the AST in s-expression notation. *) val to_sexpr : ast -> string - - (** Comparison operator. - @return True if the two ast's are from the same context - and represent the same sort; false otherwise. *) - val equal : ast -> ast -> bool - - (** Object Comparison. - @return Negative if the first ast should be sorted before the second, positive if after else zero. *) + val ( = ) : ast -> ast -> bool val compare : ast -> ast -> int - - (** Translates (copies) the AST to another context. - @return A copy of the AST which is associated with the other context. *) + val ( < ) : ast -> ast -> int val translate : ast -> context -> ast - - (** Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - [Z3native.inc_ref]). - {!wrap_ast} *) + val wrap : context -> Z3native.z3_ast -> ast val unwrap_ast : ast -> Z3native.ptr - - (** Wraps an AST. - - This function is used for transitions between native and - managed objects. Note that the native ast that is passed must be a - native object obtained from Z3 (e.g., through {!unwrap_ast}) - and that it must have a correct reference count (see e.g., - [Z3native.inc_ref]). *) - val wrap_ast : context -> Z3native.z3_ast -> ast end -(** The Sort module implements type information for ASTs *) module Sort : sig - type sort = Sort of AST.ast - - val ast_of_sort : sort -> AST.ast - - (** Comparison operator. - @return True if the two sorts are from the same context - and represent the same sort; false otherwise. *) - val equal : sort -> sort -> bool - - (** Returns a unique identifier for the sort. *) + val ( = ) : sort -> sort -> bool val get_id : sort -> int - - (** The kind of the sort. *) val get_sort_kind : sort -> Z3enums.sort_kind - - (** The name of the sort *) - val get_name : sort -> Symbol.symbol - - (** A string representation of the sort. *) + val get_name : sort -> symbol val to_string : sort -> string - - (** Create a new uninterpreted sort. *) - val mk_uninterpreted : context -> Symbol.symbol -> sort - - (** Create a new uninterpreted sort. *) - val mk_uninterpreted_s : context -> string -> sort + val mk_uninterpreted : context -> symbol -> uninterpreted_sort + val mk_uninterpreted_s : context -> string -> uninterpreted_sort end -(** Function declarations *) -module rec FuncDecl : +module FuncDecl : sig - type func_decl = FuncDecl of AST.ast - val ast_of_func_decl : FuncDecl.func_decl -> AST.ast - - (** Parameters of Func_Decls *) module Parameter : sig - (** Parameters of func_decls *) - type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - (** The kind of the parameter. *) val get_kind : parameter -> Z3enums.parameter_kind - - (** The int value of the parameter.*) val get_int : parameter -> int - - (** The float value of the parameter.*) val get_float : parameter -> float - - (** The Symbol.Symbol value of the parameter.*) - val get_symbol : parameter -> Symbol.symbol - - (** The Sort value of the parameter.*) - val get_sort : parameter -> Sort.sort - - (** The AST value of the parameter.*) - val get_ast : parameter -> AST.ast - - (** The FunctionDeclaration value of the parameter.*) - val get_func_decl : parameter -> func_decl - - (** The rational string value of the parameter.*) - val get_rational : parameter -> string + val get_symbol : parameter -> symbol + val get_sort : parameter -> sort + val get_ast : parameter -> ast + val get_func_decl : parameter -> string end - (** Creates a new function declaration. *) - val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl - - (** Creates a new function declaration. *) - val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl - (** Creates a fresh function declaration with a name prefixed with a prefix string. *) - - val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl - - (** Creates a new constant function declaration. *) - val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl - - (** Creates a new constant function declaration. *) - val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - - (** Creates a fresh constant function declaration with a name prefixed with a prefix string. - {!mk_func_decl} - {!mk_func_decl} *) - val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - - (** Comparison operator. - @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) - val equal : func_decl -> func_decl -> bool - - (** A string representations of the function declaration. *) + val mk_func_decl : context -> symbol -> sort array -> sort -> func_decl + val mk_func_decl_s : context -> string -> sort array -> sort -> func_decl + val mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl + val mk_const_decl : context -> symbol -> sort -> func_decl + val mk_const_decl_s : context -> string -> sort -> func_decl + val mk_fresh_const_decl : context -> string -> sort -> func_decl + val ( = ) : func_decl -> func_decl -> bool val to_string : func_decl -> string - - (** Returns a unique identifier for the function declaration. *) val get_id : func_decl -> int - - (** The arity of the function declaration *) val get_arity : func_decl -> int - - (** The size of the domain of the function declaration - {!get_arity} *) val get_domain_size : func_decl -> int - - (** The domain of the function declaration *) - val get_domain : func_decl -> Sort.sort list - - (** The range of the function declaration *) - val get_range : func_decl -> Sort.sort - - (** The kind of the function declaration. *) + val get_domain : func_decl -> sort array + val get_range : func_decl -> sort val get_decl_kind : func_decl -> Z3enums.decl_kind - - (** The name of the function declaration*) - val get_name : func_decl -> Symbol.symbol - - (** The number of parameters of the function declaration *) + val get_name : func_decl -> symbol val get_num_parameters : func_decl -> int - - (** The parameters of the function declaration *) - val get_parameters : func_decl -> Parameter.parameter list - - (** Create expression that applies function to arguments. *) - val apply : func_decl -> Expr.expr list -> Expr.expr + val get_parameters : func_decl -> parameter list + val apply : func_decl -> expr array -> expr end -(** Parameter sets (of Solvers, Tactics, ...) - - A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) -and Params : +module Params : sig - type params - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) module ParamDescrs : sig - type param_descrs - - (** Validate a set of parameters. *) val validate : param_descrs -> params -> unit - - (** Retrieve kind of parameter. *) - val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - - (** Retrieve all names of parameters. *) - val get_names : param_descrs -> Symbol.symbol list - - (** The size of the ParamDescrs. *) + val get_kind : param_descrs -> symbol -> Z3enums.param_kind + val get_names : param_descrs -> symbol array val get_size : param_descrs -> int - - (** Retrieves a string representation of the ParamDescrs. *) val to_string : param_descrs -> string end - (** Adds a parameter setting. *) - val add_bool : params -> Symbol.symbol -> bool -> unit - - (** Adds a parameter setting. *) - val add_int : params -> Symbol.symbol -> int -> unit - - (** Adds a parameter setting. *) - val add_float : params -> Symbol.symbol -> float -> unit - - (** Adds a parameter setting. *) - val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - - (** Creates a new parameter set *) + val add_bool : params -> symbol -> bool -> unit + val add_int : params -> symbol -> int -> unit + val add_double : params -> symbol -> float -> unit + val add_symbol : params -> symbol -> symbol -> unit + val add_s_bool : params -> string -> bool -> unit + val add_s_int : params -> string -> int -> unit + val add_s_double : params -> string -> float -> unit + val add_s_symbol : params -> string -> symbol -> unit val mk_params : context -> params - - (** A string representation of the parameter set. *) val to_string : params -> string - - (** Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - [z3.exe -p] - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. *) - val update_param_value : context -> string -> string -> unit - - (** Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - {!AST.to_string} - {!Quantifier.Pattern.to_string} - {!FuncDecl.to_string} - {!Sort.to_string} *) - val set_print_mode : context -> Z3enums.ast_print_mode -> unit end -(** General Expressions (terms) *) -and Expr : +module Expr : sig - type expr = Expr of AST.ast - - val ast_of_expr : Expr.expr -> AST.ast - val expr_of_ast : AST.ast -> Expr.expr - - (** Returns a simplified version of the expression. - {!get_simplify_help} *) - val simplify : Expr.expr -> Params.params option -> expr - - (** A string describing all available parameters to [Expr.Simplify]. *) + val simplify : expr -> params option -> expr val get_simplify_help : context -> string - - (** Retrieves parameter descriptions for simplifier. *) - val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs - - (** The function declaration of the function that is applied in this expression. *) - val get_func_decl : Expr.expr -> FuncDecl.func_decl - - (** The number of arguments of the expression. *) - val get_num_args : Expr.expr -> int - - (** The arguments of the expression. *) - val get_args : Expr.expr -> Expr.expr list - - (** Update the arguments of the expression using an array of expressions. - The number of new arguments should coincide with the current number of arguments. *) - val update : Expr.expr -> Expr.expr list -> expr - - (** Substitute every occurrence of [from[i]] in the expression with [to[i]], for [i] smaller than [num_exprs]. - - The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. - For every [i] smaller than [num_exprs], we must have that - sort of [from[i]] must be equal to sort of [to[i]]. *) - val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr - - (** Substitute every occurrence of [from] in the expression with [to]. - {!substitute} *) - val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr - - (** Substitute the free variables in the expression with the expressions in the expr array - - For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) - val substitute_vars : Expr.expr -> Expr.expr list -> expr - - (** Translates (copies) the term to another context. - @return A copy of the term which is associated with the other context *) - val translate : Expr.expr -> context -> expr - - (** Returns a string representation of the expression. *) - val to_string : Expr.expr -> string - - (** Indicates whether the term is a numeral *) - val is_numeral : Expr.expr -> bool - - (** Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. *) - val is_well_sorted : Expr.expr -> bool - - (** The Sort of the term. *) - val get_sort : Expr.expr -> Sort.sort - - (** Indicates whether the term represents a constant. *) - val is_const : Expr.expr -> bool - - (** Creates a new constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - - (** Creates a new constant. *) - val mk_const_s : context -> string -> Sort.sort -> expr - - (** Creates a constant from the func_decl. *) - val mk_const_f : context -> FuncDecl.func_decl -> expr - - (** Creates a fresh constant with a name prefixed with a string. *) - val mk_fresh_const : context -> string -> Sort.sort -> expr - - (** Create a new function application. *) - val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - - (** Create a numeral of a given sort. - @return A Term with the given value and sort *) - val mk_numeral_string : context -> string -> Sort.sort -> expr - - (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. - @return A Term with the given value and sort *) - val mk_numeral_int : context -> int -> Sort.sort -> expr - - (** Comparison operator. - @return True if the two expr's are equal; false otherwise. *) - val equal : expr -> expr -> bool - - (** Object Comparison. - @return Negative if the first expr should be sorted before the second, positive if after, else zero. *) - val compare : expr -> expr -> int + val get_simplify_parameter_descrs : context -> param_descrs + val get_func_decl : expr -> func_decl + val get_bool_value : expr -> Z3enums.lbool + val get_num_args : expr -> int + val get_args : expr -> expr array + val update : expr -> expr array -> expr + val substitute : expr -> expr array -> expr array -> expr + val substitute_one : expr -> expr -> expr -> expr + val substitute_vars : expr -> expr array -> expr + val translate : expr -> context -> expr + val to_string : expr -> string + val is_numeral : expr -> bool + val is_well_sorted : expr -> bool + val get_sort : expr -> sort + val is_bool : expr -> bool + val is_const : expr -> bool + val is_true : expr -> bool + val is_false : expr -> bool + val is_eq : expr -> bool + val is_distinct : expr -> bool + val is_ite : expr -> bool + val is_and : expr -> bool + val is_or : expr -> bool + val is_iff : expr -> bool + val is_xor : expr -> bool + val is_not : expr -> bool + val is_implies : expr -> bool + val is_label : expr -> bool + val is_oeq : expr -> bool + val mk_const : context -> symbol -> sort -> expr + val mk_const_s : context -> string -> sort -> expr + val mk_const_f : context -> func_decl -> expr + val mk_fresh_const : context -> string -> sort -> expr + val mk_app : context -> func_decl -> expr array -> expr + val mk_numeral_string : context -> string -> sort -> expr + val mk_numeral_int : context -> int -> sort -> expr end -(** Boolean expressions; Propositional logic and equality *) module Boolean : sig - (** Create a Boolean sort *) - val mk_sort : context -> Sort.sort - - (** Create a Boolean constant. *) - val mk_const : context -> Symbol.symbol -> Expr.expr - - (** Create a Boolean constant. *) - val mk_const_s : context -> string -> Expr.expr - - (** The true Term. *) - val mk_true : context -> Expr.expr - - (** The false Term. *) - val mk_false : context -> Expr.expr - - (** Creates a Boolean value. *) - val mk_val : context -> bool -> Expr.expr - - (** Mk an expression representing [not(a)]. *) - val mk_not : context -> Expr.expr -> Expr.expr - - (** Create an expression representing an if-then-else: [ite(t1, t2, t3)]. *) - val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 iff t2]. *) - val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 -> t2]. *) - val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 xor t2]. *) - val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing the AND of args *) - val mk_and : context -> Expr.expr list -> Expr.expr - - (** Create an expression representing the OR of args *) - val mk_or : context -> Expr.expr list -> Expr.expr - - (** Creates the equality between two expr's. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Creates a [distinct] term. *) - val mk_distinct : context -> Expr.expr list -> Expr.expr - - (** Indicates whether the expression is the true or false expression - or something else (L_UNDEF). *) - val get_bool_value : Expr.expr -> Z3enums.lbool - - (** Indicates whether the term has Boolean sort. *) - val is_bool : Expr.expr -> bool - - (** Indicates whether the term is the constant true. *) - val is_true : Expr.expr -> bool - - (** Indicates whether the term is the constant false. *) - val is_false : Expr.expr -> bool - - (** Indicates whether the term is an equality predicate. *) - val is_eq : Expr.expr -> bool - - (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) - val is_distinct : Expr.expr -> bool - - (** Indicates whether the term is a ternary if-then-else term *) - val is_ite : Expr.expr -> bool - - (** Indicates whether the term is an n-ary conjunction *) - val is_and : Expr.expr -> bool - - (** Indicates whether the term is an n-ary disjunction *) - val is_or : Expr.expr -> bool - - (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) - val is_iff : Expr.expr -> bool - - (** Indicates whether the term is an exclusive or *) - val is_xor : Expr.expr -> bool - - (** Indicates whether the term is a negation *) - val is_not : Expr.expr -> bool - - (** Indicates whether the term is an implication *) - val is_implies : Expr.expr -> bool + val mk_sort : context -> bool_sort + val mk_const : context -> symbol -> bool_expr + val mk_const_s : context -> string -> bool_expr + val mk_true : context -> bool_expr + val mk_false : context -> bool_expr + val mk_val : context -> bool -> bool_expr + val mk_eq : context -> expr -> expr -> bool_expr + val mk_distinct : context -> expr array -> bool_expr + val mk_not : context -> bool_expr -> bool_expr + val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr + val mk_iff : context -> bool_expr -> bool_expr -> bool_expr + val mk_implies : context -> bool_expr -> bool_expr -> bool_expr + val mk_xor : context -> bool_expr -> bool_expr -> bool_expr + val mk_and : context -> bool_expr array -> bool_expr + val mk_or : context -> bool_expr array -> bool_expr end -(** Quantifier expressions *) module Quantifier : sig - type quantifier = Quantifier of Expr.expr - val expr_of_quantifier : quantifier -> Expr.expr - val quantifier_of_expr : Expr.expr -> quantifier - - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. *) module Pattern : sig - type pattern = Pattern of AST.ast - - val ast_of_pattern : pattern -> AST.ast - val pattern_of_ast : AST.ast -> pattern - - (** The number of terms in the pattern. *) val get_num_terms : pattern -> int - - (** The terms in the pattern. *) - val get_terms : pattern -> Expr.expr list - - (** A string representation of the pattern. *) + val get_terms : pattern -> expr array val to_string : pattern -> string end - - (** The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. *) - val get_index : Expr.expr -> int - - (** Indicates whether the quantifier is universal. *) + val get_index : expr -> int val is_universal : quantifier -> bool - - (** Indicates whether the quantifier is existential. *) val is_existential : quantifier -> bool - - (** The weight of the quantifier. *) val get_weight : quantifier -> int - - (** The number of patterns. *) val get_num_patterns : quantifier -> int - - (** The patterns. *) - val get_patterns : quantifier -> Pattern.pattern list - - (** The number of no-patterns. *) + val get_patterns : quantifier -> pattern array val get_num_no_patterns : quantifier -> int - - (** The no-patterns. *) - val get_no_patterns : quantifier -> Pattern.pattern list - - (** The number of bound variables. *) + val get_no_patterns : quantifier -> pattern array val get_num_bound : quantifier -> int - - (** The symbols for the bound variables. *) - val get_bound_variable_names : quantifier -> Symbol.symbol list - - (** The sorts of the bound variables. *) - val get_bound_variable_sorts : quantifier -> Sort.sort list - - (** The body of the quantifier. *) - val get_body : quantifier -> Expr.expr - - (** Creates a new bound variable. *) - val mk_bound : context -> int -> Sort.sort -> Expr.expr - - (** Create a quantifier pattern. *) - val mk_pattern : context -> Expr.expr list -> Pattern.pattern - - (** Create a universal Quantifier. *) - val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a universal Quantifier. *) - val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create an existential Quantifier. *) - val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create an existential Quantifier. *) - val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a Quantifier. *) - val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a Quantifier. *) - val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** A string representation of the quantifier. *) - val to_string : quantifier -> string + val get_bound_variable_names : quantifier -> symbol array + val get_bound_variable_sorts : quantifier -> sort array + val get_body : quantifier -> bool_expr + val mk_bound : context -> int -> sort -> expr + val mk_pattern : context -> expr array -> pattern + val mk_forall : + context -> + sort array -> + symbol array -> + expr -> + int option -> + pattern array -> + expr array -> symbol option -> symbol option -> quantifier + val mk_forall_const : + context -> + expr array -> + expr -> + int option -> + pattern array -> + expr array -> symbol option -> symbol option -> quantifier + val mk_exists : + context -> + sort array -> + symbol array -> + expr -> + int option -> + pattern array -> + expr array -> symbol option -> symbol option -> quantifier + val mk_exists_const : + context -> + expr array -> + expr -> + int option -> + pattern array -> + expr array -> symbol option -> symbol option -> quantifier + val mk_quantifier : + context -> + bool -> + expr array -> + expr -> + int option -> + pattern array -> + expr array -> symbol option -> symbol option -> quantifier end -(** Functions to manipulate Array expressions *) -module Z3Array : +module Array_ : sig - (** Create a new array sort. *) - val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort - - (** Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. *) - val is_store : Expr.expr -> bool - - (** Indicates whether the term is an array select. *) - val is_select : Expr.expr -> bool - - (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - val is_constant_array : Expr.expr -> bool - - (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. *) - val is_default_array : Expr.expr -> bool - - (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - val is_array_map : Expr.expr -> bool - - (** Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. *) - val is_as_array : Expr.expr -> bool - - (** Indicates whether the term is of an array sort. *) - val is_array : Expr.expr -> bool - - (** The domain of the array sort. *) - val get_domain : Sort.sort -> Sort.sort - - (** The range of the array sort. *) - val get_range : Sort.sort -> Sort.sort - - (** Create an array constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> Expr.expr - - (** Create an array constant. *) - val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> Expr.expr - - (** Array read. - - The argument [a] is the array and [i] is the index - of the array that gets read. - - The node [a] must have an array sort [[domain -> range]], - and [i] must have the sort [domain]. - The sort of the result is [range]. - {!Z3Array.mk_sort} - {!mk_store} *) - val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Array update. - - The node [a] must have an array sort [[domain -> range]], - [i] must have sort [domain], - [v] must have sort range. The sort of the result is [[domain -> range]]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to [a] - (with respect to [select]) - on all indices except for [i], where it maps to [v] - (and the [select] of [a] with - respect to [i] may be a different value). - {!Z3Array.mk_sort} - {!mk_select} *) - val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create a constant array. - - The resulting term is an array, such that a [select]on an arbitrary index - produces the value [v]. - {!Z3Array.mk_sort} - {!mk_select} *) - val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr - - (** Maps f on the argument arrays. - - Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. - The function declaration [f] must have type [ range_1 .. range_n -> range]. - [v] must have sort range. The sort of the result is [[domain_i -> range]]. - {!Z3Array.mk_sort} - {!mk_select} - {!mk_store} *) - val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr - - (** Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. *) - val mk_term_array : context -> Expr.expr -> Expr.expr + val mk_sort : context -> sort -> sort -> array_sort + val is_store : expr -> bool + val is_select : expr -> bool + val is_constant_array : expr -> bool + val is_default_array : expr -> bool + val is_array_map : expr -> bool + val is_as_array : expr -> bool + val is_array : expr -> bool + val get_domain : array_sort -> sort + val get_range : array_sort -> sort + val mk_const : context -> symbol -> sort -> sort -> array_expr + val mk_const_s : context -> string -> sort -> sort -> array_expr + val mk_select : context -> array_expr -> expr -> expr -> expr + val mk_const_array : context -> sort -> expr -> expr + val mk_map : context -> func_decl -> array_expr array -> expr + val mk_term_array : context -> array_expr -> expr end -(** Functions to manipulate Set expressions *) module Set : sig - (** Create a set type. *) - val mk_sort : context -> Sort.sort -> Sort.sort - - (** Indicates whether the term is set union *) - val is_union : Expr.expr -> bool - - (** Indicates whether the term is set intersection *) - val is_intersect : Expr.expr -> bool - - (** Indicates whether the term is set difference *) - val is_difference : Expr.expr -> bool - - (** Indicates whether the term is set complement *) - val is_complement : Expr.expr -> bool - - (** Indicates whether the term is set subset *) - val is_subset : Expr.expr -> bool - - (** Create an empty set. *) - val mk_empty : context -> Sort.sort -> Expr.expr - - (** Create the full set. *) - val mk_full : context -> Sort.sort -> Expr.expr - - (** Add an element to the set. *) - val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Remove an element from a set. *) - val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Take the union of a list of sets. *) - val mk_union : context -> Expr.expr list -> Expr.expr - - (** Take the intersection of a list of sets. *) - val mk_intersection : context -> Expr.expr list -> Expr.expr - - (** Take the difference between two sets. *) - val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Take the complement of a set. *) - val mk_complement : context -> Expr.expr -> Expr.expr - - (** Check for set membership. *) - val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Check for subsetness of sets. *) - val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr + val is_union : expr -> bool + val is_intersect : expr -> bool + val is_difference : expr -> bool + val is_complement : expr -> bool + val is_subset : expr -> bool + val mk_sort : context -> sort -> set_sort + val mk_empty : context -> sort -> expr + val mk_full : context -> sort -> expr + val mk_set_add : context -> expr -> expr -> expr + val mk_del : context -> expr -> expr -> expr + val mk_union : context -> expr array -> expr + val mk_intersection : context -> expr array -> expr + val mk_difference : context -> expr -> expr -> expr + val mk_complement : context -> expr -> expr + val mk_membership : context -> expr -> expr -> expr + val mk_subset : context -> expr -> expr -> expr end -(** Functions to manipulate Finite Domain expressions *) module FiniteDomain : sig - (** Create a new finite domain sort. *) - val mk_sort : context -> Symbol.symbol -> int -> Sort.sort - - (** Create a new finite domain sort. *) - val mk_sort_s : context -> string -> int -> Sort.sort - - (** Indicates whether the term is of an array sort. *) - val is_finite_domain : Expr.expr -> bool - - (** Indicates whether the term is a less than predicate over a finite domain. *) - val is_lt : Expr.expr -> bool - - (** The size of the finite domain sort. *) - val get_size : Sort.sort -> int + val mk_sort : context -> symbol -> int -> finite_domain_sort + val mk_sort_s : context -> string -> int -> finite_domain_sort + val is_finite_domain : expr -> bool + val is_lt : expr -> bool + val get_size : finite_domain_sort -> int end - -(** Functions to manipulate Relation expressions *) module Relation : sig - (** Indicates whether the term is of a relation sort. *) - val is_relation : Expr.expr -> bool - - (** Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements - correspond to the [n] columns of the relation. *) - val is_store : Expr.expr -> bool - - (** Indicates whether the term is an empty relation *) - val is_empty : Expr.expr -> bool - - (** Indicates whether the term is a test for the emptiness of a relation *) - val is_is_empty : Expr.expr -> bool - - (** Indicates whether the term is a relational join *) - val is_join : Expr.expr -> bool - - (** Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. *) - val is_union : Expr.expr -> bool - - (** Indicates whether the term is the widening of two relations - The function takes two arguments. *) - val is_widen : Expr.expr -> bool - - (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. *) - val is_project : Expr.expr -> bool - - (** Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. *) - val is_filter : Expr.expr -> bool - - (** Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. *) - val is_negation_filter : Expr.expr -> bool - - (** Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. *) - val is_rename : Expr.expr -> bool - - (** Indicates whether the term is the complement of a relation *) - val is_complement : Expr.expr -> bool - - (** Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes [n+1] arguments, where the first argument is a relation, - and the remaining [n] arguments correspond to a record. *) - val is_select : Expr.expr -> bool - - (** Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind {!is_union} - to perform destructive updates to the first argument. *) - val is_clone : Expr.expr -> bool - - (** The arity of the relation sort. *) - val get_arity : Sort.sort -> int - - (** The sorts of the columns of the relation sort. *) - val get_column_sorts : Sort.sort -> Sort.sort list + val is_relation : expr -> bool + val is_store : expr -> bool + val is_empty : expr -> bool + val is_is_empty : expr -> bool + val is_join : expr -> bool + val is_union : expr -> bool + val is_widen : expr -> bool + val is_project : expr -> bool + val is_filter : expr -> bool + val is_negation_filter : expr -> bool + val is_rename : expr -> bool + val is_complement : expr -> bool + val is_select : expr -> bool + val is_clone : expr -> bool + val get_arity : relation_sort -> int + val get_column_sorts : relation_sort -> relation_sort array end -(** Functions to manipulate Datatype expressions *) module Datatype : sig - (** Datatype Constructors *) + module Constructor : sig - type constructor - - (** The number of fields of the constructor. *) + val get_n : constructor -> int + val tester_decl : constructor -> func_decl + val constructor_decl : constructor -> func_decl + val accessor_decls : constructor -> func_decl array val get_num_fields : constructor -> int - - (** The function declaration of the constructor. *) - val get_constructor_decl : constructor -> FuncDecl.func_decl - - (** The function declaration of the tester. *) - val get_tester_decl : constructor -> FuncDecl.func_decl - - (** The function declarations of the accessors *) - val get_accessor_decls : constructor -> FuncDecl.func_decl list + val get_constructor_decl : constructor -> func_decl + val get_tester_decl : constructor -> func_decl + val get_accessor_decls : constructor -> func_decl array end - (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) - val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor - - (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) - val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor - - (** Create a new datatype sort. *) - val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> Sort.sort - - (** Create a new datatype sort. *) - val mk_sort_s : context -> string -> Constructor.constructor list -> Sort.sort - - (** Create mutually recursive datatypes. *) - val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> Sort.sort list - - (** Create mutually recursive data-types. *) - val mk_sorts_s : context -> string list -> Constructor.constructor list list -> Sort.sort list - - - (** The number of constructors of the datatype sort. *) - val get_num_constructors : Sort.sort -> int - - (** The constructors. *) - val get_constructors : Sort.sort -> FuncDecl.func_decl list - - (** The recognizers. *) - val get_recognizers : Sort.sort -> FuncDecl.func_decl list - - (** The constructor accessors. *) - val get_accessors : Sort.sort -> FuncDecl.func_decl list list + val mk_constructor : context -> symbol -> symbol -> symbol array -> sort array -> int array -> constructor + val mk_constructor_s : context -> string -> symbol -> symbol array -> sort array -> int array -> constructor + val mk_sort : context -> symbol -> constructor array -> datatype_sort + val mk_sort_s : context -> string -> constructor array -> datatype_sort + val mk_sorts : context -> symbol array -> constructor array array -> datatype_sort array + val mk_sorts_s : context -> string array -> constructor array array -> datatype_sort array + val get_num_constructors : datatype_sort -> int + val get_constructors : datatype_sort -> func_decl array + val get_recognizers : datatype_sort -> func_decl array + val get_accessors : datatype_sort -> func_decl array array end -(** Functions to manipulate Enumeration expressions *) module Enumeration : sig - (** Create a new enumeration sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort - - (** Create a new enumeration sort. *) - val mk_sort_s : context -> string -> string list -> Sort.sort - - (** The function declarations of the constants in the enumeration. *) - val get_const_decls : Sort.sort -> FuncDecl.func_decl list - - (** The test predicates for the constants in the enumeration. *) - val get_tester_decls : Sort.sort -> FuncDecl.func_decl list + val mk_sort : context -> symbol -> symbol array -> enum_sort + val mk_sort_s : context -> string -> string array -> enum_sort + val get_const_decls : enum_sort -> func_decl array + val get_tester_decls : enum_sort -> func_decl array end -(** Functions to manipulate List expressions *) -module Z3List : +module List_ : sig - (** Create a new list sort. *) - val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort - - (** Create a new list sort. *) - val mk_list_s : context -> string -> Sort.sort -> Sort.sort - - (** The declaration of the nil function of this list sort. *) - val get_nil_decl : Sort.sort -> FuncDecl.func_decl - - (** The declaration of the isNil function of this list sort. *) - val get_is_nil_decl : Sort.sort -> FuncDecl.func_decl - - (** The declaration of the cons function of this list sort. *) - val get_cons_decl : Sort.sort -> FuncDecl.func_decl - - (** The declaration of the isCons function of this list sort. *) - val get_is_cons_decl : Sort.sort -> FuncDecl.func_decl - - (** The declaration of the head function of this list sort. *) - val get_head_decl : Sort.sort -> FuncDecl.func_decl - - (** The declaration of the tail function of this list sort. *) - val get_tail_decl : Sort.sort -> FuncDecl.func_decl - - (** The empty list. *) - val nil : Sort.sort -> Expr.expr + val mk_sort : context -> symbol -> sort -> list_sort + val mk_list_s : context -> string -> sort -> list_sort + val get_nil_decl : list_sort -> func_decl + val get_is_nil_decl : list_sort -> func_decl + val get_cons_decl : list_sort -> func_decl + val get_is_cons_decl : list_sort -> func_decl + val get_head_decl : list_sort -> func_decl + val get_tail_decl : list_sort -> func_decl + val nil : list_sort -> expr end -(** Functions to manipulate Tuple expressions *) module Tuple : sig - (** Create a new tuple sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> Sort.sort - - (** The constructor function of the tuple. *) - val get_mk_decl : Sort.sort -> FuncDecl.func_decl - - (** The number of fields in the tuple. *) - val get_num_fields : Sort.sort -> int - - (** The field declarations. *) - val get_field_decls : Sort.sort -> FuncDecl.func_decl list + val mk_sort : + context -> symbol -> symbol array -> sort array -> tuple_sort + val get_mk_decl : tuple_sort -> func_decl + val get_num_fields : tuple_sort -> int + val get_field_decls : tuple_sort -> func_decl array end -(** Functions to manipulate arithmetic expressions *) module Arithmetic : sig - (** Integer Arithmetic *) + module Integer : sig - (** Create a new integer sort. *) - val mk_sort : context -> Sort.sort - - (** Retrieve the int value. *) - val get_int : Expr.expr -> int - - (** Get a big_int from an integer numeral *) - val get_big_int : Expr.expr -> Big_int.big_int - - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string - - (** Creates an integer constant. *) - val mk_const : context -> Symbol.symbol -> Expr.expr - - (** Creates an integer constant. *) - val mk_const_s : context -> string -> Expr.expr - - (** Create an expression representing [t1 mod t2]. - The arguments must have int type. *) - val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 rem t2]. - The arguments must have int type. *) - val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an integer numeral. *) - val mk_numeral_s : context -> string -> Expr.expr - - (** Create an integer numeral. - @return A Term with the given value and sort Integer *) - val mk_numeral_i : context -> int -> Expr.expr - - (** Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term [k] and - and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. - The argument must be of integer sort. *) - val mk_int2real : context -> Expr.expr -> Expr.expr - - (** Create an n-bit bit-vector from an integer argument. - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. *) - val mk_int2bv : context -> int -> Expr.expr -> Expr.expr + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> expr + val mk_rem : context -> int_expr -> int_expr -> expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> real_expr + val mk_int2bv : context -> int -> int_expr -> bitvec_expr end - (** Real Arithmetic *) module Real : sig - (** Create a real sort. *) - val mk_sort : context -> Sort.sort - - (** The numerator of a rational numeral. *) - val get_numerator : Expr.expr -> Expr.expr - - (** The denominator of a rational numeral. *) - val get_denominator : Expr.expr -> Expr.expr - - (** Get a ratio from a real numeral *) - val get_ratio : Expr.expr -> Ratio.ratio - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as indicated by the int argument.*) - val to_decimal_string : Expr.expr-> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr-> string - - (** Creates a real constant. *) - val mk_const : context -> Symbol.symbol -> Expr.expr - - (** Creates a real constant. *) - val mk_const_s : context -> string -> Expr.expr - - (** Create a real numeral from a fraction. - @return A Term with rational value and sort Real - {!mk_numeral_s} *) - val mk_numeral_nd : context -> int -> int -> Expr.expr - - (** Create a real numeral. - @return A Term with the given value and sort Real *) - val mk_numeral_s : context -> string -> Expr.expr - - (** Create a real numeral. - @return A Term with the given value and sort Real *) - val mk_numeral_i : context -> int -> Expr.expr - - (** Creates an expression that checks whether a real number is an integer. *) - val mk_is_integer : context -> Expr.expr -> Expr.expr - - (** Coerce a real to an integer. - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. *) - val mk_real2int : context -> Expr.expr -> Expr.expr - - (** Algebraic Numbers *) - module AlgebraicNumber : - sig - (** Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_upper : Expr.expr -> int -> Expr.expr - - (** Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_lower : Expr.expr -> int -> Expr.expr - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as the int argument provided.*) - val to_decimal_string : Expr.expr -> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string - end + val mk_sort : context -> real_sort + val get_numerator : rat_num -> int_num + val get_denominator : rat_num -> int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> bool_expr + val mk_real2int : context -> real_expr -> int_expr end - (** Indicates whether the term is of integer sort. *) - val is_int : Expr.expr -> bool + module AlgebraicNumber : + sig + val to_upper : algebraic_num -> int -> rat_num + val to_lower : algebraic_num -> int -> rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end - (** Indicates whether the term is an arithmetic numeral. *) - val is_arithmetic_numeral : Expr.expr -> bool - - (** Indicates whether the term is a less-than-or-equal *) - val is_le : Expr.expr -> bool - - (** Indicates whether the term is a greater-than-or-equal *) - val is_ge : Expr.expr -> bool - - (** Indicates whether the term is a less-than *) - val is_lt : Expr.expr -> bool - - (** Indicates whether the term is a greater-than *) - val is_gt : Expr.expr -> bool - - (** Indicates whether the term is addition (binary) *) - val is_add : Expr.expr -> bool - - (** Indicates whether the term is subtraction (binary) *) - val is_sub : Expr.expr -> bool - - (** Indicates whether the term is a unary minus *) - val is_uminus : Expr.expr -> bool - - (** Indicates whether the term is multiplication (binary) *) - val is_mul : Expr.expr -> bool - - (** Indicates whether the term is division (binary) *) - val is_div : Expr.expr -> bool - - (** Indicates whether the term is integer division (binary) *) - val is_idiv : Expr.expr -> bool - - (** Indicates whether the term is remainder (binary) *) - val is_remainder : Expr.expr -> bool - - (** Indicates whether the term is modulus (binary) *) - val is_modulus : Expr.expr -> bool - - (** Indicates whether the term is a coercion of integer to real (unary) *) - val is_inttoreal : Expr.expr -> bool - - (** Indicates whether the term is a coercion of real to integer (unary) *) - val is_real_to_int : Expr.expr -> bool - - (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - val is_real_is_int : Expr.expr -> bool - - (** Indicates whether the term is of sort real. *) - val is_real : Expr.expr -> bool - - (** Indicates whether the term is an integer numeral. *) - val is_int_numeral : Expr.expr -> bool - - (** Indicates whether the term is a real numeral. *) - val is_rat_numeral : Expr.expr -> bool - - (** Indicates whether the term is an algebraic number *) - val is_algebraic_number : Expr.expr -> bool - - (** Create an expression representing [t[0] + t[1] + ...]. *) - val mk_add : context -> Expr.expr list -> Expr.expr - - (** Create an expression representing [t[0] * t[1] * ...]. *) - val mk_mul : context -> Expr.expr list -> Expr.expr - - (** Create an expression representing [t[0] - t[1] - ...]. *) - val mk_sub : context -> Expr.expr list -> Expr.expr - - (** Create an expression representing [-t]. *) - val mk_unary_minus : context -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 / t2]. *) - val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 ^ t2]. *) - val mk_power : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 < t2] *) - val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 <= t2] *) - val mk_le : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 > t2] *) - val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing [t1 >= t2] *) - val mk_ge : context -> Expr.expr -> Expr.expr -> Expr.expr + val is_int : expr -> bool + val is_arithmetic_numeral : expr -> bool + val is_le : expr -> bool + val is_ge : expr -> bool + val is_lt : expr -> bool + val is_gt : expr -> bool + val is_add : expr -> bool + val is_sub : expr -> bool + val is_uminus : expr -> bool + val is_mul : expr -> bool + val is_div : expr -> bool + val is_idiv : expr -> bool + val is_remainder : expr -> bool + val is_modulus : expr -> bool + val is_inttoreal : expr -> bool + val is_real_to_int : expr -> bool + val is_real_is_int : expr -> bool + val is_real : expr -> bool + val is_int_numeral : expr -> bool + val is_rat_num : expr -> bool + val is_algebraic_number : expr -> bool + val mk_add : context -> arith_expr array -> arith_expr + val mk_mul : context -> arith_expr array -> arith_expr + val mk_sub : context -> arith_expr array -> arith_expr + val mk_unary_minus : context -> arith_expr -> arith_expr + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + val mk_lt : context -> arith_expr -> arith_expr -> bool_expr + val mk_le : context -> arith_expr -> arith_expr -> bool_expr + val mk_gt : context -> arith_expr -> arith_expr -> bool_expr + val mk_ge : context -> arith_expr -> arith_expr -> bool_expr end -(** Functions to manipulate bit-vector expressions *) module BitVector : sig - (** Create a new bit-vector sort. *) - val mk_sort : context -> int -> Sort.sort - - (** Indicates whether the terms is of bit-vector sort. *) - val is_bv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector numeral *) - val is_bv_numeral : Expr.expr -> bool - - (** Indicates whether the term is a one-bit bit-vector with value one *) - val is_bv_bit1 : Expr.expr -> bool - - (** Indicates whether the term is a one-bit bit-vector with value zero *) - val is_bv_bit0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unary minus *) - val is_bv_uminus : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector addition (binary) *) - val is_bv_add : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector subtraction (binary) *) - val is_bv_sub : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector multiplication (binary) *) - val is_bv_mul : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed division (binary) *) - val is_bv_sdiv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned division (binary) *) - val is_bv_udiv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed remainder (binary) *) - val is_bv_SRem : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - val is_bv_urem : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed modulus *) - val is_bv_smod : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed division by zero *) - val is_bv_sdiv0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned division by zero *) - val is_bv_udiv0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed remainder by zero *) - val is_bv_srem0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - val is_bv_urem0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed modulus by zero *) - val is_bv_smod0 : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - val is_bv_ule : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - val is_bv_sle : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - val is_bv_uge : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - val is_bv_sge : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector less-than *) - val is_bv_ult : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector less-than *) - val is_bv_slt : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector greater-than *) - val is_bv_ugt : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector greater-than *) - val is_bv_sgt : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise AND *) - val is_bv_and : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise OR *) - val is_bv_or : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NOT *) - val is_bv_not : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise XOR *) - val is_bv_xor : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NAND *) - val is_bv_nand : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NOR *) - val is_bv_nor : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise XNOR *) - val is_bv_xnor : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector concatenation (binary) *) - val is_bv_concat : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector sign extension *) - val is_bv_signextension : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector zero extension *) - val is_bv_zeroextension : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector extraction *) - val is_bv_extract : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector repetition *) - val is_bv_repeat : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector reduce OR *) - val is_bv_reduceor : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector reduce AND *) - val is_bv_reduceand : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector comparison *) - val is_bv_comp : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector shift left *) - val is_bv_shiftleft : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector logical shift right *) - val is_bv_shiftrightlogical : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector arithmetic shift left *) - val is_bv_shiftrightarithmetic : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate left *) - val is_bv_rotateleft : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate right *) - val is_bv_rotateright : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - val is_bv_rotateleftextended : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - val is_bv_rotaterightextended : Expr.expr -> bool - - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - - (** Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - val is_int_to_bv : Expr.expr -> bool - - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - val is_bv_to_int : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - val is_bv_carry : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - val is_bv_xor3 : Expr.expr -> bool - - (** The size of a bit-vector sort. *) - val get_size : Sort.sort -> int - - (** Retrieve the int value. *) - val get_int : Expr.expr -> int - - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string - - (** Creates a bit-vector constant. *) - val mk_const : context -> Symbol.symbol -> int -> Expr.expr - - (** Creates a bit-vector constant. *) - val mk_const_s : context -> string -> int -> Expr.expr - - (** Bitwise negation. - The argument must have a bit-vector sort. *) - val mk_not : context -> Expr.expr -> Expr.expr - - (** Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) - val mk_redand : context -> Expr.expr -> Expr.expr - - (** Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) - val mk_redor : context -> Expr.expr -> Expr.expr - - (** Bitwise conjunction. - The arguments must have a bit-vector sort. *) - val mk_and : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bitwise disjunction. - The arguments must have a bit-vector sort. *) - val mk_or : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bitwise XOR. - The arguments must have a bit-vector sort. *) - val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bitwise NAND. - The arguments must have a bit-vector sort. *) - val mk_nand : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bitwise NOR. - The arguments must have a bit-vector sort. *) - val mk_nor : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bitwise XNOR. - The arguments must have a bit-vector sort. *) - val mk_xnor : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Standard two's complement unary minus. - The arguments must have a bit-vector sort. *) - val mk_neg : context -> Expr.expr -> Expr.expr - - (** Two's complement addition. - The arguments must have the same bit-vector sort. *) - val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement subtraction. - The arguments must have the same bit-vector sort. *) - val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement multiplication. - The arguments must have the same bit-vector sort. *) - val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Unsigned division. - - It is defined as the floor of [t1/t2] if \c t2 is - different from zero. If [t2] is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. *) - val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Signed division. - - It is defined in the following way: - - - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. - - - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. - - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Unsigned remainder. - - It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Signed remainder. - - It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement signed remainder (sign follows divisor). - - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Unsigned less-than - - The arguments must have the same bit-vector sort. *) - val mk_ult : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement signed less-than - - The arguments must have the same bit-vector sort. *) - val mk_slt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_ule : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_sle : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_uge : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_sge : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Unsigned greater-than. - - The arguments must have the same bit-vector sort. *) - val mk_ugt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. *) - val mk_sgt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size [n1+n2], where [n1] ([n2]) - is the size of [t1] ([t2]). *) - val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Bit-vector extraction. - - Extract the bits between two limits from a bitvector of - size [m] to yield a new bitvector of size [n], where - [n = high - low + 1]. *) - val mk_extract : context -> int -> int -> Expr.expr -> Expr.expr - - (** Bit-vector sign extension. - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size [m+i], where \c m is the size of the given bit-vector. *) - val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr - - (** Bit-vector zero extension. - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size [m+i], where \c m is the size of the - given bit-vector. *) - val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr - - (** Bit-vector repetition. *) - val mk_repeat : context -> int -> Expr.expr -> Expr.expr - - (** Shift left. - - It is equivalent to multiplication by [2^x] where \c x is the value of third argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling.*) - val mk_shl : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Logical shift right - - It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. *) - val mk_lshr : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. *) - val mk_ashr : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Rotate Left. - Rotate bits of \c t to the left \c i times. *) - val mk_rotate_left : context -> int -> Expr.expr -> Expr.expr - - (** Rotate Right. - Rotate bits of \c t to the right \c i times.*) - val mk_rotate_right : context -> int -> Expr.expr -> Expr.expr - - (** Rotate Left. - Rotate bits of the second argument to the left.*) - val mk_ext_rotate_left : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Rotate Right. - Rotate bits of the second argument to the right. *) - val mk_ext_rotate_right : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an integer from the bit-vector argument - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [[0..2^N-1]], where - N are the number of bits in the argument. - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function.*) - val mk_bv2int : context -> Expr.expr -> bool -> Expr.expr - - (** Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_add_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr - - (** Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_add_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_sub_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_sub_no_underflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr - - (** Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_sdiv_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_neg_no_overflow : context -> Expr.expr -> Expr.expr - - (** Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr - - (** Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create a bit-vector numeral. *) - val mk_numeral : context -> string -> int -> Expr.expr + val mk_sort : context -> int -> bitvec_sort + val is_bv : expr -> bool + val is_bv_numeral : expr -> bool + val is_bv_bit1 : expr -> bool + val is_bv_bit0 : expr -> bool + val is_bv_uminus : expr -> bool + val is_bv_add : expr -> bool + val is_bv_sub : expr -> bool + val is_bv_mul : expr -> bool + val is_bv_sdiv : expr -> bool + val is_bv_udiv : expr -> bool + val is_bv_SRem : expr -> bool + val is_bv_urem : expr -> bool + val is_bv_smod : expr -> bool + val is_bv_sdiv0 : expr -> bool + val is_bv_udiv0 : expr -> bool + val is_bv_srem0 : expr -> bool + val is_bv_urem0 : expr -> bool + val is_bv_smod0 : expr -> bool + val is_bv_ule : expr -> bool + val is_bv_sle : expr -> bool + val is_bv_uge : expr -> bool + val is_bv_sge : expr -> bool + val is_bv_ult : expr -> bool + val is_bv_slt : expr -> bool + val is_bv_ugt : expr -> bool + val is_bv_sgt : expr -> bool + val is_bv_and : expr -> bool + val is_bv_or : expr -> bool + val is_bv_not : expr -> bool + val is_bv_xor : expr -> bool + val is_bv_nand : expr -> bool + val is_bv_nor : expr -> bool + val is_bv_xnor : expr -> bool + val is_bv_concat : expr -> bool + val is_bv_signextension : expr -> bool + val is_bv_zeroextension : expr -> bool + val is_bv_extract : expr -> bool + val is_bv_repeat : expr -> bool + val is_bv_reduceor : expr -> bool + val is_bv_reduceand : expr -> bool + val is_bv_comp : expr -> bool + val is_bv_shiftleft : expr -> bool + val is_bv_shiftrightlogical : expr -> bool + val is_bv_shiftrightarithmetic : expr -> bool + val is_bv_rotateleft : expr -> bool + val is_bv_rotateright : expr -> bool + val is_bv_rotateleftextended : expr -> bool + val is_bv_rotaterightextended : expr -> bool + val is_int_to_bv : expr -> bool + val is_bv_to_int : expr -> bool + val is_bv_carry : expr -> bool + val is_bv_xor3 : expr -> bool + val get_size : bitvec_sort -> int + val get_int : bitvec_num -> int + val to_string : bitvec_num -> string + val mk_const : context -> symbol -> int -> bitvec_expr + val mk_const_s : context -> string -> int -> bitvec_expr + val mk_not : context -> bitvec_expr -> expr + val mk_redand : context -> bitvec_expr -> expr + val mk_redor : context -> bitvec_expr -> expr + val mk_and : context -> bitvec_expr -> bitvec_expr -> expr + val mk_or : context -> bitvec_expr -> bitvec_expr -> expr + val mk_xor : context -> bitvec_expr -> bitvec_expr -> expr + val mk_nand : context -> bitvec_expr -> bitvec_expr -> expr + val mk_nor : context -> bitvec_expr -> bitvec_expr -> expr + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> expr + val mk_neg : context -> bitvec_expr -> expr + val mk_add : context -> bitvec_expr -> bitvec_expr -> expr + val mk_sub : context -> bitvec_expr -> bitvec_expr -> expr + val mk_mul : context -> bitvec_expr -> bitvec_expr -> expr + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> expr + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> expr + val mk_urem : context -> bitvec_expr -> bitvec_expr -> expr + val mk_srem : context -> bitvec_expr -> bitvec_expr -> expr + val mk_smod : context -> bitvec_expr -> bitvec_expr -> expr + val mk_ult : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_slt : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_ule : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_sle : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_uge : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_sge : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_concat : context -> bitvec_expr -> bitvec_expr -> expr + val mk_extract : context -> int -> int -> bitvec_expr -> expr + val mk_sign_ext : context -> int -> bitvec_expr -> expr + val mk_zero_ext : context -> int -> bitvec_expr -> expr + val mk_repeat : context -> int -> bitvec_expr -> expr + val mk_shl : context -> bitvec_expr -> bitvec_expr -> expr + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> expr + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> expr + val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> expr + val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> expr + val mk_bv2int : context -> bitvec_expr -> bool -> int_expr + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> bool_expr + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> bool_expr + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_neg_no_overflow : context -> bitvec_expr -> bool_expr + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> bool_expr + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_numeral : context -> string -> int -> bitvec_num end -(** Functions to manipulate proof expressions *) module Proof : sig - (** Indicates whether the term is a Proof for the expression 'true'. *) - val is_true : Expr.expr -> bool - - (** Indicates whether the term is a proof for a fact asserted by the user. *) - val is_asserted : Expr.expr -> bool - - (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - val is_goal : Expr.expr -> bool - - (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) - val is_oeq : Expr.expr -> bool - - (** Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). *) - val is_modus_ponens : Expr.expr -> bool - - (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. *) - val is_reflexivity : Expr.expr -> bool - - (** Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. *) - val is_symmetry : Expr.expr -> bool - - (** Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) *) - val is_transitivity : Expr.expr -> bool - - (** Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. *) - val is_Transitivity_star : Expr.expr -> bool - - (** Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. *) - val is_monotonicity : Expr.expr -> bool - - (** Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - val is_quant_intro : Expr.expr -> bool - - (** Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. *) - val is_distributivity : Expr.expr -> bool - - (** Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i *) - val is_and_elimination : Expr.expr -> bool - - (** Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) *) - val is_or_elimination : Expr.expr -> bool - - (** Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) *) - val is_rewrite : Expr.expr -> bool - - (** Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - val is_rewrite_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - val is_pull_quant : Expr.expr -> bool - - (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents *) - val is_pull_quant_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents *) - val is_push_quant : Expr.expr -> bool - - (** Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. *) - val is_elim_unused_vars : Expr.expr -> bool - - (** Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. *) - val is_der : Expr.expr -> bool - - (** Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) *) - val is_quant_inst : Expr.expr -> bool - - (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. *) - val is_hypothesis : Expr.expr -> bool - - (** Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. *) - val is_lemma : Expr.expr -> bool - - (** Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - val is_unit_resolution : Expr.expr -> bool - - (** Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) *) - val is_iff_true : Expr.expr -> bool - - (** Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) *) - val is_iff_false : Expr.expr -> bool - - (** Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. *) - val is_commutativity : Expr.expr -> bool - - (** Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). *) - val is_def_axiom : Expr.expr -> bool - - (** Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) *) - val is_def_intro : Expr.expr -> bool - - (** Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. *) - val is_apply_def : Expr.expr -> bool - - (** Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) *) - val is_iff_oeq : Expr.expr -> bool - - (** Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. *) - val is_nnf_pos : Expr.expr -> bool - - (** Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) *) - val is_nnf_neg : Expr.expr -> bool - - (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - val is_nnf_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - val is_cnf_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. *) - val is_skolemize : Expr.expr -> bool - - (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q *) - val is_modus_ponens_oeq : Expr.expr -> bool - - (** Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - val is_theory_lemma : Expr.expr -> bool + val is_true : expr -> bool + val is_asserted : expr -> bool + val is_goal : expr -> bool + val is_modus_ponens : expr -> bool + val is_reflexivity : expr -> bool + val is_symmetry : expr -> bool + val is_transitivity : expr -> bool + val is_Transitivity_star : expr -> bool + val is_monotonicity : expr -> bool + val is_quant_intro : expr -> bool + val is_distributivity : expr -> bool + val is_and_elimination : expr -> bool + val is_or_elimination : expr -> bool + val is_rewrite : expr -> bool + val is_rewrite_star : expr -> bool + val is_pull_quant : expr -> bool + val is_pull_quant_star : expr -> bool + val is_push_quant : expr -> bool + val is_elim_unused_vars : expr -> bool + val is_der : expr -> bool + val is_quant_inst : expr -> bool + val is_hypothesis : expr -> bool + val is_lemma : expr -> bool + val is_unit_resolution : expr -> bool + val is_iff_true : expr -> bool + val is_iff_false : expr -> bool + val is_commutativity : expr -> bool + val is_def_axiom : expr -> bool + val is_def_intro : expr -> bool + val is_apply_def : expr -> bool + val is_iff_oeq : expr -> bool + val is_nnf_pos : expr -> bool + val is_nnf_neg : expr -> bool + val is_nnf_star : expr -> bool + val is_cnf_star : expr -> bool + val is_skolemize : expr -> bool + val is_modus_ponens_oeq : expr -> bool + val is_theory_lemma : expr -> bool end -(** Goals - - A goal (aka problem). A goal is essentially a - of formulas, that can be solved and/or transformed using - tactics and solvers. *) module Goal : sig - type goal - - (** The precision of the goal. - - Goals can be transformed using over and under approximations. - An under approximation is applied when the objective is to find a model for a given goal. - An over approximation is applied when the objective is to find a proof for a given goal. *) val get_precision : goal -> Z3enums.goal_prec - - (** Indicates whether the goal is precise. *) val is_precise : goal -> bool - - (** Indicates whether the goal is an under-approximation. *) val is_underapproximation : goal -> bool - - (** Indicates whether the goal is an over-approximation. *) val is_overapproximation : goal -> bool - - (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) val is_garbage : goal -> bool - - (** Adds the constraints to the given goal. *) - val add : goal -> Expr.expr list -> unit - - (** Indicates whether the goal contains `false'. *) + val assert_ : goal -> bool_expr array -> unit val is_inconsistent : goal -> bool - - (** The depth of the goal. - This tracks how many transformations were applied to it. *) val get_depth : goal -> int - - (** Erases all formulas from the given goal. *) val reset : goal -> unit - - (** The number of formulas in the goal. *) val get_size : goal -> int - - (** The formulas in the goal. *) - val get_formulas : goal -> Expr.expr list - - (** The number of formulas, subformulas and terms in the goal. *) + val get_formulas : goal -> bool_expr array val get_num_exprs : goal -> int - - (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) val is_decided_sat : goal -> bool - - (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) val is_decided_unsat : goal -> bool - - (** Translates (copies) the Goal to another context.. *) val translate : goal -> context -> goal - - (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - val simplify : goal -> Params.params option -> goal - - (** Creates a new Goal. - - Note that the Context must have been created with proof generation support if - the fourth argument is set to true here. *) + val simplify : goal -> params option -> goal val mk_goal : context -> bool -> bool -> bool -> goal - - (** A string representation of the Goal. *) val to_string : goal -> string end -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) module Model : sig - type model - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. *) module FuncInterp : sig - type func_interp - - (** Function interpretations entries - An Entry object represents an element in the finite map used to a function interpretation. *) module FuncEntry : sig - type func_entry - - (** Return the (symbolic) value of this entry. - *) - val get_value : func_entry -> Expr.expr - - (** The number of arguments of the entry. - *) + val get_value : func_entry -> expr val get_num_args : func_entry -> int - - (** The arguments of the function entry. - *) - val get_args : func_entry -> Expr.expr list - - (** A string representation of the function entry. - *) + val get_args : func_entry -> expr array val to_string : func_entry -> string end - (** The number of entries in the function interpretation. *) val get_num_entries : func_interp -> int - - (** The entries in the function interpretation *) - val get_entries : func_interp -> FuncEntry.func_entry list - - (** The (symbolic) `else' value of the function interpretation. *) - val get_else : func_interp -> Expr.expr - - (** The arity of the function interpretation *) + val get_entries : func_interp -> func_entry array + val get_else : func_interp -> expr val get_arity : func_interp -> int - - (** A string representation of the function interpretation. *) val to_string : func_interp -> string end - (** Retrieves the interpretation (the assignment) of a func_decl in the model. - @return An expression if the function has an interpretation in the model, null otherwise. *) - val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option - - (** Retrieves the interpretation (the assignment) of an expression in the model. - @return An expression if the constant has an interpretation in the model, null otherwise. *) - val get_const_interp_e : model -> Expr.expr -> Expr.expr option - - (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. - @return A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option - - (** The number of constant interpretations in the model. *) + val get_const_interp : model -> func_decl -> expr option + val get_const_interp_e : model -> expr -> expr option + val get_func_interp : model -> func_decl -> func_interp option val get_num_consts : model -> int - - (** The function declarations of the constants in the model. *) - val get_const_decls : model -> FuncDecl.func_decl list - - (** The number of function interpretations in the model. *) + val get_const_decls : model -> func_decl array val get_num_funcs : model -> int - - (** The function declarations of the function interpretations in the model. *) - val get_func_decls : model -> FuncDecl.func_decl list - - (** All symbols that have an interpretation in the model. *) - val get_decls : model -> FuncDecl.func_decl list - - (** Evaluates an expression in the current model. - - This function may fail if the argument contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. - In this case a [ModelEvaluationFailedException] is thrown. - *) - val eval : model -> Expr.expr -> bool -> Expr.expr option - - (** Alias for [eval]. *) - val evaluate : model -> Expr.expr -> bool -> Expr.expr option - - (** The number of uninterpreted sorts that the model has an interpretation for. *) + val get_func_decls : model -> func_decl array + val get_decls : model -> func_decl array + exception ModelEvaluationFailedException of string + val eval : model -> expr -> bool -> expr + val evaluate : model -> expr -> bool -> expr val get_num_sorts : model -> int - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - {!get_num_sorts} - {!sort_universe} *) - val get_sorts : model -> Sort.sort list - - (** The finite set of distinct values that represent the interpretation of a sort. - {!get_sorts} - @return A list of expressions, where each is an element of the universe of the sort *) - val sort_universe : model -> Sort.sort -> AST.ast list - - (** Conversion of models to strings. - @return A string representation of the model. *) + val get_sorts : model -> sort array + val sort_universe : model -> sort -> ast_vector array val to_string : model -> string end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures [Context.NumProbes] - and [Context.ProbeNames]. - It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. -*) module Probe : sig - type probe - - (** Execute the probe over the goal. - @return A probe always produce a float value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - val apply : probe -> Goal.goal -> float - - (** The number of supported Probes. *) + val apply : probe -> goal -> float val get_num_probes : context -> int - - (** The names of all supported Probes. *) - val get_probe_names : context -> string list - - (** Returns a string containing a description of the probe with the given name. *) + val get_probe_names : context -> string array val get_probe_description : context -> string -> string - - (** Creates a new Probe. *) val mk_probe : context -> string -> probe - - (** Create a probe that always evaluates to a float value. *) val const : context -> float -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is less than the value returned by second argument *) val lt : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is greater than the value returned by second argument *) val gt : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is less than or equal the value returned by second argument *) val le : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is greater than or equal the value returned by second argument *) val ge : context -> probe -> probe -> probe - - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is equal the value returned by second argument *) val eq : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) val and_ : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) val or_ : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) val not_ : context -> probe -> probe end -(** Tactics - - Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using [Context.get_num_tactics] - and [Context.get_tactic_names]. - It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. -*) module Tactic : sig - type tactic - (** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult : sig - type apply_result - - (** The number of Subgoals. *) val get_num_subgoals : apply_result -> int - - (** Retrieves the subgoals from the apply_result. *) - val get_subgoals : apply_result -> Goal.goal list - - (** Retrieves a subgoal from the apply_result. *) - val get_subgoal : apply_result -> int -> Goal.goal - - (** Convert a model for a subgoal into a model for the original - goal [g], that the ApplyResult was obtained from. - #return A model for [g] *) - val convert_model : apply_result -> int -> Model.model -> Model.model - - (** A string representation of the ApplyResult. *) + val get_subgoals : apply_result -> goal array + val get_subgoal : apply_result -> int -> goal + val convert_model : apply_result -> int -> model -> model val to_string : apply_result -> string end - (** A string containing a description of parameters accepted by the tactic. *) val get_help : tactic -> string - - (** Retrieves parameter descriptions for Tactics. *) - val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs - - (** Apply the tactic to the goal. *) - val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result - - (** The number of supported tactics. *) + val get_param_descrs : tactic -> param_descrs + val apply : tactic -> goal -> params option -> apply_result val get_num_tactics : context -> int - - (** The names of all supported tactics. *) - val get_tactic_names : context -> string list - - (** Returns a string containing a description of the tactic with the given name. *) + val get_tactic_names : context -> string array val get_tactic_description : context -> string -> string - - (** Creates a new Tactic. *) val mk_tactic : context -> string -> tactic - - (** Create a tactic that applies one tactic to a Goal and - then another one to every subgoal produced by the first one. *) - val and_then : context -> tactic -> tactic -> tactic list -> tactic - - (** Create a tactic that first applies one tactic to a Goal and - if it fails then returns the result of another tactic applied to the Goal. *) + val and_then : context -> tactic -> tactic -> tactic array -> tactic val or_else : context -> tactic -> tactic -> tactic - - (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). - - If the tactic does not terminate within the timeout, then it fails. *) val try_for : context -> tactic -> int -> tactic - - (** Create a tactic that applies one tactic to a given goal if the probe - evaluates to true. - - If the probe evaluates to false, then the new tactic behaves like the [skip] tactic. *) - val when_ : context -> Probe.probe -> tactic -> tactic - - (** Create a tactic that applies a tactic to a given goal if the probe - evaluates to true and another tactic otherwise. *) - val cond : context -> Probe.probe -> tactic -> tactic -> tactic - - (** Create a tactic that keeps applying one tactic until the goal is not - modified anymore or the maximum number of iterations is reached. *) + val when_ : context -> probe -> tactic -> tactic + val cond : context -> probe -> tactic -> tactic -> tactic val repeat : context -> tactic -> int -> tactic - - (** Create a tactic that just returns the given goal. *) val skip : context -> tactic - - (** Create a tactic always fails. *) val fail : context -> tactic - - (** Create a tactic that fails if the probe evaluates to false. *) - val fail_if : context -> Probe.probe -> tactic - - (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). *) + val fail_if : context -> probe -> tactic val fail_if_not_decided : context -> tactic - - (** Create a tactic that applies a tactic using the given set of parameters. *) - val using_params : context -> tactic -> Params.params -> tactic - - (** Create a tactic that applies a tactic using the given set of parameters. - Alias for [UsingParams]*) - val with_ : context -> tactic -> Params.params -> tactic - - (** Create a tactic that applies the given tactics in parallel. *) - val par_or : context -> tactic list -> tactic - - (** Create a tactic that applies a tactic to a given goal and then another tactic - to every subgoal produced by the first one. The subgoals are processed in parallel. *) + val using_params : context -> tactic -> params -> tactic + val with_ : context -> tactic -> params -> tactic + val par_or : context -> tactic array -> tactic val par_and_then : context -> tactic -> tactic -> tactic - - (** Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. *) val interrupt : context -> unit end -(** Solvers *) module Solver : sig - type solver - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - val string_of_status : status -> string - (** Objects that track statistical information about solvers. *) module Statistics : sig - type statistics - (** Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - *) module Entry : sig - type statistics_entry - - (** The key of the entry. *) val get_key : statistics_entry -> string - - (** The int-value of the entry. *) val get_int : statistics_entry -> int - - (** The float-value of the entry. *) val get_float : statistics_entry -> float - - (** True if the entry is uint-valued. *) val is_int : statistics_entry -> bool - - (** True if the entry is float-valued. *) val is_float : statistics_entry -> bool - - (** The string representation of the the entry's value. *) val to_string_value : statistics_entry -> string - - (** The string representation of the entry (key and value) *) val to_string : statistics_entry -> string end - (** A string representation of the statistical data. *) val to_string : statistics -> string - - (** The number of statistical data. *) val get_size : statistics -> int - - (** The data entries. *) - val get_entries : statistics -> Entry.statistics_entry list - - (** The statistical counters. *) - val get_keys : statistics -> string list - - (** The value of a particular statistical counter. *) - val get : statistics -> string -> Entry.statistics_entry option + val get_entries : statistics -> statistics_entry array + val get_keys : statistics -> string array + val get : statistics -> string -> statistics_entry option end - (** A string that describes all available solver parameters. *) val get_help : solver -> string - - (** Sets the solver parameters. *) - val set_parameters : solver -> Params.params -> unit - - (** Retrieves parameter descriptions for solver. *) - val get_param_descrs : solver -> Params.ParamDescrs.param_descrs - - (** The current number of backtracking points (scopes). - {!pop} - {!push} *) + val set_parameters : solver -> params -> unit + val get_param_descrs : solver -> param_descrs val get_num_scopes : solver -> int - - (** Creates a backtracking point. - {!pop} *) val push : solver -> unit - - (** Backtracks a number of backtracking points. - Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} - {!push} *) val pop : solver -> int -> unit - - (** Resets the Solver. - This removes all assertions from the solver. *) val reset : solver -> unit - - (** Assert a constraint (or multiple) into the solver. *) - val add : solver -> Expr.expr list -> unit - - (** * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) - val assert_and_track_l : solver -> Expr.expr list -> Expr.expr list -> unit - - (** * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) - val assert_and_track : solver -> Expr.expr -> Expr.expr -> unit - - (** The number of assertions in the solver. *) + val assert_ : solver -> bool_expr array -> unit + val assert_and_track : solver -> bool_expr -> bool_expr -> unit val get_num_assertions : solver -> int - - (** The set of asserted formulas. *) - val get_assertions : solver -> Expr.expr list - - (** Checks whether the assertions in the solver are consistent or not. - - {!Model} - {!get_unsat_core} - {!Proof} *) - val check : solver -> Expr.expr list -> status - - (** The model of the last [Check]. - - The result is [None] if [Check] was not invoked before, - if its results was not [SATISFIABLE], or if model production is not enabled. *) - val get_model : solver -> Model.model option - - (** The proof of the last [Check]. - - The result is [null] if [Check] was not invoked before, - if its results was not [UNSATISFIABLE], or if proof production is disabled. *) - val get_proof : solver -> Expr.expr option - - (** The unsat core of the last [Check]. - - The unsat core is a subset of [Assertions] - The result is empty if [Check] was not invoked before, - if its results was not [UNSATISFIABLE], or if core production is disabled. *) - val get_unsat_core : solver -> AST.ast list - - (** A brief justification of why the last call to [Check] returned [UNKNOWN]. *) + val get_assertions : solver -> bool_expr array + val check : solver -> bool_expr array -> status + val get_model : solver -> model option + val get_proof : solver -> expr option + val get_unsat_core : solver -> ast_vector array val get_reason_unknown : solver -> string - - (** Solver statistics. *) - val get_statistics : solver -> Statistics.statistics - - (** Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. *) - val mk_solver : context -> Symbol.symbol option -> solver - - (** Creates a new (incremental) solver. - {!mk_solver} *) + val get_statistics : solver -> statistics + val mk_solver : context -> symbol option -> solver val mk_solver_s : context -> string -> solver - - (** Creates a new (incremental) solver. *) val mk_simple_solver : context -> solver - - (** Creates a solver that is implemented using the given tactic. - - The solver supports the commands [Push] and [Pop], but it - will always solve each check from scratch. *) - val mk_solver_t : context -> Tactic.tactic -> solver - - (** A string representation of the solver. *) + val mk_solver_t : context -> tactic -> solver val to_string : solver -> string end -(** Fixedpoint solving *) module Fixedpoint : sig - type fixedpoint - - (** A string that describes all available fixedpoint solver parameters. *) val get_help : fixedpoint -> string - - (** Sets the fixedpoint solver parameters. *) - val set_params : fixedpoint -> Params.params -> unit - - (** Retrieves parameter descriptions for Fixedpoint solver. *) - val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs - - (** Assert a constraints into the fixedpoint solver. *) - val add : fixedpoint -> Expr.expr list -> unit - - (** Register predicate as recursive relation. *) - val register_relation : fixedpoint -> FuncDecl.func_decl -> unit - - (** Add rule into the fixedpoint solver. *) - val add_rule : fixedpoint -> Expr.expr -> Symbol.symbol option -> unit - - (** Add table fact to the fixedpoint solver. *) - val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit - - (** Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. *) - val query : fixedpoint -> Expr.expr -> Solver.status - - (** Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status - - (** Creates a backtracking point. - {!pop} *) + val set_params : fixedpoint -> params -> unit + val get_param_descrs : fixedpoint -> param_descrs + val assert_ : fixedpoint -> bool_expr array -> unit + val register_relation : fixedpoint -> func_decl -> unit + val add_rule : fixedpoint -> bool_expr -> symbol option -> unit + val add_fact : fixedpoint -> func_decl -> int array -> unit + val query : fixedpoint -> bool_expr -> status + val query_r : fixedpoint -> func_decl array -> status val push : fixedpoint -> unit - - (** Backtrack one backtracking point. - - Note that an exception is thrown if Pop is called without a corresponding [Push] - {!push} *) val pop : fixedpoint -> unit - - (** Update named rule into in the fixedpoint solver. *) - val update_rule : fixedpoint -> Expr.expr -> Symbol.symbol -> unit - - (** Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. *) - val get_answer : fixedpoint -> Expr.expr option - - (** Retrieve explanation why fixedpoint engine returned status Unknown. *) + val update_rule : fixedpoint -> bool_expr -> symbol -> unit + val get_answer : fixedpoint -> expr option val get_reason_unknown : fixedpoint -> string - - (** Retrieve the number of levels explored for a given predicate. *) - val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int - - (** Retrieve the cover of a predicate. *) - val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option - - (** Add property about the predicate. - The property is added at level. *) - val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit - - (** Retrieve internal string representation of fixedpoint object. *) + val get_num_levels : fixedpoint -> func_decl -> int + val get_cover_delta : fixedpoint -> int -> func_decl -> expr option + val add_cover : fixedpoint -> int -> func_decl -> expr -> unit val to_string : fixedpoint -> string - - (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit - - (** Convert benchmark given as set of axioms, rules and queries to a string. *) - val to_string_q : fixedpoint -> Expr.expr list -> string - - (** Retrieve set of rules added to fixedpoint context. *) - val get_rules : fixedpoint -> Expr.expr list - - (** Retrieve set of assertions added to fixedpoint context. *) - val get_assertions : fixedpoint -> Expr.expr list - - (** Create a Fixedpoint context. *) + val set_predicate_representation : fixedpoint -> func_decl -> symbol array -> unit + val to_string_q : fixedpoint -> bool_expr array -> string + val get_rules : fixedpoint -> bool_expr array + val get_assertions : fixedpoint -> bool_expr array val mk_fixedpoint : context -> fixedpoint end -(** Functions for handling SMT and SMT2 expressions and files *) +module Options : +sig + val update_param_value : context -> string -> string -> unit + val get_param_value : context -> string -> string option + val set_print_mode : context -> Z3enums.ast_print_mode -> unit + val toggle_warning_messages : bool -> unit +end + module SMT : sig - (** Convert a benchmark into an SMT-LIB formatted string. - - @return A string representation of the benchmark. *) - val benchmark_to_smtstring : context -> string -> string -> string -> string -> Expr.expr list -> Expr.expr -> string - - (** Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays in the third and fifth argument - don't need to match the names of the sorts and declarations in the arrays in the fourth - and sixth argument. This is a useful feature since we can use arbitrary names to - reference sorts and declarations. *) - val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - - (** Parse the given file using the SMT-LIB parser. - {!parse_smtlib_string} *) - val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - - (** The number of SMTLIB formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) + val benchmark_to_smtstring : context -> string -> string -> string -> string -> bool_expr array -> bool_expr -> string + val parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit + val parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit val get_num_smtlib_formulas : context -> int - - (** The formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) - val get_smtlib_formulas : context -> Expr.expr list - - (** The number of SMTLIB assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) + val get_smtlib_formulas : context -> bool_expr array val get_num_smtlib_assumptions : context -> int - - (** The assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) - val get_smtlib_assumptions : context -> Expr.expr list - - (** The number of SMTLIB declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) + val get_smtlib_assumptions : context -> bool_expr array val get_num_smtlib_decls : context -> int - - (** The declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) - val get_smtlib_decls : context -> FuncDecl.func_decl list - - (** The number of SMTLIB sorts parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) + val get_smtlib_decls : context -> func_decl array val get_num_smtlib_sorts : context -> int - - (** The sort declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) - val get_smtlib_sorts : context -> Sort.sort list - - (** Parse the given string using the SMT-LIB2 parser. - - {!parse_smtlib_string} - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr - - (** Parse the given file using the SMT-LIB2 parser. - {!parse_smtlib2_string} *) - val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr + val get_smtlib_sorts : context -> sort array + val parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> bool_expr + val parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> bool_expr end -(** Interpolation *) -module Interpolation : -sig - - (** Create an AST node marking a formula position for interpolation. - The expression must have Boolean sort. *) - val mk_interpolant : context -> Expr.expr -> Expr.expr - - (** The interpolation context is suitable for generation of interpolants. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val mk_interpolation_context : (string * string) list -> context - - (** Gets an interpolant. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> AST.ASTVector.ast_vector - - (** Computes an interpolant. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val compute_interpolant : context -> Expr.expr -> Params.params -> (AST.ASTVector.ast_vector * Model.model) - - (** Retrieves an interpolation profile. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val get_interpolation_profile : context -> string - - (** Read an interpolation problem from file. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val read_interpolation_problem : context -> string -> (Expr.expr list * int list * Expr.expr list) - - (** Check the correctness of an interpolant. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val check_interpolant : context -> int -> Expr.expr list -> int list -> Expr.expr list -> int -> Expr.expr list -> unit - - (** Write an interpolation problem to file suitable for reading with - Z3_read_interpolation_problem. - For more information on interpolation please refer - too the C/C++ API, which is well documented. *) - val write_interpolation_problem : context -> int -> Expr.expr list -> int list -> string -> int -> Expr.expr list -> unit - -end - -(** Set a global (or module) parameter, which is shared by all Z3 contexts. - - When a Z3 module is initialized it will use the value of these parameters - when Z3_params objects are not provided. - The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. - The character '.' is a delimiter (more later). - The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. - Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". - This function can be used to set parameters for a specific Z3 module. - This can be done by using .. - For example: - (set_global_param "pp.decimal" "true") - will set the parameter "decimal" in the module "pp" to true. -*) val set_global_param : string -> string -> unit - -(** Get a global (or module) parameter. - - Returns None if the parameter does not exist. - The caller must invoke #Z3_global_param_del_value to delete the value returned at param_value. - This function cannot be invoked simultaneously from different threads without synchronization. - The result string stored in param_value is stored in a shared location. -*) val get_global_param : string -> string option - -(** Restore the value of all global (and module) parameters. - - This command will not affect already created objects (such as tactics and solvers) - {!set_global_param} -*) - -val global_param_reset_all : unit -> unit - -(** Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. *) -val toggle_warning_messages : bool -> unit - +val global_param_reset_all : unit From fd78e45a2a6f0b040a96705494038186f4b361bd Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 20:04:11 +0000 Subject: [PATCH 396/507] ML API: got rid of "extra" objects on types. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 73 +++++++++++++++-------------------------------- src/api/ml/z3.mli | 2 +- 2 files changed, 24 insertions(+), 51 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index ea8c9576e..aa919e7fc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -93,13 +93,7 @@ type quantifier = Quantifier of expr type pattern = Pattern of ast (* Datatype stuff *) -type constructor_extra = { - m_n : int; - mutable m_tester_decl : func_decl option; - mutable m_constructor_decl : func_decl option ; - mutable m_accessor_decls : func_decl array option} - -type constructor = Constructor of (z3_native_object * constructor_extra) +type constructor = z3_native_object type constructor_list = z3_native_object (* Tactical interface *) @@ -2358,7 +2352,8 @@ struct (** Constructors *) module Constructor = struct - + let _counts = Hashtbl.create 0 + let create ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then @@ -2373,53 +2368,31 @@ struct (let f x = (Symbol.gno x) in (Array.map f field_names)) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) sort_refs) in - let no : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - let ex : constructor_extra = { m_n = n; - m_tester_decl = None; - m_constructor_decl = None; - m_accessor_decls = None} in + let no : constructor = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + Hashtbl.add _counts no n ; (z3obj_sno no ctx ptr) ; (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; - Constructor(no, ex) + no - let init_extra ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_tester_decl with - | None -> - let (a, b, c) = (Z3native.query_constructor (z3obj_gnc no) (z3obj_gno no) ex.m_n) in - ex.m_constructor_decl <- Some (func_decl_of_ptr (z3obj_gc no) a) ; - ex.m_tester_decl <- Some (func_decl_of_ptr (z3obj_gc no) b) ; - ex.m_accessor_decls <- Some (let f e = (func_decl_of_ptr (z3obj_gc no) e) in Array.map f c) ; - () - | _ -> () - - - let get_n ( x : constructor ) = - match x with Constructor(no, ex) -> - ex.m_n + let get_n ( x : constructor ) = (Hashtbl.find _counts x) - let rec tester_decl ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_tester_decl with - | Some(s) -> s - | None -> init_extra x ; tester_decl x - let rec constructor_decl ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_constructor_decl with - | Some(s) -> s - | None -> init_extra x ; constructor_decl x + let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + func_decl_of_ptr (z3obj_gc x) a + + let rec tester_decl ( x : constructor ) = + let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + func_decl_of_ptr (z3obj_gc x) b let rec accessor_decls ( x : constructor ) = - match x with Constructor(no, ex) -> - match ex.m_accessor_decls with - | Some(s) -> s - | None -> init_extra x ; accessor_decls x + let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + let f y = func_decl_of_ptr (z3obj_gc x) y in + Array.map f c (** The number of fields of the constructor. *) let get_num_fields ( x : constructor ) = get_n x @@ -2443,7 +2416,7 @@ struct m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in - let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + let f x =(z3obj_gno x) in (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Array.map f c))) ; (z3obj_create res) ; let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in @@ -2462,7 +2435,7 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array) = + let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = Constructor.create ctx name recognizer field_names sorts sort_refs @@ -2483,8 +2456,8 @@ struct (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array) = - let f x = match x with Constructor(no,_) -> (z3obj_gno no) in + let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array ) = + let f x = (z3obj_gno x) in let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in create_sort ctx x diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index f82492e8a..5d5d7adf0 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -482,8 +482,8 @@ sig module Constructor : sig val get_n : constructor -> int - val tester_decl : constructor -> func_decl val constructor_decl : constructor -> func_decl + val tester_decl : constructor -> func_decl val accessor_decls : constructor -> func_decl array val get_num_fields : constructor -> int val get_constructor_decl : constructor -> func_decl From 25615aedd9173d7f17b113e50aab9b9ab89fc2c2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 22:49:19 +0000 Subject: [PATCH 397/507] ML API: build system fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index cfea8d0f1..5a5dbc3a4 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1342,40 +1342,49 @@ class MLComponent(Component): def mk_makefile(self, out): if is_ml_enabled(): + CP_CMD = "cp" + if IS_WINDOWS: + CP_CMD = "copy" src_dir = self.to_src_dir sub_dir = os.path.join('api', 'ml') mk_dir(os.path.join(BUILD_DIR, sub_dir)) api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): - shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) + out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) + out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): - shutil.copyfile(os.path.join(self.src_dir, f), os.path.join(BUILD_DIR, sub_dir, f)) - cmis = '%s/z3enums.cmi %s/z3native.cmi %s/z3.cmi' % (src_dir,src_dir,src_dir) - out.write('%s/z3enums.cmi: %s/z3enums.mli\n' % (src_dir,src_dir)) - out.write('\t%s -I %s -c %s/z3enums.mli\n' % (OCAMLC,src_dir,src_dir)) - out.write('%s/z3native.cmi: %s/z3native.mli\n' % (src_dir,src_dir)) - out.write('\t%s -I %s -c %s/z3native.mli\n' % (OCAMLC,src_dir,src_dir)) - out.write('%s/z3.cmi: %s/z3.mli\n' % (src_dir,src_dir)) - out.write('\t%s -I %s -c %s/z3.mli\n' % (OCAMLC,src_dir,src_dir)) - out.write('api/ml/libz3ml$(LIB_EXT): %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, src_dir)) + out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) + out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) + modules = ["z3enums", "z3native", "z3"] # dependencies in this order! + prev = '' + for m in modules: + out.write('%s/%s.mli: %s/%s.ml %s\n' % (sub_dir,m,sub_dir,m,prev)) + out.write('\t%s -I %s -i -c %s/%s.ml > %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m,sub_dir,m)) + prev = prev + ' ' + sub_dir + '/' + m + '.mli' + cmis = '' + for m in modules: + out.write('%s/%s.cmi: %s/%s.mli\n' % (sub_dir,m,sub_dir,m)) + out.write('\t%s -I %s -c %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m)) + cmis = cmis + ' ' + sub_dir + '/' + m + '.cmi' + out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(src_dir, mlfile)) + out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) + out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(self.to_src_dir, mlfile)) + out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-ccopt "-I../../%s" -cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (api_src,src_dir,src_dir,src_dir,src_dir)) + out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') From 9142901efe0322e9d30c20c3da819924727ece18 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Feb 2013 23:42:50 +0000 Subject: [PATCH 398/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 54 +++++++++++++++++++++-------------- src/api/ml/z3.ml | 60 ++++++++++++++++++++++----------------- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 3b13a2462..49db6fb50 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -7,6 +7,7 @@ open Z3 open Z3.Symbol open Z3.Sort open Z3.Expr +open Z3.Boolean open Z3.FuncDecl open Z3.Goal open Z3.Tactic @@ -22,12 +23,20 @@ exception TestFailedException of string *) let model_converter_test ( ctx : context ) = Printf.printf "ModelConverterTest\n"; - let xr = ((mk_const ctx (Symbol.mk_string ctx "x") (mk_real_sort ctx )) :> arith_expr) in - let yr = ((mk_const ctx (Symbol.mk_string ctx "y") (mk_real_sort ctx )) :> arith_expr) in + let xr = (arith_expr_of_expr + (Expr.mk_const ctx (Symbol.mk_string ctx "x") + (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in + let yr = (arith_expr_of_expr + (Expr.mk_const ctx (Symbol.mk_string ctx "y") + (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [| (mk_gt ctx xr (mk_real_numeral_nd ctx 10 1)) |]) ; - (Goal.assert_ g4 [| (mk_eq ctx yr (mk_add ctx [| xr; (mk_real_numeral_nd ctx 1 1) |] )) |] ) ; - (Goal.assert_ g4 [| (mk_gt ctx yr (mk_real_numeral_nd ctx 1 1)) |]) ; + (Goal.assert_ g4 [| (mk_gt ctx xr + (arith_expr_of_real_expr (real_expr_of_rat_num + (Real.mk_numeral_nd ctx 10 1)))) |]) ; + (Goal.assert_ g4 [| (mk_eq ctx + (expr_of_arith_expr yr) + (expr_of_arith_expr (mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |] ))) |] ) ; + (Goal.assert_ g4 [| (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) |]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -67,15 +76,15 @@ let model_converter_test ( ctx : context ) = *) let basic_tests ( ctx : context ) = Printf.printf "BasicTests\n" ; - let qi = (mk_int ctx 1) in +(* let qi = (mk_int ctx 1) in *) let fname = (mk_string ctx "f") in let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in - let bs = (Sort.mk_bool ctx) in + let bs = (sort_of_bool_sort (Boolean.mk_sort ctx)) in let domain = [| bs; bs |] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in let fapp = (mk_app ctx f - [| (mk_const ctx x bs); (mk_const ctx y bs) |]) in + [| (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) |]) in let fargs2 = [| (mk_fresh_const ctx "cp" bs) |] in let domain2 = [| bs |] in let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in @@ -110,8 +119,11 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ); - (Goal.assert_ g [| (mk_eq ctx (mk_numeral_int ctx 1 (BitVectors.mk_sort ctx 32)) - (mk_numeral_int ctx 2 (BitVectors.mk_sort ctx 32))) |] ) + (Goal.assert_ g [| (mk_eq ctx + (mk_numeral_int ctx 1 + (sort_of_bitvec_sort (BitVector.mk_sort ctx 32))) + (mk_numeral_int ctx 2 + (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) |] ) ; ( let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in @@ -132,7 +144,7 @@ let basic_tests ( ctx : context ) = ); ( let g2 = (mk_goal ctx true true false) in - (Goal.assert_ g2 [| (mk_false ctx) |]) ; + (Goal.assert_ g2 [| (Boolean.mk_false ctx) |]) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then @@ -142,10 +154,10 @@ let basic_tests ( ctx : context ) = ); ( let g3 = (mk_goal ctx true true false) in - let xc = (mk_const ctx (Symbol.mk_string ctx "x") (mk_int_sort ctx)) in - let yc = (mk_const ctx (Symbol.mk_string ctx "y") (mk_int_sort ctx)) in - (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (mk_int_sort ctx))) |]) ; - (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (mk_int_sort ctx))) |]) ; + let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in + let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in + (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; + (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; let constr = (mk_eq ctx xc yc) in (Goal.assert_ g3 [| constr |] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in @@ -208,14 +220,14 @@ let _ = let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in let ss = (Symbol.mk_string ctx "mySymbol") in - let bs = (Sort.mk_bool ctx) in - let ints = (mk_int_sort ctx) in - let rs = (mk_real_sort ctx) in + let bs = (Boolean.mk_sort ctx) in + let ints = (Integer.mk_sort ctx) in + let rs = (Real.mk_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string is); Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string bs); - Printf.printf "int sort: %s\n" (Sort.to_string ints); - Printf.printf "real sort: %s\n" (Sort.to_string rs); + Printf.printf "bool sort: %s\n" (Sort.to_string (sort_of_bool_sort bs)); + Printf.printf "int sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_int_sort ints))); + Printf.printf "real sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_real_sort rs))); basic_tests ctx ; Printf.printf "Disposing...\n"; Gc.full_major () diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index aa919e7fc..651102bc8 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -240,7 +240,7 @@ struct Expr(z3_native_object_of_ast_ptr ctx no) else let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in if (Z3native.is_algebraic_number (context_gno ctx) no) then Expr(z3_native_object_of_ast_ptr ctx no) else @@ -376,92 +376,99 @@ let expr_of_ast a = Expr(a) let bool_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.BOOL_SORT) then raise (Z3native.Exception "Invalid coercion") else BoolExpr(e) let arith_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then raise (Z3native.Exception "Invalid coercion") else ArithExpr(e) let bitvec_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.BV_SORT) then raise (Z3native.Exception "Invalid coercion") else BitVecExpr(e) let array_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.ARRAY_SORT) then raise (Z3native.Exception "Invalid coercion") else ArrayExpr(e) let datatype_expr_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.DATATYPE_SORT) then raise (Z3native.Exception "Invalid coercion") else DatatypeExpr(e) let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(no)) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.INT_SORT) then raise (Z3native.Exception "Invalid coercion") else IntExpr(e) let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(no)) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in if (q != Z3enums.REAL_SORT) then raise (Z3native.Exception "Invalid coercion") else RealExpr(e) let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(no))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + match e with IntExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else IntNum(e) let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(no))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + match e with RealExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else RatNum(e) let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(no)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc no) (z3obj_gno no))) then + match e with ArithExpr(Expr(a)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else AlgebraicNum(e) let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(no)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc no) (z3obj_gno no))) then + match e with BitVecExpr(Expr(a)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then raise (Z3native.Exception "Invalid coercion") else BitVecNum(e) let quantifier_of_expr e = - match e with Expr(no) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc no) (z3obj_gno no))) in + match e with Expr(a) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in if (q != Z3enums.QUANTIFIER_AST) then raise (Z3native.Exception "Invalid coercion") else @@ -4378,7 +4385,8 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i)) in + let f i = (bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in Array.init n f (** The number of formulas, subformulas and terms in the goal. *) From dcdcd7b14050991be33513212e8b95dc21fc5032 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 11:49:00 +0000 Subject: [PATCH 399/507] ML API: Build system and error handling fixes. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 8 ++++++-- scripts/update_api.py | 12 ++++++++++++ src/api/ml/z3.ml | 6 +----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5a5dbc3a4..4082bb2b8 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1351,10 +1351,14 @@ class MLComponent(Component): api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) + str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) + if IS_WINDOWS: str = str.replace('/','\\') + out.write(str) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - out.write('\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f)) + str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) + if IS_WINDOWS: str = str.replace('/','\\') + out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: diff --git a/scripts/update_api.py b/scripts/update_api.py index 6e9c14355..e5c66dd39 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1169,9 +1169,11 @@ def mk_ml(): ml_i.write('\n') ml_native.write('external is_null : ptr -> bool\n = "n_is_null"\n\n') ml_native.write('external mk_null : unit -> ptr\n = "n_mk_null"\n\n') + ml_native.write('external set_internal_error_handler : ptr -> unit\n = "n_set_internal_error_handler"\n\n') ml_native.write('exception Exception of string\n\n') ml_i.write('val is_null : ptr -> bool\n') ml_i.write('val mk_null : unit -> ptr\n') + ml_i.write('val set_internal_error_handler : ptr -> unit\n\n') ml_i.write('exception Exception of string\n\n') # ML declarations @@ -1329,6 +1331,16 @@ def mk_ml(): ml_wrapper.write(' memcpy( Data_custom_val(result), &z3_result, sizeof(void*));\n') ml_wrapper.write(' CAMLreturn (result);\n') ml_wrapper.write('}\n\n') + ml_wrapper.write('void MLErrorHandler(Z3_context c, Z3_error_code e)\n') + ml_wrapper.write('{\n') + ml_wrapper.write(' // Internal do-nothing error handler. This is required to avoid that Z3 calls exit()\n') + ml_wrapper.write(' // upon errors, but the actual error handling is done by throwing exceptions in the\n') + ml_wrapper.write(' // wrappers below.\n') + ml_wrapper.write('}\n\n') + ml_wrapper.write('void n_set_internal_error_handler(Z3_context c)\n') + ml_wrapper.write('{\n') + ml_wrapper.write(' Z3_set_error_handler(c, MLErrorHandler);\n') + ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) op = outparams(params) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 651102bc8..45faae468 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -135,16 +135,12 @@ struct let v = Z3native.mk_context_rc cfg in Z3native.del_config(cfg) ; Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + Z3native.set_internal_error_handler v ; (* Printf.printf "Installing finalizer on context \n" ; *) let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in let f = fun o -> dispose_context o in Gc.finalise f res; res - (* CMW: Install error handler here! - m_n_err_handler = new Z3native.error_handler(NativeErrorHandler); keep reference so it doesn't get collected. - Z3native.set_error_handler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); - *) let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) From 6842acbea85d6417dc4f1deb0752a551c9e5f580 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 18:37:52 +0000 Subject: [PATCH 400/507] ML API: Cleanup Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 5 +- scripts/update_api.py | 2 + src/api/ml/z3.ml | 2247 +++++++++++++++++++------------------ src/api/ml/z3.mli | 1462 +++++++++++++++--------- 4 files changed, 2064 insertions(+), 1652 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 49db6fb50..6dfe11623 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -15,6 +15,9 @@ open Z3.Tactic.ApplyResult open Z3.Probe open Z3.Solver open Z3.Arithmetic +open Z3.Arithmetic.Integer +open Z3.Arithmetic.Real +open Z3.BitVector exception TestFailedException of string @@ -35,7 +38,7 @@ let model_converter_test ( ctx : context ) = (Real.mk_numeral_nd ctx 10 1)))) |]) ; (Goal.assert_ g4 [| (mk_eq ctx (expr_of_arith_expr yr) - (expr_of_arith_expr (mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |] ))) |] ) ; + (expr_of_arith_expr (Arithmetic.mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |]) ) ) |] ) ; (Goal.assert_ g4 [| (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) |]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in diff --git a/scripts/update_api.py b/scripts/update_api.py index e5c66dd39..a0b7e6250 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1155,6 +1155,7 @@ def mk_ml(): ml_native.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') ml_i.write('(* Automatically generated file *)\n\n') ml_i.write('(** The native (raw) interface to the dynamic Z3 library. *)\n\n') + ml_i.write('(**/**)\n\n'); ml_native.write('open Z3enums\n\n') ml_native.write('(**/**)\n') ml_native.write('type ptr\n') @@ -1214,6 +1215,7 @@ def mk_ml(): ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) ml_native.write('\n') ml_native.write(' end\n\n') + ml_i.write('\n(**/**)\n'); # Exception wrappers for name, result, params in _dotnet_decls: diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 45faae468..c261fce05 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -16,104 +16,11 @@ let is_null o = (Z3native.is_null o) type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } type context = z3_native_context - - type z3_native_object = { m_ctx : context ; mutable m_n_obj : Z3native.ptr ; inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - - -(* Symbol types *) -type int_symbol = z3_native_object -type string_symbol = z3_native_object - -type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - -(* AST types *) -type ast = z3_native_object -type ast_vector = z3_native_object -type ast_map = z3_native_object - -(* FuncDecl types *) -type func_decl = FuncDecl of ast - -(* Sort types *) -type sort = Sort of ast -type uninterpreted_sort = UninterpretedSort of sort -type bool_sort = BoolSort of sort -type array_sort = ArraySort of sort -type set_sort = SetSort of sort -type datatype_sort = DatatypeSort of sort -type relation_sort = RelationSort of sort -type finite_domain_sort = FiniteDomainSort of sort -type enum_sort = EnumSort of sort -type list_sort = ListSort of sort -type tuple_sort = TupleSort of sort -type arith_sort = ArithSort of sort -type bitvec_sort = BitVecSort of sort - -type int_sort = IntSort of arith_sort -type real_sort = RealSort of arith_sort - -(* FuncDecl parameters *) -type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of symbol - | P_Srt of sort - | P_Ast of ast - | P_Fdl of func_decl - | P_Rat of string -type params = z3_native_object -type param_descrs = z3_native_object - -(* Expr types *) -type expr = Expr of ast - -type bool_expr = BoolExpr of expr -type arith_expr = ArithExpr of expr -type int_expr = IntExpr of arith_expr -type real_expr = RealExpr of arith_expr -type bitvec_expr = BitVecExpr of expr -type array_expr = ArrayExpr of expr -type datatype_expr = DatatypeExpr of expr - -(* Numerals *) -type int_num = IntNum of int_expr -type rat_num = RatNum of real_expr -type algebraic_num = AlgebraicNum of arith_expr -type bitvec_num = BitVecNum of bitvec_expr - -(* Quantifier stuff *) -type quantifier = Quantifier of expr -type pattern = Pattern of ast - -(* Datatype stuff *) -type constructor = z3_native_object -type constructor_list = z3_native_object - -(* Tactical interface *) -type goal = z3_native_object -type model = z3_native_object -type func_interp = z3_native_object -type func_entry = z3_native_object -type probe = z3_native_object -type tactic = z3_native_object -type apply_result = z3_native_object -type solver = z3_native_object -type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE -type statistics = z3_native_object -type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } -type fixedpoint = z3_native_object (** Internal stuff *) @@ -121,11 +28,9 @@ module Internal = struct let dispose_context ctx = if ctx.m_n_obj_cnt == 0 then ( - (* Printf.printf "Disposing context \n" ; *) (Z3native.del_context ctx.m_n_ctx) ) else ( - Printf.printf "NOT DISPOSING context because it still has %d objects alive\n" ctx.m_n_obj_cnt; - (* re-queue for finalization? *) + Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; ) let create_context settings = @@ -136,7 +41,6 @@ struct Z3native.del_config(cfg) ; Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; Z3native.set_internal_error_handler v ; - (* Printf.printf "Installing finalizer on context \n" ; *) let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in let f = fun o -> dispose_context o in Gc.finalise f res; @@ -178,16 +82,6 @@ struct let array_to_native a = let f e = (z3obj_gno e) in Array.map f a - - (* Internal coercions *) - let context_of_ast ( x : ast ) = (z3obj_gc x) - let nc_of_ast ( x : ast ) = (z3obj_gnc x) - let ptr_of_ast ( x : ast ) = (z3obj_gno x) - - let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) - let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) - let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> let res : z3_native_object = { m_ctx = ctx ; @@ -196,323 +90,25 @@ struct dec_ref = Z3native.dec_ref } in (z3obj_sno res ctx no) ; (z3obj_create res) ; - res - - let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> - let q = (z3_native_object_of_ast_ptr ctx no) in - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then - raise (Z3native.Exception "Invalid coercion") - else - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - - let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - FuncDecl(z3_native_object_of_ast_ptr ctx no) - - let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST - | SORT_AST - | QUANTIFIER_AST - | APP_AST - | NUMERAL_AST - | VAR_AST -> z3_native_object_of_ast_ptr ctx no - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") - - and expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then - Expr(z3_native_object_of_ast_ptr ctx no) - else - let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) no) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - raise (Z3native.Exception "Unsupported numeral object") - else - Expr(z3_native_object_of_ast_ptr ctx no) - - let expr_aton ( a : expr array ) = - let f ( e : expr ) = match e with Expr(a) -> (ptr_of_ast a) in - Array.map f a - - let expr_of_func_app : context -> func_decl -> expr array -> expr = fun ctx f args -> - match f with FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (ptr_of_ast fa) (Array.length args) (expr_aton args) in - expr_of_ptr ctx o + res end - open Internal - - -(* Sort coercions *) -let ast_of_sort s = match s with Sort(x) -> x -let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x -let sort_of_bool_sort s = match s with BoolSort(x) -> x -let sort_of_array_sort s = match s with ArraySort(x) -> x -let sort_of_set_sort s = match s with SetSort(x) -> x -let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x -let sort_of_relation_sort s = match s with RelationSort(x) -> x -let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x -let sort_of_enum_sort s = match s with EnumSort(x) -> x -let sort_of_list_sort s = match s with ListSort(x) -> x -let sort_of_tuple_sort s = match s with TupleSort(x) -> x -let sort_of_arith_sort s = match s with ArithSort(x) -> x -let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x -let arith_sort_of_int_sort s = match s with IntSort(x) -> x -let arith_sort_of_real_sort s = match s with RealSort(x) -> x - -let uninterpreted_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - UninterpretedSort(s) - -let bool_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolSort(s) - -let array_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArraySort(s) - -let datatype_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeSort(s) - -let relation_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RelationSort(s) - -let finite_domain_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - FiniteDomainSort(s) - -let arith_sort_of_sort s = match s with Sort(a) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithSort(s) - -let bitvec_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecSort(s) - -let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntSort(s) - -let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealSort(s) - -(* FuncDecl coercions *) -let ast_of_func_decl f = match f with FuncDecl(x) -> x - -(* Expr coercions *) -let ast_of_expr e = match e with Expr(a) -> a -let expr_of_bool_expr e = match e with BoolExpr(x) -> x -let expr_of_arith_expr e = match e with ArithExpr(x) -> x -let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x -let expr_of_array_expr e = match e with ArrayExpr(x) -> x -let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x - -let arith_expr_of_int_expr e = match e with IntExpr(x) -> x -let arith_expr_of_real_expr e = match e with RealExpr(x) -> x - -let int_expr_of_int_num e = match e with IntNum(x) -> x -let real_expr_of_rat_num e = match e with RatNum(x) -> x -let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x -let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x - -let expr_of_quantifier e = match e with Quantifier(x) -> x -let ast_of_pattern e = match e with Pattern(x) -> x - - -let expr_of_ast a = - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Expr(a) - -let bool_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolExpr(e) - -let arith_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithExpr(e) - -let bitvec_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecExpr(e) - -let array_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArrayExpr(e) - -let datatype_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeExpr(e) - -let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntExpr(e) - -let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealExpr(e) - -let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - IntNum(e) - -let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - RatNum(e) - -let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - AlgebraicNum(e) - -let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(a)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecNum(e) - -let quantifier_of_expr e = - match e with Expr(a) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.QUANTIFIER_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Quantifier(e) - -let pattern_of_ast a = - (* CMW: Unchecked ok? *) - Pattern(a) - - - -(** Interaction logging for Z3 - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) module Log = struct - (** Open an interaction log file. - @param filename the name of the file to open. - @return True if opening the log file succeeds, false otherwise. - *) - (* CMW: "open" seems to be a reserved keyword? *) let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - - (** Closes the interaction log. *) let close = Z3native.close_log - - (** Appends a user-provided string to the interaction log. - @param s the string to append*) let append s = Z3native.append_log s end -(** Version information *) module Version = struct - (** The major version. *) let major = let (x, _, _, _) = Z3native.get_version in x - - (** The minor version. *) let minor = let (_, x, _, _) = Z3native.get_version in x - - (** The build version. *) let build = let (_, _, x, _) = Z3native.get_version in x - - (** The revision. *) let revision = let (_, _, _, x) = Z3native.get_version in x - - (** A string representation of the version information. *) let to_string = let (mj, mn, bld, rev) = Z3native.get_version in string_of_int mj ^ "." ^ @@ -532,35 +128,21 @@ let mk_list ( f : int -> 'a ) ( n : int ) = mk_list' f 0 n [] -(** Create a context object. - - Most interactions with Z3 are interpreted in some context; many users will only - require one such object, but power users may require more than one. To start using - Z3, do - - - let ctx = (mk_context []) in - (...) - - - where a list of pairs of strings may be passed to set options on - the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (mk_context cfg) in - (...) - -*) let mk_context ( cfg : ( string * string ) list ) = create_context cfg - - -(** Symbols are used to name several term and type constructors *) module Symbol = -struct +struct + (* Symbol types *) + type int_symbol = z3_native_object + type string_symbol = z3_native_object + + type symbol = + | S_Int of int_symbol + | S_Str of string_symbol + + let create_i ( ctx : context ) ( no : Z3native.ptr ) = let res : int_symbol = { m_ctx = ctx ; m_n_obj = null ; @@ -588,7 +170,7 @@ struct match x with | S_Int(n) -> (z3obj_gc n) | S_Str(n) -> (z3obj_gc n) - + let gnc ( x : symbol ) = match x with | S_Int(n) -> (z3obj_gnc n) @@ -599,59 +181,55 @@ struct | S_Int(n) -> (z3obj_gno n) | S_Str(n) -> (z3obj_gno n) - (** The kind of the symbol (int or string) *) - let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) - - (** Indicates whether the symbol is of Int kind *) + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL - - (** Indicates whether the symbol is of string kind. *) let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - - (** The int value of the symbol. *) let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - - (** The string value of the symbol. *) let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) - - (** A string representation of the symbol. *) let to_string ( o : symbol ) = match (kind o) with | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) - (** - Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) let mk_int ( ctx : context ) ( i : int ) = S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) - (** Creates a new symbol using a string. *) let mk_string ( ctx : context ) ( s : string ) = S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - (** Create an array of symbols. *) let mk_ints ( ctx : context ) ( names : int array ) = let f elem = mk_int ( ctx : context ) elem in (Array.map f names) - (** Create an array of symbols. *) let mk_strings ( ctx : context ) ( names : string array ) = let f elem = mk_string ( ctx : context ) elem in (Array.map f names) end -(** The abstract syntax tree (AST) module *) module AST = -struct - (** Vectors of ASTs *) +struct + type ast = z3_native_object + + let context_of_ast ( x : ast ) = (z3obj_gc x) + let nc_of_ast ( x : ast ) = (z3obj_gnc x) + let ptr_of_ast ( x : ast ) = (z3obj_gno x) + + let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST + | SORT_AST + | QUANTIFIER_AST + | APP_AST + | NUMERAL_AST + | VAR_AST -> z3_native_object_of_ast_ptr ctx no + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") + module ASTVector = struct - let create ( ctx : context ) ( no : Z3native.ptr ) = + type ast_vector = z3_native_object + + let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_vector_inc_ref ; @@ -659,55 +237,34 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - - - (** The size of the vector *) + let get_size ( x : ast_vector ) = Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) - (** - Retrieves the i-th object in the vector. - @param i Index - @return An AST - *) let get ( x : ast_vector ) ( i : int ) = - create (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) + ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) - (** Sets the i-th object in the vector. *) let set ( x : ast_vector ) ( i : int ) ( value : ast ) = Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) - (** Resize the vector to . - @param newSize The new size of the vector. *) let resize ( x : ast_vector ) ( new_size : int ) = Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size - (** - Add the AST to the back of the vector. The size - is increased by 1. - @param a An AST - *) let push ( x : ast_vector ) ( a : ast ) = Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) - (** - Translates all ASTs in the vector to . - @param to_ctx A context - @return A new ASTVector - *) let translate ( x : ast_vector ) ( to_ctx : context ) = - create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - (** Retrieves a string representation of the vector. *) let to_string ( x : ast_vector ) = Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) end - (** Map from AST to AST *) module ASTMap = struct + type ast_map = z3_native_object - let create ( ctx : context ) ( no : Z3native.ptr ) = + let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_map_inc_ref ; @@ -715,73 +272,36 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - - - (** Checks whether the map contains the key . - @param k An AST - @return True if is a key in the map, false otherwise. *) + let contains ( x : ast_map ) ( key : ast ) = Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - (** Finds the value associated with the key . - - This function signs an error when is not a key in the map. - @param k An AST - *) let find ( x : ast_map ) ( key : ast ) = - create (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) + ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - (** - Stores or replaces a new key/value pair in the map. - @param k The key AST - @param v The value AST - *) let insert ( x : ast_map ) ( key : ast ) ( value : ast) = Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) - (** - Erases the key from the map. - @param k An AST - *) let erase ( x : ast_map ) ( key : ast ) = Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - (** Removes all keys from the map. *) let reset ( x : ast_map ) = Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) - (** The size of the map *) let get_size ( x : ast_map ) = Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) - (** The keys stored in the map. *) let get_keys ( x : ast_map ) = - ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) - (** Retrieves a string representation of the map.*) let to_string ( x : ast_map ) = Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) end - (** - The AST's hash code. - @return A hash code - *) let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) - - (** - A unique identifier for the AST (unique among all ASTs). - *) let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) - - (** - The kind of the AST. - *) let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) - (** - Indicates whether the AST is an Expr - *) let is_expr ( x : ast ) = match get_ast_kind ( x : ast ) with | APP_AST @@ -790,117 +310,77 @@ struct | VAR_AST -> true | _ -> false - (** - Indicates whether the AST is a bound variable - *) let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST - - (** - Indicates whether the AST is a Quantifier - *) let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST - - - (** - Indicates whether the AST is a Sort - *) let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST - - (** - Indicates whether the AST is a FunctionDeclaration - *) let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST - (** - A string representation of the AST. - *) let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - - (** - A string representation of the AST in s-expression notation. - *) let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - (** - Comparison operator. - @param a An AST - @param b An AST - @return True if and are from the same context - and represent the same sort; false otherwise. - *) + let ( = ) ( a : ast ) ( b : ast ) = (a == b) || if (z3obj_gnc a) != (z3obj_gnc b) then false else Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) - (** - Object Comparison. - @param other Another ast - @return Negative if the object should be sorted before , positive if after else zero. - *) let compare a b = if (get_id a) < (get_id b) then -1 else if (get_id a) > (get_id b) then 1 else 0 - (** Operator < *) let ( < ) (a : ast) (b : ast) = (compare a b) - (** - Translates (copies) the AST to the Context . - @param ctx A context - @return A copy of the AST which is associated with - *) let translate ( x : ast ) ( to_ctx : context ) = if (z3obj_gnc x) == (context_gno to_ctx) then x else ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - (** - Wraps an AST. - - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) - and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - *) - let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = - ast_of_ptr ctx ptr - - (** - Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - *) + let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr let unwrap_ast ( x : ast ) = (z3obj_gno x) end -(** The Sort module implements type information for ASTs *) +open AST + + module Sort = struct - + type sort = Sort of AST.ast + type uninterpreted_sort = UninterpretedSort of sort + + let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> + let q = (z3_native_object_of_ast_ptr ctx no) in + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then + raise (Z3native.Exception "Invalid coercion") + else + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + let ast_of_sort s = match s with Sort(x) -> x + let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x + + let uninterpreted_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + UninterpretedSort(s) + + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - - (** - Comparison operator. - @param a A sort - @param b A sort - @return True if and are from the same context - and represent the same sort; false otherwise. - *) + let ( = ) : sort -> sort -> bool = fun a b -> (a == b) || if (gnc a) != (gnc b) then @@ -908,30 +388,13 @@ struct else (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) - (** - Returns a unique identifier for the sort. - *) + let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) - - (** - The kind of the sort. - *) let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) - - (** - The name of the sort - *) let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) - - (** - A string representation of the sort. - *) let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) - - (** - Create a new uninterpreted sort. - *) - let mk_uninterpreted ( ctx : context ) ( s : symbol ) = + + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; @@ -940,24 +403,76 @@ struct (z3obj_create res) ; UninterpretedSort(Sort(res)) - (** - Create a new uninterpreted sort. - *) let mk_uninterpreted_s ( ctx : context ) ( s : string ) = mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) end +open Sort -(** Function declarations *) -module FuncDecl = -struct - (**/**) - let create_ndr ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = + +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + val func_decl_of_ptr : context -> Z3native.ptr -> func_decl + val gc : func_decl -> context + val gnc : func_decl -> Z3native.ptr + val gno : func_decl -> Z3native.ptr + module Parameter : + sig + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + val get_kind : parameter -> Z3enums.parameter_kind + val get_int : parameter -> int + val get_float : parameter -> float + val get_symbol : parameter -> Symbol.symbol + val get_sort : parameter -> Sort.sort + val get_ast : parameter -> AST.ast + val get_func_decl : parameter -> func_decl + val get_rational : parameter -> string + end + val mk_func_decl : context -> Symbol.symbol -> Sort.sort array -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + val ( = ) : func_decl -> func_decl -> bool + val to_string : func_decl -> string + val get_id : func_decl -> int + val get_arity : func_decl -> int + val get_domain_size : func_decl -> int + val get_domain : func_decl -> Sort.sort array + val get_range : func_decl -> Sort.sort + val get_decl_kind : func_decl -> Z3enums.decl_kind + val get_name : func_decl -> Symbol.symbol + val get_num_parameters : func_decl -> int + val get_parameters : func_decl -> Parameter.parameter list + val apply : func_decl -> Expr.expr array -> Expr.expr +end = struct + type func_decl = FuncDecl of AST.ast + + let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + FuncDecl(z3_native_object_of_ast_ptr ctx no) + + let ast_of_func_decl f = match f with FuncDecl(x) -> x + + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (ptr_of_ast (ast_of_sort x)) in + let f x = (AST.ptr_of_ast (ast_of_sort x)) in (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) @@ -967,20 +482,26 @@ struct m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (ptr_of_ast (ast_of_sort x)) in + let f x = (AST.ptr_of_ast (ast_of_sort x)) in (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Array.map f domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) - let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - (**/**) + let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - (** Parameters of Func_Decls *) module Parameter = - struct - (** The kind of the parameter. *) + struct + type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + let get_kind ( x : parameter ) = (match x with | P_Int(_) -> PARAMETER_INT @@ -991,188 +512,137 @@ struct | P_Fdl(_) -> PARAMETER_FUNC_DECL | P_Rat(_) -> PARAMETER_RATIONAL) - (**The int value of the parameter.*) let get_int ( x : parameter ) = match x with | P_Int(x) -> x | _ -> raise (Z3native.Exception "parameter is not an int") - - (**The double value of the parameter.*) + let get_float ( x : parameter ) = match x with | P_Dbl(x) -> x | _ -> raise (Z3native.Exception "parameter is not a double") - - (**The Symbol value of the parameter.*) + let get_symbol ( x : parameter ) = match x with | P_Sym(x) -> x | _ -> raise (Z3native.Exception "parameter is not a symbol") - (**The Sort value of the parameter.*) let get_sort ( x : parameter ) = match x with | P_Srt(x) -> x | _ -> raise (Z3native.Exception "parameter is not a sort") - (**The AST value of the parameter.*) let get_ast ( x : parameter ) = match x with | P_Ast(x) -> x | _ -> raise (Z3native.Exception "parameter is not an ast") - (**The FunctionDeclaration value of the parameter.*) let get_func_decl ( x : parameter ) = match x with | P_Fdl(x) -> x | _ -> raise (Z3native.Exception "parameter is not a func_decl") - (**The rational string value of the parameter.*) - let get_func_decl ( x : parameter ) = + let get_rational ( x : parameter ) = match x with | P_Rat(x) -> x | _ -> raise (Z3native.Exception "parameter is not a rational string") end - (** - Creates a new function declaration. - *) - let mk_func_decl ( ctx : context ) ( name : symbol ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = create_ndr ctx name domain range - (** - Creates a new function declaration. - *) let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range - (** - Creates a fresh function declaration with a name prefixed with . - - - *) let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = create_pdr ctx prefix domain range - (** - Creates a new constant function declaration. - *) - let mk_const_decl ( ctx : context ) ( name : symbol ) ( range : sort ) = + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = create_ndr ctx name [||] range - (** - Creates a new constant function declaration. - *) let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = create_ndr ctx (Symbol.mk_string ctx name) [||] range - (** - Creates a fresh constant function declaration with a name prefixed with . - - - *) let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = create_pdr ctx prefix [||] range - (** - Comparison operator. - @param a A func_decl - @param b A func_decl - @return True if and are from the same context - and represent the same func_decl; false otherwise. - *) let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || if (gnc a) != (gnc b) then false else (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) - (** - A string representations of the function declaration. - *) let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) - (** - Returns a unique identifier for the function declaration. - *) let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) - (** - The arity of the function declaration - *) let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) - (** - The size of the domain of the function declaration - - *) let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) - (** - The domain of the function declaration - *) let get_domain ( x : func_decl ) = let n = (get_domain_size x) in let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in Array.init n f - (** - The range of the function declaration - *) let get_range ( x : func_decl ) = sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) - (** - The kind of the function declaration. - *) let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) - (** - The name of the function declaration - *) let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) - (** - The number of parameters of the function declaration - *) let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) - (** - The parameters of the function declaration - *) let get_parameters ( x : func_decl ) = let n = (get_num_parameters x) in let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> P_Ast (ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) ) in mk_list f n - (** - Create expression that applies function to arguments. - @param args The arguments - *) - let apply ( x : func_decl ) ( args : expr array ) = expr_of_func_app (gc x) x args + let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.expr_of_func_app (gc x) x args end -(** - Parameter sets (of Solvers, Tactics, ...) - A Params objects represents a configuration in the form of symbol/value pairs. -*) -module Params = -struct - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) +and Params : +sig + type params = z3_native_object + module ParamDescrs : + sig + type param_descrs + val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + val get_names : param_descrs -> Symbol.symbol array + val get_size : param_descrs -> int + val to_string : param_descrs -> string + end + val add_bool : params -> Symbol.symbol -> bool -> unit + val add_int : params -> Symbol.symbol -> int -> unit + val add_double : params -> Symbol.symbol -> float -> unit + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + val add_s_bool : params -> string -> bool -> unit + val add_s_int : params -> string -> int -> unit + val add_s_double : params -> string -> float -> unit + val add_s_symbol : params -> string -> Symbol.symbol -> unit + val mk_params : context -> params + val to_string : params -> string +end = struct + type params = z3_native_object + module ParamDescrs = - struct - - let create ( ctx : context ) ( no : Z3native.ptr ) = + struct + type param_descrs = z3_native_object + + let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : param_descrs = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.param_descrs_inc_ref ; @@ -1180,79 +650,46 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - - - (** Validate a set of parameters. *) + let validate ( x : param_descrs ) ( p : params ) = Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) - (** Retrieve kind of parameter. *) - let get_kind ( x : param_descrs ) ( name : symbol ) = + let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) - (** Retrieve all names of parameters. *) let get_names ( x : param_descrs ) = let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** The size of the ParamDescrs. *) - let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) - - (** Retrieves a string representation of the ParamDescrs. *) + let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) end - (** - Adds a parameter setting. - *) - let add_bool ( x : params ) ( name : symbol ) ( value : bool ) = + let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - (** - Adds a parameter setting. - *) - let add_int ( x : params ) (name : symbol ) ( value : int ) = + let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - (** - Adds a parameter setting. - *) - let add_double ( x : params ) ( name : symbol ) ( value : float ) = + let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - (** - Adds a parameter setting. - *) - let add_symbol ( x : params ) ( name : symbol ) ( value : symbol ) = + let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - (** - Adds a parameter setting. - *) let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = add_bool x (Symbol.mk_string (z3obj_gc x) name) value - (** - Adds a parameter setting. - *) let add_s_int ( x : params) ( name : string ) ( value : int ) = add_int x (Symbol.mk_string (z3obj_gc x) name) value - (** - Adds a parameter setting. - *) let add_s_double ( x : params ) ( name : string ) ( value : float ) = add_double x (Symbol.mk_string (z3obj_gc x) name) value - (** - Adds a parameter setting. - *) - let add_s_symbol ( x : params ) ( name : string ) ( value : symbol ) = + + let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = add_symbol x (Symbol.mk_string (z3obj_gc x) name) value - (** - Creates a new parameter set - *) let mk_params ( ctx : context ) = let res : params = { m_ctx = ctx ; m_n_obj = null ; @@ -1262,21 +699,107 @@ struct (z3obj_create res) ; res - (** - A string representation of the parameter set. - *) let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) end (** General expressions (terms) *) -module Expr = -struct +and Expr : +sig + type expr = Expr of AST.ast + val expr_of_ptr : context -> Z3native.ptr -> expr + val c_of_expr : expr -> context + val nc_of_expr : expr -> Z3native.ptr + val ptr_of_expr : expr -> Z3native.ptr + val expr_aton : expr array -> Z3native.ptr array + val ast_of_expr : expr -> AST.ast + val expr_of_ast : AST.ast -> expr + val expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr + val simplify : expr -> Params.params option -> expr + val get_simplify_help : context -> string + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + val get_func_decl : expr -> FuncDecl.func_decl + val get_bool_value : expr -> Z3enums.lbool + val get_num_args : expr -> int + val get_args : expr -> expr array + val update : expr -> expr array -> expr + val substitute : expr -> expr array -> expr array -> expr + val substitute_one : expr -> expr -> expr -> expr + val substitute_vars : expr -> expr array -> expr + val translate : expr -> context -> expr + val to_string : expr -> string + val is_numeral : expr -> bool + val is_well_sorted : expr -> bool + val get_sort : expr -> Sort.sort + val is_bool : expr -> bool + val is_const : expr -> bool + val is_true : expr -> bool + val is_false : expr -> bool + val is_eq : expr -> bool + val is_distinct : expr -> bool + val is_ite : expr -> bool + val is_and : expr -> bool + val is_or : expr -> bool + val is_iff : expr -> bool + val is_xor : expr -> bool + val is_not : expr -> bool + val is_implies : expr -> bool + val is_label : expr -> bool + val is_oeq : expr -> bool + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val mk_const_s : context -> string -> Sort.sort -> expr + val mk_const_f : context -> FuncDecl.func_decl -> expr + val mk_fresh_const : context -> string -> Sort.sort -> expr + val mk_app : context -> FuncDecl.func_decl -> expr array -> expr + val mk_numeral_string : context -> string -> Sort.sort -> expr + val mk_numeral_int : context -> int -> Sort.sort -> expr +end = struct + type expr = Expr of AST.ast + + let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) + let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) + let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + + let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then + Expr(z3_native_object_of_ast_ptr ctx no) + else + let s = Z3native.get_sort (context_gno ctx) no in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) no) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + if (Z3native.is_numeral_ast (context_gno ctx) no) then + if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + raise (Z3native.Exception "Unsupported numeral object") + else + Expr(z3_native_object_of_ast_ptr ctx no) + + let expr_of_ast a = + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Expr(a) + + let ast_of_expr e = match e with Expr(a) -> a + + let expr_aton ( a : expr array ) = + let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in + Array.map f a + + let expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr = fun ctx f args -> + match f with FuncDecl.FuncDecl(fa) -> + let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (Array.length args) (expr_aton args) in + expr_of_ptr ctx o + (** Returns a simplified version of the expression. @param p A set of parameters to configure the simplifier *) - let simplify ( x : expr ) ( p : params option ) = match p with + let simplify ( x : expr ) ( p : Params.params option ) = match p with | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) @@ -1290,12 +813,12 @@ struct Retrieves parameter descriptions for simplifier. *) let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.create ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) + Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) (** The function declaration of the function that is applied in this expression. *) - let get_func_decl ( x : expr ) = func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) (** Indicates whether the expression is the true or false expression @@ -1477,7 +1000,7 @@ struct (** Creates a new Constant of sort and named . *) - let mk_const ( ctx : context ) ( name : symbol ) ( range : sort ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -1492,8 +1015,7 @@ struct Creates a constant from the func_decl . @param f An expression of a 0-arity function *) - let mk_const_f ( ctx : context ) ( f : func_decl ) = - expr_of_func_app ctx f [||] + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [||] (** Creates a fresh constant of sort and a @@ -1505,8 +1027,7 @@ struct (** Create a new function application. *) - let mk_app ( ctx : context ) ( f : func_decl ) ( args : expr array ) = - expr_of_func_app ctx f args + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = expr_of_func_app ctx f args (** Create a numeral of a given sort. @@ -1528,19 +1049,44 @@ struct expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) end +open FuncDecl +open Expr + (** Boolean expressions *) module Boolean = -struct +struct + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (ast_of_ptr ctx no) in - BoolExpr(Expr(a)) + let a = (AST.ast_of_ptr ctx no) in + BoolExpr(Expr.Expr(a)) + + let bool_expr_of_expr e = + match e with Expr.Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolExpr(e) let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = BoolSort(sort_of_ptr ctx no) - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (c_of_expr e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (nc_of_expr e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (ptr_of_expr e) + let sort_of_bool_sort s = match s with BoolSort(x) -> x + + let bool_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolSort(s) + + let expr_of_bool_expr e = match e with BoolExpr(x) -> x + + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) let mk_sort ( ctx : context ) = BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) @@ -1548,7 +1094,7 @@ struct (** Create a Boolean constant. *) - let mk_const ( ctx : context ) ( name : symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = let s = (match (mk_sort ctx) with BoolSort(q) -> q) in BoolExpr(Expr.mk_const ctx name s) @@ -1638,17 +1184,38 @@ end (** Quantifier expressions *) module Quantifier = struct + type quantifier = Quantifier of expr + + let expr_of_quantifier e = match e with Quantifier(x) -> x + + let quantifier_of_expr e = + match e with Expr.Expr(a) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.QUANTIFIER_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Quantifier(e) + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (c_of_expr e) let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) - + (** Quantifier patterns Patterns comprise a list of terms. The list should be non-empty. If the list comprises of more than one term, it is also called a multi-pattern. *) - module Pattern = struct + module Pattern = + struct + type pattern = Pattern of ast + + let ast_of_pattern e = match e with Pattern(x) -> x + + let pattern_of_ast a = + (* CMW: Unchecked ok? *) + Pattern(a) + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) @@ -1692,7 +1259,7 @@ struct index. *) let get_index ( x : expr ) = - if not (AST.is_var (match x with Expr(a) -> a)) then + if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) @@ -1723,7 +1290,7 @@ struct *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1736,7 +1303,7 @@ struct *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in - let f i = Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f (** @@ -1781,7 +1348,7 @@ struct if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) + Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) (** Create a universal Quantifier. @@ -1802,14 +1369,14 @@ struct @param quantifierID optional symbol to track quantifier. @param skolemID optional symbol to track skolem constants. *) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) else @@ -1817,21 +1384,21 @@ struct (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) (** Create a universal Quantifier. *) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true @@ -1839,7 +1406,7 @@ struct (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) @@ -1847,14 +1414,14 @@ struct Create an existential Quantifier. *) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) else @@ -1862,21 +1429,21 @@ struct (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) - + (** Create an existential Quantifier. *) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false @@ -1884,14 +1451,14 @@ struct (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (ptr_of_ast (ast_of_pattern x)) in (Array.map f patterns)) + (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : symbol array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else @@ -1901,7 +1468,7 @@ struct (** Create a Quantifier. *) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : pattern array ) ( nopatterns : expr array ) ( quantifier_id : symbol option ) ( skolem_id : symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -1911,14 +1478,35 @@ end (** Functions to manipulate Array expressions *) module Array_ = struct + type array_sort = ArraySort of sort + type array_expr = ArrayExpr of expr - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let e = (expr_of_ptr ctx no) in ArrayExpr(e) - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in - ArraySort(s) + ArraySort(s) + + let sort_of_array_sort s = match s with ArraySort(x) -> x + + let array_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArraySort(s) + + let array_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArrayExpr(e) + + let expr_of_array_expr e = match e with ArrayExpr(x) -> x let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) @@ -1932,7 +1520,7 @@ struct Create a new array sort. *) let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - create_sort ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) + array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) (** Indicates whether the term is an array store. @@ -1979,16 +1567,15 @@ struct ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) (** The domain of the array sort. *) - let get_domain ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) + let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) (** The range of the array sort. *) - let get_range ( x : array_sort ) = sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) - + let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) (** Create an array constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( domain : sort ) ( range : sort ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) (** @@ -2010,7 +1597,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) + array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) (** Array update. @@ -2029,7 +1616,7 @@ struct *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = - expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) + array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) (** Create a constant array. @@ -2040,7 +1627,7 @@ struct *) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) + array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) (** Maps f on the argument arrays. @@ -2054,7 +1641,7 @@ struct *) let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = let m x = (ptr_of_expr (expr_of_array_expr x)) in - expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) + array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) (** Access the array default value. @@ -2063,16 +1650,20 @@ struct finite maps with a default range value. *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = - expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) + array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end (** Functions to manipulate Set expressions *) module Set = struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + type set_sort = SetSort of sort + + let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in SetSort(s) + let sort_of_set_sort s = match s with SetSort(x) -> x + (** Indicates whether the term is set union *) @@ -2102,7 +1693,7 @@ struct Create a set type. *) let mk_sort ( ctx : context ) ( ty : sort ) = - create_sort ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) + set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) (** Create an empty set. @@ -2169,14 +1760,24 @@ end (** Functions to manipulate Finite Domain expressions *) module FiniteDomain = struct + type finite_domain_sort = FiniteDomainSort of sort + + let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x + + let finite_domain_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + FiniteDomainSort(s) + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - + (** Create a new finite domain sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( size : int ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in FiniteDomainSort(s) @@ -2210,15 +1811,24 @@ end (** Functions to manipulate Relation expressions *) module Relation = struct - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + type relation_sort = RelationSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in RelationSort(s) + let sort_of_relation_sort s = match s with RelationSort(x) -> x + + let relation_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RelationSort(s) + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - + (** Indicates whether the term is of a relation sort. @@ -2335,29 +1945,53 @@ struct (** The sorts of the columns of the relation sort. *) let get_column_sorts ( x : relation_sort ) = let n = get_arity x in - let f i = (create_sort (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in + let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in Array.init n f end (** Functions to manipulate Datatype expressions *) module Datatype = -struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = +struct + type datatype_sort = DatatypeSort of sort + type datatype_expr = DatatypeExpr of expr + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in DatatypeSort(s) + let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x + + let datatype_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeSort(s) + + let datatype_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeExpr(e) + + let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - + (** Constructors *) module Constructor = struct + type constructor = z3_native_object + let _counts = Hashtbl.create 0 - let create ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -2366,11 +2000,11 @@ struct raise (Z3native.Exception "Number of field names does not match number of sort refs") else let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) - (Symbol.gno recognizer) - n - (let f x = (Symbol.gno x) in (Array.map f field_names)) - (let f x = (ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - sort_refs) in + (Symbol.gno recognizer) + n + (let f x = (Symbol.gno x) in (Array.map f field_names)) + (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) + sort_refs) in let no : constructor = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; @@ -2383,7 +2017,7 @@ struct no let get_n ( x : constructor ) = (Hashtbl.find _counts x) - + let rec constructor_decl ( x : constructor ) = let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in func_decl_of_ptr (z3obj_gc x) a @@ -2391,12 +2025,12 @@ struct let rec tester_decl ( x : constructor ) = let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in func_decl_of_ptr (z3obj_gc x) b - + let rec accessor_decls ( x : constructor ) = let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in let f y = func_decl_of_ptr (z3obj_gc x) y in Array.map f c - + (** The number of fields of the constructor. *) let get_num_fields ( x : constructor ) = get_n x @@ -2413,8 +2047,9 @@ struct (** Constructor list objects *) module ConstructorList = struct - - let create ( ctx : context ) ( c : constructor array ) = + type constructor_list = z3_native_object + + let create ( ctx : context ) ( c : Constructor.constructor array ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; @@ -2438,7 +2073,7 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor ( ctx : context ) ( name : symbol ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = Constructor.create ctx name recognizer field_names sorts sort_refs @@ -2452,22 +2087,22 @@ struct if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : symbol ) ( field_names : symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs (** Create a new datatype sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( constructors : constructor array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array ) = let f x = (z3obj_gno x) in let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in - create_sort ctx x + sort_of_ptr ctx x (** Create a new datatype sort. *) - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : constructor array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors (** @@ -2475,17 +2110,17 @@ struct @param names names of datatype sorts @param c list of constructors, one list per sort. *) - let mk_sorts ( ctx : context ) ( names : symbol array ) ( c : constructor array array ) = + let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = let n = (Array.length names) in - let f e = (ptr_of_ast (ConstructorList.create ctx e)) in + let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in let cla = (Array.map f c) in let f2 x = (Symbol.gno x) in let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Array.map f2 names) cla) in - let g e = (create_sort ctx e) in + let g e = (sort_of_ptr ctx e) in (Array.map g r) (** Create mutually recursive data-types. *) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in @@ -2522,17 +2157,21 @@ end (** Functions to manipulate Enumeration expressions *) module Enumeration = -struct +struct + type enum_sort = EnumSort of sort + let _constdecls = Hashtbl.create 0 let _testerdecls = Hashtbl.create 0 - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = let s = (sort_of_ptr ctx no) in let res = EnumSort(s) in Hashtbl.add _constdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f cdecls)) ; Hashtbl.add _testerdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f tdecls)) ; res + let sort_of_enum_sort s = match s with EnumSort(x) -> x + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) @@ -2540,10 +2179,10 @@ struct (** Create a new enumeration sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( enum_names : symbol array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = let f x = Symbol.gno x in let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in - create_sort ctx a b c + sort_of_ptr ctx a b c (** Create a new enumeration sort. @@ -2561,14 +2200,16 @@ end (** Functions to manipulate List expressions *) module List_ = struct + type list_sort = ListSort of sort + let _nildecls = Hashtbl.create 0 let _is_nildecls = Hashtbl.create 0 let _consdecls = Hashtbl.create 0 let _is_consdecls = Hashtbl.create 0 let _headdecls = Hashtbl.create 0 let _taildecls = Hashtbl.create 0 - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in let res = ListSort(s) in Hashtbl.add _nildecls res (func_decl_of_ptr ctx nildecl) ; @@ -2578,16 +2219,18 @@ struct Hashtbl.add _headdecls res (func_decl_of_ptr ctx headdecl) ; Hashtbl.add _taildecls res (func_decl_of_ptr ctx taildecl) ; res + + let sort_of_list_sort s = match s with ListSort(x) -> x let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - - + + (** Create a new list sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( elem_sort : sort ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - create_sort ctx r a b c d e f + sort_of_ptr ctx r a b c d e f (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = @@ -2618,23 +2261,26 @@ end (** Functions to manipulate Tuple expressions *) module Tuple = struct - - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + type tuple_sort = TupleSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in TupleSort(s) + let sort_of_tuple_sort s = match s with TupleSort(x) -> x + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - + (** Create a new tuple sort. *) - let mk_sort ( ctx : context ) ( name : symbol ) ( field_names : symbol array ) ( field_sorts : sort array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : sort array ) = let f x = Symbol.gno x in let f2 x = ptr_of_ast (ast_of_sort x) in let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in (* CMW: leaks a,b? *) - create_sort ctx r + sort_of_ptr ctx r (** The constructor function of the tuple. *) let get_mk_decl ( x : tuple_sort ) = @@ -2651,13 +2297,144 @@ struct end (** Functions to manipulate arithmetic expressions *) -module Arithmetic = -struct - - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - arith_expr_of_expr (expr_of_ptr ctx no) +module rec Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr + + val sort_of_arith_sort : arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> arith_sort + val expr_of_arith_expr : arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> arith_expr - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end + + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool + val mk_add : context -> arith_expr array -> arith_expr + val mk_mul : context -> arith_expr array -> arith_expr + val mk_sub : context -> arith_expr array -> arith_expr + val mk_unary_minus : context -> arith_expr -> arith_expr + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr +end = struct + type arith_sort = ArithSort of sort + type arith_expr = ArithExpr of expr + + let arith_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithExpr(e) + + let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + arith_expr_of_expr (expr_of_ptr ctx no) + + let sort_of_arith_sort s = match s with ArithSort(x) -> x + let expr_of_arith_expr e = match e with ArithExpr(x) -> x + + let arith_sort_of_sort s = match s with Sort(a) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithSort(s) + + let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = arith_sort_of_sort (sort_of_ptr ctx no) let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) @@ -2667,16 +2444,72 @@ struct let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (nc_of_expr e) let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (ptr_of_expr e) - module Integer = - struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - int_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - int_num_of_int_expr (create_expr ctx no) + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end = struct + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + let int_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntExpr(e) + + let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let int_num_of_int_expr e = + match e with IntExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + IntNum(e) + + let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_num_of_int_expr (int_expr_of_ptr ctx no) + + let arith_sort_of_int_sort s = match s with IntSort(x) -> x + let arith_expr_of_int_expr e = match e with IntExpr(x) -> x + let int_expr_of_int_num e = match e with IntNum(x) -> x + + let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntSort(s) + + let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) @@ -2687,11 +2520,11 @@ struct let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - + (** Create a new integer sort. *) let mk_sort ( ctx : context ) = - create_sort ctx (Z3native.mk_int_sort (context_gno ctx)) + int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) (** Retrieve the int value. *) let get_int ( x : int_num ) = @@ -2705,7 +2538,7 @@ struct (** Creates an integer constant. *) - let mk_int_const ( ctx : context ) ( name : symbol ) = + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) (** @@ -2719,21 +2552,21 @@ struct The arguments must have int type. *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) (** Create an expression representing t1 rem t2. The arguments must have int type. *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) (** Create an integer numeral. @param v A string representing the Term value in decimal notation. *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) (** Create an integer numeral. @@ -2741,7 +2574,7 @@ struct @return A Term with value and sort Integer *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) (** Coerce an integer to a real. @@ -2754,7 +2587,7 @@ struct The argument must be of integer sort. *) let mk_int2real ( ctx : context ) ( t : int_expr ) = - real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) + Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) (** Create an bit bit-vector from the integer argument . @@ -2767,19 +2600,76 @@ struct The argument must be of integer sort. *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - bitvec_expr_of_expr (expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) + BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) end - module Real = - struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = - real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = - real_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - rat_num_of_real_expr (create_expr ctx no) + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : real_sort -> arith_sort + val real_sort_of_arith_sort : arith_sort -> real_sort + val arith_expr_of_real_expr : real_expr -> arith_expr + val real_expr_of_rat_num : rat_num -> real_expr + val real_expr_of_arith_expr : arith_expr -> real_expr + val rat_num_of_real_expr : real_expr -> rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end = struct + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + let arith_sort_of_real_sort s = match s with RealSort(x) -> x + let arith_expr_of_real_expr e = match e with RealExpr(x) -> x + let real_expr_of_rat_num e = match e with RatNum(x) -> x + + let real_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealExpr(e) + + let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let rat_num_of_real_expr e = + match e with RealExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + RatNum(e) + + let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + rat_num_of_real_expr (real_expr_of_ptr ctx no) + + let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealSort(s) + + let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) @@ -2790,19 +2680,19 @@ struct let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - + (** Create a real sort. *) let mk_sort ( ctx : context ) = - create_sort ctx (Z3native.mk_real_sort (context_gno ctx)) + real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = - Integer.create_num (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = - Integer.create_num (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -2813,7 +2703,7 @@ struct let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) (** Creates a real constant. *) - let mk_real_const ( ctx : context ) ( name : symbol ) = + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) (** Creates a real constant. *) @@ -2832,7 +2722,7 @@ struct if (den == 0) then raise (Z3native.Exception "Denominator is zero") else - create_num ctx (Z3native.mk_real (context_gno ctx) num den) + rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) (** Create a real numeral. @@ -2840,7 +2730,7 @@ struct @return A Term with value and sort Real *) let mk_numeral_s ( ctx : context ) ( v : string ) = - create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) (** Create a real numeral. @@ -2849,11 +2739,11 @@ struct @return A Term with value and sort Real *) let mk_numeral_i ( ctx : context ) ( v : int ) = - create_num ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) (** Coerce a real to an integer. @@ -2863,18 +2753,39 @@ struct The argument must be of real sort. *) let mk_real2int ( ctx : context ) ( t : real_expr ) = - int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) + Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) end - module AlgebraicNumber = - struct - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end = struct + type algebraic_num = AlgebraicNum of arith_expr + + let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x + + let algebraic_num_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + AlgebraicNum(e) + + let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - + (** Return a upper bound for a given real algebraic number. @@ -2884,7 +2795,7 @@ struct @return A numeral Expr of sort Real *) let to_upper ( x : algebraic_num ) ( precision : int ) = - Real.create_num (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) (** Return a lower bound for the given real algebraic number. @@ -2894,7 +2805,7 @@ struct @return A numeral Expr of sort Real *) let to_lower ( x : algebraic_num ) precision = - Real.create_num (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) (** Returns a string representation in decimal notation. The result has at most decimal places.*) @@ -3056,38 +2967,186 @@ struct Create an expression representing t1 < t2 *) let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 <= t2 *) let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 > t2 *) let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) (** Create an expression representing t1 >= t2 *) let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) end (** Functions to manipulate bit-vector expressions *) -module BitVector = -struct - let create_sort ( ctx : context ) ( no : Z3native.ptr ) = +and BitVector : +sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + + val mk_sort : context -> int -> bitvec_sort + val is_bv : Expr.expr -> bool + val is_bv_numeral : Expr.expr -> bool + val is_bv_bit1 : Expr.expr -> bool + val is_bv_bit0 : Expr.expr -> bool + val is_bv_uminus : Expr.expr -> bool + val is_bv_add : Expr.expr -> bool + val is_bv_sub : Expr.expr -> bool + val is_bv_mul : Expr.expr -> bool + val is_bv_sdiv : Expr.expr -> bool + val is_bv_udiv : Expr.expr -> bool + val is_bv_SRem : Expr.expr -> bool + val is_bv_urem : Expr.expr -> bool + val is_bv_smod : Expr.expr -> bool + val is_bv_sdiv0 : Expr.expr -> bool + val is_bv_udiv0 : Expr.expr -> bool + val is_bv_srem0 : Expr.expr -> bool + val is_bv_urem0 : Expr.expr -> bool + val is_bv_smod0 : Expr.expr -> bool + val is_bv_ule : Expr.expr -> bool + val is_bv_sle : Expr.expr -> bool + val is_bv_uge : Expr.expr -> bool + val is_bv_sge : Expr.expr -> bool + val is_bv_ult : Expr.expr -> bool + val is_bv_slt : Expr.expr -> bool + val is_bv_ugt : Expr.expr -> bool + val is_bv_sgt : Expr.expr -> bool + val is_bv_and : Expr.expr -> bool + val is_bv_or : Expr.expr -> bool + val is_bv_not : Expr.expr -> bool + val is_bv_xor : Expr.expr -> bool + val is_bv_nand : Expr.expr -> bool + val is_bv_nor : Expr.expr -> bool + val is_bv_xnor : Expr.expr -> bool + val is_bv_concat : Expr.expr -> bool + val is_bv_signextension : Expr.expr -> bool + val is_bv_zeroextension : Expr.expr -> bool + val is_bv_extract : Expr.expr -> bool + val is_bv_repeat : Expr.expr -> bool + val is_bv_reduceor : Expr.expr -> bool + val is_bv_reduceand : Expr.expr -> bool + val is_bv_comp : Expr.expr -> bool + val is_bv_shiftleft : Expr.expr -> bool + val is_bv_shiftrightlogical : Expr.expr -> bool + val is_bv_shiftrightarithmetic : Expr.expr -> bool + val is_bv_rotateleft : Expr.expr -> bool + val is_bv_rotateright : Expr.expr -> bool + val is_bv_rotateleftextended : Expr.expr -> bool + val is_bv_rotaterightextended : Expr.expr -> bool + val is_int_to_bv : Expr.expr -> bool + val is_bv_to_int : Expr.expr -> bool + val is_bv_carry : Expr.expr -> bool + val is_bv_xor3 : Expr.expr -> bool + val get_size : bitvec_sort -> int + val get_int : bitvec_num -> int + val to_string : bitvec_num -> string + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + val mk_const_s : context -> string -> int -> bitvec_expr + val mk_not : context -> bitvec_expr -> Expr.expr + val mk_redand : context -> bitvec_expr -> Expr.expr + val mk_redor : context -> bitvec_expr -> Expr.expr + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_neg : context -> bitvec_expr -> bitvec_expr + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_numeral : context -> string -> int -> bitvec_num +end = struct + type bitvec_sort = BitVecSort of sort + type bitvec_expr = BitVecExpr of expr + type bitvec_num = BitVecNum of bitvec_expr + + let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x + + let bitvec_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecSort(s) + + let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = bitvec_sort_of_sort (sort_of_ptr ctx no) - let create_expr ( ctx : context ) ( no : Z3native.ptr ) = + let bitvec_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecExpr(e) + + let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = bitvec_expr_of_expr (expr_of_ptr ctx no) - let create_num ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_num_of_bitvec_expr (create_expr ctx no) + let bitvec_num_of_bitvec_expr e = + match e with BitVecExpr(Expr(a)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecNum(e) + + let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) + + let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x + let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x + let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) @@ -3098,13 +3157,13 @@ struct let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - + (** Create a new bit-vector sort. *) let mk_sort ( ctx : context ) size = - create_sort ctx (Z3native.mk_bv_sort (context_gno ctx) size) + bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) (** Indicates whether the terms is of bit-vector sort. @@ -3391,8 +3450,8 @@ struct (** Creates a bit-vector constant. *) - let mk_const ( ctx : context ) ( name : symbol ) ( size : int ) = - BitVecExpr(Expr.mk_const ctx name (match (mk_sort ctx size) with BitVecSort(s) -> s)) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) (** Creates a bit-vector constant. @@ -3426,70 +3485,70 @@ struct The arguments must have a bit-vector sort. *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise disjunction. The arguments must have a bit-vector sort. *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XOR. The arguments must have a bit-vector sort. *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NAND. The arguments must have a bit-vector sort. *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) (** Bitwise NOR. The arguments must have a bit-vector sort. *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) (** Bitwise XNOR. The arguments must have a bit-vector sort. *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) (** Two's complement addition. The arguments must have the same bit-vector sort. *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) (** Unsigned division. @@ -3501,7 +3560,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) (** Signed division. @@ -3516,7 +3575,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) (** Unsigned remainder. @@ -3526,7 +3585,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) (** Signed remainder. @@ -3538,7 +3597,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) (** Two's complement signed remainder (sign follows divisor). @@ -3547,7 +3606,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) (** Unsigned less-than @@ -3555,7 +3614,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than @@ -3563,7 +3622,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) (** Unsigned less-than or equal to. @@ -3571,7 +3630,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed less-than or equal to. @@ -3579,7 +3638,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater than or equal to. @@ -3587,7 +3646,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater than or equal to. @@ -3595,7 +3654,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) (** Unsigned greater-than. @@ -3603,7 +3662,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) (** Two's complement signed greater-than. @@ -3611,7 +3670,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) (** Bit-vector concatenation. @@ -3622,7 +3681,7 @@ struct is the size of t1 (t2). *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) (** Bit-vector extraction. @@ -3633,7 +3692,7 @@ struct The argument must have a bit-vector sort. *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) (** Bit-vector sign extension. @@ -3643,7 +3702,7 @@ struct The argument must have a bit-vector sort. *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) (** Bit-vector zero extension. @@ -3654,7 +3713,7 @@ struct The argument must have a bit-vector sort. *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) (** Bit-vector repetition. @@ -3662,7 +3721,7 @@ struct The argument must have a bit-vector sort. *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) (** Shift left. @@ -3677,8 +3736,8 @@ struct The arguments must have a bit-vector sort. *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - + bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + (** Logical shift right @@ -3692,7 +3751,7 @@ struct The arguments must have a bit-vector sort. *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) (** Arithmetic shift right @@ -3708,7 +3767,7 @@ struct The arguments must have a bit-vector sort. *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) (** Rotate Left. @@ -3717,7 +3776,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) (** Rotate Right. @@ -3726,7 +3785,7 @@ struct The argument must have a bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) (** Rotate Left. @@ -3735,7 +3794,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) (** Rotate Right. @@ -3745,7 +3804,7 @@ struct The arguments must have the same bit-vector sort. *) let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) (** Create an integer from the bit-vector argument . @@ -3763,7 +3822,7 @@ struct The argument must be of bit-vector sort. *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integer.create_expr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) + Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) (** Create a predicate that checks that the bit-wise addition does not overflow. @@ -3771,7 +3830,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise addition does not underflow. @@ -3779,7 +3838,7 @@ struct The arguments must be of bit-vector sort. *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not overflow. @@ -3787,7 +3846,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise subtraction does not underflow. @@ -3795,7 +3854,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise signed division does not overflow. @@ -3803,7 +3862,7 @@ struct The arguments must be of bit-vector sort. *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) (** Create a predicate that checks that the bit-wise negation does not overflow. @@ -3811,7 +3870,7 @@ struct The arguments must be of bit-vector sort. *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) (** Create a predicate that checks that the bit-wise multiplication does not overflow. @@ -3819,7 +3878,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) (** Create a predicate that checks that the bit-wise multiplication does not underflow. @@ -3827,7 +3886,7 @@ struct The arguments must be of bit-vector sort. *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) (** Create a bit-vector numeral. @@ -3836,7 +3895,7 @@ struct @param size the size of the bit-vector *) let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - create_num ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx size))) + bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) end (** Functions to manipulate proof expressions *) @@ -4321,7 +4380,8 @@ end tactics and solvers. *) module Goal = struct - + type goal = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : goal = { m_ctx = ctx ; m_n_obj = null ; @@ -4330,7 +4390,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** The precision of the goal. @@ -4359,7 +4419,7 @@ struct (** Adds the constraints to the given goal. *) (* CMW: assert seems to be a keyword. *) - let assert_ ( x : goal ) ( constraints : bool_expr array ) = + let assert_ ( x : goal ) ( constraints : Boolean.bool_expr array ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in ignore (Array.map f constraints) ; () @@ -4381,7 +4441,7 @@ struct (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in - let f i = (bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in Array.init n f @@ -4401,7 +4461,7 @@ struct create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - let simplify ( x : goal ) ( p : params option ) = + let simplify ( x : goal ) ( p : Params.params option ) = let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in Z3native.tactic_inc_ref (z3obj_gnc x) tn ; let arn = match p with @@ -4441,7 +4501,8 @@ end A Model contains interpretations (assignments) of constants and functions. *) module Model = struct - + type model = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : model = { m_ctx = ctx ; m_n_obj = null ; @@ -4450,7 +4511,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Function interpretations @@ -4459,7 +4520,8 @@ struct *) module FuncInterp = struct - + type func_interp = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_interp = { m_ctx = ctx ; m_n_obj = null ; @@ -4468,7 +4530,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Function interpretations entries @@ -4476,7 +4538,8 @@ struct *) module FuncEntry = struct - + type func_entry = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : func_entry = { m_ctx = ctx ; m_n_obj = null ; @@ -4485,7 +4548,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Return the (symbolic) value of this entry. @@ -4677,7 +4740,7 @@ struct An array of expressions, where each is an element of the universe of *) let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f @@ -4699,7 +4762,8 @@ end *) module Probe = struct - + type probe = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : probe = { m_ctx = ctx ; m_n_obj = null ; @@ -4708,14 +4772,14 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Execute the probe over the goal. A probe always produce a double value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - let apply ( x : probe ) (g : goal) = + let apply ( x : probe ) ( g : Goal.goal ) = Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (** @@ -4820,7 +4884,8 @@ end *) module Tactic = struct - + type tactic = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : tactic = { m_ctx = ctx ; m_n_obj = null ; @@ -4829,7 +4894,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** Tactic application results @@ -4837,7 +4902,8 @@ struct tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult = struct - + type apply_result = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : apply_result = { m_ctx = ctx ; m_n_obj = null ; @@ -4846,7 +4912,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + (** The number of Subgoals. *) let get_num_subgoals ( x : apply_result ) = @@ -4866,7 +4932,7 @@ struct goal g, that the ApplyResult was obtained from. #return A model for g *) - let convert_model ( x : apply_result ) ( i : int ) ( m : model ) = + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) (** A string representation of the ApplyResult. *) @@ -4878,10 +4944,10 @@ struct (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.create (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Apply the tactic to the goal. *) - let apply ( x : tactic ) ( g : goal ) ( p : params option ) = + let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) @@ -4949,14 +5015,14 @@ struct If evaluates to false, then the new tactic behaves like the skip tactic. *) (* CMW: when is a keyword *) - let when_ ( ctx : context ) ( p : probe ) ( t : tactic ) = + let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) (** Create a tactic that applies to a given goal if the probe evaluates to true and otherwise. *) - let cond ( ctx : context ) ( p : probe ) ( t1 : tactic ) ( t2 : tactic ) = + let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) (** @@ -4981,7 +5047,7 @@ struct (** Create a tactic that fails if the probe evaluates to false. *) - let fail_if ( ctx : context ) ( p : probe ) = + let fail_if ( ctx : context ) ( p : Probe.probe ) = create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) (** @@ -4994,14 +5060,14 @@ struct (** Create a tactic that applies using the given set of parameters . *) - let using_params ( ctx : context ) ( t : tactic ) ( p : params ) = + let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) (** Create a tactic that applies using the given set of parameters . Alias for UsingParams*) (* CMW: with is a keyword *) - let with_ ( ctx : context ) ( t : tactic ) ( p : params ) = + let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p (** @@ -5029,7 +5095,9 @@ end (** Solvers *) module Solver = struct - + type solver = z3_native_object + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : solver = { m_ctx = ctx ; m_n_obj = null ; @@ -5038,7 +5106,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + let string_of_status ( s : status) = match s with | UNSATISFIABLE -> "unsatisfiable" @@ -5048,7 +5116,8 @@ struct (** Objects that track statistical information about solvers. *) module Statistics = struct - + type statistics = z3_native_object + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : statistics = { m_ctx = ctx ; m_n_obj = null ; @@ -5066,7 +5135,13 @@ struct *) module Entry = struct - + type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } + let create_si k v = let res : statistics_entry = { m_key = k ; @@ -5086,7 +5161,7 @@ struct m_float = v } in res - + (** The key of the entry. *) let get_key (x : statistics_entry) = x.m_key @@ -5142,11 +5217,9 @@ struct let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** - The value of a particular statistical counter. - *) + (** The value of a particular statistical counter. *) let get ( x : statistics ) ( key : string ) = - let f p c = (if (Entry.get_key c) = key then (Some c) else p) in + let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in Array.fold_left f None (get_entries x) end @@ -5158,14 +5231,14 @@ struct (** Sets the solver parameters. *) - let set_parameters ( x : solver ) ( p : params )= + let set_parameters ( x : solver ) ( p : Params.params )= Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for solver. *) let get_param_descrs ( x : solver ) = - Params.ParamDescrs.create (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** The current number of backtracking points (scopes). @@ -5196,7 +5269,7 @@ struct (** Assert a constraint (or multiple) into the solver. *) - let assert_ ( x : solver ) ( constraints : bool_expr array ) = + let assert_ ( x : solver ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) @@ -5213,7 +5286,7 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( cs : bool_expr array ) ( ps : bool_expr array ) = + let assert_and_track ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else @@ -5232,14 +5305,14 @@ struct * and the Boolean literals * provided using with assumptions. *) - let assert_and_track ( x : solver ) ( c : bool_expr ) ( p : bool_expr ) = + let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) (** The number of assertions in the solver. *) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) @@ -5247,9 +5320,9 @@ struct The set of asserted formulas. *) let get_assertions ( x : solver ) = - let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in Array.init n f (** @@ -5259,12 +5332,12 @@ struct *) - let check ( x : solver ) ( assumptions : bool_expr array) = + let check ( x : solver ) ( assumptions : Boolean.bool_expr array) = let r = if ((Array.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - let f x = (ptr_of_expr (expr_of_bool_expr x)) in + let f x = (ptr_of_expr (Boolean.expr_of_bool_expr x)) in lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Array.map f assumptions)) in match r with @@ -5306,7 +5379,7 @@ struct if its results was not UNSATISFIABLE, or if core production is disabled. *) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f @@ -5330,7 +5403,7 @@ struct check-sat command, and check-sat commands that take more than a given number of milliseconds to be solved. *) - let mk_solver ( ctx : context ) ( logic : symbol option ) = + let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) @@ -5354,7 +5427,7 @@ struct The solver supports the commands Push and Pop, but it will always solve each check from scratch. *) - let mk_solver_t ( ctx : context ) ( t : tactic ) = + let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) (** @@ -5366,7 +5439,9 @@ end (** Fixedpoint solving *) module Fixedpoint = -struct +struct + type fixedpoint = z3_native_object + let create ( ctx : context ) = let res : fixedpoint = { m_ctx = ctx ; m_n_obj = null ; @@ -5375,7 +5450,7 @@ struct (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; (z3obj_create res) ; res - + (** A string that describes all available fixedpoint solver parameters. @@ -5386,19 +5461,19 @@ struct (** Sets the fixedpoint solver parameters. *) - let set_params ( x : fixedpoint ) ( p : params )= + let set_params ( x : fixedpoint ) ( p : Params.params )= Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) (** Retrieves parameter descriptions for Fixedpoint solver. *) let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.create (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) (** Assert a constraints into the fixedpoint solver. *) - let assert_ ( x : fixedpoint ) ( constraints : bool_expr array ) = + let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) ; () @@ -5412,7 +5487,7 @@ struct (** Add rule into the fixedpoint solver. *) - let add_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = match name with | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) @@ -5429,11 +5504,11 @@ struct The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - let query ( x : fixedpoint ) ( query : bool_expr ) = + let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN (** Query the fixedpoint solver. @@ -5444,9 +5519,9 @@ struct let query_r ( x : fixedpoint ) ( relations : func_decl array ) = let f x = ptr_of_ast (ast_of_func_decl x) in match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN (** Creates a backtracking point. @@ -5467,7 +5542,7 @@ struct (** Update named rule into in the fixedpoint solver. *) - let update_rule ( x : fixedpoint ) ( rule : bool_expr ) ( name : symbol ) = + let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) (** @@ -5518,33 +5593,33 @@ struct (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : symbol array ) = + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = let f2 x = (Symbol.gno x) in Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) (** Convert benchmark given as set of axioms, rules and queries to a string. *) - let to_string_q ( x : fixedpoint ) ( queries : bool_expr array ) = - let f x = ptr_of_expr (expr_of_bool_expr x) in + let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr array ) = + let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) (** Retrieve set of rules added to fixedpoint context. *) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** Retrieve set of assertions added to fixedpoint context. *) let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f (** @@ -5628,9 +5703,9 @@ struct @param formula Formula to be checked for consistency in conjunction with assumptions. @return A string representation of the benchmark. *) - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : bool_expr array ) ( formula : bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr array ) ( formula : Boolean.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (let f x = ptr_of_expr (expr_of_bool_expr x) in (Array.map f assumptions)) + (Array.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.map f assumptions)) (Boolean.gno formula) (** @@ -5642,7 +5717,7 @@ struct and . This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5662,7 +5737,7 @@ struct Parse the given file using the SMT-LIB parser. *) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5688,7 +5763,7 @@ struct *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in Array.init n f @@ -5702,7 +5777,7 @@ struct *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in Array.init n f (** @@ -5737,7 +5812,7 @@ struct @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5745,19 +5820,19 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) - cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) + cd + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) (** Parse the given file using the SMT-LIB2 parser. *) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : symbol array ) ( sorts : sort array ) ( decl_names : symbol array ) ( decls : func_decl array ) = + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in let cdn = (Array.length decl_names) in @@ -5765,13 +5840,13 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) - cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name + cs + (let f x = Symbol.gno x in (Array.map f sort_names)) + (let f x = Sort.gno x in (Array.map f sorts)) + cd + (let f x = Symbol.gno x in (Array.map f decl_names)) + (let f x = FuncDecl.gno x in (Array.map f decls)))) end @@ -5818,23 +5893,3 @@ let get_global_param ( id : string ) = *) let global_param_reset_all = Z3native.global_param_reset_all - - - -(* - -(** - A delegate which is executed when an error is raised. - - Note that it is possible for memory leaks to occur if error handlers - throw exceptions. -*) - public delegate void ErrorHandler(Context ctx, error_code errorCode, string errorString); - - internal Z3native.error_handler m_n_err_handler = null; - - internal void NativeErrorHandler(IntPtr ctx, error_code errorCode) - - Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - -*) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 5d5d7adf0..5b1b2073a 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -7,333 +7,566 @@ type context -type int_symbol -type string_symbol -type symbol = S_Int of int_symbol | S_Str of string_symbol +(** Create a context object. -type ast -type ast_vector -type ast_map + Most interactions with Z3 are interpreted in some context; many users will only + require one such object, but power users may require more than one. To start using + Z3, do -type sort = Sort of ast + + let ctx = (mk_context []) in + (...) + -type uninterpreted_sort = UninterpretedSort of sort -type bool_sort = BoolSort of sort -type array_sort = ArraySort of sort -type set_sort = SetSort of sort -type datatype_sort = DatatypeSort of sort -type relation_sort = RelationSort of sort -type finite_domain_sort = FiniteDomainSort of sort -type enum_sort = EnumSort of sort -type list_sort = ListSort of sort -type tuple_sort = TupleSort of sort -type arith_sort = ArithSort of sort -type bitvec_sort = BitVecSort of sort -type int_sort = IntSort of arith_sort -type real_sort = RealSort of arith_sort + where a list of pairs of strings may be passed to set options on + the context, e.g., like so: -type func_decl = FuncDecl of ast + + let cfg = [("model", "true"); ("...", "...")] in + let ctx = (mk_context cfg) in + (...) + +*) +val mk_context : (string * string) list -> context -type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of symbol - | P_Srt of sort - | P_Ast of ast - | P_Fdl of func_decl - | P_Rat of string - -type params -type param_descrs - -type expr = Expr of ast -type bool_expr = BoolExpr of expr -type arith_expr = ArithExpr of expr -type int_expr = IntExpr of arith_expr -type real_expr = RealExpr of arith_expr -type bitvec_expr = BitVecExpr of expr -type array_expr = ArrayExpr of expr -type datatype_expr = DatatypeExpr of expr -type int_num = IntNum of int_expr -type rat_num = RatNum of real_expr -type algebraic_num = AlgebraicNum of arith_expr -type bitvec_num = BitVecNum of bitvec_expr -type quantifier = Quantifier of expr -type pattern = Pattern of ast - -type constructor - -type goal - -type model -type func_interp -type func_entry - -type probe - -type tactic -type apply_result - -type solver -type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - -type statistics -type statistics_entry - -type fixedpoint - -val ast_of_sort : sort -> ast -val sort_of_uninterpreted_sort : uninterpreted_sort -> sort -val sort_of_bool_sort : bool_sort -> sort -val sort_of_array_sort : array_sort -> sort -val sort_of_set_sort : set_sort -> sort -val sort_of_datatype_sort : datatype_sort -> sort -val sort_of_relation_sort : relation_sort -> sort -val sort_of_finite_domain_sort : finite_domain_sort -> sort -val sort_of_enum_sort : enum_sort -> sort -val sort_of_list_sort : list_sort -> sort -val sort_of_tuple_sort : tuple_sort -> sort -val sort_of_arith_sort : arith_sort -> sort -val sort_of_bitvec_sort : bitvec_sort -> sort -val arith_sort_of_int_sort : int_sort -> arith_sort -val arith_sort_of_real_sort : real_sort -> arith_sort -val uninterpreted_sort_of_sort : sort -> uninterpreted_sort -val bool_sort_of_sort : sort -> bool_sort -val array_sort_of_sort : sort -> array_sort -val datatype_sort_of_sort : sort -> datatype_sort -val relation_sort_of_sort : sort -> relation_sort -val finite_domain_sort_of_sort : sort -> finite_domain_sort -val arith_sort_of_sort : sort -> arith_sort -val bitvec_sort_of_sort : sort -> bitvec_sort -val int_sort_of_arith_sort : arith_sort -> int_sort -val real_sort_of_arith_sort : arith_sort -> real_sort -val ast_of_func_decl : func_decl -> ast -val ast_of_expr : expr -> ast -val expr_of_bool_expr : bool_expr -> expr -val expr_of_arith_expr : arith_expr -> expr -val expr_of_bitvec_expr : bitvec_expr -> expr -val expr_of_array_expr : array_expr -> expr -val expr_of_datatype_expr : datatype_expr -> expr -val arith_expr_of_int_expr : int_expr -> arith_expr -val arith_expr_of_real_expr : real_expr -> arith_expr -val int_expr_of_int_num : int_num -> int_expr -val real_expr_of_rat_num : rat_num -> real_expr -val arith_expr_of_algebraic_num : algebraic_num -> arith_expr -val bitvec_expr_of_bitvec_num : bitvec_num -> bitvec_expr -val expr_of_quantifier : quantifier -> expr -val ast_of_pattern : pattern -> ast -val expr_of_ast : ast -> expr -val bool_expr_of_expr : expr -> bool_expr -val arith_expr_of_expr : expr -> arith_expr -val bitvec_expr_of_expr : expr -> bitvec_expr -val array_expr_of_expr : expr -> array_expr -val datatype_expr_of_expr : expr -> datatype_expr -val int_expr_of_arith_expr : arith_expr -> int_expr -val real_expr_of_arith_expr : arith_expr -> real_expr -val int_num_of_int_expr : int_expr -> int_num -val rat_num_of_real_expr : real_expr -> rat_num -val algebraic_num_of_arith_expr : arith_expr -> algebraic_num -val bitvec_num_of_bitvec_expr : bitvec_expr -> bitvec_num -val quantifier_of_expr : expr -> quantifier -val pattern_of_ast : ast -> pattern +(** Interaction logging for Z3 + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) module Log : sig + (** Open an interaction log file. + @param filename the name of the file to open. + @return True if opening the log file succeeds, false otherwise. + *) + (* CMW: "open" seems to be a reserved keyword? *) val open_ : string -> bool + + (** Closes the interaction log. *) val close : unit + + (** Appends a user-provided string to the interaction log. + @param s the string to append*) val append : string -> unit end +(** Version information *) module Version : sig + (** The major version. *) val major : int + + (** The minor version. *) val minor : int + + (** The build version. *) val build : int + + (** The revision. *) val revision : int + + (** A string representation of the version information. *) val to_string : string end -val mk_context : (string * string) list -> context - +(** Symbols are used to name several term and type constructors *) module Symbol : sig + (** Numbered Symbols *) + type int_symbol + + (** Named Symbols *) + type string_symbol + + (** Symbols *) + type symbol = S_Int of int_symbol | S_Str of string_symbol + + (** The kind of the symbol (int or string) *) val kind : symbol -> Z3enums.symbol_kind + + (** Indicates whether the symbol is of Int kind *) val is_int_symbol : symbol -> bool + + (** Indicates whether the symbol is of string kind. *) val is_string_symbol : symbol -> bool + + (** The int value of the symbol. *) val get_int : int_symbol -> int + + (** The string value of the symbol. *) val get_string : string_symbol -> string + + (** A string representation of the symbol. *) val to_string : symbol -> string + + (** + Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. + *) val mk_int : context -> int -> symbol + + (** Creates a new symbol using a string. *) val mk_string : context -> string -> symbol + + (** Create an array of symbols. *) val mk_ints : context -> int array -> symbol array + + (** Create an array of symbols. *) val mk_strings : context -> string array -> symbol array end +(** The abstract syntax tree (AST) module *) module AST : sig + type ast + (** Vectors of ASTs *) module ASTVector : sig + type ast_vector + + (** The size of the vector *) val get_size : ast_vector -> int - val get : ast_vector -> int -> ast_vector + + (** + Retrieves the i-th object in the vector. + @param i Index + @return An AST + *) + val get : ast_vector -> int -> ast + + (** Sets the i-th object in the vector. *) val set : ast_vector -> int -> ast -> unit + + (** Resize the vector to . + @param newSize The new size of the vector. *) val resize : ast_vector -> int -> unit + + (** + Add the AST to the back of the vector. The size + is increased by 1. + @param a An AST + *) val push : ast_vector -> ast -> unit + + (** + Translates all ASTs in the vector to . + @param to_ctx A context + @return A new ASTVector + *) val translate : ast_vector -> context -> ast_vector + + (** Retrieves a string representation of the vector. *) val to_string : ast_vector -> string end + (** Map from AST to AST *) module ASTMap : sig + type ast_map + + (** Checks whether the map contains the key . + @param k An AST + @return True if is a key in the map, false otherwise. *) val contains : ast_map -> ast -> bool - val find : ast_map -> ast -> ast_map + + (** Finds the value associated with the key . + + This function signs an error when is not a key in the map. + @param k An AST + *) + val find : ast_map -> ast -> ast + + (** + Stores or replaces a new key/value pair in the map. + @param k The key AST + @param v The value AST + *) val insert : ast_map -> ast -> ast -> unit + + (** + Erases the key from the map. + @param k An AST + *) val erase : ast_map -> ast -> unit + + (** Removes all keys from the map. *) val reset : ast_map -> unit + + (** The size of the map *) val get_size : ast_map -> int - val get_keys : ast_map -> ast_vector + + (** The keys stored in the map. *) + val get_keys : ast_map -> ASTVector.ast_vector + + (** Retrieves a string representation of the map.*) val to_string : ast_map -> string end + (** + The AST's hash code. + @return A hash code + *) val get_hash_code : ast -> int + + (** A unique identifier for the AST (unique among all ASTs). *) val get_id : ast -> int + + (** The kind of the AST. *) val get_ast_kind : ast -> Z3enums.ast_kind + + (** Indicates whether the AST is an Expr *) val is_expr : ast -> bool + + (** Indicates whether the AST is a bound variable*) val is_var : ast -> bool + + (** Indicates whether the AST is a Quantifier *) val is_quantifier : ast -> bool + + (** Indicates whether the AST is a Sort *) val is_sort : ast -> bool + + (** Indicates whether the AST is a func_decl *) val is_func_decl : ast -> bool + + (** A string representation of the AST. *) val to_string : ast -> string + + (** A string representation of the AST in s-expression notation. *) val to_sexpr : ast -> string + + (** + Comparison operator. + @param a An AST + @param b An AST + @return True if and are from the same context + and represent the same sort; false otherwise. + *) val ( = ) : ast -> ast -> bool + + (** + Object Comparison. + @param other Another ast + @return Negative if the object should be sorted before , positive if after else zero. + *) val compare : ast -> ast -> int + + (** Operator < *) val ( < ) : ast -> ast -> int + + (** + Translates (copies) the AST to the Context . + @param ctx A context + @return A copy of the AST which is associated with + *) val translate : ast -> context -> ast + + (** + Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that must be a + native object obtained from Z3 (e.g., through ) + and that it must have a correct reference count (see e.g., + . + + @param nativeObject The native pointer to wrap. + *) val wrap : context -> Z3native.z3_ast -> ast + + (** + Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + ). + + @param a The AST to unwrap. + *) val unwrap_ast : ast -> Z3native.ptr end +(** The Sort module implements type information for ASTs *) module Sort : sig + (** Sorts *) + type sort = Sort of AST.ast + + (** Uninterpreted Sorts *) + type uninterpreted_sort = UninterpretedSort of sort + + val ast_of_sort : sort -> AST.ast + val sort_of_uninterpreted_sort : uninterpreted_sort -> sort + val uninterpreted_sort_of_sort : sort -> uninterpreted_sort + + (** + Comparison operator. + @param a A sort + @param b A sort + @return True if and are from the same context + and represent the same sort; false otherwise. + *) val ( = ) : sort -> sort -> bool + + (** Returns a unique identifier for the sort. *) val get_id : sort -> int + + (** The kind of the sort. *) val get_sort_kind : sort -> Z3enums.sort_kind - val get_name : sort -> symbol + + (** The name of the sort *) + val get_name : sort -> Symbol.symbol + + (** A string representation of the sort. *) val to_string : sort -> string - val mk_uninterpreted : context -> symbol -> uninterpreted_sort + + (** Create a new uninterpreted sort. *) + val mk_uninterpreted : context -> Symbol.symbol -> uninterpreted_sort + + (** Create a new uninterpreted sort. *) val mk_uninterpreted_s : context -> string -> uninterpreted_sort end -module FuncDecl : +(** Function declarations *) +module rec FuncDecl : sig + type func_decl = FuncDecl of AST.ast + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + + (** Parameters of Func_Decls *) module Parameter : sig + (** Parameters of func_decls *) + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + (** The kind of the parameter. *) val get_kind : parameter -> Z3enums.parameter_kind + + (** The int value of the parameter.*) val get_int : parameter -> int + + (** The double value of the parameter.*) val get_float : parameter -> float - val get_symbol : parameter -> symbol - val get_sort : parameter -> sort - val get_ast : parameter -> ast - val get_func_decl : parameter -> string + + (** The Symbol.Symbol value of the parameter.*) + val get_symbol : parameter -> Symbol.symbol + + (** The Sort value of the parameter.*) + val get_sort : parameter -> Sort.sort + + (** The AST value of the parameter.*) + val get_ast : parameter -> AST.ast + + (** The FunctionDeclaration value of the parameter.*) + val get_func_decl : parameter -> func_decl + + (** The rational string value of the parameter.*) + val get_rational : parameter -> string end - val mk_func_decl : context -> symbol -> sort array -> sort -> func_decl - val mk_func_decl_s : context -> string -> sort array -> sort -> func_decl - val mk_fresh_func_decl : context -> string -> sort array -> sort -> func_decl - val mk_const_decl : context -> symbol -> sort -> func_decl - val mk_const_decl_s : context -> string -> sort -> func_decl - val mk_fresh_const_decl : context -> string -> sort -> func_decl + (** Creates a new function declaration. *) + val mk_func_decl : context -> Symbol.symbol -> Sort.sort array -> Sort.sort -> func_decl + + (** Creates a new function declaration. *) + val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl + (** Creates a fresh function declaration with a name prefixed with . + + *) + + val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl + + (** Creates a new constant function declaration. *) + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + + (** Creates a new constant function declaration. *) + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + + (** Creates a fresh constant function declaration with a name prefixed with . + + *) + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + + (** Comparison operator. + @param a A func_decl + @param b A func_decl + @return True if and are from the same context + and represent the same func_decl; false otherwise. *) val ( = ) : func_decl -> func_decl -> bool + + (** A string representations of the function declaration. *) val to_string : func_decl -> string + + (** Returns a unique identifier for the function declaration. *) val get_id : func_decl -> int + + (** The arity of the function declaration *) val get_arity : func_decl -> int + + (** The size of the domain of the function declaration + *) val get_domain_size : func_decl -> int - val get_domain : func_decl -> sort array - val get_range : func_decl -> sort + + (** The domain of the function declaration *) + val get_domain : func_decl -> Sort.sort array + + (** The range of the function declaration *) + val get_range : func_decl -> Sort.sort + + (** The kind of the function declaration. *) val get_decl_kind : func_decl -> Z3enums.decl_kind - val get_name : func_decl -> symbol + + (** The name of the function declaration*) + val get_name : func_decl -> Symbol.symbol + + (** The number of parameters of the function declaration *) val get_num_parameters : func_decl -> int - val get_parameters : func_decl -> parameter list - val apply : func_decl -> expr array -> expr + + (** The parameters of the function declaration *) + val get_parameters : func_decl -> Parameter.parameter list + + (** Create expression that applies function to arguments. + @param args The arguments *) + val apply : func_decl -> Expr.expr array -> Expr.expr end -module Params : -sig +(** Parameter sets (of Solvers, Tactics, ...) + A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) +and Params : +sig + type params + + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) module ParamDescrs : sig + type param_descrs + + (** Validate a set of parameters. *) val validate : param_descrs -> params -> unit - val get_kind : param_descrs -> symbol -> Z3enums.param_kind - val get_names : param_descrs -> symbol array + + (** Retrieve kind of parameter. *) + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + + (** Retrieve all names of parameters. *) + val get_names : param_descrs -> Symbol.symbol array + + (** The size of the ParamDescrs. *) val get_size : param_descrs -> int + + (** Retrieves a string representation of the ParamDescrs. *) val to_string : param_descrs -> string end - val add_bool : params -> symbol -> bool -> unit - val add_int : params -> symbol -> int -> unit - val add_double : params -> symbol -> float -> unit - val add_symbol : params -> symbol -> symbol -> unit + (** Adds a parameter setting. *) + val add_bool : params -> Symbol.symbol -> bool -> unit + + (** Adds a parameter setting. *) + val add_int : params -> Symbol.symbol -> int -> unit + + (** Adds a parameter setting. *) + val add_double : params -> Symbol.symbol -> float -> unit + + (** Adds a parameter setting. *) + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + + (** Adds a parameter setting. *) val add_s_bool : params -> string -> bool -> unit + + (** Adds a parameter setting. *) val add_s_int : params -> string -> int -> unit + + (** Adds a parameter setting. *) val add_s_double : params -> string -> float -> unit - val add_s_symbol : params -> string -> symbol -> unit + + (** Adds a parameter setting. *) + val add_s_symbol : params -> string -> Symbol.symbol -> unit + + (** Creates a new parameter set *) val mk_params : context -> params + + (** A string representation of the parameter set. *) val to_string : params -> string end -module Expr : +and Expr : sig - val simplify : expr -> params option -> expr + (** General Expressions (Terms) *) + type expr = Expr of AST.ast + + val ast_of_expr : Expr.expr -> AST.ast + val expr_of_ast : AST.ast -> Expr.expr + + val simplify : Expr.expr -> Params.params option -> expr val get_simplify_help : context -> string - val get_simplify_parameter_descrs : context -> param_descrs - val get_func_decl : expr -> func_decl - val get_bool_value : expr -> Z3enums.lbool - val get_num_args : expr -> int - val get_args : expr -> expr array - val update : expr -> expr array -> expr - val substitute : expr -> expr array -> expr array -> expr - val substitute_one : expr -> expr -> expr -> expr - val substitute_vars : expr -> expr array -> expr - val translate : expr -> context -> expr - val to_string : expr -> string - val is_numeral : expr -> bool - val is_well_sorted : expr -> bool - val get_sort : expr -> sort - val is_bool : expr -> bool - val is_const : expr -> bool - val is_true : expr -> bool - val is_false : expr -> bool - val is_eq : expr -> bool - val is_distinct : expr -> bool - val is_ite : expr -> bool - val is_and : expr -> bool - val is_or : expr -> bool - val is_iff : expr -> bool - val is_xor : expr -> bool - val is_not : expr -> bool - val is_implies : expr -> bool - val is_label : expr -> bool - val is_oeq : expr -> bool - val mk_const : context -> symbol -> sort -> expr - val mk_const_s : context -> string -> sort -> expr - val mk_const_f : context -> func_decl -> expr - val mk_fresh_const : context -> string -> sort -> expr - val mk_app : context -> func_decl -> expr array -> expr - val mk_numeral_string : context -> string -> sort -> expr - val mk_numeral_int : context -> int -> sort -> expr + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + val get_func_decl : Expr.expr -> FuncDecl.func_decl + val get_bool_value : Expr.expr -> Z3enums.lbool + val get_num_args : Expr.expr -> int + val get_args : Expr.expr -> Expr.expr array + val update : Expr.expr -> Expr.expr array -> expr + val substitute : Expr.expr -> Expr.expr array -> Expr.expr array -> expr + val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr + val substitute_vars : Expr.expr -> Expr.expr array -> expr + val translate : Expr.expr -> context -> expr + val to_string : Expr.expr -> string + val is_numeral : Expr.expr -> bool + val is_well_sorted : Expr.expr -> bool + val get_sort : Expr.expr -> Sort.sort + val is_bool : Expr.expr -> bool + val is_const : Expr.expr -> bool + val is_true : Expr.expr -> bool + val is_false : Expr.expr -> bool + val is_eq : Expr.expr -> bool + val is_distinct : Expr.expr -> bool + val is_ite : Expr.expr -> bool + val is_and : Expr.expr -> bool + val is_or : Expr.expr -> bool + val is_iff : Expr.expr -> bool + val is_xor : Expr.expr -> bool + val is_not : Expr.expr -> bool + val is_implies : Expr.expr -> bool + val is_label : Expr.expr -> bool + val is_oeq : Expr.expr -> bool + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val mk_const_s : context -> string -> Sort.sort -> expr + val mk_const_f : context -> FuncDecl.func_decl -> expr + val mk_fresh_const : context -> string -> Sort.sort -> expr + val mk_app : context -> FuncDecl.func_decl -> Expr.expr array -> expr + val mk_numeral_string : context -> string -> Sort.sort -> expr + val mk_numeral_int : context -> int -> Sort.sort -> expr end module Boolean : sig + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + + val expr_of_bool_expr : bool_expr -> Expr.expr + val sort_of_bool_sort : bool_sort -> Sort.sort + val bool_sort_of_sort : Sort.sort -> bool_sort + val bool_expr_of_expr : Expr.expr -> bool_expr + val mk_sort : context -> bool_sort - val mk_const : context -> symbol -> bool_expr + val mk_const : context -> Symbol.symbol -> bool_expr val mk_const_s : context -> string -> bool_expr val mk_true : context -> bool_expr val mk_false : context -> bool_expr val mk_val : context -> bool -> bool_expr - val mk_eq : context -> expr -> expr -> bool_expr - val mk_distinct : context -> expr array -> bool_expr + val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr + val mk_distinct : context -> Expr.expr array -> bool_expr val mk_not : context -> bool_expr -> bool_expr val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr val mk_iff : context -> bool_expr -> bool_expr -> bool_expr @@ -345,482 +578,590 @@ end module Quantifier : sig + type quantifier = Quantifier of Expr.expr + + val expr_of_quantifier : quantifier -> Expr.expr + val quantifier_of_expr : Expr.expr -> quantifier + module Pattern : sig + type pattern = Pattern of AST.ast + + val ast_of_pattern : pattern -> AST.ast + val pattern_of_ast : AST.ast -> pattern + val get_num_terms : pattern -> int - val get_terms : pattern -> expr array + val get_terms : pattern -> Expr.expr array val to_string : pattern -> string end - val get_index : expr -> int + val get_index : Expr.expr -> int val is_universal : quantifier -> bool val is_existential : quantifier -> bool val get_weight : quantifier -> int val get_num_patterns : quantifier -> int - val get_patterns : quantifier -> pattern array + val get_patterns : quantifier -> Pattern.pattern array val get_num_no_patterns : quantifier -> int - val get_no_patterns : quantifier -> pattern array + val get_no_patterns : quantifier -> Pattern.pattern array val get_num_bound : quantifier -> int - val get_bound_variable_names : quantifier -> symbol array - val get_bound_variable_sorts : quantifier -> sort array - val get_body : quantifier -> bool_expr - val mk_bound : context -> int -> sort -> expr - val mk_pattern : context -> expr array -> pattern + val get_bound_variable_names : quantifier -> Symbol.symbol array + val get_bound_variable_sorts : quantifier -> Sort.sort array + val get_body : quantifier -> Boolean.bool_expr + val mk_bound : context -> int -> Sort.sort -> Expr.expr + val mk_pattern : context -> Expr.expr array -> Pattern.pattern val mk_forall : context -> - sort array -> - symbol array -> - expr -> + Sort.sort array -> + Symbol.symbol array -> + Expr.expr -> int option -> - pattern array -> - expr array -> symbol option -> symbol option -> quantifier + Pattern.pattern array -> + Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier val mk_forall_const : context -> - expr array -> - expr -> + Expr.expr array -> + Expr.expr -> int option -> - pattern array -> - expr array -> symbol option -> symbol option -> quantifier + Pattern.pattern array -> + Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier val mk_exists : context -> - sort array -> - symbol array -> - expr -> + Sort.sort array -> + Symbol.symbol array -> + Expr.expr -> int option -> - pattern array -> - expr array -> symbol option -> symbol option -> quantifier + Pattern.pattern array -> + Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier val mk_exists_const : context -> - expr array -> - expr -> + Expr.expr array -> + Expr.expr -> int option -> - pattern array -> - expr array -> symbol option -> symbol option -> quantifier + Pattern.pattern array -> + Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier val mk_quantifier : context -> bool -> - expr array -> - expr -> + Expr.expr array -> + Expr.expr -> int option -> - pattern array -> - expr array -> symbol option -> symbol option -> quantifier + Pattern.pattern array -> + Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier end module Array_ : sig - val mk_sort : context -> sort -> sort -> array_sort - val is_store : expr -> bool - val is_select : expr -> bool - val is_constant_array : expr -> bool - val is_default_array : expr -> bool - val is_array_map : expr -> bool - val is_as_array : expr -> bool - val is_array : expr -> bool - val get_domain : array_sort -> sort - val get_range : array_sort -> sort - val mk_const : context -> symbol -> sort -> sort -> array_expr - val mk_const_s : context -> string -> sort -> sort -> array_expr - val mk_select : context -> array_expr -> expr -> expr -> expr - val mk_const_array : context -> sort -> expr -> expr - val mk_map : context -> func_decl -> array_expr array -> expr - val mk_term_array : context -> array_expr -> expr + type array_sort = ArraySort of Sort.sort + type array_expr = ArrayExpr of Expr.expr + + val sort_of_array_sort : array_sort -> Sort.sort + val array_sort_of_sort : Sort.sort -> array_sort + val expr_of_array_expr : array_expr -> Expr.expr + + val array_expr_of_expr : Expr.expr -> array_expr + + val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort + val is_store : Expr.expr -> bool + val is_select : Expr.expr -> bool + val is_constant_array : Expr.expr -> bool + val is_default_array : Expr.expr -> bool + val is_array_map : Expr.expr -> bool + val is_as_array : Expr.expr -> bool + val is_array : Expr.expr -> bool + val get_domain : array_sort -> Sort.sort + val get_range : array_sort -> Sort.sort + val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr + val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr + val mk_select : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr + val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr + val mk_map : context -> FuncDecl.func_decl -> array_expr array -> array_expr + val mk_term_array : context -> array_expr -> array_expr end module Set : sig - val is_union : expr -> bool - val is_intersect : expr -> bool - val is_difference : expr -> bool - val is_complement : expr -> bool - val is_subset : expr -> bool - val mk_sort : context -> sort -> set_sort - val mk_empty : context -> sort -> expr - val mk_full : context -> sort -> expr - val mk_set_add : context -> expr -> expr -> expr - val mk_del : context -> expr -> expr -> expr - val mk_union : context -> expr array -> expr - val mk_intersection : context -> expr array -> expr - val mk_difference : context -> expr -> expr -> expr - val mk_complement : context -> expr -> expr - val mk_membership : context -> expr -> expr -> expr - val mk_subset : context -> expr -> expr -> expr + type set_sort = SetSort of Sort.sort + + val sort_of_set_sort : set_sort -> Sort.sort + + val is_union : Expr.expr -> bool + val is_intersect : Expr.expr -> bool + val is_difference : Expr.expr -> bool + val is_complement : Expr.expr -> bool + val is_subset : Expr.expr -> bool + val mk_sort : context -> Sort.sort -> set_sort + val mk_empty : context -> Sort.sort -> Expr.expr + val mk_full : context -> Sort.sort -> Expr.expr + val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr + val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr + val mk_union : context -> Expr.expr array -> Expr.expr + val mk_intersection : context -> Expr.expr array -> Expr.expr + val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr + val mk_complement : context -> Expr.expr -> Expr.expr + val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr + val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr end module FiniteDomain : sig - val mk_sort : context -> symbol -> int -> finite_domain_sort + type finite_domain_sort = FiniteDomainSort of Sort.sort + + val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort + val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort + + val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort val mk_sort_s : context -> string -> int -> finite_domain_sort - val is_finite_domain : expr -> bool - val is_lt : expr -> bool + val is_finite_domain : Expr.expr -> bool + val is_lt : Expr.expr -> bool val get_size : finite_domain_sort -> int end module Relation : sig - val is_relation : expr -> bool - val is_store : expr -> bool - val is_empty : expr -> bool - val is_is_empty : expr -> bool - val is_join : expr -> bool - val is_union : expr -> bool - val is_widen : expr -> bool - val is_project : expr -> bool - val is_filter : expr -> bool - val is_negation_filter : expr -> bool - val is_rename : expr -> bool - val is_complement : expr -> bool - val is_select : expr -> bool - val is_clone : expr -> bool + type relation_sort = RelationSort of Sort.sort + + val sort_of_relation_sort : relation_sort -> Sort.sort + val relation_sort_of_sort : Sort.sort -> relation_sort + + val is_relation : Expr.expr -> bool + val is_store : Expr.expr -> bool + val is_empty : Expr.expr -> bool + val is_is_empty : Expr.expr -> bool + val is_join : Expr.expr -> bool + val is_union : Expr.expr -> bool + val is_widen : Expr.expr -> bool + val is_project : Expr.expr -> bool + val is_filter : Expr.expr -> bool + val is_negation_filter : Expr.expr -> bool + val is_rename : Expr.expr -> bool + val is_complement : Expr.expr -> bool + val is_select : Expr.expr -> bool + val is_clone : Expr.expr -> bool val get_arity : relation_sort -> int val get_column_sorts : relation_sort -> relation_sort array end module Datatype : sig + type datatype_sort = DatatypeSort of Sort.sort + type datatype_expr = DatatypeExpr of Expr.expr + + val sort_of_datatype_sort : datatype_sort -> Sort.sort + val datatype_sort_of_sort : Sort.sort -> datatype_sort + val expr_of_datatype_expr : datatype_expr -> Expr.expr + val datatype_expr_of_expr : Expr.expr -> datatype_expr module Constructor : sig + (** Constructors *) + type constructor + val get_n : constructor -> int - val constructor_decl : constructor -> func_decl - val tester_decl : constructor -> func_decl - val accessor_decls : constructor -> func_decl array + val constructor_decl : constructor -> FuncDecl.func_decl + val tester_decl : constructor -> FuncDecl.func_decl + val accessor_decls : constructor -> FuncDecl.func_decl array val get_num_fields : constructor -> int - val get_constructor_decl : constructor -> func_decl - val get_tester_decl : constructor -> func_decl - val get_accessor_decls : constructor -> func_decl array + val get_constructor_decl : constructor -> FuncDecl.func_decl + val get_tester_decl : constructor -> FuncDecl.func_decl + val get_accessor_decls : constructor -> FuncDecl.func_decl array end - val mk_constructor : context -> symbol -> symbol -> symbol array -> sort array -> int array -> constructor - val mk_constructor_s : context -> string -> symbol -> symbol array -> sort array -> int array -> constructor - val mk_sort : context -> symbol -> constructor array -> datatype_sort - val mk_sort_s : context -> string -> constructor array -> datatype_sort - val mk_sorts : context -> symbol array -> constructor array array -> datatype_sort array - val mk_sorts_s : context -> string array -> constructor array array -> datatype_sort array + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> Constructor.constructor + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> Constructor.constructor + val mk_sort : context -> Symbol.symbol -> Constructor.constructor array -> datatype_sort + val mk_sort_s : context -> string -> Constructor.constructor array -> datatype_sort + val mk_sorts : context -> Symbol.symbol array -> Constructor.constructor array array -> datatype_sort array + val mk_sorts_s : context -> string array -> Constructor.constructor array array -> datatype_sort array val get_num_constructors : datatype_sort -> int - val get_constructors : datatype_sort -> func_decl array - val get_recognizers : datatype_sort -> func_decl array - val get_accessors : datatype_sort -> func_decl array array + val get_constructors : datatype_sort -> FuncDecl.func_decl array + val get_recognizers : datatype_sort -> FuncDecl.func_decl array + val get_accessors : datatype_sort -> FuncDecl.func_decl array array end module Enumeration : sig - val mk_sort : context -> symbol -> symbol array -> enum_sort + type enum_sort = EnumSort of Sort.sort + + val sort_of_enum_sort : enum_sort -> Sort.sort + + val mk_sort : context -> Symbol.symbol -> Symbol.symbol array -> enum_sort val mk_sort_s : context -> string -> string array -> enum_sort - val get_const_decls : enum_sort -> func_decl array - val get_tester_decls : enum_sort -> func_decl array + val get_const_decls : enum_sort -> FuncDecl.func_decl array + val get_tester_decls : enum_sort -> FuncDecl.func_decl array end module List_ : sig - val mk_sort : context -> symbol -> sort -> list_sort - val mk_list_s : context -> string -> sort -> list_sort - val get_nil_decl : list_sort -> func_decl - val get_is_nil_decl : list_sort -> func_decl - val get_cons_decl : list_sort -> func_decl - val get_is_cons_decl : list_sort -> func_decl - val get_head_decl : list_sort -> func_decl - val get_tail_decl : list_sort -> func_decl - val nil : list_sort -> expr + type list_sort = ListSort of Sort.sort + + val sort_of_list_sort : list_sort -> Sort.sort + + val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort + val mk_list_s : context -> string -> Sort.sort -> list_sort + val get_nil_decl : list_sort -> FuncDecl.func_decl + val get_is_nil_decl : list_sort -> FuncDecl.func_decl + val get_cons_decl : list_sort -> FuncDecl.func_decl + val get_is_cons_decl : list_sort -> FuncDecl.func_decl + val get_head_decl : list_sort -> FuncDecl.func_decl + val get_tail_decl : list_sort -> FuncDecl.func_decl + val nil : list_sort -> Expr.expr end module Tuple : sig - val mk_sort : - context -> symbol -> symbol array -> sort array -> tuple_sort - val get_mk_decl : tuple_sort -> func_decl + type tuple_sort = TupleSort of Sort.sort + + val sort_of_tuple_sort : tuple_sort -> Sort.sort + + val mk_sort : context -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> tuple_sort + val get_mk_decl : tuple_sort -> FuncDecl.func_decl val get_num_fields : tuple_sort -> int - val get_field_decls : tuple_sort -> func_decl array + val get_field_decls : tuple_sort -> FuncDecl.func_decl array end -module Arithmetic : +module rec Arithmetic : sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr - module Integer : + val sort_of_arith_sort : Arithmetic.arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> Arithmetic.arith_sort + val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr + + module rec Integer : sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val arith_sort_of_int_sort : Arithmetic.Integer.int_sort -> Arithmetic.arith_sort + val int_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Integer.int_sort + val arith_expr_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.arith_expr + val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr + val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr + val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num + val mk_sort : context -> int_sort val get_int : int_num -> int val to_string : int_num -> string - val mk_int_const : context -> symbol -> int_expr + val mk_int_const : context -> Symbol.symbol -> int_expr val mk_int_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> expr - val mk_rem : context -> int_expr -> int_expr -> expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr val mk_int_numeral_s : context -> string -> int_num val mk_int_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> real_expr - val mk_int2bv : context -> int -> int_expr -> bitvec_expr + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr end - module Real : + and Real : sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + val mk_sort : context -> real_sort - val get_numerator : rat_num -> int_num - val get_denominator : rat_num -> int_num + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num val to_decimal_string : rat_num -> int -> string val to_string : rat_num -> string - val mk_real_const : context -> symbol -> real_expr + val mk_real_const : context -> Symbol.symbol -> real_expr val mk_real_const_s : context -> string -> real_expr val mk_numeral_nd : context -> int -> int -> rat_num val mk_numeral_s : context -> string -> rat_num val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> bool_expr - val mk_real2int : context -> real_expr -> int_expr + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr end - module AlgebraicNumber : + and AlgebraicNumber : sig - val to_upper : algebraic_num -> int -> rat_num - val to_lower : algebraic_num -> int -> rat_num + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr + val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num val to_decimal_string : algebraic_num -> int -> string val to_string : algebraic_num -> string end - val is_int : expr -> bool - val is_arithmetic_numeral : expr -> bool - val is_le : expr -> bool - val is_ge : expr -> bool - val is_lt : expr -> bool - val is_gt : expr -> bool - val is_add : expr -> bool - val is_sub : expr -> bool - val is_uminus : expr -> bool - val is_mul : expr -> bool - val is_div : expr -> bool - val is_idiv : expr -> bool - val is_remainder : expr -> bool - val is_modulus : expr -> bool - val is_inttoreal : expr -> bool - val is_real_to_int : expr -> bool - val is_real_is_int : expr -> bool - val is_real : expr -> bool - val is_int_numeral : expr -> bool - val is_rat_num : expr -> bool - val is_algebraic_number : expr -> bool + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool val mk_add : context -> arith_expr array -> arith_expr val mk_mul : context -> arith_expr array -> arith_expr val mk_sub : context -> arith_expr array -> arith_expr val mk_unary_minus : context -> arith_expr -> arith_expr val mk_div : context -> arith_expr -> arith_expr -> arith_expr val mk_power : context -> arith_expr -> arith_expr -> arith_expr - val mk_lt : context -> arith_expr -> arith_expr -> bool_expr - val mk_le : context -> arith_expr -> arith_expr -> bool_expr - val mk_gt : context -> arith_expr -> arith_expr -> bool_expr - val mk_ge : context -> arith_expr -> arith_expr -> bool_expr + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr end -module BitVector : +and BitVector : sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + val mk_sort : context -> int -> bitvec_sort - val is_bv : expr -> bool - val is_bv_numeral : expr -> bool - val is_bv_bit1 : expr -> bool - val is_bv_bit0 : expr -> bool - val is_bv_uminus : expr -> bool - val is_bv_add : expr -> bool - val is_bv_sub : expr -> bool - val is_bv_mul : expr -> bool - val is_bv_sdiv : expr -> bool - val is_bv_udiv : expr -> bool - val is_bv_SRem : expr -> bool - val is_bv_urem : expr -> bool - val is_bv_smod : expr -> bool - val is_bv_sdiv0 : expr -> bool - val is_bv_udiv0 : expr -> bool - val is_bv_srem0 : expr -> bool - val is_bv_urem0 : expr -> bool - val is_bv_smod0 : expr -> bool - val is_bv_ule : expr -> bool - val is_bv_sle : expr -> bool - val is_bv_uge : expr -> bool - val is_bv_sge : expr -> bool - val is_bv_ult : expr -> bool - val is_bv_slt : expr -> bool - val is_bv_ugt : expr -> bool - val is_bv_sgt : expr -> bool - val is_bv_and : expr -> bool - val is_bv_or : expr -> bool - val is_bv_not : expr -> bool - val is_bv_xor : expr -> bool - val is_bv_nand : expr -> bool - val is_bv_nor : expr -> bool - val is_bv_xnor : expr -> bool - val is_bv_concat : expr -> bool - val is_bv_signextension : expr -> bool - val is_bv_zeroextension : expr -> bool - val is_bv_extract : expr -> bool - val is_bv_repeat : expr -> bool - val is_bv_reduceor : expr -> bool - val is_bv_reduceand : expr -> bool - val is_bv_comp : expr -> bool - val is_bv_shiftleft : expr -> bool - val is_bv_shiftrightlogical : expr -> bool - val is_bv_shiftrightarithmetic : expr -> bool - val is_bv_rotateleft : expr -> bool - val is_bv_rotateright : expr -> bool - val is_bv_rotateleftextended : expr -> bool - val is_bv_rotaterightextended : expr -> bool - val is_int_to_bv : expr -> bool - val is_bv_to_int : expr -> bool - val is_bv_carry : expr -> bool - val is_bv_xor3 : expr -> bool + val is_bv : Expr.expr -> bool + val is_bv_numeral : Expr.expr -> bool + val is_bv_bit1 : Expr.expr -> bool + val is_bv_bit0 : Expr.expr -> bool + val is_bv_uminus : Expr.expr -> bool + val is_bv_add : Expr.expr -> bool + val is_bv_sub : Expr.expr -> bool + val is_bv_mul : Expr.expr -> bool + val is_bv_sdiv : Expr.expr -> bool + val is_bv_udiv : Expr.expr -> bool + val is_bv_SRem : Expr.expr -> bool + val is_bv_urem : Expr.expr -> bool + val is_bv_smod : Expr.expr -> bool + val is_bv_sdiv0 : Expr.expr -> bool + val is_bv_udiv0 : Expr.expr -> bool + val is_bv_srem0 : Expr.expr -> bool + val is_bv_urem0 : Expr.expr -> bool + val is_bv_smod0 : Expr.expr -> bool + val is_bv_ule : Expr.expr -> bool + val is_bv_sle : Expr.expr -> bool + val is_bv_uge : Expr.expr -> bool + val is_bv_sge : Expr.expr -> bool + val is_bv_ult : Expr.expr -> bool + val is_bv_slt : Expr.expr -> bool + val is_bv_ugt : Expr.expr -> bool + val is_bv_sgt : Expr.expr -> bool + val is_bv_and : Expr.expr -> bool + val is_bv_or : Expr.expr -> bool + val is_bv_not : Expr.expr -> bool + val is_bv_xor : Expr.expr -> bool + val is_bv_nand : Expr.expr -> bool + val is_bv_nor : Expr.expr -> bool + val is_bv_xnor : Expr.expr -> bool + val is_bv_concat : Expr.expr -> bool + val is_bv_signextension : Expr.expr -> bool + val is_bv_zeroextension : Expr.expr -> bool + val is_bv_extract : Expr.expr -> bool + val is_bv_repeat : Expr.expr -> bool + val is_bv_reduceor : Expr.expr -> bool + val is_bv_reduceand : Expr.expr -> bool + val is_bv_comp : Expr.expr -> bool + val is_bv_shiftleft : Expr.expr -> bool + val is_bv_shiftrightlogical : Expr.expr -> bool + val is_bv_shiftrightarithmetic : Expr.expr -> bool + val is_bv_rotateleft : Expr.expr -> bool + val is_bv_rotateright : Expr.expr -> bool + val is_bv_rotateleftextended : Expr.expr -> bool + val is_bv_rotaterightextended : Expr.expr -> bool + val is_int_to_bv : Expr.expr -> bool + val is_bv_to_int : Expr.expr -> bool + val is_bv_carry : Expr.expr -> bool + val is_bv_xor3 : Expr.expr -> bool val get_size : bitvec_sort -> int val get_int : bitvec_num -> int val to_string : bitvec_num -> string - val mk_const : context -> symbol -> int -> bitvec_expr + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr val mk_const_s : context -> string -> int -> bitvec_expr - val mk_not : context -> bitvec_expr -> expr - val mk_redand : context -> bitvec_expr -> expr - val mk_redor : context -> bitvec_expr -> expr - val mk_and : context -> bitvec_expr -> bitvec_expr -> expr - val mk_or : context -> bitvec_expr -> bitvec_expr -> expr - val mk_xor : context -> bitvec_expr -> bitvec_expr -> expr - val mk_nand : context -> bitvec_expr -> bitvec_expr -> expr - val mk_nor : context -> bitvec_expr -> bitvec_expr -> expr - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> expr - val mk_neg : context -> bitvec_expr -> expr - val mk_add : context -> bitvec_expr -> bitvec_expr -> expr - val mk_sub : context -> bitvec_expr -> bitvec_expr -> expr - val mk_mul : context -> bitvec_expr -> bitvec_expr -> expr - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> expr - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> expr - val mk_urem : context -> bitvec_expr -> bitvec_expr -> expr - val mk_srem : context -> bitvec_expr -> bitvec_expr -> expr - val mk_smod : context -> bitvec_expr -> bitvec_expr -> expr - val mk_ult : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_slt : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_ule : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_sle : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_uge : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_sge : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_concat : context -> bitvec_expr -> bitvec_expr -> expr - val mk_extract : context -> int -> int -> bitvec_expr -> expr - val mk_sign_ext : context -> int -> bitvec_expr -> expr - val mk_zero_ext : context -> int -> bitvec_expr -> expr - val mk_repeat : context -> int -> bitvec_expr -> expr - val mk_shl : context -> bitvec_expr -> bitvec_expr -> expr - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> expr - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> expr - val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> expr - val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> expr - val mk_bv2int : context -> bitvec_expr -> bool -> int_expr - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> bool_expr - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> bool_expr - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool_expr - val mk_neg_no_overflow : context -> bitvec_expr -> bool_expr - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> bool_expr - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool_expr + val mk_not : context -> bitvec_expr -> Expr.expr + val mk_redand : context -> bitvec_expr -> Expr.expr + val mk_redor : context -> bitvec_expr -> Expr.expr + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_neg : context -> bitvec_expr -> bitvec_expr + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr val mk_numeral : context -> string -> int -> bitvec_num end module Proof : sig - val is_true : expr -> bool - val is_asserted : expr -> bool - val is_goal : expr -> bool - val is_modus_ponens : expr -> bool - val is_reflexivity : expr -> bool - val is_symmetry : expr -> bool - val is_transitivity : expr -> bool - val is_Transitivity_star : expr -> bool - val is_monotonicity : expr -> bool - val is_quant_intro : expr -> bool - val is_distributivity : expr -> bool - val is_and_elimination : expr -> bool - val is_or_elimination : expr -> bool - val is_rewrite : expr -> bool - val is_rewrite_star : expr -> bool - val is_pull_quant : expr -> bool - val is_pull_quant_star : expr -> bool - val is_push_quant : expr -> bool - val is_elim_unused_vars : expr -> bool - val is_der : expr -> bool - val is_quant_inst : expr -> bool - val is_hypothesis : expr -> bool - val is_lemma : expr -> bool - val is_unit_resolution : expr -> bool - val is_iff_true : expr -> bool - val is_iff_false : expr -> bool - val is_commutativity : expr -> bool - val is_def_axiom : expr -> bool - val is_def_intro : expr -> bool - val is_apply_def : expr -> bool - val is_iff_oeq : expr -> bool - val is_nnf_pos : expr -> bool - val is_nnf_neg : expr -> bool - val is_nnf_star : expr -> bool - val is_cnf_star : expr -> bool - val is_skolemize : expr -> bool - val is_modus_ponens_oeq : expr -> bool - val is_theory_lemma : expr -> bool + val is_true : Expr.expr -> bool + val is_asserted : Expr.expr -> bool + val is_goal : Expr.expr -> bool + val is_modus_ponens : Expr.expr -> bool + val is_reflexivity : Expr.expr -> bool + val is_symmetry : Expr.expr -> bool + val is_transitivity : Expr.expr -> bool + val is_Transitivity_star : Expr.expr -> bool + val is_monotonicity : Expr.expr -> bool + val is_quant_intro : Expr.expr -> bool + val is_distributivity : Expr.expr -> bool + val is_and_elimination : Expr.expr -> bool + val is_or_elimination : Expr.expr -> bool + val is_rewrite : Expr.expr -> bool + val is_rewrite_star : Expr.expr -> bool + val is_pull_quant : Expr.expr -> bool + val is_pull_quant_star : Expr.expr -> bool + val is_push_quant : Expr.expr -> bool + val is_elim_unused_vars : Expr.expr -> bool + val is_der : Expr.expr -> bool + val is_quant_inst : Expr.expr -> bool + val is_hypothesis : Expr.expr -> bool + val is_lemma : Expr.expr -> bool + val is_unit_resolution : Expr.expr -> bool + val is_iff_true : Expr.expr -> bool + val is_iff_false : Expr.expr -> bool + val is_commutativity : Expr.expr -> bool + val is_def_axiom : Expr.expr -> bool + val is_def_intro : Expr.expr -> bool + val is_apply_def : Expr.expr -> bool + val is_iff_oeq : Expr.expr -> bool + val is_nnf_pos : Expr.expr -> bool + val is_nnf_neg : Expr.expr -> bool + val is_nnf_star : Expr.expr -> bool + val is_cnf_star : Expr.expr -> bool + val is_skolemize : Expr.expr -> bool + val is_modus_ponens_oeq : Expr.expr -> bool + val is_theory_lemma : Expr.expr -> bool end + module Goal : sig + type goal + val get_precision : goal -> Z3enums.goal_prec val is_precise : goal -> bool val is_underapproximation : goal -> bool val is_overapproximation : goal -> bool val is_garbage : goal -> bool - val assert_ : goal -> bool_expr array -> unit + val assert_ : goal -> Boolean.bool_expr array -> unit val is_inconsistent : goal -> bool val get_depth : goal -> int val reset : goal -> unit val get_size : goal -> int - val get_formulas : goal -> bool_expr array + val get_formulas : goal -> Boolean.bool_expr array val get_num_exprs : goal -> int val is_decided_sat : goal -> bool val is_decided_unsat : goal -> bool val translate : goal -> context -> goal - val simplify : goal -> params option -> goal + val simplify : goal -> Params.params option -> goal val mk_goal : context -> bool -> bool -> bool -> goal val to_string : goal -> string end module Model : sig + type model module FuncInterp : sig - + type func_interp + module FuncEntry : sig - val get_value : func_entry -> expr + type func_entry + + val get_value : func_entry -> Expr.expr val get_num_args : func_entry -> int - val get_args : func_entry -> expr array + val get_args : func_entry -> Expr.expr array val to_string : func_entry -> string end val get_num_entries : func_interp -> int - val get_entries : func_interp -> func_entry array - val get_else : func_interp -> expr + val get_entries : func_interp -> FuncEntry.func_entry array + val get_else : func_interp -> Expr.expr val get_arity : func_interp -> int val to_string : func_interp -> string end - val get_const_interp : model -> func_decl -> expr option - val get_const_interp_e : model -> expr -> expr option - val get_func_interp : model -> func_decl -> func_interp option + val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option + val get_const_interp_e : model -> Expr.expr -> Expr.expr option + val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option val get_num_consts : model -> int - val get_const_decls : model -> func_decl array + val get_const_decls : model -> FuncDecl.func_decl array val get_num_funcs : model -> int - val get_func_decls : model -> func_decl array - val get_decls : model -> func_decl array + val get_func_decls : model -> FuncDecl.func_decl array + val get_decls : model -> FuncDecl.func_decl array exception ModelEvaluationFailedException of string - val eval : model -> expr -> bool -> expr - val evaluate : model -> expr -> bool -> expr + val eval : model -> Expr.expr -> bool -> Expr.expr + val evaluate : model -> Expr.expr -> bool -> Expr.expr val get_num_sorts : model -> int - val get_sorts : model -> sort array - val sort_universe : model -> sort -> ast_vector array + val get_sorts : model -> Sort.sort array + val sort_universe : model -> Sort.sort -> AST.ASTVector.ast_vector array val to_string : model -> string end module Probe : sig - val apply : probe -> goal -> float + type probe + + val apply : probe -> Goal.goal -> float val get_num_probes : context -> int val get_probe_names : context -> string array val get_probe_description : context -> string -> string @@ -838,19 +1179,22 @@ end module Tactic : sig + type tactic module ApplyResult : sig + type apply_result + val get_num_subgoals : apply_result -> int - val get_subgoals : apply_result -> goal array - val get_subgoal : apply_result -> int -> goal - val convert_model : apply_result -> int -> model -> model + val get_subgoals : apply_result -> Goal.goal array + val get_subgoal : apply_result -> int -> Goal.goal + val convert_model : apply_result -> int -> Model.model -> Model.model val to_string : apply_result -> string end val get_help : tactic -> string - val get_param_descrs : tactic -> param_descrs - val apply : tactic -> goal -> params option -> apply_result + val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs + val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result val get_num_tactics : context -> int val get_tactic_names : context -> string array val get_tactic_description : context -> string -> string @@ -858,15 +1202,15 @@ sig val and_then : context -> tactic -> tactic -> tactic array -> tactic val or_else : context -> tactic -> tactic -> tactic val try_for : context -> tactic -> int -> tactic - val when_ : context -> probe -> tactic -> tactic - val cond : context -> probe -> tactic -> tactic -> tactic + val when_ : context -> Probe.probe -> tactic -> tactic + val cond : context -> Probe.probe -> tactic -> tactic -> tactic val repeat : context -> tactic -> int -> tactic val skip : context -> tactic val fail : context -> tactic - val fail_if : context -> probe -> tactic + val fail_if : context -> Probe.probe -> tactic val fail_if_not_decided : context -> tactic - val using_params : context -> tactic -> params -> tactic - val with_ : context -> tactic -> params -> tactic + val using_params : context -> tactic -> Params.params -> tactic + val with_ : context -> tactic -> Params.params -> tactic val par_or : context -> tactic array -> tactic val par_and_then : context -> tactic -> tactic -> tactic val interrupt : context -> unit @@ -874,13 +1218,19 @@ end module Solver : sig + type solver + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + val string_of_status : status -> string module Statistics : sig + type statistics module Entry : sig + type statistics_entry + val get_key : statistics_entry -> string val get_int : statistics_entry -> int val get_float : statistics_entry -> float @@ -892,59 +1242,61 @@ sig val to_string : statistics -> string val get_size : statistics -> int - val get_entries : statistics -> statistics_entry array + val get_entries : statistics -> Entry.statistics_entry array val get_keys : statistics -> string array - val get : statistics -> string -> statistics_entry option + val get : statistics -> string -> Entry.statistics_entry option end val get_help : solver -> string - val set_parameters : solver -> params -> unit - val get_param_descrs : solver -> param_descrs + val set_parameters : solver -> Params.params -> unit + val get_param_descrs : solver -> Params.ParamDescrs.param_descrs val get_num_scopes : solver -> int val push : solver -> unit val pop : solver -> int -> unit val reset : solver -> unit - val assert_ : solver -> bool_expr array -> unit - val assert_and_track : solver -> bool_expr -> bool_expr -> unit + val assert_ : solver -> Boolean.bool_expr array -> unit + val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit val get_num_assertions : solver -> int - val get_assertions : solver -> bool_expr array - val check : solver -> bool_expr array -> status - val get_model : solver -> model option - val get_proof : solver -> expr option - val get_unsat_core : solver -> ast_vector array + val get_assertions : solver -> Boolean.bool_expr array + val check : solver -> Boolean.bool_expr array -> status + val get_model : solver -> Model.model option + val get_proof : solver -> Expr.expr option + val get_unsat_core : solver -> AST.ASTVector.ast_vector array val get_reason_unknown : solver -> string - val get_statistics : solver -> statistics - val mk_solver : context -> symbol option -> solver + val get_statistics : solver -> Statistics.statistics + val mk_solver : context -> Symbol.symbol option -> solver val mk_solver_s : context -> string -> solver val mk_simple_solver : context -> solver - val mk_solver_t : context -> tactic -> solver + val mk_solver_t : context -> Tactic.tactic -> solver val to_string : solver -> string end module Fixedpoint : sig + type fixedpoint + val get_help : fixedpoint -> string - val set_params : fixedpoint -> params -> unit - val get_param_descrs : fixedpoint -> param_descrs - val assert_ : fixedpoint -> bool_expr array -> unit - val register_relation : fixedpoint -> func_decl -> unit - val add_rule : fixedpoint -> bool_expr -> symbol option -> unit - val add_fact : fixedpoint -> func_decl -> int array -> unit - val query : fixedpoint -> bool_expr -> status - val query_r : fixedpoint -> func_decl array -> status + val set_params : fixedpoint -> Params.params -> unit + val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs + val assert_ : fixedpoint -> Boolean.bool_expr array -> unit + val register_relation : fixedpoint -> FuncDecl.func_decl -> unit + val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit + val add_fact : fixedpoint -> FuncDecl.func_decl -> int array -> unit + val query : fixedpoint -> Boolean.bool_expr -> Solver.status + val query_r : fixedpoint -> FuncDecl.func_decl array -> Solver.status val push : fixedpoint -> unit val pop : fixedpoint -> unit - val update_rule : fixedpoint -> bool_expr -> symbol -> unit - val get_answer : fixedpoint -> expr option + val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit + val get_answer : fixedpoint -> Expr.expr option val get_reason_unknown : fixedpoint -> string - val get_num_levels : fixedpoint -> func_decl -> int - val get_cover_delta : fixedpoint -> int -> func_decl -> expr option - val add_cover : fixedpoint -> int -> func_decl -> expr -> unit + val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int + val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option + val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit val to_string : fixedpoint -> string - val set_predicate_representation : fixedpoint -> func_decl -> symbol array -> unit - val to_string_q : fixedpoint -> bool_expr array -> string - val get_rules : fixedpoint -> bool_expr array - val get_assertions : fixedpoint -> bool_expr array + val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol array -> unit + val to_string_q : fixedpoint -> Boolean.bool_expr array -> string + val get_rules : fixedpoint -> Boolean.bool_expr array + val get_assertions : fixedpoint -> Boolean.bool_expr array val mk_fixedpoint : context -> fixedpoint end @@ -958,19 +1310,19 @@ end module SMT : sig - val benchmark_to_smtstring : context -> string -> string -> string -> string -> bool_expr array -> bool_expr -> string - val parse_smtlib_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit - val parse_smtlib_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> unit + val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr array -> Boolean.bool_expr -> string + val parse_smtlib_string : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> unit + val parse_smtlib_file : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> unit val get_num_smtlib_formulas : context -> int - val get_smtlib_formulas : context -> bool_expr array + val get_smtlib_formulas : context -> Boolean.bool_expr array val get_num_smtlib_assumptions : context -> int - val get_smtlib_assumptions : context -> bool_expr array + val get_smtlib_assumptions : context -> Boolean.bool_expr array val get_num_smtlib_decls : context -> int - val get_smtlib_decls : context -> func_decl array + val get_smtlib_decls : context -> FuncDecl.func_decl array val get_num_smtlib_sorts : context -> int - val get_smtlib_sorts : context -> sort array - val parse_smtlib2_string : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> bool_expr - val parse_smtlib2_file : context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> bool_expr + val get_smtlib_sorts : context -> Sort.sort array + val parse_smtlib2_string : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> Boolean.bool_expr + val parse_smtlib2_file : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> Boolean.bool_expr end val set_global_param : string -> string -> unit From dc03e2903f619d1191b143c62c84e8ce9f092c57 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 19:49:09 +0000 Subject: [PATCH 401/507] ML API: proper use of datatype API for list/enum/constructor. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/Makefile | 2 +- src/api/ml/z3.ml | 47 ++++++++++++++++++++------------------------- src/api/ml/z3.mli | 7 +++++-- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile index abcefa4af..96fd0a55d 100644 --- a/src/api/ml/Makefile +++ b/src/api/ml/Makefile @@ -7,4 +7,4 @@ all: doc: *.ml mkdir -p doc - ocamldoc -html -d doc -I ../../../bld_dbg/api/ml -sort *.mli -hide Z3 + ocamldoc -html -d doc -I _build -sort *.mli -hide Z3 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c261fce05..344e542f7 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -2159,15 +2159,10 @@ end module Enumeration = struct type enum_sort = EnumSort of sort - - let _constdecls = Hashtbl.create 0 - let _testerdecls = Hashtbl.create 0 let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = let s = (sort_of_ptr ctx no) in let res = EnumSort(s) in - Hashtbl.add _constdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f cdecls)) ; - Hashtbl.add _testerdecls res (let f e = func_decl_of_ptr ctx e in (Array.map f tdecls)) ; res let sort_of_enum_sort s = match s with EnumSort(x) -> x @@ -2191,33 +2186,27 @@ struct mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) (** The function declarations of the constants in the enumeration. *) - let get_const_decls ( x : enum_sort ) = Hashtbl.find _constdecls x + let get_const_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in + Array.init n f (** The test predicates for the constants in the enumeration. *) - let get_tester_decls ( x : enum_sort ) = Hashtbl.find _testerdecls x + let get_tester_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in + Array.init n f + end (** Functions to manipulate List expressions *) module List_ = struct type list_sort = ListSort of sort - - let _nildecls = Hashtbl.create 0 - let _is_nildecls = Hashtbl.create 0 - let _consdecls = Hashtbl.create 0 - let _is_consdecls = Hashtbl.create 0 - let _headdecls = Hashtbl.create 0 - let _taildecls = Hashtbl.create 0 let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = let s = (sort_of_ptr ctx no) in let res = ListSort(s) in - Hashtbl.add _nildecls res (func_decl_of_ptr ctx nildecl) ; - Hashtbl.add _is_nildecls res (func_decl_of_ptr ctx is_nildecl) ; - Hashtbl.add _consdecls res (func_decl_of_ptr ctx consdecl) ; - Hashtbl.add _is_consdecls res (func_decl_of_ptr ctx is_consdecl) ; - Hashtbl.add _headdecls res (func_decl_of_ptr ctx headdecl) ; - Hashtbl.add _taildecls res (func_decl_of_ptr ctx taildecl) ; res let sort_of_list_sort s = match s with ListSort(x) -> x @@ -2237,22 +2226,28 @@ struct mk_sort ctx (Symbol.mk_string ctx name) elem_sort (** The declaration of the nil function of this list sort. *) - let get_nil_decl ( x : list_sort ) = (Hashtbl.find _nildecls x) + let get_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) (** The declaration of the isNil function of this list sort. *) - let get_is_nil_decl ( x : list_sort ) = (Hashtbl.find _is_nildecls x) + let get_is_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) (** The declaration of the cons function of this list sort. *) - let get_cons_decl ( x : list_sort ) = (Hashtbl.find _consdecls x) + let get_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) (** The declaration of the isCons function of this list sort. *) - let get_is_cons_decl ( x : list_sort ) = (Hashtbl.find _is_consdecls x) + let get_is_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) (** The declaration of the head function of this list sort. *) - let get_head_decl ( x : list_sort ) = (Hashtbl.find _headdecls x) + let get_head_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) (** The declaration of the tail function of this list sort. *) - let get_tail_decl ( x : list_sort ) = (Hashtbl.find _taildecls x) + let get_tail_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) (** The empty list. *) let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 5b1b2073a..87318d2a7 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -5,9 +5,9 @@ @author CM Wintersteiger (cwinter) 2012-12-17 *) -type context -(** Create a context object. + +(** Context objects. Most interactions with Z3 are interpreted in some context; many users will only require one such object, but power users may require more than one. To start using @@ -27,6 +27,9 @@ type context (...) *) +type context + +(** Create a context object *) val mk_context : (string * string) list -> context From 303b4e6735246634bcb3f76aa25e687c8c8e2b44 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 20 Feb 2013 22:07:18 +0000 Subject: [PATCH 402/507] ML API savepoint Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2595 +-------------------------------------------- src/api/ml/z3.mli | 2049 ++++++++++++++++++++++++++++++++--- 2 files changed, 1942 insertions(+), 2702 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 344e542f7..b1e40fcac 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -338,7 +338,7 @@ struct else ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - let wrap ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr + let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr let unwrap_ast ( x : ast ) = (z3obj_gno x) end @@ -744,6 +744,7 @@ sig val is_not : expr -> bool val is_implies : expr -> bool val is_label : expr -> bool + val is_label_lit : expr -> bool val is_oeq : expr -> bool val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val mk_const_s : context -> string -> Sort.sort -> expr @@ -794,257 +795,97 @@ end = struct let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (Array.length args) (expr_aton args) in expr_of_ptr ctx o - (** - Returns a simplified version of the expression. - @param p A set of parameters to configure the simplifier - - *) let simplify ( x : expr ) ( p : Params.params option ) = match p with | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) - (** - a string describing all available parameters to Expr.Simplify. - *) let get_simplify_help ( ctx : context ) = Z3native.simplify_get_help (context_gno ctx) - (** - Retrieves parameter descriptions for simplifier. - *) let get_simplify_parameter_descrs ( ctx : context ) = Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - - (** - The function declaration of the function that is applied in this expression. - *) let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) - (** - Indicates whether the expression is the true or false expression - or something else (L_UNDEF). - *) let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (nc_of_expr x) (ptr_of_expr x)) - (** - The number of arguments of the expression. - *) let get_num_args ( x : expr ) = Z3native.get_app_num_args (nc_of_expr x) (ptr_of_expr x) - (** - The arguments of the expression. - *) let get_args ( x : expr ) = let n = (get_num_args x) in let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in Array.init n f - (** - Update the arguments of the expression using the arguments - The number of new arguments should coincide with the current number of arguments. - *) let update ( x : expr ) args = if (Array.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (Array.length args) (expr_aton args)) - (** - Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. - - The result is the new expression. The arrays from and to must have size num_exprs. - For every i smaller than num_exprs, we must have that - sort of from[i] must be equal to sort of to[i]. - *) let substitute ( x : expr ) from to_ = if (Array.length from) <> (Array.length to_) then raise (Z3native.Exception "Argument sizes do not match") else expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (Array.length from) (expr_aton from) (expr_aton to_)) - (** - Substitute every occurrence of from in the expression with to. - - *) let substitute_one ( x : expr ) from to_ = substitute ( x : expr ) [| from |] [| to_ |] - (** - Substitute the free variables in the expression with the expressions in - - For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. - *) let substitute_vars ( x : expr ) to_ = expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (Array.length to_) (expr_aton to_)) - (** - Translates (copies) the term to the Context . - @param ctx A context - @return A copy of the term which is associated with - *) let translate ( x : expr ) to_ctx = if (c_of_expr x) == to_ctx then x else expr_of_ptr to_ctx (Z3native.translate (nc_of_expr x) (ptr_of_expr x) (context_gno to_ctx)) - (** - Returns a string representation of the expression. - *) let to_string ( x : expr ) = Z3native.ast_to_string (nc_of_expr x) (ptr_of_expr x) - (** - Indicates whether the term is a numeral - *) let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (ptr_of_expr x)) - (** - Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. - *) let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (nc_of_expr x) (ptr_of_expr x) - (** - The Sort of the term. - *) let get_sort ( x : expr ) = sort_of_ptr (c_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)) - (** - Indicates whether the term has Boolean sort. - *) let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (Z3native.is_eq_sort (nc_of_expr x) (Z3native.mk_bool_sort (nc_of_expr x)) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x))) - (** - Indicates whether the term represents a constant. - *) let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - - (** - Indicates whether the term is the constant true. - *) + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - - (** - Indicates whether the term is the constant false. - *) let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - - (** - Indicates whether the term is an equality predicate. - *) let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - - (** - Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). - *) let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - - (** - Indicates whether the term is a ternary if-then-else term - *) let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - - (** - Indicates whether the term is an n-ary conjunction - *) let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - - (** - Indicates whether the term is an n-ary disjunction - *) let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - - (** - Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) - *) let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - - (** - Indicates whether the term is an exclusive or - *) let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - - (** - Indicates whether the term is a negation - *) let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - - (** - Indicates whether the term is an implication - *) let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - - (** - Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. - *) let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) - - (** - Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) - *) - - (** - Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. - *) + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) - (** - Creates a new Constant of sort and named . - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) - - (** - Creates a new Constant of sort and named . - *) let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) range - - (** - Creates a constant from the func_decl . - @param f An expression of a 0-arity function - *) let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [||] - (** - Creates a fresh constant of sort and a - name prefixed with . - *) let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - (** - Create a new function application. - *) let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = expr_of_func_app ctx f args - (** - Create a numeral of a given sort. - @param v A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - @param ty The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - @return A Term with value and sort - *) let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) - (** - Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. - @param v Value of the numeral - @param ty Sort of the numeral - @return A Term with value and type - *) let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) end @@ -1052,7 +893,6 @@ end open FuncDecl open Expr -(** Boolean expressions *) module Boolean = struct type bool_sort = BoolSort of Sort.sort @@ -1091,97 +931,53 @@ struct let mk_sort ( ctx : context ) = BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) - (** - Create a Boolean constant. - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) = let s = (match (mk_sort ctx) with BoolSort(q) -> q) in BoolExpr(Expr.mk_const ctx name s) - (** - Create a Boolean constant. - *) let mk_const_s ( ctx : context ) ( name : string ) = mk_const ctx (Symbol.mk_string ctx name) - (** - The true Term. - *) let mk_true ( ctx : context ) = bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) - (** - The false Term. - *) let mk_false ( ctx : context ) = bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) - (** - Creates a Boolean value. - *) let mk_val ( ctx : context ) ( value : bool ) = if value then mk_true ctx else mk_false ctx - (** - Creates the equality = . - *) let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) - (** - Creates a distinct term. - *) let mk_distinct ( ctx : context ) ( args : expr array ) = bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (expr_aton args)) - (** - Mk an expression representing not(a). - *) let mk_not ( ctx : context ) ( a : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - (** - Create an expression representing an if-then-else: ite(t1, t2, t3). - @param t1 An expression with Boolean sort - @param t2 An expression - @param t3 An expression with the same sort as - *) let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - (** - Create an expression representing t1 iff t2. - *) let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - (** - Create an expression representing t1 -> t2. - *) let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - (** - Create an expression representing t1 xor t2. - *) + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - (** - Create an expression representing the AND of args - *) let mk_and ( ctx : context ) ( args : bool_expr array ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (Array.map f args)) - (** - Create an expression representing the OR of args - *) let mk_or ( ctx : context ) ( args : bool_expr array ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (Array.map f args)) end -(** Quantifier expressions *) + module Quantifier = struct type quantifier = Quantifier of expr @@ -1200,12 +996,6 @@ struct let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. - *) module Pattern = struct type pattern = Pattern of ast @@ -1220,155 +1010,68 @@ struct let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - (** - The number of terms in the pattern. - *) let get_num_terms ( x : pattern ) = Z3native.get_pattern_num_terms (gnc x) (gno x) - (** - The terms in the pattern. - *) let get_terms ( x : pattern ) = let n = (get_num_terms x) in let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in Array.init n f - (** - A string representation of the pattern. - *) let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) end - (** - The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. - *) let get_index ( x : expr ) = if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) - (** - Indicates whether the quantifier is universal. - *) let is_universal ( x : quantifier ) = Z3native.is_quantifier_forall (gnc x) (gno x) - (** - Indicates whether the quantifier is existential. - *) let is_existential ( x : quantifier ) = not (is_universal x) - (** - The weight of the quantifier. - *) let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) - (** - The number of patterns. - *) let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) - (** - The patterns. - *) let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in Array.init n f - (** - The number of no-patterns. - *) let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) - (** - The no-patterns. - *) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in Array.init n f - (** - The number of bound variables. - *) let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) - (** - The symbols for the bound variables. - *) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in Array.init n f - (** - The sorts of the bound variables. - *) let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in Array.init n f - (** - The body of the quantifier. - *) let get_body ( x : quantifier ) = Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) - (** - Creates a new bound variable. - @param index The de-Bruijn index of the variable - @param ty The sort of the variable - *) let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - (** - Create a quantifier pattern. - *) let mk_pattern ( ctx : context ) ( terms : expr array ) = if (Array.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) - (** - Create a universal Quantifier. - - Creates a forall formula, where is the weight, - is an array of patterns, is an array - with the sorts of the bound variables, is an array with the - 'names' of the bound variables, and is the body of the - quantifier. Quantifiers are associated with weights indicating - the importance of using the quantifier during instantiation. - - @param sorts the sorts of the bound variables. - @param names names of the bound variables - @param body the body of the quantifier. - @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - @param patterns array containing the patterns created using MkPattern. - @param noPatterns array containing the anti-patterns created using MkPattern. - @param quantifierID optional symbol to track quantifier. - @param skolemID optional symbol to track skolem constants. - *) let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") @@ -1390,9 +1093,6 @@ struct (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) - (** - Create a universal Quantifier. - *) let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true @@ -1410,10 +1110,6 @@ struct (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) - (** - Create an existential Quantifier. - - *) let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (Array.length sorts) != (Array.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") @@ -1435,9 +1131,6 @@ struct (let f x = (Symbol.gno x) in (Array.map f names)) (ptr_of_expr body))) - (** - Create an existential Quantifier. - *) let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false @@ -1455,19 +1148,12 @@ struct (Array.length nopatterns) (expr_aton nopatterns) (ptr_of_expr body))) - (** - Create a Quantifier. - *) let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - - (** - Create a Quantifier. - *) let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id @@ -1475,7 +1161,7 @@ struct mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id end -(** Functions to manipulate Array expressions *) + module Array_ = struct type array_sort = ArraySort of sort @@ -1516,144 +1202,46 @@ struct let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - (** - Create a new array sort. - *) let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - (** - Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. - *) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - - (** - Indicates whether the term is an array select. - *) let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - - (** - Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. - *) let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - - (** - Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. - *) let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - - (** - Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. - *) let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - - (** - Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. - *) let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) - - (** - Indicates whether the term is of an array sort. - *) let is_array ( x : expr ) = (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) - (** The domain of the array sort. *) let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) - - (** The range of the array sort. *) let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) - (** - Create an array constant. - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) - (** - Create an array constant. - *) let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range - (** - Array read. - - The argument a is the array and i is the index - of the array that gets read. - - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. - - - *) let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) - - (** - Array update. - - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). - - - *) - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = + array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) + + let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) - (** - Create a constant array. - - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. - - - *) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) - (** - Maps f on the argument arrays. - - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. - - - - *) let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = let m x = (ptr_of_expr (expr_of_array_expr x)) in array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) - (** - Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. - *) let mk_term_array ( ctx : context ) ( arg : array_expr ) = array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) end -(** Functions to manipulate Set expressions *) + module Set = struct type set_sort = SetSort of sort @@ -1664,100 +1252,49 @@ struct let sort_of_set_sort s = match s with SetSort(x) -> x - (** - Indicates whether the term is set union - *) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - - (** - Indicates whether the term is set intersection - *) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - - (** - Indicates whether the term is set difference - *) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - - (** - Indicates whether the term is set complement - *) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - - (** - Indicates whether the term is set subset - *) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) - - (** - Create a set type. - *) let mk_sort ( ctx : context ) ( ty : sort ) = set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - (** - Create an empty set. - *) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + + let mk_empty ( ctx : context ) ( domain : sort ) = (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) - (** - Create the full set. - *) let mk_full ( ctx : context ) ( domain : sort ) = expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) - (** - Add an element to the set. - *) let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) - (** - Remove an element from a set. - *) let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) - (** - Take the union of a list of sets. - *) let mk_union ( ctx : context ) ( args : expr array ) = expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (expr_aton args)) - (** - Take the intersection of a list of sets. - *) let mk_intersection ( ctx : context ) ( args : expr array ) = expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (expr_aton args)) - (** - Take the difference between two sets. - *) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) - (** - Take the complement of a set. - *) let mk_complement ( ctx : context ) ( arg : expr ) = expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (ptr_of_expr arg)) - (** - Check for set membership. - *) let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (ptr_of_expr elem) (ptr_of_expr set)) - (** - Check for subsetness of sets. - *) let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) end -(** Functions to manipulate Finite Domain expressions *) + module FiniteDomain = struct type finite_domain_sort = FiniteDomainSort of sort @@ -1774,41 +1311,28 @@ struct let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - (** - Create a new finite domain sort. - *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in FiniteDomainSort(s) - (** - Create a new finite domain sort. - *) let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = mk_sort ctx (Symbol.mk_string ctx name) size - (** - Indicates whether the term is of an array sort. - *) let is_finite_domain ( x : expr ) = let nc = (nc_of_expr x) in (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == FINITE_DOMAIN_SORT) - (** - Indicates whether the term is a less than predicate over a finite domain. - *) let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - (** The size of the finite domain sort. *) let get_size ( x : finite_domain_sort ) = let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in if r then v else raise (Z3native.Exception "Conversion failed.") end -(** Functions to manipulate Relation expressions *) + module Relation = struct type relation_sort = RelationSort of sort @@ -1830,119 +1354,27 @@ struct let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - (** - Indicates whether the term is of a relation sort. - *) let is_relation ( x : expr ) = let nc = (nc_of_expr x) in ((Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == RELATION_SORT)) - (** - Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. - *) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - - (** - Indicates whether the term is an empty relation - *) let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - - (** - Indicates whether the term is a test for the emptiness of a relation - *) let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - - (** - Indicates whether the term is a relational join - *) let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - - (** - Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. - *) let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - - (** - Indicates whether the term is the widening of two relations - The function takes two arguments. - *) let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - - (** - Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. - *) let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - - (** - Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. - *) let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - - (** - Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. - *) let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - - (** - Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. - *) let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - - (** - Indicates whether the term is the complement of a relation - *) let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - - (** - Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. - *) let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - - (** - Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind - to perform destructive updates to the first argument. - *) let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - (** The arity of the relation sort. *) let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) - (** The sorts of the columns of the relation sort. *) let get_column_sorts ( x : relation_sort ) = let n = get_arity x in let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in @@ -1950,7 +1382,7 @@ struct end -(** Functions to manipulate Datatype expressions *) + module Datatype = struct type datatype_sort = DatatypeSort of sort @@ -1983,14 +1415,10 @@ struct let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - - (** Constructors *) module Constructor = struct type constructor = z3_native_object - let _counts = Hashtbl.create 0 - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = let n = (Array.length field_names) in if n != (Array.length sorts) then @@ -2009,42 +1437,29 @@ struct m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in - Hashtbl.add _counts no n ; (z3obj_sno no ctx ptr) ; (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; no + + let get_num_fields ( x : constructor ) = Z3native.get_arity (z3obj_gnc x) (z3obj_gno x) - let get_n ( x : constructor ) = (Hashtbl.find _counts x) - - let rec constructor_decl ( x : constructor ) = - let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + let get_constructor_decl ( x : constructor ) = + let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in func_decl_of_ptr (z3obj_gc x) a - let rec tester_decl ( x : constructor ) = - let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + let get_tester_decl ( x : constructor ) = + let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in func_decl_of_ptr (z3obj_gc x) b - - let rec accessor_decls ( x : constructor ) = - let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (Hashtbl.find _counts x)) in + + let get_accessor_decls ( x : constructor ) = + let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in let f y = func_decl_of_ptr (z3obj_gc x) y in Array.map f c - (** The number of fields of the constructor. *) - let get_num_fields ( x : constructor ) = get_n x - - (** The function declaration of the constructor. *) - let get_constructor_decl ( x : constructor ) = constructor_decl x - - (** The function declaration of the tester. *) - let get_tester_decl ( x : constructor ) = tester_decl x - - (** The function declarations of the accessors *) - let get_accessor_decls ( x : constructor ) = accessor_decls x end - (** Constructor list objects *) module ConstructorList = struct type constructor_list = z3_native_object @@ -2062,54 +1477,21 @@ struct res end - (* DATATYPES *) - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = Constructor.create ctx name recognizer field_names sorts sort_refs - (** - Create a datatype constructor. - @param name constructor name - @param recognizer name of recognizer function. - @param fieldNames names of the constructor fields. - @param sorts field sorts, 0 if the field sort refers to a recursive sort. - @param sortRefs reference to datatype sort that is an argument to the constructor; - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. - *) let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - - (** - Create a new datatype sort. - *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array ) = let f x = (z3obj_gno x) in let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in sort_of_ptr ctx x - (** - Create a new datatype sort. - *) let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = mk_sort ctx (Symbol.mk_string ctx name) constructors - (** - Create mutually recursive datatypes. - @param names names of datatype sorts - @param c list of constructors, one list per sort. - *) let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = let n = (Array.length names) in let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in @@ -2119,7 +1501,6 @@ struct let g e = (sort_of_ptr ctx e) in (Array.map g r) - (** Create mutually recursive data-types. *) let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = mk_sorts ctx ( @@ -2128,22 +1509,18 @@ struct ) c - (** The number of constructors of the datatype sort. *) let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) - (** The range of the array sort. *) let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in Array.init n f - (** The recognizers. *) let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in Array.init n f - (** The constructor accessors. *) let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = ( @@ -2155,7 +1532,7 @@ struct Array.init n f end -(** Functions to manipulate Enumeration expressions *) + module Enumeration = struct type enum_sort = EnumSort of sort @@ -2171,27 +1548,19 @@ struct let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - (** - Create a new enumeration sort. - *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = let f x = Symbol.gno x in let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in sort_of_ptr ctx a b c - (** - Create a new enumeration sort. - *) let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string array ) = mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - (** The function declarations of the constants in the enumeration. *) let get_const_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in Array.init n f - (** The test predicates for the constants in the enumeration. *) let get_tester_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in @@ -2199,7 +1568,7 @@ struct end -(** Functions to manipulate List expressions *) + module List_ = struct type list_sort = ListSort of sort @@ -2214,46 +1583,36 @@ struct let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - - - (** Create a new list sort. *) + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in sort_of_ptr ctx r a b c d e f - (** Create a new list sort. *) let mk_list_s ( ctx : context ) (name : string) elem_sort = mk_sort ctx (Symbol.mk_string ctx name) elem_sort - (** The declaration of the nil function of this list sort. *) let get_nil_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) - (** The declaration of the isNil function of this list sort. *) let get_is_nil_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) - (** The declaration of the cons function of this list sort. *) let get_cons_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) - (** The declaration of the isCons function of this list sort. *) let get_is_cons_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) - (** The declaration of the head function of this list sort. *) let get_head_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) - (** The declaration of the tail function of this list sort. *) let get_tail_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) - (** The empty list. *) let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] end -(** Functions to manipulate Tuple expressions *) + module Tuple = struct type tuple_sort = TupleSort of sort @@ -2268,30 +1627,24 @@ struct let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - - (** Create a new tuple sort. *) let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : sort array ) = let f x = Symbol.gno x in let f2 x = ptr_of_ast (ast_of_sort x) in - let (r, a, b) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in - (* CMW: leaks a,b? *) + let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in sort_of_ptr ctx r - (** The constructor function of the tuple. *) let get_mk_decl ( x : tuple_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) - (** The number of fields in the tuple. *) let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) - (** The field declarations. *) let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in Array.init n f end -(** Functions to manipulate arithmetic expressions *) + module rec Arithmetic : sig type arith_sort = ArithSort of Sort.sort @@ -2516,84 +1869,37 @@ end = struct let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - - (** Create a new integer sort. *) let mk_sort ( ctx : context ) = int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - (** Retrieve the int value. *) let get_int ( x : int_num ) = let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - (** Returns a string representation of the numeral. *) let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - (** - Creates an integer constant. - *) let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) - (** - Creates an integer constant. - *) let mk_int_const_s ( ctx : context ) ( name : string ) = mk_int_const ctx (Symbol.mk_string ctx name) - (** - Create an expression representing t1 mod t2. - The arguments must have int type. - *) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) - (** - Create an expression representing t1 rem t2. - The arguments must have int type. - *) let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) - (** - Create an integer numeral. - @param v A string representing the Term value in decimal notation. - *) let mk_int_numeral_s ( ctx : context ) ( v : string ) = int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - (** - Create an integer numeral. - @param v value of the numeral. - @return A Term with value and sort Integer - *) let mk_int_numeral_i ( ctx : context ) ( v : int ) = int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - (** - Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. - *) let mk_int2real ( ctx : context ) ( t : int_expr ) = Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) - (** - Create an bit bit-vector from the integer argument . - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. - *) let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) end @@ -2677,76 +1983,41 @@ end = struct let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - (** Create a real sort. *) let mk_sort ( ctx : context ) = real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - (** The numerator of a rational numeral. *) let get_numerator ( x : rat_num ) = Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) - (** The denominator of a rational numeral. *) let get_denominator ( x : rat_num ) = Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) let to_decimal_string ( x : rat_num ) ( precision : int ) = Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - (** Returns a string representation of the numeral. *) let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - (** Creates a real constant. *) let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) - (** Creates a real constant. *) let mk_real_const_s ( ctx : context ) ( name : string ) = mk_real_const ctx (Symbol.mk_string ctx name) - (** - Create a real from a fraction. - - @param num numerator of rational. - @param den denominator of rational. - @return A Term with value / and sort Real - - *) let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = if (den == 0) then raise (Z3native.Exception "Denominator is zero") else rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) - (** - Create a real numeral. - @param v A string representing the Term value in decimal notation. - @return A Term with value and sort Real - *) let mk_numeral_s ( ctx : context ) ( v : string ) = rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - (** - Create a real numeral. - - @param v value of the numeral. - @return A Term with value and sort Real - *) let mk_numeral_i ( ctx : context ) ( v : int ) = rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - (** Creates an expression that checks whether a real number is an integer. *) let mk_is_integer ( ctx : context ) ( t : real_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) - (** - Coerce a real to an integer. - - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. - *) let mk_real2int ( ctx : context ) ( t : real_expr ) = Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) end @@ -2782,208 +2053,97 @@ end = struct let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - (** - Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) let to_upper ( x : algebraic_num ) ( precision : int ) = Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) - (** - Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^. - - @param precision the precision of the result - @return A numeral Expr of sort Real - *) let to_lower ( x : algebraic_num ) precision = Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) - (** Returns a string representation in decimal notation. - The result has at most decimal places.*) let to_decimal_string ( x : algebraic_num ) ( precision : int ) = Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - (** Returns a string representation of the numeral. *) let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) end - (** - Indicates whether the term is of integer sort. - *) let is_int ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (nc_of_expr x)) && ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == INT_SORT) - (** - Indicates whether the term is an arithmetic numeral. - *) let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - (** - Indicates whether the term is a less-than-or-equal - *) let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - (** - Indicates whether the term is a greater-than-or-equal - *) let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - (** - Indicates whether the term is a less-than - *) let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - (** - Indicates whether the term is a greater-than - *) let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - (** - Indicates whether the term is addition (binary) - *) let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - (** - Indicates whether the term is subtraction (binary) - *) let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - (** - Indicates whether the term is a unary minus - *) let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - (** - Indicates whether the term is multiplication (binary) - *) let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - (** - Indicates whether the term is division (binary) - *) let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - (** - Indicates whether the term is integer division (binary) - *) let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - (** - Indicates whether the term is remainder (binary) - *) let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - (** - Indicates whether the term is modulus (binary) - *) let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - (** - Indicates whether the term is a coercion of integer to real (unary) - *) let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - (** - Indicates whether the term is a coercion of real to integer (unary) - *) let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - (** - Indicates whether the term is a check that tests whether a real is integral (unary) - *) let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - (** - Indicates whether the term is of sort real. - *) let is_real ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == REAL_SORT) - - (** - Indicates whether the term is an integer numeral. - *) let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - (** - Indicates whether the term is a real numeral. - *) let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - (** - Indicates whether the term is an algebraic number - *) let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) - (** - Create an expression representing t[0] + t[1] + .... - *) let mk_add ( ctx : context ) ( t : arith_expr array ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Array.map f t))) - (** - Create an expression representing t[0] * t[1] * .... - *) let mk_mul ( ctx : context ) ( t : arith_expr array ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Array.map f t))) - (** - Create an expression representing t[0] - t[1] - .... - *) let mk_sub ( ctx : context ) ( t : arith_expr array ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Array.map f t))) - (** - Create an expression representing -t. - *) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) - (** - Create an expression representing t1 / t2. - *) let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 ^ t2. - *) let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 < t2 - *) let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 <= t2 - *) let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 > t2 - *) let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) - (** - Create an expression representing t1 >= t2 - *) let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) end -(** Functions to manipulate bit-vector expressions *) + and BitVector : sig type bitvec_sort = BitVecSort of Sort.sort @@ -3089,8 +2249,10 @@ sig val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr @@ -3154,1225 +2316,213 @@ end = struct let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - (** - Create a new bit-vector sort. - *) let mk_sort ( ctx : context ) size = bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) - - (** - Indicates whether the terms is of bit-vector sort. - *) let is_bv ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == BV_SORT) - - (** - Indicates whether the term is a bit-vector numeral - *) let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - - (** - Indicates whether the term is a one-bit bit-vector with value one - *) let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - - (** - Indicates whether the term is a one-bit bit-vector with value zero - *) let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - - (** - Indicates whether the term is a bit-vector unary minus - *) let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - - (** - Indicates whether the term is a bit-vector addition (binary) - *) let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - - (** - Indicates whether the term is a bit-vector subtraction (binary) - *) let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - - (** - Indicates whether the term is a bit-vector multiplication (binary) - *) let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - - (** - Indicates whether the term is a bit-vector signed division (binary) - *) let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - - (** - Indicates whether the term is a bit-vector unsigned division (binary) - *) let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - - (** - Indicates whether the term is a bit-vector signed remainder (binary) - *) let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - - (** - Indicates whether the term is a bit-vector unsigned remainder (binary) - *) let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - - (** - Indicates whether the term is a bit-vector signed modulus - *) let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - - (** - Indicates whether the term is a bit-vector signed division by zero - *) let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - - (** - Indicates whether the term is a bit-vector unsigned division by zero - *) let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - - (** - Indicates whether the term is a bit-vector signed remainder by zero - *) let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - - (** - Indicates whether the term is a bit-vector unsigned remainder by zero - *) let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - - (** - Indicates whether the term is a bit-vector signed modulus by zero - *) let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - - (** - Indicates whether the term is an unsigned bit-vector less-than-or-equal - *) let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - - (** - Indicates whether the term is a signed bit-vector less-than-or-equal - *) let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - - (** - Indicates whether the term is an unsigned bit-vector greater-than-or-equal - *) let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - - (** - Indicates whether the term is a signed bit-vector greater-than-or-equal - *) let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - - (** - Indicates whether the term is an unsigned bit-vector less-than - *) let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - - (** - Indicates whether the term is a signed bit-vector less-than - *) let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - - (** - Indicates whether the term is an unsigned bit-vector greater-than - *) let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - - (** - Indicates whether the term is a signed bit-vector greater-than - *) let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - - (** - Indicates whether the term is a bit-wise AND - *) let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - - (** - Indicates whether the term is a bit-wise OR - *) let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - - (** - Indicates whether the term is a bit-wise NOT - *) let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - - (** - Indicates whether the term is a bit-wise XOR - *) let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - - (** - Indicates whether the term is a bit-wise NAND - *) let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - - (** - Indicates whether the term is a bit-wise NOR - *) let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - - (** - Indicates whether the term is a bit-wise XNOR - *) let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - - (** - Indicates whether the term is a bit-vector concatenation (binary) - *) let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - - (** - Indicates whether the term is a bit-vector sign extension - *) let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - - (** - Indicates whether the term is a bit-vector zero extension - *) let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - - (** - Indicates whether the term is a bit-vector extraction - *) let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - - (** - Indicates whether the term is a bit-vector repetition - *) let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - - (** - Indicates whether the term is a bit-vector reduce OR - *) let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - - (** - Indicates whether the term is a bit-vector reduce AND - *) let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - - (** - Indicates whether the term is a bit-vector comparison - *) let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - - (** - Indicates whether the term is a bit-vector shift left - *) let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - - (** - Indicates whether the term is a bit-vector logical shift right - *) let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - - (** - Indicates whether the term is a bit-vector arithmetic shift left - *) let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - - (** - Indicates whether the term is a bit-vector rotate left - *) let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - - (** - Indicates whether the term is a bit-vector rotate right - *) let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - - (** - Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. - *) let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - - (** - Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. - *) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - - (** - Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - *) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - - (** - Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. - *) let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - - (** - Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) - *) let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - - (** - Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) - *) let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - - (** The size of a bit-vector sort. *) let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) - - (** Retrieve the int value. *) let get_int ( x : bitvec_num ) = let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - - (** Returns a string representation of the numeral. *) let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - - (** - Creates a bit-vector constant. - *) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) - - (** - Creates a bit-vector constant. - *) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = mk_const ctx (Symbol.mk_string ctx name) size - - (** - Bitwise negation. - The argument must have a bit-vector sort. - *) let mk_not ( ctx : context ) ( t : bitvec_expr ) = expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) - - (** - Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. - *) let mk_redand ( ctx : context ) ( t : bitvec_expr) = expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) - - (** - Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. - *) let mk_redor ( ctx : context ) ( t : bitvec_expr) = expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) - - (** - Bitwise conjunction. - The arguments must have a bit-vector sort. - *) let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise disjunction. - The arguments must have a bit-vector sort. - *) let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise XOR. - The arguments must have a bit-vector sort. - *) let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise NAND. - The arguments must have a bit-vector sort. - *) let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise NOR. - The arguments must have a bit-vector sort. - *) let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) - - (** - Bitwise XNOR. - The arguments must have a bit-vector sort. - *) let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) - - (** - Standard two's complement unary minus. - The arguments must have a bit-vector sort. - *) let mk_neg ( ctx : context ) ( t : bitvec_expr) = bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) - - (** - Two's complement addition. - The arguments must have the same bit-vector sort. - *) let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) - - (** - Two's complement subtraction. - The arguments must have the same bit-vector sort. - *) let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) - - (** - Two's complement multiplication. - The arguments must have the same bit-vector sort. - *) let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) - - (** - Unsigned division. - - - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. - *) let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) - - (** - Signed division. - - It is defined in the following way: - - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) - - (** - Unsigned remainder. - - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) - - (** - Signed remainder. - - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) - - (** - Two's complement signed remainder (sign follows divisor). - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. - *) let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) - - (** - Unsigned less-than - - The arguments must have the same bit-vector sort. - *) let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed less-than - - The arguments must have the same bit-vector sort. - *) let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) - - (** - Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) - - (** - Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. - *) let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) - - (** - Unsigned greater-than. - - The arguments must have the same bit-vector sort. - *) let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) - - (** - Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. - *) let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) - - (** - Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). - *) let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) - - (** - Bit-vector extraction. - - Extract the bits down to from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. - The argument must have a bit-vector sort. - *) let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) - - (** - Bit-vector sign extension. - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. - The argument must have a bit-vector sort. - *) let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) - - (** - Bit-vector zero extension. - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the - given bit-vector. - The argument must have a bit-vector sort. - *) let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) - - (** - Bit-vector repetition. - - The argument must have a bit-vector sort. - *) let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) - - (** - Shift left. - - - It is equivalent to multiplication by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - *) let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - - - (** - Logical shift right - - It is equivalent to unsigned division by 2^x where \c x is the value of . - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - *) let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) - - (** - Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. - *) let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) - - (** - Rotate Left. - - Rotate bits of \c t to the left \c i times. - The argument must have a bit-vector sort. - *) let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) - - (** - Rotate Right. - - Rotate bits of \c t to the right \c i times. - The argument must have a bit-vector sort. - *) let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) - - (** - Rotate Left. - - Rotate bits of to the left times. - The arguments must have the same bit-vector sort. - *) - let mk_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) - - (** - Rotate Right. - - - Rotate bits of to the right times. - The arguments must have the same bit-vector sort. - *) - let mk_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) - - (** - Create an integer from the bit-vector argument . - - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where - N are the number of bits in . - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of bit-vector sort. - *) let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) - - (** - Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - - (** - Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. - *) let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. - *) let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) - - (** - Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) - - (** - Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. - *) let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - - (** - Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. - *) let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) - - (** - Create a bit-vector numeral. - - @param v A string representing the value in decimal notation. - @param size the size of the bit-vector - *) let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) end -(** Functions to manipulate proof expressions *) + module Proof = struct - (** - Indicates whether the term is a Proof for the expression 'true'. - *) let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - - (** - Indicates whether the term is a proof for a fact asserted by the user. - *) let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - - (** - Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. - *) let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - - (** - Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). - *) let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - - (** - Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. - *) let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - - (** - Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. - *) let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - - (** - Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) - *) let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - - (** - Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. - *) let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - - - (** - Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. - *) let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - - (** - Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - *) let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - - (** - Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. - *) let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - - (** - Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i - *) let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - - (** - Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) - *) let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - - (** - Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) - *) let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - - (** - Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - *) let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - - (** - Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - *) let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - - (** - Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents - *) let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - - (** - Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents - *) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - - (** - Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. - *) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - - (** - Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. - *) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - - (** - Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) - *) let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - - (** - Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. - *) let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - - (** - Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. - *) let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - - (** - Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - *) let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - - (** - Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) - *) let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - - (** - Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) - *) let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - - (** - Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. - *) let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - - (** - Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). - *) let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - - (** - Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) - *) let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - - (** - Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. - *) let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - - (** - Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) - *) let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - - (** - Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. - *) let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - - (** - Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) - *) let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - - (** - Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - - (** - Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - *) let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - - (** - Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. - *) let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - - (** - Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q - *) let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - - (** - Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - *) let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end -(** Goals - - A goal (aka problem). A goal is essentially a - of formulas, that can be solved and/or transformed using - tactics and solvers. *) module Goal = struct type goal = z3_native_object @@ -4386,76 +2536,52 @@ struct (z3obj_create res) ; res - - (** The precision of the goal. - - Goals can be transformed using over and under approximations. - An under approximation is applied when the objective is to find a model for a given goal. - An over approximation is applied when the objective is to find a proof for a given goal. - *) let get_precision ( x : goal ) = goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) - (** Indicates whether the goal is precise. *) let is_precise ( x : goal ) = (get_precision x) == GOAL_PRECISE - (** Indicates whether the goal is an under-approximation. *) let is_underapproximation ( x : goal ) = (get_precision x) == GOAL_UNDER - (** Indicates whether the goal is an over-approximation. *) let is_overapproximation ( x : goal ) = (get_precision x) == GOAL_OVER - (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - (** Adds the constraints to the given goal. *) - (* CMW: assert seems to be a keyword. *) let assert_ ( x : goal ) ( constraints : Boolean.bool_expr array ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in ignore (Array.map f constraints) ; () - (** Indicates whether the goal contains `false'. *) let is_inconsistent ( x : goal ) = Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) - (** The depth of the goal. - This tracks how many transformations were applied to it. *) let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) - (** Erases all formulas from the given goal. *) let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) - (** The number of formulas in the goal. *) let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) - (** The formulas in the goal. *) let get_formulas ( x : goal ) = let n = get_size x in let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in Array.init n f - (** The number of formulas, subformulas and terms in the goal. *) let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) - (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) let is_decided_sat ( x : goal ) = Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) - (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) let is_decided_unsat ( x : goal ) = Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) - (** Translates (copies) the Goal to the target Context . *) let translate ( x : goal ) ( to_ctx : context ) = create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) let simplify ( x : goal ) ( p : Params.params option ) = let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in Z3native.tactic_inc_ref (z3obj_gnc x) tn ; @@ -4473,27 +2599,13 @@ struct Z3native.tactic_dec_ref (z3obj_gnc x) tn ; create (z3obj_gc x) res - - (** - Creates a new Goal. - - Note that the Context must have been created with proof generation support if - is set to true here. - @param models Indicates whether model generation should be enabled. - @param unsat_cores Indicates whether unsat core generation should be enabled. - @param proofs Indicates whether proof generation should be enabled. - *) let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) - (** A string representation of the Goal. *) let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) module Model = struct type model = z3_native_object @@ -4507,12 +2619,6 @@ struct (z3obj_create res) ; res - - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. - *) module FuncInterp = struct type func_interp = z3_native_object @@ -4526,11 +2632,6 @@ struct (z3obj_create res) ; res - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. - *) module FuncEntry = struct type func_entry = z3_native_object @@ -4544,61 +2645,33 @@ struct (z3obj_create res) ; res - - (** - Return the (symbolic) value of this entry. - *) let get_value ( x : func_entry ) = expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) - (** - The number of arguments of the entry. - *) let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) - (** - The arguments of the function entry. - *) let get_args ( x : func_entry ) = let n = (get_num_args x) in let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f - (** - A string representation of the function entry. - *) let to_string ( x : func_entry ) = let a = (get_args x) in let f c p = (p ^ (Expr.to_string c) ^ ", ") in "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") end - (** - The number of entries in the function interpretation. - *) let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) - (** - The entries in the function interpretation - *) let get_entries ( x : func_interp ) = let n = (get_num_entries x) in let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f - (** - The (symbolic) `else' value of the function interpretation. - *) let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) - (** - The arity of the function interpretation - *) let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) - (** - A string representation of the function interpretation. - *) let to_string ( x : func_interp ) = let f c p = ( let n = (FuncEntry.get_num_args c) in @@ -4613,9 +2686,6 @@ struct Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") end - (** Retrieves the interpretation (the assignment) of in the model. - A function declaration of zero arity - An expression if the function has an interpretation in the model, null otherwise. *) let get_const_interp ( x : model ) ( f : func_decl ) = if (FuncDecl.get_arity f) != 0 || (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then @@ -4627,16 +2697,9 @@ struct else Some (expr_of_ptr (z3obj_gc x) np) - (** Retrieves the interpretation (the assignment) of in the model. - A Constant - An expression if the constant has an interpretation in the model, null otherwise. - *) let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - (** Retrieves the interpretation (the assignment) of a non-constant in the model. - A function declaration of non-zero arity - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) let rec get_func_interp ( x : model ) ( f : func_decl ) = let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in if (FuncDecl.get_arity f) == 0 then @@ -4659,23 +2722,18 @@ struct (** The number of constants that have an interpretation in the model. *) let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) - (** The function declarations of the constants in the model. *) let get_const_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - - (** The number of function interpretations in the model. *) let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) - (** The function declarations of the function interpretations in the model. *) let get_func_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** All symbols that have an interpretation in the model. *) let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in @@ -4683,24 +2741,8 @@ struct let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in Array.append (Array.init n_funcs f) (Array.init n_consts g) - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) exception ModelEvaluationFailedException of string - (** - Evaluates the expression in the current model. - - - This function may fail if contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - - An expression - - When this flag is enabled, a model value will be assigned to any constant - or function that does not have an interpretation in the model. - - The evaluation of in the model. - *) let eval ( x : model ) ( t : expr ) ( completion : bool ) = let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (ptr_of_expr t) completion) in if not r then @@ -4708,53 +2750,26 @@ struct else expr_of_ptr (z3obj_gc x) v - (** Alias for eval. *) let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = eval x t completion - (** The number of uninterpreted sorts that the model has an interpretation for. *) let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - - - *) let get_sorts ( x : model ) = let n = (get_num_sorts x) in let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in Array.init n f - - (** The finite set of distinct values that represent the interpretation for sort . - - An uninterpreted sort - An array of expressions, where each is an element of the universe of - *) let sort_universe ( x : model ) ( s : sort ) = let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in Array.init n f - - (** Conversion of models to strings. - A string representation of the model. - *) + let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) module Probe = struct type probe = z3_native_object @@ -4769,114 +2784,52 @@ struct res - (** - Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - *) let apply ( x : probe ) ( g : Goal.goal ) = Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) - (** - The number of supported Probes. - *) let get_num_probes ( ctx : context ) = Z3native.get_num_probes (context_gno ctx) - (** - The names of all supported Probes. - *) let get_probe_names ( ctx : context ) = let n = (get_num_probes ctx) in let f i = (Z3native.get_probe_name (context_gno ctx) i) in Array.init n f - (** - Returns a string containing a description of the probe with the given name. - *) let get_probe_description ( ctx : context ) ( name : string ) = Z3native.probe_get_descr (context_gno ctx) name - (** - Creates a new Probe. - *) let mk_probe ( ctx : context ) ( name : string ) = (create ctx (Z3native.mk_probe (context_gno ctx) name)) - (** - Create a probe that always evaluates to . - *) let const ( ctx : context ) ( v : float ) = (create ctx (Z3native.probe_const (context_gno ctx) v)) - (** - Create a probe that evaluates to "true" when the value returned by - is less than the value returned by - *) let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is greater than the value returned by - *) let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is less than or equal the value returned by - *) let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is greater than or equal the value returned by - *) let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value returned by - is equal to the value returned by - *) let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value - and evaluate to "true". - *) - (* CMW: and is a keyword *) let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value - or evaluate to "true". - *) - (* CMW: or is a keyword *) let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - (** - Create a probe that evaluates to "true" when the value - does not evaluate to "true". - *) - (* CMW: is not a keyword? *) let not_ ( ctx : context ) ( p : probe ) = (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) end -(** Tactics - - Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using Context.get_num_tactics - and Context.get_tactic_names. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) module Tactic = struct type tactic = z3_native_object @@ -4890,11 +2843,6 @@ struct (z3obj_create res) ; res - - (** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult = struct type apply_result = z3_native_object @@ -4908,75 +2856,46 @@ struct (z3obj_create res) ; res - - (** The number of Subgoals. *) let get_num_subgoals ( x : apply_result ) = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) - (** Retrieves the subgoals from the apply_result. *) let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** Retrieves the subgoals from the apply_result. *) let get_subgoal ( x : apply_result ) ( i : int ) = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) - (** Convert a model for the subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g - *) let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) - (** A string representation of the ApplyResult. *) let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) end - (** A string containing a description of parameters accepted by the tactic. *) let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) - (** Retrieves parameter descriptions for Tactics. *) let get_param_descrs ( x : tactic ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - (** Apply the tactic to the goal. *) let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = match p with | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) - (** - The number of supported tactics. - *) let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) - (** - The names of all supported tactics. - *) let get_tactic_names ( ctx : context ) = let n = (get_num_tactics ctx ) in let f i = (Z3native.get_tactic_name (context_gno ctx) i) in Array.init n f - - (** - Returns a string containing a description of the tactic with the given name. - *) let get_tactic_description ( ctx : context ) ( name : string ) = Z3native.tactic_get_descr (context_gno ctx) name - (** - Creates a new Tactic. - *) let mk_tactic ( ctx : context ) ( name : string ) = create ctx (Z3native.mk_tactic (context_gno ctx) name) - (** - Create a tactic that applies to a Goal and - then to every subgoal produced by . - *) let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = let f p c = (match p with | None -> (Some (z3obj_gno c)) @@ -4988,106 +2907,50 @@ struct let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) - (** - Create a tactic that first applies to a Goal and - if it fails then returns the result of applied to the Goal. - *) let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - (** - Create a tactic that applies to a goal for milliseconds. - - If does not terminate within milliseconds, then it fails. - *) let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) - (** - Create a tactic that applies to a given goal if the probe - evaluates to true. - - If evaluates to false, then the new tactic behaves like the skip tactic. - *) - (* CMW: when is a keyword *) let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) - (** - Create a tactic that applies to a given goal if the probe - evaluates to true and otherwise. - *) let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) - (** - Create a tactic that keeps applying until the goal is not - modified anymore or the maximum number of iterations is reached. - *) let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) - (** - Create a tactic that just returns the given goal. - *) let skip ( ctx : context ) = create ctx (Z3native.tactic_skip (context_gno ctx)) - (** - Create a tactic always fails. - *) let fail ( ctx : context ) = create ctx (Z3native.tactic_fail (context_gno ctx)) - (** - Create a tactic that fails if the probe evaluates to false. - *) let fail_if ( ctx : context ) ( p : Probe.probe ) = create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) - (** - Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). - *) let fail_if_not_decided ( ctx : context ) = create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) - (** - Create a tactic that applies using the given set of parameters . - *) let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) - (** - Create a tactic that applies using the given set of parameters . - Alias for UsingParams*) - (* CMW: with is a keyword *) let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p - (** - Create a tactic that applies the given tactics in parallel. - *) let par_or ( ctx : context ) ( t : tactic array ) = create ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) - (** - Create a tactic that applies to a given goal and then - to every subgoal produced by . The subgoals are processed in parallel. - *) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - (** - Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. - *) let interrupt ( ctx : context ) = Z3native.interrupt (context_gno ctx) end -(** Solvers *) module Solver = struct type solver = z3_native_object @@ -5102,13 +2965,11 @@ struct (z3obj_create res) ; res - let string_of_status ( s : status) = match s with | UNSATISFIABLE -> "unsatisfiable" | SATISFIABLE -> "satisfiable" | _ -> "unknown" - (** Objects that track statistical information about solvers. *) module Statistics = struct type statistics = z3_native_object @@ -5123,11 +2984,6 @@ struct res - (** - Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - - *) module Entry = struct type statistics_entry = { @@ -5158,22 +3014,11 @@ struct res - (** The key of the entry. *) let get_key (x : statistics_entry) = x.m_key - - (** The int-value of the entry. *) - let get_int (x : statistics_entry) = x.m_int - - (** The float-value of the entry. *) + let get_int (x : statistics_entry) = x.m_int let get_float (x : statistics_entry) = x.m_float - - (** True if the entry is uint-valued. *) let is_int (x : statistics_entry) = x.m_is_int - - (** True if the entry is double-valued. *) let is_float (x : statistics_entry) = x.m_is_float - - (** The string representation of the the entry's value. *) let to_string_value (x : statistics_entry) = if (is_int x) then string_of_int (get_int x) @@ -5181,18 +3026,13 @@ struct string_of_float (get_float x) else raise (Z3native.Exception "Unknown statistical entry type") - - (** The string representation of the entry (key and value) *) let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) end - (** A string representation of the statistical data. *) let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) - (** The number of statistical data. *) let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) - (** The data entries. *) let get_entries ( x : statistics ) = let n = (get_size x ) in let f i = ( @@ -5204,129 +3044,56 @@ struct ) in Array.init n f - (** - The statistical counters. - *) let get_keys ( x : statistics ) = let n = (get_size x) in let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in Array.init n f - (** The value of a particular statistical counter. *) let get ( x : statistics ) ( key : string ) = let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in Array.fold_left f None (get_entries x) end - (** - A string that describes all available solver parameters. - *) let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) - (** - Sets the solver parameters. - *) let set_parameters ( x : solver ) ( p : Params.params )= Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - (** - Retrieves parameter descriptions for solver. - *) let get_param_descrs ( x : solver ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - (** - The current number of backtracking points (scopes). - - - *) let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) - (** - Creates a backtracking point. - - *) let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) - (** - Backtracks backtracking points. - Note that an exception is thrown if is not smaller than NumScopes - - *) let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n - (** - Resets the Solver. - This removes all assertions from the solver. - *) let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - (** - Assert a constraint (or multiple) into the solver. - *) let assert_ ( x : solver ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) - (** - * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using - * and the Boolean literals - * provided using with assumptions. - *) - let assert_and_track ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = + let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = if ((Array.length cs) != (Array.length ps)) then raise (Z3native.Exception "Argument size mismatch") else let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) (Boolean.gno (Array.get ps i))) in ignore (Array.iteri f cs) - (** - * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using - * and the Boolean literals - * provided using with assumptions. - *) let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) - (** - The number of assertions in the solver. - *) let get_num_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) - - (** - The set of asserted formulas. - *) let get_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in Array.init n f - (** - Checks whether the assertions in the solver are consistent or not. - - - - - *) let check ( x : solver ) ( assumptions : Boolean.bool_expr array) = let r = if ((Array.length assumptions) == 0) then @@ -5340,12 +3107,6 @@ struct | L_FALSE -> UNSATISFIABLE | _ -> UNKNOWN - (** - The model of the last Check. - - The result is None if Check was not invoked before, - if its results was not SATISFIABLE, or if model production is not enabled. - *) let get_model ( x : solver ) = let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then @@ -5353,12 +3114,6 @@ struct else Some (Model.create (z3obj_gc x) q) - (** - The proof of the last Check. - - The result is null if Check was not invoked before, - if its results was not UNSATISFIABLE, or if proof production is disabled. - *) let get_proof ( x : solver ) = let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in if (Z3native.is_null q) then @@ -5366,73 +3121,35 @@ struct else Some (expr_of_ptr (z3obj_gc x) q) - (** - The unsat core of the last Check. - - The unsat core is a subset of Assertions - The result is empty if Check was not invoked before, - if its results was not UNSATISFIABLE, or if core production is disabled. - *) let get_unsat_core ( x : solver ) = let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in Array.init n f - (** - A brief justification of why the last call to Check returned UNKNOWN. - *) let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - (** - Solver statistics. - *) let get_statistics ( x : solver ) = (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) - (** - Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. - *) let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = match logic with | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) - (** - Creates a new (incremental) solver. - - *) let mk_solver_s ( ctx : context ) ( logic : string ) = mk_solver ctx (Some (Symbol.mk_string ctx logic)) - (** - Creates a new (incremental) solver. - *) let mk_simple_solver ( ctx : context ) = (create ctx (Z3native.mk_simple_solver (context_gno ctx))) - (** - Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. - *) let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) - (** - A string representation of the solver. - *) let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) end -(** Fixedpoint solving *) module Fixedpoint = struct type fixedpoint = z3_native_object @@ -5447,70 +3164,37 @@ struct res - (** - A string that describes all available fixedpoint solver parameters. - *) let get_help ( x : fixedpoint ) = Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) - (** - Sets the fixedpoint solver parameters. - *) let set_params ( x : fixedpoint ) ( p : Params.params )= Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - (** - Retrieves parameter descriptions for Fixedpoint solver. - *) let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - (** - Assert a constraints into the fixedpoint solver. - *) let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr array ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in ignore (Array.map f constraints) ; () - (** - Register predicate as recursive relation. - *) let register_relation ( x : fixedpoint ) ( f : func_decl ) = Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - (** - Add rule into the fixedpoint solver. - *) let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = match name with | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) - (** - Add table fact to the fixedpoint solver. - *) let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args - (** - Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. - *) let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN - (** - Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. - *) let query_r ( x : fixedpoint ) ( relations : func_decl array ) = let f x = ptr_of_ast (ast_of_func_decl x) in match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with @@ -5518,32 +3202,15 @@ struct | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN - (** - Creates a backtracking point. - - *) let push ( x : fixedpoint ) = Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) - (** - Backtrack one backtracking point. - - Note that an exception is thrown if Pop is called without a corresponding Push - - *) let pop ( x : fixedpoint ) = Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - (** - Update named rule into in the fixedpoint solver. - *) let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) - (** - Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. - *) let get_answer ( x : fixedpoint ) = let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in if (Z3native.is_null q) then @@ -5551,21 +3218,12 @@ struct else Some (expr_of_ptr (z3obj_gc x) q) - (** - Retrieve explanation why fixedpoint engine returned status Unknown. - *) let get_reason_unknown ( x : fixedpoint ) = Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - (** - Retrieve the number of levels explored for a given predicate. - *) let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) - (** - Retrieve the cover of a predicate. - *) let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in if (Z3native.is_null q) then @@ -5573,82 +3231,40 @@ struct else Some (expr_of_ptr (z3obj_gc x) q) - (** - Add property about the predicate. - The property is added at level. - *) let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (ptr_of_expr property) - (** - Retrieve internal string representation of fixedpoint object. - *) let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - (** - Instrument the Datalog engine on which table representation to use for recursive predicate. - *) let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = let f2 x = (Symbol.gno x) in Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) - (** - Convert benchmark given as set of axioms, rules and queries to a string. - *) let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr array ) = let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) - (** - Retrieve set of rules added to fixedpoint context. - *) let get_rules ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f - (** - Retrieve set of assertions added to fixedpoint context. - *) let get_assertions ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in Array.init n f - (** - Create a Fixedpoint context. - *) let mk_fixedpoint ( ctx : context ) = create ctx end -(** Global and context options - - Note: This module contains functions that set parameters/options for context - objects as well as functions that set options that are used globally, across - contexts.*) module Options = struct - (** - Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - - *) let update_param_value ( ctx : context ) ( id : string) ( value : string )= Z3native.update_param_value (context_gno ctx) id value - (** - Get a configuration parameter. - - Returns None if the parameter value does not exist. - - *) let get_param_value ( ctx : context ) ( id : string ) = let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in if not r then @@ -5656,62 +3272,21 @@ struct else Some v - (** - Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - - - - - *) let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) - (** - Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. - *) let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled end -(** Functions for handling SMT and SMT2 expressions and files *) + module SMT = struct - (** - Convert a benchmark into an SMT-LIB formatted string. - - @param name Name of the benchmark. The argument is optional. - @param logic The benchmark logic. - @param status The status string (sat, unsat, or unknown) - @param attributes Other attributes, such as source, difficulty or category. - @param assumptions Auxiliary assumptions. - @param formula Formula to be checked for consistency in conjunction with assumptions. - @return A string representation of the benchmark. - *) let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr array ) ( formula : Boolean.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes (Array.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.map f assumptions)) (Boolean.gno formula) - (** - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays and - don't need to match the names of the sorts and declarations in the arrays - and . This is a useful feature since we can use arbitrary names to - reference sorts and declarations. - *) let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5728,10 +3303,6 @@ struct (let f x = Symbol.gno x in (Array.map f decl_names)) (let f x = FuncDecl.gno x in (Array.map f decls)) - (** - Parse the given file using the SMT-LIB parser. - - *) let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5748,65 +3319,34 @@ struct (let f x = Symbol.gno x in (Array.map f decl_names)) (let f x = FuncDecl.gno x in (Array.map f decls)) - (** - The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) - (** - The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in Array.init n f - - (** - The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) - (** - The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in Array.init n f - (** - The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) - (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in Array.init n f - (** - The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - - (** - The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - *) + let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in Array.init n f - (** - Parse the given string using the SMT-LIB2 parser. - - - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - *) let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5823,10 +3363,6 @@ struct (let f x = Symbol.gno x in (Array.map f decl_names)) (let f x = FuncDecl.gno x in (Array.map f decls)))) - (** - Parse the given file using the SMT-LIB2 parser. - - *) let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = let csn = (Array.length sort_names) in let cs = (Array.length sorts) in @@ -5845,34 +3381,9 @@ struct end -(* Global functions *) - -(** - * Set a global (or module) parameter, which is shared by all Z3 contexts. - * - * When a Z3 module is initialized it will use the value of these parameters - * when Z3_params objects are not provided. - * The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. - * The character '.' is a delimiter (more later). - * The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. - * Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". - * This function can be used to set parameters for a specific Z3 module. - * This can be done by using .. - * For example: - * (set_global_param "pp.decimal" "true") - * will set the parameter "decimal" in the module "pp" to true. -*) let set_global_param ( id : string ) ( value : string ) = (Z3native.global_param_set id value) -(** - * Get a global (or module) parameter. - * - * Returns None if the parameter does not exist. - * The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. - * This function cannot be invoked simultaneously from different threads without synchronization. - * The result string stored in param_value is stored in a shared location. -*) let get_global_param ( id : string ) = let (r, v) = (Z3native.global_param_get id) in if not r then @@ -5880,11 +3391,5 @@ let get_global_param ( id : string ) = else Some v -(** - * Restore the value of all global (and module) parameters. - * - * This command will not affect already created objects (such as tactics and solvers) - * -*) let global_param_reset_all = Z3native.global_param_reset_all diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 87318d2a7..49a78f724 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -5,8 +5,6 @@ @author CM Wintersteiger (cwinter) 2012-12-17 *) - - (** Context objects. Most interactions with Z3 are interpreted in some context; many users will only @@ -39,17 +37,14 @@ val mk_context : (string * string) list -> context module Log : sig (** Open an interaction log file. - @param filename the name of the file to open. - @return True if opening the log file succeeds, false otherwise. - *) + @return True if opening the log file succeeds, false otherwise. *) (* CMW: "open" seems to be a reserved keyword? *) val open_ : string -> bool (** Closes the interaction log. *) val close : unit - (** Appends a user-provided string to the interaction log. - @param s the string to append*) + (** Appends a user-provided string to the interaction log. *) val append : string -> unit end @@ -102,12 +97,10 @@ sig (** A string representation of the symbol. *) val to_string : symbol -> string - (** - Creates a new symbol using an integer. + (** Creates a new symbol using an integer. Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. - *) + The legal range of unsigned integers is 0 to 2^30-1. *) val mk_int : context -> int -> symbol (** Creates a new symbol using a string. *) @@ -135,30 +128,21 @@ sig (** Retrieves the i-th object in the vector. - @param i Index - @return An AST - *) + @return An AST *) val get : ast_vector -> int -> ast (** Sets the i-th object in the vector. *) val set : ast_vector -> int -> ast -> unit - (** Resize the vector to . - @param newSize The new size of the vector. *) + (** Resize the vector to a new size. *) val resize : ast_vector -> int -> unit - (** - Add the AST to the back of the vector. The size - is increased by 1. - @param a An AST - *) + (** Add an ast to the back of the vector. The size + is increased by 1. *) val push : ast_vector -> ast -> unit - (** - Translates all ASTs in the vector to . - @param to_ctx A context - @return A new ASTVector - *) + (** Translates all ASTs in the vector to another context. + @return A new ASTVector *) val translate : ast_vector -> context -> ast_vector (** Retrieves a string representation of the vector. *) @@ -170,29 +154,18 @@ sig sig type ast_map - (** Checks whether the map contains the key . - @param k An AST - @return True if is a key in the map, false otherwise. *) + (** Checks whether the map contains a key. + @return True if the key in the map, false otherwise. *) val contains : ast_map -> ast -> bool - (** Finds the value associated with the key . - - This function signs an error when is not a key in the map. - @param k An AST - *) + (** Finds the value associated with the key. + This function signs an error when the key is not a key in the map. *) val find : ast_map -> ast -> ast - (** - Stores or replaces a new key/value pair in the map. - @param k The key AST - @param v The value AST - *) + (** Stores or replaces a new key/value pair in the map. *) val insert : ast_map -> ast -> ast -> unit - (** - Erases the key from the map. - @param k An AST - *) + (** Erases the key from the map.*) val erase : ast_map -> ast -> unit (** Removes all keys from the map. *) @@ -208,10 +181,8 @@ sig val to_string : ast_map -> string end - (** - The AST's hash code. - @return A hash code - *) + (** The AST's hash code. + @return A hash code *) val get_hash_code : ast -> int (** A unique identifier for the AST (unique among all ASTs). *) @@ -241,56 +212,39 @@ sig (** A string representation of the AST in s-expression notation. *) val to_sexpr : ast -> string - (** - Comparison operator. - @param a An AST - @param b An AST - @return True if and are from the same context - and represent the same sort; false otherwise. - *) + (** Comparison operator. + @return True if the two ast's are from the same context + and represent the same sort; false otherwise. *) val ( = ) : ast -> ast -> bool - (** - Object Comparison. - @param other Another ast - @return Negative if the object should be sorted before , positive if after else zero. - *) + (** Object Comparison. + @return Negative if the first ast should be sorted before the second, positive if after else zero. *) val compare : ast -> ast -> int (** Operator < *) val ( < ) : ast -> ast -> int - (** - Translates (copies) the AST to the Context . - @param ctx A context - @return A copy of the AST which is associated with - *) + (** Translates (copies) the AST to another context. + @return A copy of the AST which is associated with the other context. *) val translate : ast -> context -> ast - (** - Wraps an AST. + (** Wraps an AST. - This function is used for transitions between native and - managed objects. Note that must be a - native object obtained from Z3 (e.g., through ) + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) and that it must have a correct reference count (see e.g., - . - - @param nativeObject The native pointer to wrap. - *) - val wrap : context -> Z3native.z3_ast -> ast + Z3native.inc_ref). *) + val wrap_ast : context -> Z3native.z3_ast -> ast - (** - Unwraps an AST. - This function is used for transitions between native and + (** Unwraps an AST. + This function is used for transitions between native and managed objects. It returns the native pointer to the AST. Note that AST objects are reference counted and unwrapping an AST disables automatic reference counting, i.e., all references to the IntPtr that is returned must be handled externally and through native calls (see e.g., - ). - - @param a The AST to unwrap. - *) + Z3native.inc_ref). + {!wrap_ast} *) val unwrap_ast : ast -> Z3native.ptr end @@ -307,13 +261,9 @@ sig val sort_of_uninterpreted_sort : uninterpreted_sort -> sort val uninterpreted_sort_of_sort : sort -> uninterpreted_sort - (** - Comparison operator. - @param a A sort - @param b A sort - @return True if and are from the same context - and represent the same sort; false otherwise. - *) + (** Comparison operator. + @return True if the two sorts are from the same context + and represent the same sort; false otherwise. *) val ( = ) : sort -> sort -> bool (** Returns a unique identifier for the sort. *) @@ -385,9 +335,7 @@ sig (** Creates a new function declaration. *) val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl - (** Creates a fresh function declaration with a name prefixed with . - - *) + (** Creates a fresh function declaration with a name prefixed with a prefix string. *) val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl @@ -397,16 +345,13 @@ sig (** Creates a new constant function declaration. *) val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - (** Creates a fresh constant function declaration with a name prefixed with . - - *) + (** Creates a fresh constant function declaration with a name prefixed with a prefix string. + {!mk_func_decl} + {!mk_func_decl} *) val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl (** Comparison operator. - @param a A func_decl - @param b A func_decl - @return True if and are from the same context - and represent the same func_decl; false otherwise. *) + @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) val ( = ) : func_decl -> func_decl -> bool (** A string representations of the function declaration. *) @@ -419,7 +364,7 @@ sig val get_arity : func_decl -> int (** The size of the domain of the function declaration - *) + {!get_arity} *) val get_domain_size : func_decl -> int (** The domain of the function declaration *) @@ -440,8 +385,7 @@ sig (** The parameters of the function declaration *) val get_parameters : func_decl -> Parameter.parameter list - (** Create expression that applies function to arguments. - @param args The arguments *) + (** Create expression that applies function to arguments. *) val apply : func_decl -> Expr.expr array -> Expr.expr end @@ -504,54 +448,153 @@ sig val to_string : params -> string end +(** General Expressions (terms) *) and Expr : sig - (** General Expressions (Terms) *) type expr = Expr of AST.ast val ast_of_expr : Expr.expr -> AST.ast val expr_of_ast : AST.ast -> Expr.expr + (** Returns a simplified version of the expression. + {!get_simplify_help} *) val simplify : Expr.expr -> Params.params option -> expr + + (** A string describing all available parameters to Expr.Simplify. *) val get_simplify_help : context -> string + + (** Retrieves parameter descriptions for simplifier. *) val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + + (** The function declaration of the function that is applied in this expression. *) val get_func_decl : Expr.expr -> FuncDecl.func_decl + + (** Indicates whether the expression is the true or false expression + or something else (L_UNDEF). *) val get_bool_value : Expr.expr -> Z3enums.lbool + + (** The number of arguments of the expression. *) val get_num_args : Expr.expr -> int + + (** The arguments of the expression. *) val get_args : Expr.expr -> Expr.expr array + + (** Update the arguments of the expression using an array of expressions. + The number of new arguments should coincide with the current number of arguments. *) val update : Expr.expr -> Expr.expr array -> expr + + (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + + The result is the new expression. The arrays from and to must have size num_exprs. + For every i smaller than num_exprs, we must have that + sort of from[i] must be equal to sort of to[i]. *) val substitute : Expr.expr -> Expr.expr array -> Expr.expr array -> expr + + (** Substitute every occurrence of from in the expression with to. + {!substitute} *) val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr + + (** Substitute the free variables in the expression with the expressions in the expr array + + For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) val substitute_vars : Expr.expr -> Expr.expr array -> expr + + (** Translates (copies) the term to another context. + @return A copy of the term which is associated with the other context *) val translate : Expr.expr -> context -> expr + + (** Returns a string representation of the expression. *) val to_string : Expr.expr -> string + + (** Indicates whether the term is a numeral *) val is_numeral : Expr.expr -> bool + + (** Indicates whether the term is well-sorted. + @return True if the term is well-sorted, false otherwise. *) val is_well_sorted : Expr.expr -> bool + + (** The Sort of the term. *) val get_sort : Expr.expr -> Sort.sort + + (** Indicates whether the term has Boolean sort. *) val is_bool : Expr.expr -> bool + + (** Indicates whether the term represents a constant. *) val is_const : Expr.expr -> bool + + (** Indicates whether the term is the constant true. *) val is_true : Expr.expr -> bool + + (** Indicates whether the term is the constant false. *) val is_false : Expr.expr -> bool + + (** Indicates whether the term is an equality predicate. *) val is_eq : Expr.expr -> bool + + (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) val is_distinct : Expr.expr -> bool + + (** Indicates whether the term is a ternary if-then-else term *) val is_ite : Expr.expr -> bool + + (** Indicates whether the term is an n-ary conjunction *) val is_and : Expr.expr -> bool + + (** Indicates whether the term is an n-ary disjunction *) val is_or : Expr.expr -> bool + + (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) val is_iff : Expr.expr -> bool + + (** Indicates whether the term is an exclusive or *) val is_xor : Expr.expr -> bool + + (** Indicates whether the term is a negation *) val is_not : Expr.expr -> bool + + (** Indicates whether the term is an implication *) val is_implies : Expr.expr -> bool + + (** Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) val is_label : Expr.expr -> bool + + (** Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) + val is_label_lit : Expr.expr -> bool + + (** Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) val is_oeq : Expr.expr -> bool + + (** Creates a new constant. *) val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + + (** Creates a new constant. *) val mk_const_s : context -> string -> Sort.sort -> expr + + (** Creates a constant from the func_decl. *) val mk_const_f : context -> FuncDecl.func_decl -> expr + + (** Creates a fresh constant with a name prefixed with a string. *) val mk_fresh_const : context -> string -> Sort.sort -> expr + + (** Create a new function application. *) val mk_app : context -> FuncDecl.func_decl -> Expr.expr array -> expr + + (** Create a numeral of a given sort. + @return A Term with the goven value and sort *) val mk_numeral_string : context -> string -> Sort.sort -> expr + + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @return A Term with the given value and sort *) val mk_numeral_int : context -> int -> Sort.sort -> expr end +(** Boolean expressions *) module Boolean : sig type bool_sort = BoolSort of Sort.sort @@ -562,23 +605,53 @@ sig val bool_sort_of_sort : Sort.sort -> bool_sort val bool_expr_of_expr : Expr.expr -> bool_expr + (** Create a Boolean sort *) val mk_sort : context -> bool_sort + + (** Create a Boolean constant. *) val mk_const : context -> Symbol.symbol -> bool_expr + + (** Create a Boolean constant. *) val mk_const_s : context -> string -> bool_expr + + (** The true Term. *) val mk_true : context -> bool_expr + + (** The false Term. *) val mk_false : context -> bool_expr + + (** Creates a Boolean value. *) val mk_val : context -> bool -> bool_expr + + (** Creates the equality between two expr's. *) val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr + + (** Creates a distinct term. *) val mk_distinct : context -> Expr.expr array -> bool_expr + + (** Mk an expression representing not(a). *) val mk_not : context -> bool_expr -> bool_expr + + (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 iff t2. *) val mk_iff : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 -> t2. *) val mk_implies : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 xor t2. *) val mk_xor : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing the AND of args *) val mk_and : context -> bool_expr array -> bool_expr + + (** Create an expression representing the OR of args *) val mk_or : context -> bool_expr array -> bool_expr end +(** Quantifier expressions *) module Quantifier : sig type quantifier = Quantifier of Expr.expr @@ -586,7 +659,11 @@ sig val expr_of_quantifier : quantifier -> Expr.expr val quantifier_of_expr : Expr.expr -> quantifier + (** Quantifier patterns + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. *) module Pattern : sig type pattern = Pattern of AST.ast @@ -594,65 +671,94 @@ sig val ast_of_pattern : pattern -> AST.ast val pattern_of_ast : AST.ast -> pattern + (** The number of terms in the pattern. *) val get_num_terms : pattern -> int + + (** The terms in the pattern. *) val get_terms : pattern -> Expr.expr array + + (** A string representation of the pattern. *) val to_string : pattern -> string end + + (** The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. *) val get_index : Expr.expr -> int + + (** Indicates whether the quantifier is universal. *) val is_universal : quantifier -> bool + + (** Indicates whether the quantifier is existential. *) val is_existential : quantifier -> bool + + (** The weight of the quantifier. *) val get_weight : quantifier -> int + + (** The number of patterns. *) val get_num_patterns : quantifier -> int + + (** The patterns. *) val get_patterns : quantifier -> Pattern.pattern array + + (** The number of no-patterns. *) val get_num_no_patterns : quantifier -> int + + (** The no-patterns. *) val get_no_patterns : quantifier -> Pattern.pattern array - val get_num_bound : quantifier -> int + + (** The number of bound variables. *) + val get_num_bound : quantifier -> int + + (** The symbols for the bound variables. *) val get_bound_variable_names : quantifier -> Symbol.symbol array + + (** The sorts of the bound variables. *) val get_bound_variable_sorts : quantifier -> Sort.sort array + + (** The body of the quantifier. *) val get_body : quantifier -> Boolean.bool_expr + + (** Creates a new bound variable. *) val mk_bound : context -> int -> Sort.sort -> Expr.expr + + (** Create a quantifier pattern. *) val mk_pattern : context -> Expr.expr array -> Pattern.pattern - val mk_forall : - context -> - Sort.sort array -> - Symbol.symbol array -> - Expr.expr -> - int option -> - Pattern.pattern array -> - Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier - val mk_forall_const : - context -> - Expr.expr array -> - Expr.expr -> - int option -> - Pattern.pattern array -> - Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier - val mk_exists : - context -> - Sort.sort array -> - Symbol.symbol array -> - Expr.expr -> - int option -> - Pattern.pattern array -> - Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier - val mk_exists_const : - context -> - Expr.expr array -> - Expr.expr -> - int option -> - Pattern.pattern array -> - Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier - val mk_quantifier : - context -> - bool -> - Expr.expr array -> - Expr.expr -> - int option -> - Pattern.pattern array -> - Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a universal Quantifier. *) + val mk_forall : context -> Sort.sort array -> Symbol.symbol array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a universal Quantifier. *) + val mk_forall_const : context -> Expr.expr array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists : context -> Sort.sort array -> Symbol.symbol array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists_const : context -> Expr.expr array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> Sort.sort array -> Symbol.symbol array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> bool -> Expr.expr array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier end +(** Functions to manipulate Array expressions *) module Array_ : sig type array_sort = ArraySort of Sort.sort @@ -664,48 +770,159 @@ sig val array_expr_of_expr : Expr.expr -> array_expr + (** Create a new array sort. *) val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort + + (** Indicates whether the term is an array store. + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. *) val is_store : Expr.expr -> bool + + (** Indicates whether the term is an array select. *) val is_select : Expr.expr -> bool + + (** Indicates whether the term is a constant array. + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) val is_constant_array : Expr.expr -> bool + + (** Indicates whether the term is a default array. + For example default(const(v)) = v. The function is unary. *) val is_default_array : Expr.expr -> bool + + (** Indicates whether the term is an array map. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) val is_array_map : Expr.expr -> bool + + (** Indicates whether the term is an as-array term. + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. *) val is_as_array : Expr.expr -> bool + + (** Indicates whether the term is of an array sort. *) val is_array : Expr.expr -> bool + + (** The domain of the array sort. *) val get_domain : array_sort -> Sort.sort + + (** The range of the array sort. *) val get_range : array_sort -> Sort.sort + + (** Create an array constant. *) val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr + + (** Create an array constant. *) val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr - val mk_select : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr + + (** Array read. + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + {!Array_.mk_sort} + {!mk_store} *) + val mk_select : context -> array_expr -> Expr.expr -> array_expr + + (** Array update. + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + {!Array_.mk_sort} + {!mk_select} *) + val mk_store : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr + + (** Create a constant array. + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + {!Array_.mk_sort} + {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr + + (** Maps f on the argument arrays. + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + {!Array_.mk_sort} + {!mk_select} + {!mk_store} *) val mk_map : context -> FuncDecl.func_decl -> array_expr array -> array_expr + + (** Access the array default value. + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. *) val mk_term_array : context -> array_expr -> array_expr end +(** Functions to manipulate Set expressions *) module Set : sig type set_sort = SetSort of Sort.sort val sort_of_set_sort : set_sort -> Sort.sort - val is_union : Expr.expr -> bool - val is_intersect : Expr.expr -> bool - val is_difference : Expr.expr -> bool - val is_complement : Expr.expr -> bool - val is_subset : Expr.expr -> bool + (** Create a set type. *) val mk_sort : context -> Sort.sort -> set_sort + + (** Indicates whether the term is set union *) + val is_union : Expr.expr -> bool + + (** Indicates whether the term is set intersection *) + val is_intersect : Expr.expr -> bool + + (** Indicates whether the term is set difference *) + val is_difference : Expr.expr -> bool + + (** Indicates whether the term is set complement *) + val is_complement : Expr.expr -> bool + + (** Indicates whether the term is set subset *) + val is_subset : Expr.expr -> bool + + (** Create an empty set. *) val mk_empty : context -> Sort.sort -> Expr.expr + + (** Create the full set. *) val mk_full : context -> Sort.sort -> Expr.expr + + (** Add an element to the set. *) val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Remove an element from a set. *) val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Take the union of a list of sets. *) val mk_union : context -> Expr.expr array -> Expr.expr + + (** Take the intersection of a list of sets. *) val mk_intersection : context -> Expr.expr array -> Expr.expr + + (** Take the difference between two sets. *) val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Take the complement of a set. *) val mk_complement : context -> Expr.expr -> Expr.expr + + (** Check for set membership. *) val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Check for subsetness of sets. *) val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr end +(** Functions to manipulate Finite Domain expressions *) module FiniteDomain : sig type finite_domain_sort = FiniteDomainSort of Sort.sort @@ -713,13 +930,24 @@ sig val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort + (** Create a new finite domain sort. *) val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort + + (** Create a new finite domain sort. *) val mk_sort_s : context -> string -> int -> finite_domain_sort + + (** Indicates whether the term is of an array sort. *) val is_finite_domain : Expr.expr -> bool + + (** Indicates whether the term is a less than predicate over a finite domain. *) val is_lt : Expr.expr -> bool + + (** The size of the finite domain sort. *) val get_size : finite_domain_sort -> int end + +(** Functions to manipulate Relation expressions *) module Relation : sig type relation_sort = RelationSort of Sort.sort @@ -727,24 +955,92 @@ sig val sort_of_relation_sort : relation_sort -> Sort.sort val relation_sort_of_sort : Sort.sort -> relation_sort + (** Indicates whether the term is of a relation sort. *) val is_relation : Expr.expr -> bool + + (** Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. *) val is_store : Expr.expr -> bool + + (** Indicates whether the term is an empty relation *) val is_empty : Expr.expr -> bool + + (** Indicates whether the term is a test for the emptiness of a relation *) val is_is_empty : Expr.expr -> bool + + (** Indicates whether the term is a relational join *) val is_join : Expr.expr -> bool + + (** Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. *) val is_union : Expr.expr -> bool + + (** Indicates whether the term is the widening of two relations + The function takes two arguments. *) val is_widen : Expr.expr -> bool + + (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. *) val is_project : Expr.expr -> bool + + (** Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. *) val is_filter : Expr.expr -> bool + + (** Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. *) val is_negation_filter : Expr.expr -> bool + + (** Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. *) val is_rename : Expr.expr -> bool + + (** Indicates whether the term is the complement of a relation *) val is_complement : Expr.expr -> bool + + (** Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. *) val is_select : Expr.expr -> bool + + (** Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind {!is_union} + to perform destructive updates to the first argument. *) val is_clone : Expr.expr -> bool + + (** The arity of the relation sort. *) val get_arity : relation_sort -> int + + (** The sorts of the columns of the relation sort. *) val get_column_sorts : relation_sort -> relation_sort array end +(** Functions to manipulate Datatype expressions *) module Datatype : sig type datatype_sort = DatatypeSort of Sort.sort @@ -755,74 +1051,136 @@ sig val expr_of_datatype_expr : datatype_expr -> Expr.expr val datatype_expr_of_expr : Expr.expr -> datatype_expr + (** Datatype Constructors *) module Constructor : sig - (** Constructors *) type constructor - val get_n : constructor -> int - val constructor_decl : constructor -> FuncDecl.func_decl - val tester_decl : constructor -> FuncDecl.func_decl - val accessor_decls : constructor -> FuncDecl.func_decl array + (** The number of fields of the constructor. *) val get_num_fields : constructor -> int + + (** The function declaration of the constructor. *) val get_constructor_decl : constructor -> FuncDecl.func_decl + + (** The function declaration of the tester. *) val get_tester_decl : constructor -> FuncDecl.func_decl + + (** The function declarations of the accessors *) val get_accessor_decls : constructor -> FuncDecl.func_decl array end + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> Constructor.constructor + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> Constructor.constructor + + (** Create a new datatype sort. *) val mk_sort : context -> Symbol.symbol -> Constructor.constructor array -> datatype_sort + + (** Create a new datatype sort. *) val mk_sort_s : context -> string -> Constructor.constructor array -> datatype_sort + + (** Create mutually recursive datatypes. *) val mk_sorts : context -> Symbol.symbol array -> Constructor.constructor array array -> datatype_sort array + + (** Create mutually recursive data-types. *) val mk_sorts_s : context -> string array -> Constructor.constructor array array -> datatype_sort array + + + (** The number of constructors of the datatype sort. *) val get_num_constructors : datatype_sort -> int + + (** The constructors. *) val get_constructors : datatype_sort -> FuncDecl.func_decl array + + (** The recognizers. *) val get_recognizers : datatype_sort -> FuncDecl.func_decl array + + (** The constructor accessors. *) val get_accessors : datatype_sort -> FuncDecl.func_decl array array end +(** Functions to manipulate Enumeration expressions *) module Enumeration : sig type enum_sort = EnumSort of Sort.sort val sort_of_enum_sort : enum_sort -> Sort.sort + (** Create a new enumeration sort. *) val mk_sort : context -> Symbol.symbol -> Symbol.symbol array -> enum_sort + + (** Create a new enumeration sort. *) val mk_sort_s : context -> string -> string array -> enum_sort + + (** The function declarations of the constants in the enumeration. *) val get_const_decls : enum_sort -> FuncDecl.func_decl array + + (** The test predicates for the constants in the enumeration. *) val get_tester_decls : enum_sort -> FuncDecl.func_decl array end +(** Functions to manipulate List expressions *) module List_ : sig type list_sort = ListSort of Sort.sort val sort_of_list_sort : list_sort -> Sort.sort + (** Create a new list sort. *) val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort + + (** Create a new list sort. *) val mk_list_s : context -> string -> Sort.sort -> list_sort + + (** The declaration of the nil function of this list sort. *) val get_nil_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the isNil function of this list sort. *) val get_is_nil_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the cons function of this list sort. *) val get_cons_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the isCons function of this list sort. *) val get_is_cons_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the head function of this list sort. *) val get_head_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the tail function of this list sort. *) val get_tail_decl : list_sort -> FuncDecl.func_decl + + (** The empty list. *) val nil : list_sort -> Expr.expr end +(** Functions to manipulate Tuple expressions *) module Tuple : sig type tuple_sort = TupleSort of Sort.sort val sort_of_tuple_sort : tuple_sort -> Sort.sort + (** Create a new tuple sort. *) val mk_sort : context -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> tuple_sort + + (** The constructor function of the tuple. *) val get_mk_decl : tuple_sort -> FuncDecl.func_decl + + (** The number of fields in the tuple. *) val get_num_fields : tuple_sort -> int + + (** The field declarations. *) val get_field_decls : tuple_sort -> FuncDecl.func_decl array end +(** Functions to manipulate arithmetic expressions *) module rec Arithmetic : sig type arith_sort = ArithSort of Sort.sort @@ -833,6 +1191,7 @@ sig val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr + (** Integer Arithmetic *) module rec Integer : sig type int_sort = IntSort of arith_sort @@ -845,20 +1204,59 @@ sig val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num - + + (** Create a new integer sort. *) val mk_sort : context -> int_sort + + (** Retrieve the int value. *) val get_int : int_num -> int + + (** Returns a string representation of the numeral. *) val to_string : int_num -> string + + (** Creates an integer constant. *) val mk_int_const : context -> Symbol.symbol -> int_expr + + (** Creates an integer constant. *) val mk_int_const_s : context -> string -> int_expr + + (** Create an expression representing t1 mod t2. + The arguments must have int type. *) val mk_mod : context -> int_expr -> int_expr -> int_expr + + (** Create an expression representing t1 rem t2. + The arguments must have int type. *) val mk_rem : context -> int_expr -> int_expr -> int_expr + + (** Create an integer numeral. *) val mk_int_numeral_s : context -> string -> int_num + + (** Create an integer numeral. + @return A Term with the given value and sort Integer *) val mk_int_numeral_i : context -> int -> int_num + + (** Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. *) val mk_int2real : context -> int_expr -> Real.real_expr + + (** Create an n-bit bit-vector from an integer argument. + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. *) val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr end + (** Real Arithmetic *) and Real : sig type real_sort = RealSort of arith_sort @@ -872,20 +1270,52 @@ sig val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + (** Create a real sort. *) val mk_sort : context -> real_sort + + (** The numerator of a rational numeral. *) val get_numerator : rat_num -> Integer.int_num + + (** The denominator of a rational numeral. *) val get_denominator : rat_num -> Integer.int_num + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as indicated by the int argument.*) val to_decimal_string : rat_num -> int -> string + + (** Returns a string representation of the numeral. *) val to_string : rat_num -> string + + (** Creates a real constant. *) val mk_real_const : context -> Symbol.symbol -> real_expr + + (** Creates a real constant. *) val mk_real_const_s : context -> string -> real_expr + + (** Create a real numeral from a fraction. + @return A Term with rational value and sort Real + {!mk_numeral_s} *) val mk_numeral_nd : context -> int -> int -> rat_num + + (** Create a real numeral. + @return A Term with the given value and sort Real *) val mk_numeral_s : context -> string -> rat_num + + (** Create a real numeral. + @return A Term with the given value and sort Real *) val mk_numeral_i : context -> int -> rat_num + + (** Creates an expression that checks whether a real number is an integer. *) val mk_is_integer : context -> real_expr -> Boolean.bool_expr + + (** Coerce a real to an integer. + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) val mk_real2int : context -> real_expr -> Integer.int_expr end + (** Algebraic Numbers *) and AlgebraicNumber : sig type algebraic_num = AlgebraicNum of arith_expr @@ -893,45 +1323,121 @@ sig val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num + (** Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) val to_upper : algebraic_num -> int -> Real.rat_num + + (** Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) val to_lower : algebraic_num -> int -> Real.rat_num + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as the int argument provided.*) val to_decimal_string : algebraic_num -> int -> string + + (** Returns a string representation of the numeral. *) val to_string : algebraic_num -> string end + (** Indicates whether the term is of integer sort. *) val is_int : Expr.expr -> bool + + (** Indicates whether the term is an arithmetic numeral. *) val is_arithmetic_numeral : Expr.expr -> bool + + (** Indicates whether the term is a less-than-or-equal *) val is_le : Expr.expr -> bool + + (** Indicates whether the term is a greater-than-or-equal *) val is_ge : Expr.expr -> bool + + (** Indicates whether the term is a less-than *) val is_lt : Expr.expr -> bool + + (** Indicates whether the term is a greater-than *) val is_gt : Expr.expr -> bool + + (** Indicates whether the term is addition (binary) *) val is_add : Expr.expr -> bool + + (** Indicates whether the term is subtraction (binary) *) val is_sub : Expr.expr -> bool + + (** Indicates whether the term is a unary minus *) val is_uminus : Expr.expr -> bool + + (** Indicates whether the term is multiplication (binary) *) val is_mul : Expr.expr -> bool + + (** Indicates whether the term is division (binary) *) val is_div : Expr.expr -> bool + + (** Indicates whether the term is integer division (binary) *) val is_idiv : Expr.expr -> bool + + (** Indicates whether the term is remainder (binary) *) val is_remainder : Expr.expr -> bool + + (** Indicates whether the term is modulus (binary) *) val is_modulus : Expr.expr -> bool + + (** Indicates whether the term is a coercion of integer to real (unary) *) val is_inttoreal : Expr.expr -> bool + + (** Indicates whether the term is a coercion of real to integer (unary) *) val is_real_to_int : Expr.expr -> bool + + (** Indicates whether the term is a check that tests whether a real is integral (unary) *) val is_real_is_int : Expr.expr -> bool + + (** Indicates whether the term is of sort real. *) val is_real : Expr.expr -> bool + + (** Indicates whether the term is an integer numeral. *) val is_int_numeral : Expr.expr -> bool + + (** Indicates whether the term is a real numeral. *) val is_rat_num : Expr.expr -> bool + + (** Indicates whether the term is an algebraic number *) val is_algebraic_number : Expr.expr -> bool + + (** Create an expression representing t[0] + t[1] + .... *) val mk_add : context -> arith_expr array -> arith_expr + + (** Create an expression representing t[0] * t[1] * .... *) val mk_mul : context -> arith_expr array -> arith_expr + + (** Create an expression representing t[0] - t[1] - .... *) val mk_sub : context -> arith_expr array -> arith_expr + + (** Create an expression representing -t. *) val mk_unary_minus : context -> arith_expr -> arith_expr + + (** Create an expression representing t1 / t2. *) val mk_div : context -> arith_expr -> arith_expr -> arith_expr + + (** Create an expression representing t1 ^ t2. *) val mk_power : context -> arith_expr -> arith_expr -> arith_expr + + (** Create an expression representing t1 < t2 *) val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 <= t2 *) val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 > t2 *) val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 >= t2 *) val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr end +(** Functions to manipulate bit-vector expressions *) and BitVector : sig type bitvec_sort = BitVecSort of Sort.sort @@ -945,280 +1451,1229 @@ sig val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + (** Create a new bit-vector sort. *) val mk_sort : context -> int -> bitvec_sort + + (** Indicates whether the terms is of bit-vector sort. *) val is_bv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector numeral *) val is_bv_numeral : Expr.expr -> bool + + (** Indicates whether the term is a one-bit bit-vector with value one *) val is_bv_bit1 : Expr.expr -> bool + + (** Indicates whether the term is a one-bit bit-vector with value zero *) val is_bv_bit0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unary minus *) val is_bv_uminus : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector addition (binary) *) val is_bv_add : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector subtraction (binary) *) val is_bv_sub : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector multiplication (binary) *) val is_bv_mul : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed division (binary) *) val is_bv_sdiv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned division (binary) *) val is_bv_udiv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed remainder (binary) *) val is_bv_SRem : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) val is_bv_urem : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed modulus *) val is_bv_smod : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed division by zero *) val is_bv_sdiv0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned division by zero *) val is_bv_udiv0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed remainder by zero *) val is_bv_srem0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned remainder by zero *) val is_bv_urem0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed modulus by zero *) val is_bv_smod0 : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) val is_bv_ule : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector less-than-or-equal *) val is_bv_sle : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) val is_bv_uge : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) val is_bv_sge : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector less-than *) val is_bv_ult : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector less-than *) val is_bv_slt : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector greater-than *) val is_bv_ugt : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector greater-than *) val is_bv_sgt : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise AND *) val is_bv_and : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise OR *) val is_bv_or : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NOT *) val is_bv_not : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise XOR *) val is_bv_xor : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NAND *) val is_bv_nand : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NOR *) val is_bv_nor : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise XNOR *) val is_bv_xnor : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector concatenation (binary) *) val is_bv_concat : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector sign extension *) val is_bv_signextension : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector zero extension *) val is_bv_zeroextension : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector extraction *) val is_bv_extract : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector repetition *) val is_bv_repeat : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector reduce OR *) val is_bv_reduceor : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector reduce AND *) val is_bv_reduceand : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector comparison *) val is_bv_comp : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector shift left *) val is_bv_shiftleft : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector logical shift right *) val is_bv_shiftrightlogical : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector arithmetic shift left *) val is_bv_shiftrightarithmetic : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate left *) val is_bv_rotateleft : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate right *) val is_bv_rotateright : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate left (extended) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) val is_bv_rotateleftextended : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate right (extended) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) val is_bv_rotaterightextended : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + + (** Indicates whether the term is a coercion from bit-vector to integer + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) val is_int_to_bv : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) val is_bv_to_int : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector carry + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) val is_bv_carry : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector ternary XOR + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) val is_bv_xor3 : Expr.expr -> bool + + (** The size of a bit-vector sort. *) val get_size : bitvec_sort -> int + + (** Retrieve the int value. *) val get_int : bitvec_num -> int + + (** Returns a string representation of the numeral. *) val to_string : bitvec_num -> string + + (** Creates a bit-vector constant. *) val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + + (** Creates a bit-vector constant. *) val mk_const_s : context -> string -> int -> bitvec_expr + + (** Bitwise negation. + The argument must have a bit-vector sort. *) val mk_not : context -> bitvec_expr -> Expr.expr + + (** Take conjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) val mk_redand : context -> bitvec_expr -> Expr.expr + + (** Take disjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) val mk_redor : context -> bitvec_expr -> Expr.expr + + (** Bitwise conjunction. + The arguments must have a bit-vector sort. *) val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise disjunction. + The arguments must have a bit-vector sort. *) val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise XOR. + The arguments must have a bit-vector sort. *) val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise NAND. + The arguments must have a bit-vector sort. *) val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise NOR. + The arguments must have a bit-vector sort. *) val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise XNOR. + The arguments must have a bit-vector sort. *) val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Standard two's complement unary minus. + The arguments must have a bit-vector sort. *) val mk_neg : context -> bitvec_expr -> bitvec_expr + + (** Two's complement addition. + The arguments must have the same bit-vector sort. *) val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement subtraction. + The arguments must have the same bit-vector sort. *) val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement multiplication. + The arguments must have the same bit-vector sort. *) val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned division. + + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. *) val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Signed remainder. + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned less-than + + The arguments must have the same bit-vector sort. *) val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed less-than + + The arguments must have the same bit-vector sort. *) val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned less-than or equal to. + + The arguments must have the same bit-vector sort. *) val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed less-than or equal to. + + The arguments must have the same bit-vector sort. *) val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned greater than or equal to. + + The arguments must have the same bit-vector sort. *) val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed greater than or equal to. + + The arguments must have the same bit-vector sort. *) val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned greater-than. + + The arguments must have the same bit-vector sort. *) val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed greater-than. + + The arguments must have the same bit-vector sort. *) val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Bit-vector concatenation. + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). *) val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bit-vector extraction. + + Extract the bits between two limits from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. *) val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector sign extension. + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. *) val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector zero extension. + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. *) val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector repetition. *) val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + + (** Shift left. + + It is equivalent to multiplication by 2^x where \c x is the value of third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling.*) val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Logical shift right + + It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Arithmetic shift right + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Rotate Left. + Rotate bits of \c t to the left \c i times. *) + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + + (** Rotate Right. + Rotate bits of \c t to the right \c i times.*) + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + + (** Rotate Left. + Rotate bits of the second argument to the left.*) + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Rotate Right. + Rotate bits of the second argument to the right. *) + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Create an integer from the bit-vector argument + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in the argument. + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function.*) val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + + (** Create a predicate that checks that the bit-wise addition does not overflow. + + The arguments must be of bit-vector sort. *) val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise addition does not underflow. + + The arguments must be of bit-vector sort. *) val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise subtraction does not overflow. + + The arguments must be of bit-vector sort. *) val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise subtraction does not underflow. + + The arguments must be of bit-vector sort. *) val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise signed division does not overflow. + + The arguments must be of bit-vector sort. *) val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise negation does not overflow. + + The arguments must be of bit-vector sort. *) val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise multiplication does not overflow. + + The arguments must be of bit-vector sort. *) val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise multiplication does not underflow. + + The arguments must be of bit-vector sort. *) val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a bit-vector numeral. *) val mk_numeral : context -> string -> int -> bitvec_num end +(** Functions to manipulate proof expressions *) module Proof : sig + (** Indicates whether the term is a Proof for the expression 'true'. *) val is_true : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact asserted by the user. *) val is_asserted : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) val is_goal : Expr.expr -> bool + + (** Indicates whether the term is proof via modus ponens + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). *) val is_modus_ponens : Expr.expr -> bool + + (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. *) val is_reflexivity : Expr.expr -> bool + + (** Indicates whether the term is proof by symmetricity of a relation + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. *) val is_symmetry : Expr.expr -> bool + + (** Indicates whether the term is a proof by transitivity of a relation + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) *) val is_transitivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by condensed transitivity of a relation + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. *) val is_Transitivity_star : Expr.expr -> bool + + (** Indicates whether the term is a monotonicity proof object. + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. *) val is_monotonicity : Expr.expr -> bool + + (** Indicates whether the term is a quant-intro proof + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) val is_quant_intro : Expr.expr -> bool + + (** Indicates whether the term is a distributivity proof object. + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. *) val is_distributivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by elimination of AND + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i *) val is_and_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by eliminiation of not-or + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) *) val is_or_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) val is_rewrite : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) val is_rewrite_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) val is_pull_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents *) val is_pull_quant_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pushing quantifiers in. + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents *) val is_push_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for elimination of unused variables. + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. *) val is_elim_unused_vars : Expr.expr -> bool + + (** Indicates whether the term is a proof for destructive equality resolution + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. *) val is_der : Expr.expr -> bool + + (** Indicates whether the term is a proof for quantifier instantiation + + A proof of (or (not (forall (x) (P x))) (P a)) *) val is_quant_inst : Expr.expr -> bool + + (** Indicates whether the term is a hypthesis marker. + Mark a hypothesis in a natural deduction style proof. *) val is_hypothesis : Expr.expr -> bool + + (** Indicates whether the term is a proof by lemma + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. *) val is_lemma : Expr.expr -> bool + + (** Indicates whether the term is a proof by unit resolution + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) val is_unit_resolution : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-true + + T1: p + [iff-true T1]: (iff p true) *) val is_iff_true : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-false + + T1: (not p) + [iff-false T1]: (iff p false) *) val is_iff_false : Expr.expr -> bool + + (** Indicates whether the term is a proof by commutativity + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. *) val is_commutativity : Expr.expr -> bool + + (** Indicates whether the term is a proof for Tseitin-like axioms + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). *) val is_def_axiom : Expr.expr -> bool + + (** Indicates whether the term is a proof for introduction of a name + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) *) val is_def_intro : Expr.expr -> bool + + (** Indicates whether the term is a proof for application of a definition + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. *) val is_apply_def : Expr.expr -> bool + + (** Indicates whether the term is a proof iff-oeq + + T1: (iff p q) + [iff~ T1]: (~ p q) *) val is_iff_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for a positive NNF step + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. *) val is_nnf_pos : Expr.expr -> bool + + (** Indicates whether the term is a proof for a negative NNF step + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) *) val is_nnf_neg : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) val is_nnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) val is_cnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for a Skolemization step + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. *) val is_skolemize : Expr.expr -> bool + + (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q *) val is_modus_ponens_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for theory lemma + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) val is_theory_lemma : Expr.expr -> bool end +(** Goals + A goal (aka problem). A goal is essentially a + of formulas, that can be solved and/or transformed using + tactics and solvers. *) module Goal : sig type goal + (** The precision of the goal. + + Goals can be transformed using over and under approximations. + An under approximation is applied when the objective is to find a model for a given goal. + An over approximation is applied when the objective is to find a proof for a given goal. *) val get_precision : goal -> Z3enums.goal_prec + + (** Indicates whether the goal is precise. *) val is_precise : goal -> bool + + (** Indicates whether the goal is an under-approximation. *) val is_underapproximation : goal -> bool + + (** Indicates whether the goal is an over-approximation. *) val is_overapproximation : goal -> bool + + (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) val is_garbage : goal -> bool + + (** Adds the constraints to the given goal. *) val assert_ : goal -> Boolean.bool_expr array -> unit + + (** Indicates whether the goal contains `false'. *) val is_inconsistent : goal -> bool + + (** The depth of the goal. + This tracks how many transformations were applied to it. *) val get_depth : goal -> int + + (** Erases all formulas from the given goal. *) val reset : goal -> unit + + (** The number of formulas in the goal. *) val get_size : goal -> int + + (** The formulas in the goal. *) val get_formulas : goal -> Boolean.bool_expr array + + (** The number of formulas, subformulas and terms in the goal. *) val get_num_exprs : goal -> int + + (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) val is_decided_sat : goal -> bool + + (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) val is_decided_unsat : goal -> bool + + (** Translates (copies) the Goal to another context.. *) val translate : goal -> context -> goal + + (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) val simplify : goal -> Params.params option -> goal + + (** Creates a new Goal. + + Note that the Context must have been created with proof generation support if + the fourth argument is set to true here. *) val mk_goal : context -> bool -> bool -> bool -> goal + + (** A string representation of the Goal. *) val to_string : goal -> string end +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) module Model : sig type model + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. *) module FuncInterp : sig type func_interp - + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. *) module FuncEntry : sig type func_entry - + + (** Return the (symbolic) value of this entry. + *) val get_value : func_entry -> Expr.expr + + (** The number of arguments of the entry. + *) val get_num_args : func_entry -> int + + (** The arguments of the function entry. + *) val get_args : func_entry -> Expr.expr array + + (** A string representation of the function entry. + *) val to_string : func_entry -> string end + (** The number of entries in the function interpretation. *) val get_num_entries : func_interp -> int + + (** The entries in the function interpretation *) val get_entries : func_interp -> FuncEntry.func_entry array + + (** The (symbolic) `else' value of the function interpretation. *) val get_else : func_interp -> Expr.expr + + (** The arity of the function interpretation *) val get_arity : func_interp -> int + + (** A string representation of the function interpretation. *) val to_string : func_interp -> string end + (** Retrieves the interpretation (the assignment) of a func_decl in the model. + An expression if the function has an interpretation in the model, null otherwise. *) val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option + + (** Retrieves the interpretation (the assignment) of an expression in the model. + An expression if the constant has an interpretation in the model, null otherwise. *) val get_const_interp_e : model -> Expr.expr -> Expr.expr option + + (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option + + (** The number of constant interpretations in the model. *) val get_num_consts : model -> int + + (** The function declarations of the constants in the model. *) val get_const_decls : model -> FuncDecl.func_decl array + + (** The number of function interpretations in the model. *) val get_num_funcs : model -> int + + (** The function declarations of the function interpretations in the model. *) val get_func_decls : model -> FuncDecl.func_decl array + + (** All symbols that have an interpretation in the model. *) val get_decls : model -> FuncDecl.func_decl array + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) exception ModelEvaluationFailedException of string + + (** Evaluates an expression in the current model. + + This function may fail if the argument contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + *) val eval : model -> Expr.expr -> bool -> Expr.expr + + (** Alias for eval. *) val evaluate : model -> Expr.expr -> bool -> Expr.expr + + (** The number of uninterpreted sorts that the model has an interpretation for. *) val get_num_sorts : model -> int + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + {!get_num_sorts} + {!sort_universe} *) val get_sorts : model -> Sort.sort array + + (** The finite set of distinct values that represent the interpretation of a sort. + {!get_sorts} + @returns An array of expressions, where each is an element of the universe of the sort *) val sort_universe : model -> Sort.sort -> AST.ASTVector.ast_vector array + + (** Conversion of models to strings. + A string representation of the model. *) val to_string : model -> string end +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) module Probe : sig type probe + (** Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) val apply : probe -> Goal.goal -> float + + (** The number of supported Probes. *) val get_num_probes : context -> int + + (** The names of all supported Probes. *) val get_probe_names : context -> string array + + (** Returns a string containing a description of the probe with the given name. *) val get_probe_description : context -> string -> string + + (** Creates a new Probe. *) val mk_probe : context -> string -> probe + + (** Create a probe that always evaluates to a float value. *) val const : context -> float -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than the value returned by second argument *) val lt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than the value returned by second argument *) val gt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than or equal the value returned by second argument *) val le : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than or equal the value returned by second argument *) val ge : context -> probe -> probe -> probe + + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is equal the value returned by second argument *) val eq : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) val and_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) val or_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) val not_ : context -> probe -> probe end +(** Tactics + + Tactics are the basic building block for creating custom solvers for specific problem domains. + The complete list of tactics may be obtained using Context.get_num_tactics + and Context.get_tactic_names. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) module Tactic : sig type tactic + (** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) module ApplyResult : sig type apply_result + (** The number of Subgoals. *) val get_num_subgoals : apply_result -> int + + (** Retrieves the subgoals from the apply_result. *) val get_subgoals : apply_result -> Goal.goal array + + (** Retrieves a subgoal from the apply_result. *) val get_subgoal : apply_result -> int -> Goal.goal + + (** Convert a model for a subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g *) val convert_model : apply_result -> int -> Model.model -> Model.model + + (** A string representation of the ApplyResult. *) val to_string : apply_result -> string end + (** A string containing a description of parameters accepted by the tactic. *) val get_help : tactic -> string + + (** Retrieves parameter descriptions for Tactics. *) val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs + + (** Apply the tactic to the goal. *) val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result + + (** The number of supported tactics. *) val get_num_tactics : context -> int + + (** The names of all supported tactics. *) val get_tactic_names : context -> string array + + (** Returns a string containing a description of the tactic with the given name. *) val get_tactic_description : context -> string -> string + + (** Creates a new Tactic. *) val mk_tactic : context -> string -> tactic + + (** Create a tactic that applies one tactic to a Goal and + then another one to every subgoal produced by the first one. *) val and_then : context -> tactic -> tactic -> tactic array -> tactic + + (** Create a tactic that first applies one tactic to a Goal and + if it fails then returns the result of another tactic applied to the Goal. *) val or_else : context -> tactic -> tactic -> tactic + + (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). + + If the tactic does not terminate within the timeout, then it fails. *) val try_for : context -> tactic -> int -> tactic + + (** Create a tactic that applies one tactic to a given goal if the probe + evaluates to true. + + If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) val when_ : context -> Probe.probe -> tactic -> tactic + + (** Create a tactic that applies a tactic to a given goal if the probe + evaluates to true and another tactic otherwise. *) val cond : context -> Probe.probe -> tactic -> tactic -> tactic + + (** Create a tactic that keeps applying one tactic until the goal is not + modified anymore or the maximum number of iterations is reached. *) val repeat : context -> tactic -> int -> tactic + + (** Create a tactic that just returns the given goal. *) val skip : context -> tactic + + (** Create a tactic always fails. *) val fail : context -> tactic + + (** Create a tactic that fails if the probe evaluates to false. *) val fail_if : context -> Probe.probe -> tactic + + (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) val fail_if_not_decided : context -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. *) val using_params : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. + Alias for UsingParams*) val with_ : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies the given tactics in parallel. *) val par_or : context -> tactic array -> tactic + + (** Create a tactic that applies a tactic to a given goal and then another tactic + to every subgoal produced by the first one. The subgoals are processed in parallel. *) val par_and_then : context -> tactic -> tactic -> tactic + + (** Interrupt the execution of a Z3 procedure. + This procedure can be used to interrupt: solvers, simplifiers and tactics. *) val interrupt : context -> unit end +(** Solvers *) module Solver : sig type solver @@ -1226,108 +2681,388 @@ sig val string_of_status : status -> string + (** Objects that track statistical information about solvers. *) module Statistics : sig type statistics + (** Statistical data is organized into pairs of \[Key, Entry\], where every + Entry is either a floating point or integer value. + *) module Entry : sig type statistics_entry + (** The key of the entry. *) val get_key : statistics_entry -> string + + (** The int-value of the entry. *) val get_int : statistics_entry -> int + + (** The float-value of the entry. *) val get_float : statistics_entry -> float + + (** True if the entry is uint-valued. *) val is_int : statistics_entry -> bool + + (** True if the entry is double-valued. *) val is_float : statistics_entry -> bool + + (** The string representation of the the entry's value. *) val to_string_value : statistics_entry -> string + + (** The string representation of the entry (key and value) *) val to_string : statistics_entry -> string end + (** A string representation of the statistical data. *) val to_string : statistics -> string + + (** The number of statistical data. *) val get_size : statistics -> int + + (** The data entries. *) val get_entries : statistics -> Entry.statistics_entry array + + (** The statistical counters. *) val get_keys : statistics -> string array + + (** The value of a particular statistical counter. *) val get : statistics -> string -> Entry.statistics_entry option end + (** A string that describes all available solver parameters. *) val get_help : solver -> string + + (** Sets the solver parameters. *) val set_parameters : solver -> Params.params -> unit + + (** Retrieves parameter descriptions for solver. *) val get_param_descrs : solver -> Params.ParamDescrs.param_descrs + + (** The current number of backtracking points (scopes). + {!pop} + {!push} *) val get_num_scopes : solver -> int + + (** Creates a backtracking point. + {!pop} *) val push : solver -> unit + + (** Backtracks a number of backtracking points. + Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} + {!push} *) val pop : solver -> int -> unit + + (** Resets the Solver. + This removes all assertions from the solver. *) val reset : solver -> unit + + (** Assert a constraint (or multiple) into the solver. *) val assert_ : solver -> Boolean.bool_expr array -> unit + + (** * Assert multiple constraints (cs) into the solver, and track them (in the + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track_a : solver -> Boolean.bool_expr array -> Boolean.bool_expr array -> unit + + (** * Assert a constraint (c) into the solver, and track it (in the unsat) core + * using the Boolean constant p. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit + + (** The number of assertions in the solver. *) val get_num_assertions : solver -> int + + (** The set of asserted formulas. *) val get_assertions : solver -> Boolean.bool_expr array + + (** Checks whether the assertions in the solver are consistent or not. + + {!Model} + {!get_unsat_core} + {!Proof} *) val check : solver -> Boolean.bool_expr array -> status + + (** The model of the last Check. + + The result is None if Check was not invoked before, + if its results was not SATISFIABLE, or if model production is not enabled. *) val get_model : solver -> Model.model option + + (** The proof of the last Check. + + The result is null if Check was not invoked before, + if its results was not UNSATISFIABLE, or if proof production is disabled. *) val get_proof : solver -> Expr.expr option + + (** The unsat core of the last Check. + + The unsat core is a subset of Assertions + The result is empty if Check was not invoked before, + if its results was not UNSATISFIABLE, or if core production is disabled. *) val get_unsat_core : solver -> AST.ASTVector.ast_vector array + + (** A brief justification of why the last call to Check returned UNKNOWN. *) val get_reason_unknown : solver -> string + + (** Solver statistics. *) val get_statistics : solver -> Statistics.statistics + + (** Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) val mk_solver : context -> Symbol.symbol option -> solver + + (** Creates a new (incremental) solver. + {!mk_solver} *) val mk_solver_s : context -> string -> solver + + (** Creates a new (incremental) solver. *) val mk_simple_solver : context -> solver + + (** Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) val mk_solver_t : context -> Tactic.tactic -> solver + + (** A string representation of the solver. *) val to_string : solver -> string end +(** Fixedpoint solving *) module Fixedpoint : sig type fixedpoint + (** A string that describes all available fixedpoint solver parameters. *) val get_help : fixedpoint -> string + + (** Sets the fixedpoint solver parameters. *) val set_params : fixedpoint -> Params.params -> unit + + (** Retrieves parameter descriptions for Fixedpoint solver. *) val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs + + (** Assert a constraints into the fixedpoint solver. *) val assert_ : fixedpoint -> Boolean.bool_expr array -> unit + + (** Register predicate as recursive relation. *) val register_relation : fixedpoint -> FuncDecl.func_decl -> unit + + (** Add rule into the fixedpoint solver. *) val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit + + (** Add table fact to the fixedpoint solver. *) val add_fact : fixedpoint -> FuncDecl.func_decl -> int array -> unit + + (** Query the fixedpoint solver. + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. *) val query : fixedpoint -> Boolean.bool_expr -> Solver.status + + (** Query the fixedpoint solver. + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. *) val query_r : fixedpoint -> FuncDecl.func_decl array -> Solver.status + + (** Creates a backtracking point. + {!pop} *) val push : fixedpoint -> unit + + (** Backtrack one backtracking point. + + Note that an exception is thrown if Pop is called without a corresponding Push + {!push} *) val pop : fixedpoint -> unit + + (** Update named rule into in the fixedpoint solver. *) val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit + + (** Retrieve satisfying instance or instances of solver, + or definitions for the recursive predicates that show unsatisfiability. *) val get_answer : fixedpoint -> Expr.expr option + + (** Retrieve explanation why fixedpoint engine returned status Unknown. *) val get_reason_unknown : fixedpoint -> string + + (** Retrieve the number of levels explored for a given predicate. *) val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int + + (** Retrieve the cover of a predicate. *) val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option + + (** Add property about the predicate. + The property is added at level. *) val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit + + (** Retrieve internal string representation of fixedpoint object. *) val to_string : fixedpoint -> string + + (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol array -> unit + + (** Convert benchmark given as set of axioms, rules and queries to a string. *) val to_string_q : fixedpoint -> Boolean.bool_expr array -> string + + (** Retrieve set of rules added to fixedpoint context. *) val get_rules : fixedpoint -> Boolean.bool_expr array + + (** Retrieve set of assertions added to fixedpoint context. *) val get_assertions : fixedpoint -> Boolean.bool_expr array + + (** Create a Fixedpoint context. *) val mk_fixedpoint : context -> fixedpoint end +(** Global and context options + + Note: This module contains functions that set parameters/options for context + objects as well as functions that set options that are used globally, across + contexts.*) module Options : sig + (** Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + {!get_param_value} *) val update_param_value : context -> string -> string -> unit + + (** Get a configuration parameter. + + Returns None if the parameter value does not exist. + {!update_param_value} *) val get_param_value : context -> string -> string option + + (** Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) val set_print_mode : context -> Z3enums.ast_print_mode -> unit + + (** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) val toggle_warning_messages : bool -> unit end +(** Functions for handling SMT and SMT2 expressions and files *) module SMT : sig + (** Convert a benchmark into an SMT-LIB formatted string. + + @return A string representation of the benchmark. *) val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr array -> Boolean.bool_expr -> string + + (** Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays in the third and fifth argument + don't need to match the names of the sorts and declarations in the arrays in the fourth + and sixth argument. This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) val parse_smtlib_string : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> unit + + (** Parse the given file using the SMT-LIB parser. + {!parse_smtlib_string} *) val parse_smtlib_file : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> unit + + (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_formulas : context -> int + + (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_smtlib_formulas : context -> Boolean.bool_expr array + + (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_assumptions : context -> int + + (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_smtlib_assumptions : context -> Boolean.bool_expr array + + (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_decls : context -> int + + (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_smtlib_decls : context -> FuncDecl.func_decl array + + (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_sorts : context -> int + + (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_smtlib_sorts : context -> Sort.sort array + + (** Parse the given string using the SMT-LIB2 parser. + + {!parse_smtlib_string} + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) val parse_smtlib2_string : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> Boolean.bool_expr + + (** Parse the given file using the SMT-LIB2 parser. + {!parse_smtlib2_string} *) val parse_smtlib2_file : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> Boolean.bool_expr end +(** Set a global (or module) parameter, which is shared by all Z3 contexts. + + When a Z3 module is initialized it will use the value of these parameters + when Z3_params objects are not provided. + The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + The character '.' is a delimiter (more later). + The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + This function can be used to set parameters for a specific Z3 module. + This can be done by using .. + For example: + (set_global_param "pp.decimal" "true") + will set the parameter "decimal" in the module "pp" to true. +*) val set_global_param : string -> string -> unit + +(** Get a global (or module) parameter. + + Returns None if the parameter does not exist. + The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + This function cannot be invoked simultaneously from different threads without synchronization. + The result string stored in param_value is stored in a shared location. +*) val get_global_param : string -> string option + +(** Restore the value of all global (and module) parameters. + + This command will not affect already created objects (such as tactics and solvers) + {!set_global_param} +*) val global_param_reset_all : unit From 79d0c32c919a18b175b1d33e6b64b7a0caa1319a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 00:29:51 +0000 Subject: [PATCH 403/507] ML API: replaced arrays with lists. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 46 ++-- src/api/ml/z3.ml | 507 +++++++++++++++++++------------------- src/api/ml/z3.mli | 184 +++++++------- 3 files changed, 371 insertions(+), 366 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 6dfe11623..31f31d566 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -33,13 +33,13 @@ let model_converter_test ( ctx : context ) = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [| (mk_gt ctx xr + (Goal.assert_ g4 [ (mk_gt ctx xr (arith_expr_of_real_expr (real_expr_of_rat_num - (Real.mk_numeral_nd ctx 10 1)))) |]) ; - (Goal.assert_ g4 [| (mk_eq ctx + (Real.mk_numeral_nd ctx 10 1)))) ]) ; + (Goal.assert_ g4 [ (mk_eq ctx (expr_of_arith_expr yr) - (expr_of_arith_expr (Arithmetic.mk_add ctx [| xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) |]) ) ) |] ) ; - (Goal.assert_ g4 [| (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) |]) ; + (expr_of_arith_expr (Arithmetic.mk_add ctx [ xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) ]) ) ) ] ) ; + (Goal.assert_ g4 [ (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) ]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -50,7 +50,7 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ); ( - let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") [||]) g4 None) in + let ar = (Tactic.apply (and_then ctx (mk_tactic ctx ("simplify")) (mk_tactic ctx "solve-eqs") []) g4 None) in if ((get_num_subgoals ar) == 1 && ((is_decided_sat (get_subgoal ar 0)) || (is_decided_unsat (get_subgoal ar 0)))) then @@ -59,9 +59,9 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ; let solver = (mk_solver ctx None) in - let f e = (Solver.assert_ solver [| e |]) in - ignore (Array.map f (get_formulas (get_subgoal ar 0))) ; - let q = (check solver [||]) in + let f e = (Solver.assert_ solver [ e ]) in + ignore (List.map f (get_formulas (get_subgoal ar 0))) ; + let q = (check solver []) in if q != SATISFIABLE then raise (TestFailedException "") else @@ -84,23 +84,23 @@ let basic_tests ( ctx : context ) = let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in let bs = (sort_of_bool_sort (Boolean.mk_sort ctx)) in - let domain = [| bs; bs |] in + let domain = [ bs; bs ] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in let fapp = (mk_app ctx f - [| (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) |]) in - let fargs2 = [| (mk_fresh_const ctx "cp" bs) |] in - let domain2 = [| bs |] in + [ (Expr.mk_const ctx x bs); (Expr.mk_const ctx y bs) ]) in + let fargs2 = [ (mk_fresh_const ctx "cp" bs) ] in + let domain2 = [ bs ] in let fapp2 = (mk_app ctx (mk_fresh_func_decl ctx "fp" domain2 bs) fargs2) in let trivial_eq = (mk_eq ctx fapp fapp) in let nontrivial_eq = (mk_eq ctx fapp fapp2) in let g = (mk_goal ctx true false false) in - (Goal.assert_ g [| trivial_eq |]) ; - (Goal.assert_ g [| nontrivial_eq |]) ; + (Goal.assert_ g [ trivial_eq ]) ; + (Goal.assert_ g [ nontrivial_eq ]) ; Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; ( let solver = (mk_solver ctx None) in - (Array.iter (fun a -> (Solver.assert_ solver [| a |])) (get_formulas g)) ; - if (check solver [||]) != SATISFIABLE then + (List.iter (fun a -> (Solver.assert_ solver [ a ])) (get_formulas g)) ; + if (check solver []) != SATISFIABLE then raise (TestFailedException "") else Printf.printf "Test passed.\n" @@ -122,11 +122,11 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ); - (Goal.assert_ g [| (mk_eq ctx + (Goal.assert_ g [ (mk_eq ctx (mk_numeral_int ctx 1 (sort_of_bitvec_sort (BitVector.mk_sort ctx 32))) (mk_numeral_int ctx 2 - (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) |] ) + (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) ] ) ; ( let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in @@ -147,7 +147,7 @@ let basic_tests ( ctx : context ) = ); ( let g2 = (mk_goal ctx true true false) in - (Goal.assert_ g2 [| (Boolean.mk_false ctx) |]) ; + (Goal.assert_ g2 [ (Boolean.mk_false ctx) ]) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then @@ -159,10 +159,10 @@ let basic_tests ( ctx : context ) = let g3 = (mk_goal ctx true true false) in let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in - (Goal.assert_ g3 [| (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; - (Goal.assert_ g3 [| (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) |]) ; + (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; + (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; let constr = (mk_eq ctx xc yc) in - (Goal.assert_ g3 [| constr |] ) ; + (Goal.assert_ g3 [ constr ] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b1e40fcac..56d319c1a 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -79,10 +79,6 @@ struct let z3obj_nil_ref x y = () - let array_to_native a = - let f e = (z3obj_gno e) in - Array.map f a - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> let res : z3_native_object = { m_ctx = ctx ; m_n_obj = null ; @@ -127,6 +123,9 @@ let mk_list ( f : int -> 'a ) ( n : int ) = in mk_list' f 0 n [] +let list_of_array ( x : _ array ) = + let f i = (Array.get x i) in + mk_list f (Array.length x) let mk_context ( cfg : ( string * string ) list ) = create_context cfg @@ -180,6 +179,10 @@ struct match x with | S_Int(n) -> (z3obj_gno n) | S_Str(n) -> (z3obj_gno n) + + let symbol_lton ( a : symbol list ) = + let f ( e : symbol ) = (gno e) in + Array.of_list (List.map f a) let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL @@ -197,13 +200,13 @@ struct let mk_string ( ctx : context ) ( s : string ) = S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - let mk_ints ( ctx : context ) ( names : int array ) = + let mk_ints ( ctx : context ) ( names : int list ) = let f elem = mk_int ( ctx : context ) elem in - (Array.map f names) + (List.map f names) - let mk_strings ( ctx : context ) ( names : string array ) = + let mk_strings ( ctx : context ) ( names : string list ) = let f elem = mk_string ( ctx : context ) elem in - (Array.map f names) + (List.map f names) end @@ -292,7 +295,9 @@ struct Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) let get_keys ( x : ast_map ) = - ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) + let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in + let f i = (ASTVector.get av i) in + mk_list f (ASTVector.get_size av) let to_string ( x : ast_map ) = Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) @@ -376,10 +381,13 @@ struct else UninterpretedSort(s) - let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) + + let sort_lton ( a : sort list ) = + let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) let ( = ) : sort -> sort -> bool = fun a b -> (a == b) || @@ -438,9 +446,9 @@ sig val get_func_decl : parameter -> func_decl val get_rational : parameter -> string end - val mk_func_decl : context -> Symbol.symbol -> Sort.sort array -> Sort.sort -> func_decl - val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl - val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl val mk_const_decl_s : context -> string -> Sort.sort -> func_decl val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl @@ -449,13 +457,13 @@ sig val get_id : func_decl -> int val get_arity : func_decl -> int val get_domain_size : func_decl -> int - val get_domain : func_decl -> Sort.sort array + val get_domain : func_decl -> Sort.sort list val get_range : func_decl -> Sort.sort val get_decl_kind : func_decl -> Z3enums.decl_kind val get_name : func_decl -> Symbol.symbol val get_num_parameters : func_decl -> int val get_parameters : func_decl -> Parameter.parameter list - val apply : func_decl -> Expr.expr array -> Expr.expr + val apply : func_decl -> Expr.expr list -> Expr.expr end = struct type func_decl = FuncDecl of AST.ast @@ -467,23 +475,21 @@ end = struct let ast_of_func_decl f = match f with FuncDecl(x) -> x - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (AST.ptr_of_ast (ast_of_sort x)) in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (Array.length domain) (Array.map f domain) (Sort.gno range))) ; + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = let res = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.inc_ref ; dec_ref = Z3native.dec_ref } in - let f x = (AST.ptr_of_ast (ast_of_sort x)) in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (Array.length domain) (Array.map f domain) (Sort.gno range))) ; + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; (z3obj_create res) ; FuncDecl(res) @@ -548,23 +554,23 @@ end = struct | _ -> raise (Z3native.Exception "parameter is not a rational string") end - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = create_ndr ctx name domain range - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort array ) ( range : sort ) = + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = mk_func_decl ctx (Symbol.mk_string ctx name) domain range - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort array ) ( range : sort ) = + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = create_pdr ctx prefix domain range let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_ndr ctx name [||] range + create_ndr ctx name [] range let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = - create_ndr ctx (Symbol.mk_string ctx name) [||] range + create_ndr ctx (Symbol.mk_string ctx name) [] range let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = - create_pdr ctx prefix [||] range + create_pdr ctx prefix [] range let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || @@ -584,7 +590,7 @@ end = struct let get_domain ( x : func_decl ) = let n = (get_domain_size x) in let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in - Array.init n f + mk_list f n let get_range ( x : func_decl ) = sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) @@ -608,7 +614,7 @@ end = struct ) in mk_list f n - let apply ( x : func_decl ) ( args : Expr.expr array ) = Expr.expr_of_func_app (gc x) x args + let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args end @@ -621,7 +627,7 @@ sig val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs val validate : param_descrs -> params -> unit val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - val get_names : param_descrs -> Symbol.symbol array + val get_names : param_descrs -> Symbol.symbol list val get_size : param_descrs -> int val to_string : param_descrs -> string end @@ -660,7 +666,7 @@ end = struct let get_names ( x : param_descrs ) = let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) @@ -710,21 +716,21 @@ sig val c_of_expr : expr -> context val nc_of_expr : expr -> Z3native.ptr val ptr_of_expr : expr -> Z3native.ptr - val expr_aton : expr array -> Z3native.ptr array + val expr_lton : expr list -> Z3native.ptr array val ast_of_expr : expr -> AST.ast val expr_of_ast : AST.ast -> expr - val expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr + val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr val simplify : expr -> Params.params option -> expr val get_simplify_help : context -> string val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs val get_func_decl : expr -> FuncDecl.func_decl val get_bool_value : expr -> Z3enums.lbool val get_num_args : expr -> int - val get_args : expr -> expr array - val update : expr -> expr array -> expr - val substitute : expr -> expr array -> expr array -> expr + val get_args : expr -> expr list + val update : expr -> expr list -> expr + val substitute : expr -> expr list -> expr list -> expr val substitute_one : expr -> expr -> expr -> expr - val substitute_vars : expr -> expr array -> expr + val substitute_vars : expr -> expr list -> expr val translate : expr -> context -> expr val to_string : expr -> string val is_numeral : expr -> bool @@ -750,7 +756,7 @@ sig val mk_const_s : context -> string -> Sort.sort -> expr val mk_const_f : context -> FuncDecl.func_decl -> expr val mk_fresh_const : context -> string -> Sort.sort -> expr - val mk_app : context -> FuncDecl.func_decl -> expr array -> expr + val mk_app : context -> FuncDecl.func_decl -> expr list -> expr val mk_numeral_string : context -> string -> Sort.sort -> expr val mk_numeral_int : context -> int -> Sort.sort -> expr end = struct @@ -786,13 +792,13 @@ end = struct let ast_of_expr e = match e with Expr(a) -> a - let expr_aton ( a : expr array ) = + let expr_lton ( a : expr list ) = let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in - Array.map f a + Array.of_list (List.map f a) - let expr_of_func_app : context -> FuncDecl.func_decl -> expr array -> expr = fun ctx f args -> + let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> match f with FuncDecl.FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (Array.length args) (expr_aton args) in + let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in expr_of_ptr ctx o let simplify ( x : expr ) ( p : Params.params option ) = match p with @@ -812,25 +818,25 @@ end = struct let get_args ( x : expr ) = let n = (get_num_args x) in let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in - Array.init n f + mk_list f n - let update ( x : expr ) args = - if (Array.length args <> (get_num_args x)) then + let update ( x : expr ) ( args : expr list ) = + if (List.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (Array.length args) (expr_aton args)) + expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (List.length args) (expr_lton args)) let substitute ( x : expr ) from to_ = - if (Array.length from) <> (Array.length to_) then + if (List.length from) <> (List.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (Array.length from) (expr_aton from) (expr_aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (List.length from) (expr_lton from) (expr_lton to_)) let substitute_one ( x : expr ) from to_ = - substitute ( x : expr ) [| from |] [| to_ |] + substitute ( x : expr ) [ from ] [ to_ ] let substitute_vars ( x : expr ) to_ = - expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (Array.length to_) (expr_aton to_)) + expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (List.length to_) (expr_lton to_)) let translate ( x : expr ) to_ctx = if (c_of_expr x) == to_ctx then @@ -876,12 +882,12 @@ end = struct let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) range - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [||] + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr array ) = expr_of_func_app ctx f args + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) @@ -950,8 +956,8 @@ struct let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) - let mk_distinct ( ctx : context ) ( args : expr array ) = - bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (Array.length args) (expr_aton args)) + let mk_distinct ( ctx : context ) ( args : expr list ) = + bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) let mk_not ( ctx : context ) ( a : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) @@ -968,13 +974,13 @@ struct let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - let mk_and ( ctx : context ) ( args : bool_expr array ) = + let mk_and ( ctx : context ) ( args : bool_expr list ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (Array.length args) (Array.map f args)) + bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - let mk_or ( ctx : context ) ( args : bool_expr array ) = + let mk_or ( ctx : context ) ( args : bool_expr list ) = let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (Array.length args) (Array.map f args)) + bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) end @@ -1016,7 +1022,7 @@ struct let get_terms ( x : pattern ) = let n = (get_num_terms x) in let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) end @@ -1039,26 +1045,26 @@ struct let get_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) let get_no_patterns ( x : quantifier ) = let n = (get_num_patterns x) in let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) let get_bound_variable_names ( x : quantifier ) = let n = (get_num_bound x) in let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_bound_variable_sorts ( x : quantifier ) = let n = (get_num_bound x) in let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in - Array.init n f + mk_list f n let get_body ( x : quantifier ) = Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) @@ -1066,95 +1072,95 @@ struct let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - let mk_pattern ( ctx : context ) ( terms : expr array ) = - if (Array.length terms) == 0 then + let mk_pattern ( ctx : context ) ( terms : expr list ) = + if (List.length terms) == 0 then raise (Z3native.Exception "Cannot create a pattern from zero terms") else - Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (Array.length terms) (expr_aton terms))) + Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) - let mk_forall ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (Array.length sorts) != (Array.length names) then + let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) - let mk_forall_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) (ptr_of_expr body))) - let mk_exists ( ctx : context ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (Array.length sorts) != (Array.length names) then + let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) - (Array.length sorts) (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - (let f x = (Symbol.gno x) in (Array.map f names)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) (ptr_of_expr body))) - let mk_exists_const ( ctx : context ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((Array.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (ptr_of_expr body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (Array.length bound_constants) (expr_aton bound_constants) - (Array.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.map f patterns)) - (Array.length nopatterns) (expr_aton nopatterns) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) (ptr_of_expr body))) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort array ) ( names : Symbol.symbol array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) else (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr array ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern array ) ( nopatterns : expr array ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else @@ -1233,9 +1239,9 @@ struct let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr array ) = + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = let m x = (ptr_of_expr (expr_of_array_expr x)) in - array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (Array.length args) (Array.map m args)) + array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) let mk_term_array ( ctx : context ) ( arg : array_expr ) = array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) @@ -1274,11 +1280,11 @@ struct let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) - let mk_union ( ctx : context ) ( args : expr array ) = - expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (Array.length args) (expr_aton args)) + let mk_union ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) - let mk_intersection ( ctx : context ) ( args : expr array ) = - expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (Array.length args) (expr_aton args)) + let mk_intersection ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) @@ -1378,7 +1384,7 @@ struct let get_column_sorts ( x : relation_sort ) = let n = get_arity x in let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in - Array.init n f + mk_list f n end @@ -1418,21 +1424,23 @@ struct module Constructor = struct type constructor = z3_native_object + + let _sizes = Hashtbl.create 0 - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = - let n = (Array.length field_names) in - if n != (Array.length sorts) then + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let n = (List.length field_names) in + if n != (List.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") else - if n != (Array.length sort_refs) then + if n != (List.length sort_refs) then raise (Z3native.Exception "Number of field names does not match number of sort refs") else let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) (Symbol.gno recognizer) n - (let f x = (Symbol.gno x) in (Array.map f field_names)) - (let f x = (AST.ptr_of_ast (ast_of_sort x)) in (Array.map f sorts)) - sort_refs) in + (Symbol.symbol_lton field_names) + (sort_lton sorts) + (Array.of_list sort_refs)) in let no : constructor = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; @@ -1441,9 +1449,10 @@ struct (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; + Hashtbl.add _sizes no n ; no - let get_num_fields ( x : constructor ) = Z3native.get_arity (z3obj_gnc x) (z3obj_gno x) + let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x let get_constructor_decl ( x : constructor ) = let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in @@ -1455,8 +1464,8 @@ struct let get_accessor_decls ( x : constructor ) = let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - let f y = func_decl_of_ptr (z3obj_gc x) y in - Array.map f c + let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in + mk_list f (Array.length c) end @@ -1464,48 +1473,47 @@ struct struct type constructor_list = z3_native_object - let create ( ctx : context ) ( c : Constructor.constructor array ) = + let create ( ctx : context ) ( c : Constructor.constructor list ) = let res : constructor_list = { m_ctx = ctx ; m_n_obj = null ; inc_ref = z3obj_nil_ref ; dec_ref = z3obj_nil_ref} in let f x =(z3obj_gno x) in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (Array.length c) (Array.map f c))) ; + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; (z3obj_create res) ; let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f res; res end - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = Constructor.create ctx name recognizer field_names sorts sort_refs - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( sorts : sort array ) ( sort_refs : int array ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor array ) = + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = let f x = (z3obj_gno x) in - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (Array.length constructors) (Array.map f constructors)) in + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in sort_of_ptr ctx x - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = mk_sort ctx (Symbol.mk_string ctx name) constructors - let mk_sorts ( ctx : context ) ( names : Symbol.symbol array ) ( c : Constructor.constructor array array ) = - let n = (Array.length names) in + let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = + let n = (List.length names) in let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in - let cla = (Array.map f c) in - let f2 x = (Symbol.gno x) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Array.map f2 names) cla) in - let g e = (sort_of_ptr ctx e) in - (Array.map g r) + let cla = (Array.of_list (List.map f c)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in + let g i = (sort_of_ptr ctx (Array.get r i)) in + mk_list g (Array.length r) - let mk_sorts_s ( ctx : context ) ( names : string array ) ( c : Constructor.constructor array array ) = + let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = mk_sorts ctx ( let f e = (Symbol.mk_string ctx e) in - Array.map f names + List.map f names ) c @@ -1514,12 +1522,12 @@ struct let get_constructors ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in - Array.init n f + mk_list f n let get_recognizers ( x : datatype_sort ) = let n = (get_num_constructors x) in let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in - Array.init n f + mk_list f n let get_accessors ( x : datatype_sort ) = let n = (get_num_constructors x) in @@ -1527,9 +1535,9 @@ struct let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in - Array.init ds g + mk_list g ds ) in - Array.init n f + mk_list f n end @@ -1537,7 +1545,7 @@ module Enumeration = struct type enum_sort = EnumSort of sort - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl array ) ( tdecls : Z3native.z3_func_decl array ) = + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = let s = (sort_of_ptr ctx no) in let res = EnumSort(s) in res @@ -1548,23 +1556,22 @@ struct let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol array ) = - let f x = Symbol.gno x in - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (Array.length enum_names) (Array.map f enum_names)) in - sort_of_ptr ctx a b c + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in + sort_of_ptr ctx a (list_of_array b) (list_of_array c) - let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string array ) = + let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) let get_const_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in - Array.init n f + mk_list f n let get_tester_decls ( x : enum_sort ) = let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in - Array.init n f + mk_list f n end @@ -1609,7 +1616,7 @@ struct let get_tail_decl ( x : list_sort ) = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) - let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [||] + let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] end @@ -1627,10 +1634,8 @@ struct let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol array ) ( field_sorts : sort array ) = - let f x = Symbol.gno x in - let f2 x = ptr_of_ast (ast_of_sort x) in - let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (Array.length field_names) (Array.map f field_names) (Array.map f2 field_sorts)) in + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = + let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in sort_of_ptr ctx r let get_mk_decl ( x : tuple_sort ) = @@ -1641,7 +1646,7 @@ struct let get_field_decls ( x : tuple_sort ) = let n = get_num_fields x in let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in - Array.init n f + mk_list f n end @@ -1746,9 +1751,9 @@ sig val is_int_numeral : Expr.expr -> bool val is_rat_num : Expr.expr -> bool val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr array -> arith_expr - val mk_mul : context -> arith_expr array -> arith_expr - val mk_sub : context -> arith_expr array -> arith_expr + val mk_add : context -> arith_expr list -> arith_expr + val mk_mul : context -> arith_expr list -> arith_expr + val mk_sub : context -> arith_expr list -> arith_expr val mk_unary_minus : context -> arith_expr -> arith_expr val mk_div : context -> arith_expr -> arith_expr -> arith_expr val mk_power : context -> arith_expr -> arith_expr -> arith_expr @@ -2109,17 +2114,17 @@ end = struct let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) - let mk_add ( ctx : context ) ( t : arith_expr array ) = + let mk_add ( ctx : context ) ( t : arith_expr list ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (Array.length t) (Array.map f t))) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_mul ( ctx : context ) ( t : arith_expr array ) = + let mk_mul ( ctx : context ) ( t : arith_expr list ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (Array.length t) (Array.map f t))) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_sub ( ctx : context ) ( t : arith_expr array ) = + let mk_sub ( ctx : context ) ( t : arith_expr list ) = let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (Array.length t) (Array.map f t))) + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) @@ -2551,9 +2556,9 @@ struct let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - let assert_ ( x : goal ) ( constraints : Boolean.bool_expr array ) = + let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in - ignore (Array.map f constraints) ; + ignore (List.map f constraints) ; () let is_inconsistent ( x : goal ) = @@ -2569,7 +2574,7 @@ struct let n = get_size x in let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in - Array.init n f + mk_list f n let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) @@ -2653,12 +2658,12 @@ struct let get_args ( x : func_entry ) = let n = (get_num_args x) in let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in - Array.init n f + mk_list f n let to_string ( x : func_entry ) = let a = (get_args x) in let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ Array.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") end let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) @@ -2666,7 +2671,7 @@ struct let get_entries ( x : func_interp ) = let n = (get_num_entries x) in let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in - Array.init n f + mk_list f n let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) @@ -2678,12 +2683,12 @@ struct p ^ let g c p = (p ^ (Expr.to_string c) ^ ", ") in (if n > 1 then "[" else "") ^ - (Array.fold_right + (List.fold_right g (FuncEntry.get_args c) ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) ) in - Array.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") end let get_const_interp ( x : model ) ( f : func_decl ) = @@ -2725,21 +2730,21 @@ struct let get_const_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) let get_func_decls ( x : model ) = let n = (get_num_consts x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_decls ( x : model ) = let n_funcs = (get_num_funcs x) in let n_consts = (get_num_consts x ) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - Array.append (Array.init n_funcs f) (Array.init n_consts g) + (mk_list f n_funcs) @ (mk_list g n_consts) exception ModelEvaluationFailedException of string @@ -2758,13 +2763,13 @@ struct let get_sorts ( x : model ) = let n = (get_num_sorts x) in let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in - Array.init n f + mk_list f n let sort_universe ( x : model ) ( s : sort ) = let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in - Array.init n f + mk_list f n let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) end @@ -2793,7 +2798,7 @@ struct let get_probe_names ( ctx : context ) = let n = (get_num_probes ctx) in let f i = (Z3native.get_probe_name (context_gno ctx) i) in - Array.init n f + mk_list f n let get_probe_description ( ctx : context ) ( name : string ) = Z3native.probe_get_descr (context_gno ctx) name @@ -2862,7 +2867,7 @@ struct let get_subgoals ( x : apply_result ) = let n = (get_num_subgoals x) in let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get_subgoal ( x : apply_result ) ( i : int ) = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) @@ -2888,7 +2893,7 @@ struct let get_tactic_names ( ctx : context ) = let n = (get_num_tactics ctx ) in let f i = (Z3native.get_tactic_name (context_gno ctx) i) in - Array.init n f + mk_list f n let get_tactic_description ( ctx : context ) ( name : string ) = Z3native.tactic_get_descr (context_gno ctx) name @@ -2896,11 +2901,11 @@ struct let mk_tactic ( ctx : context ) ( name : string ) = create ctx (Z3native.mk_tactic (context_gno ctx) name) - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic array ) = + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = let f p c = (match p with | None -> (Some (z3obj_gno c)) | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in - match (Array.fold_left f None ts) with + match (List.fold_left f None ts) with | None -> create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) | Some(x) -> @@ -2940,8 +2945,9 @@ struct let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = using_params ctx t p - let par_or ( ctx : context ) ( t : tactic array ) = - create ctx (Z3native.tactic_par_or (context_gno ctx) (Array.length t) (array_to_native t)) + let par_or ( ctx : context ) ( t : tactic list ) = + let f e = (z3obj_gno e) in + create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) @@ -3042,16 +3048,16 @@ struct else (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in - Array.init n f + mk_list f n let get_keys ( x : statistics ) = let n = (get_size x) in let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in - Array.init n f + mk_list f n let get ( x : statistics ) ( key : string ) = let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in - Array.fold_left f None (get_entries x) + List.fold_left f None (get_entries x) end let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) @@ -3070,16 +3076,16 @@ struct let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - let assert_ ( x : solver ) ( constraints : Boolean.bool_expr array ) = + let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (Array.map f constraints) + ignore (List.map f constraints) - let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr array ) ( ps : Boolean.bool_expr array ) = - if ((Array.length cs) != (Array.length ps)) then + let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = + if ((List.length cs) != (List.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f i e = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) (Boolean.gno (Array.get ps i))) in - ignore (Array.iteri f cs) + let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in + ignore (List.iter2 f cs ps) let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) @@ -3092,15 +3098,15 @@ struct let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in - Array.init n f + mk_list f n - let check ( x : solver ) ( assumptions : Boolean.bool_expr array) = + let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = let r = - if ((Array.length assumptions) == 0) then + if ((List.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else let f x = (ptr_of_expr (Boolean.expr_of_bool_expr x)) in - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (Array.length assumptions) (Array.map f assumptions)) + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) in match r with | L_TRUE -> SATISFIABLE @@ -3125,7 +3131,7 @@ struct let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in - Array.init n f + mk_list f n let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) @@ -3173,9 +3179,9 @@ struct let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr array ) = + let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (Array.map f constraints) ; + ignore (List.map f constraints) ; () let register_relation ( x : fixedpoint ) ( f : func_decl ) = @@ -3186,8 +3192,8 @@ struct | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int array ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (Array.length args) args + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with @@ -3195,9 +3201,9 @@ struct | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN - let query_r ( x : fixedpoint ) ( relations : func_decl array ) = + let query_r ( x : fixedpoint ) ( relations : func_decl list ) = let f x = ptr_of_ast (ast_of_func_decl x) in - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (Array.length relations) (Array.map f relations))) with + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -3236,25 +3242,24 @@ struct let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol array ) = - let f2 x = (Symbol.gno x) in - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (Array.length kinds) (Array.map f2 kinds) + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr array ) = + let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (Array.length queries) (Array.map f queries) + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) let get_rules ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - Array.init n f + mk_list f n let get_assertions ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - Array.init n f + mk_list f n let mk_fixedpoint ( ctx : context ) = create ctx end @@ -3282,102 +3287,102 @@ end module SMT = struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr array ) ( formula : Boolean.bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (Array.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.map f assumptions)) + (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) (Boolean.gno formula) - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Z3native.parse_smtlib_string (context_gno ctx) str cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Z3native.parse_smtlib_file (context_gno ctx) file_name cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in - Array.init n f + mk_list f n let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in - Array.init n f + mk_list f n let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) let get_smtlib_decls ( ctx : context ) = let n = (get_num_smtlib_decls ctx) in let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in - Array.init n f + mk_list f n let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in - Array.init n f + mk_list f n - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol array ) ( sorts : sort array ) ( decl_names : Symbol.symbol array ) ( decls : func_decl array ) = - let csn = (Array.length sort_names) in - let cs = (Array.length sorts) in - let cdn = (Array.length decl_names) in - let cd = (Array.length decls) in + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name cs - (let f x = Symbol.gno x in (Array.map f sort_names)) - (let f x = Sort.gno x in (Array.map f sorts)) + (Symbol.symbol_lton sort_names) + (sort_lton sorts) cd - (let f x = Symbol.gno x in (Array.map f decl_names)) - (let f x = FuncDecl.gno x in (Array.map f decls)))) + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) end diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 49a78f724..9f451c45f 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -106,11 +106,11 @@ sig (** Creates a new symbol using a string. *) val mk_string : context -> string -> symbol - (** Create an array of symbols. *) - val mk_ints : context -> int array -> symbol array + (** Create a list of symbols. *) + val mk_ints : context -> int list -> symbol list - (** Create an array of symbols. *) - val mk_strings : context -> string array -> symbol array + (** Create a list of symbols. *) + val mk_strings : context -> string list -> symbol list end (** The abstract syntax tree (AST) module *) @@ -175,7 +175,7 @@ sig val get_size : ast_map -> int (** The keys stored in the map. *) - val get_keys : ast_map -> ASTVector.ast_vector + val get_keys : ast_map -> ast list (** Retrieves a string representation of the map.*) val to_string : ast_map -> string @@ -331,13 +331,13 @@ sig end (** Creates a new function declaration. *) - val mk_func_decl : context -> Symbol.symbol -> Sort.sort array -> Sort.sort -> func_decl + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl (** Creates a new function declaration. *) - val mk_func_decl_s : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl (** Creates a fresh function declaration with a name prefixed with a prefix string. *) - val mk_fresh_func_decl : context -> string -> Sort.sort array -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl (** Creates a new constant function declaration. *) val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl @@ -368,7 +368,7 @@ sig val get_domain_size : func_decl -> int (** The domain of the function declaration *) - val get_domain : func_decl -> Sort.sort array + val get_domain : func_decl -> Sort.sort list (** The range of the function declaration *) val get_range : func_decl -> Sort.sort @@ -386,7 +386,7 @@ sig val get_parameters : func_decl -> Parameter.parameter list (** Create expression that applies function to arguments. *) - val apply : func_decl -> Expr.expr array -> Expr.expr + val apply : func_decl -> Expr.expr list -> Expr.expr end (** Parameter sets (of Solvers, Tactics, ...) @@ -408,7 +408,7 @@ sig val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind (** Retrieve all names of parameters. *) - val get_names : param_descrs -> Symbol.symbol array + val get_names : param_descrs -> Symbol.symbol list (** The size of the ParamDescrs. *) val get_size : param_descrs -> int @@ -477,18 +477,18 @@ sig val get_num_args : Expr.expr -> int (** The arguments of the expression. *) - val get_args : Expr.expr -> Expr.expr array + val get_args : Expr.expr -> Expr.expr list (** Update the arguments of the expression using an array of expressions. The number of new arguments should coincide with the current number of arguments. *) - val update : Expr.expr -> Expr.expr array -> expr + val update : Expr.expr -> Expr.expr list -> expr (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. The result is the new expression. The arrays from and to must have size num_exprs. For every i smaller than num_exprs, we must have that sort of from[i] must be equal to sort of to[i]. *) - val substitute : Expr.expr -> Expr.expr array -> Expr.expr array -> expr + val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr (** Substitute every occurrence of from in the expression with to. {!substitute} *) @@ -497,7 +497,7 @@ sig (** Substitute the free variables in the expression with the expressions in the expr array For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) - val substitute_vars : Expr.expr -> Expr.expr array -> expr + val substitute_vars : Expr.expr -> Expr.expr list -> expr (** Translates (copies) the term to another context. @return A copy of the term which is associated with the other context *) @@ -582,7 +582,7 @@ sig val mk_fresh_const : context -> string -> Sort.sort -> expr (** Create a new function application. *) - val mk_app : context -> FuncDecl.func_decl -> Expr.expr array -> expr + val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr (** Create a numeral of a given sort. @return A Term with the goven value and sort *) @@ -627,7 +627,7 @@ sig val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr (** Creates a distinct term. *) - val mk_distinct : context -> Expr.expr array -> bool_expr + val mk_distinct : context -> Expr.expr list -> bool_expr (** Mk an expression representing not(a). *) val mk_not : context -> bool_expr -> bool_expr @@ -645,10 +645,10 @@ sig val mk_xor : context -> bool_expr -> bool_expr -> bool_expr (** Create an expression representing the AND of args *) - val mk_and : context -> bool_expr array -> bool_expr + val mk_and : context -> bool_expr list -> bool_expr (** Create an expression representing the OR of args *) - val mk_or : context -> bool_expr array -> bool_expr + val mk_or : context -> bool_expr list -> bool_expr end (** Quantifier expressions *) @@ -675,7 +675,7 @@ sig val get_num_terms : pattern -> int (** The terms in the pattern. *) - val get_terms : pattern -> Expr.expr array + val get_terms : pattern -> Expr.expr list (** A string representation of the pattern. *) val to_string : pattern -> string @@ -713,22 +713,22 @@ sig val get_num_patterns : quantifier -> int (** The patterns. *) - val get_patterns : quantifier -> Pattern.pattern array + val get_patterns : quantifier -> Pattern.pattern list (** The number of no-patterns. *) val get_num_no_patterns : quantifier -> int (** The no-patterns. *) - val get_no_patterns : quantifier -> Pattern.pattern array + val get_no_patterns : quantifier -> Pattern.pattern list (** The number of bound variables. *) val get_num_bound : quantifier -> int (** The symbols for the bound variables. *) - val get_bound_variable_names : quantifier -> Symbol.symbol array + val get_bound_variable_names : quantifier -> Symbol.symbol list (** The sorts of the bound variables. *) - val get_bound_variable_sorts : quantifier -> Sort.sort array + val get_bound_variable_sorts : quantifier -> Sort.sort list (** The body of the quantifier. *) val get_body : quantifier -> Boolean.bool_expr @@ -737,25 +737,25 @@ sig val mk_bound : context -> int -> Sort.sort -> Expr.expr (** Create a quantifier pattern. *) - val mk_pattern : context -> Expr.expr array -> Pattern.pattern + val mk_pattern : context -> Expr.expr list -> Pattern.pattern (** Create a universal Quantifier. *) - val mk_forall : context -> Sort.sort array -> Symbol.symbol array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** Create a universal Quantifier. *) - val mk_forall_const : context -> Expr.expr array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** Create an existential Quantifier. *) - val mk_exists : context -> Sort.sort array -> Symbol.symbol array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** Create an existential Quantifier. *) - val mk_exists_const : context -> Expr.expr array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** Create a Quantifier. *) - val mk_quantifier : context -> Sort.sort array -> Symbol.symbol array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** Create a Quantifier. *) - val mk_quantifier : context -> bool -> Expr.expr array -> Expr.expr -> int option -> Pattern.pattern array -> Expr.expr array -> Symbol.symbol option -> Symbol.symbol option -> quantifier + val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier end (** Functions to manipulate Array expressions *) @@ -857,7 +857,7 @@ sig {!Array_.mk_sort} {!mk_select} {!mk_store} *) - val mk_map : context -> FuncDecl.func_decl -> array_expr array -> array_expr + val mk_map : context -> FuncDecl.func_decl -> array_expr list -> array_expr (** Access the array default value. @@ -904,10 +904,10 @@ sig val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr (** Take the union of a list of sets. *) - val mk_union : context -> Expr.expr array -> Expr.expr + val mk_union : context -> Expr.expr list -> Expr.expr (** Take the intersection of a list of sets. *) - val mk_intersection : context -> Expr.expr array -> Expr.expr + val mk_intersection : context -> Expr.expr list -> Expr.expr (** Take the difference between two sets. *) val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1037,7 +1037,7 @@ sig val get_arity : relation_sort -> int (** The sorts of the columns of the relation sort. *) - val get_column_sorts : relation_sort -> relation_sort array + val get_column_sorts : relation_sort -> relation_sort list end (** Functions to manipulate Datatype expressions *) @@ -1066,43 +1066,43 @@ sig val get_tester_decl : constructor -> FuncDecl.func_decl (** The function declarations of the accessors *) - val get_accessor_decls : constructor -> FuncDecl.func_decl array + val get_accessor_decls : constructor -> FuncDecl.func_decl list end (** Create a datatype constructor. if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> Constructor.constructor + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor (** Create a datatype constructor. if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> int array -> Constructor.constructor + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor (** Create a new datatype sort. *) - val mk_sort : context -> Symbol.symbol -> Constructor.constructor array -> datatype_sort + val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> datatype_sort (** Create a new datatype sort. *) - val mk_sort_s : context -> string -> Constructor.constructor array -> datatype_sort + val mk_sort_s : context -> string -> Constructor.constructor list -> datatype_sort (** Create mutually recursive datatypes. *) - val mk_sorts : context -> Symbol.symbol array -> Constructor.constructor array array -> datatype_sort array + val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> datatype_sort list (** Create mutually recursive data-types. *) - val mk_sorts_s : context -> string array -> Constructor.constructor array array -> datatype_sort array + val mk_sorts_s : context -> string list -> Constructor.constructor list list -> datatype_sort list (** The number of constructors of the datatype sort. *) val get_num_constructors : datatype_sort -> int (** The constructors. *) - val get_constructors : datatype_sort -> FuncDecl.func_decl array + val get_constructors : datatype_sort -> FuncDecl.func_decl list (** The recognizers. *) - val get_recognizers : datatype_sort -> FuncDecl.func_decl array + val get_recognizers : datatype_sort -> FuncDecl.func_decl list (** The constructor accessors. *) - val get_accessors : datatype_sort -> FuncDecl.func_decl array array + val get_accessors : datatype_sort -> FuncDecl.func_decl list list end (** Functions to manipulate Enumeration expressions *) @@ -1113,16 +1113,16 @@ sig val sort_of_enum_sort : enum_sort -> Sort.sort (** Create a new enumeration sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol array -> enum_sort + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> enum_sort (** Create a new enumeration sort. *) - val mk_sort_s : context -> string -> string array -> enum_sort + val mk_sort_s : context -> string -> string list -> enum_sort (** The function declarations of the constants in the enumeration. *) - val get_const_decls : enum_sort -> FuncDecl.func_decl array + val get_const_decls : enum_sort -> FuncDecl.func_decl list (** The test predicates for the constants in the enumeration. *) - val get_tester_decls : enum_sort -> FuncDecl.func_decl array + val get_tester_decls : enum_sort -> FuncDecl.func_decl list end (** Functions to manipulate List expressions *) @@ -1168,7 +1168,7 @@ sig val sort_of_tuple_sort : tuple_sort -> Sort.sort (** Create a new tuple sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol array -> Sort.sort array -> tuple_sort + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> tuple_sort (** The constructor function of the tuple. *) val get_mk_decl : tuple_sort -> FuncDecl.func_decl @@ -1177,7 +1177,7 @@ sig val get_num_fields : tuple_sort -> int (** The field declarations. *) - val get_field_decls : tuple_sort -> FuncDecl.func_decl array + val get_field_decls : tuple_sort -> FuncDecl.func_decl list end (** Functions to manipulate arithmetic expressions *) @@ -1407,13 +1407,13 @@ sig val is_algebraic_number : Expr.expr -> bool (** Create an expression representing t[0] + t[1] + .... *) - val mk_add : context -> arith_expr array -> arith_expr + val mk_add : context -> arith_expr list -> arith_expr (** Create an expression representing t[0] * t[1] * .... *) - val mk_mul : context -> arith_expr array -> arith_expr + val mk_mul : context -> arith_expr list -> arith_expr (** Create an expression representing t[0] - t[1] - .... *) - val mk_sub : context -> arith_expr array -> arith_expr + val mk_sub : context -> arith_expr list -> arith_expr (** Create an expression representing -t. *) val mk_unary_minus : context -> arith_expr -> arith_expr @@ -2332,7 +2332,7 @@ sig val is_garbage : goal -> bool (** Adds the constraints to the given goal. *) - val assert_ : goal -> Boolean.bool_expr array -> unit + val assert_ : goal -> Boolean.bool_expr list -> unit (** Indicates whether the goal contains `false'. *) val is_inconsistent : goal -> bool @@ -2348,7 +2348,7 @@ sig val get_size : goal -> int (** The formulas in the goal. *) - val get_formulas : goal -> Boolean.bool_expr array + val get_formulas : goal -> Boolean.bool_expr list (** The number of formulas, subformulas and terms in the goal. *) val get_num_exprs : goal -> int @@ -2407,7 +2407,7 @@ sig (** The arguments of the function entry. *) - val get_args : func_entry -> Expr.expr array + val get_args : func_entry -> Expr.expr list (** A string representation of the function entry. *) @@ -2418,7 +2418,7 @@ sig val get_num_entries : func_interp -> int (** The entries in the function interpretation *) - val get_entries : func_interp -> FuncEntry.func_entry array + val get_entries : func_interp -> FuncEntry.func_entry list (** The (symbolic) `else' value of the function interpretation. *) val get_else : func_interp -> Expr.expr @@ -2446,16 +2446,16 @@ sig val get_num_consts : model -> int (** The function declarations of the constants in the model. *) - val get_const_decls : model -> FuncDecl.func_decl array + val get_const_decls : model -> FuncDecl.func_decl list (** The number of function interpretations in the model. *) val get_num_funcs : model -> int (** The function declarations of the function interpretations in the model. *) - val get_func_decls : model -> FuncDecl.func_decl array + val get_func_decls : model -> FuncDecl.func_decl list (** All symbols that have an interpretation in the model. *) - val get_decls : model -> FuncDecl.func_decl array + val get_decls : model -> FuncDecl.func_decl list (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) exception ModelEvaluationFailedException of string @@ -2481,12 +2481,12 @@ sig the "universe" of the sort. {!get_num_sorts} {!sort_universe} *) - val get_sorts : model -> Sort.sort array + val get_sorts : model -> Sort.sort list (** The finite set of distinct values that represent the interpretation of a sort. {!get_sorts} - @returns An array of expressions, where each is an element of the universe of the sort *) - val sort_universe : model -> Sort.sort -> AST.ASTVector.ast_vector array + @returns A list of expressions, where each is an element of the universe of the sort *) + val sort_universe : model -> Sort.sort -> AST.ast list (** Conversion of models to strings. A string representation of the model. *) @@ -2514,7 +2514,7 @@ sig val get_num_probes : context -> int (** The names of all supported Probes. *) - val get_probe_names : context -> string array + val get_probe_names : context -> string list (** Returns a string containing a description of the probe with the given name. *) val get_probe_description : context -> string -> string @@ -2579,7 +2579,7 @@ sig val get_num_subgoals : apply_result -> int (** Retrieves the subgoals from the apply_result. *) - val get_subgoals : apply_result -> Goal.goal array + val get_subgoals : apply_result -> Goal.goal list (** Retrieves a subgoal from the apply_result. *) val get_subgoal : apply_result -> int -> Goal.goal @@ -2606,7 +2606,7 @@ sig val get_num_tactics : context -> int (** The names of all supported tactics. *) - val get_tactic_names : context -> string array + val get_tactic_names : context -> string list (** Returns a string containing a description of the tactic with the given name. *) val get_tactic_description : context -> string -> string @@ -2616,7 +2616,7 @@ sig (** Create a tactic that applies one tactic to a Goal and then another one to every subgoal produced by the first one. *) - val and_then : context -> tactic -> tactic -> tactic array -> tactic + val and_then : context -> tactic -> tactic -> tactic list -> tactic (** Create a tactic that first applies one tactic to a Goal and if it fails then returns the result of another tactic applied to the Goal. *) @@ -2662,7 +2662,7 @@ sig val with_ : context -> tactic -> Params.params -> tactic (** Create a tactic that applies the given tactics in parallel. *) - val par_or : context -> tactic array -> tactic + val par_or : context -> tactic list -> tactic (** Create a tactic that applies a tactic to a given goal and then another tactic to every subgoal produced by the first one. The subgoals are processed in parallel. *) @@ -2722,10 +2722,10 @@ sig val get_size : statistics -> int (** The data entries. *) - val get_entries : statistics -> Entry.statistics_entry array + val get_entries : statistics -> Entry.statistics_entry list (** The statistical counters. *) - val get_keys : statistics -> string array + val get_keys : statistics -> string list (** The value of a particular statistical counter. *) val get : statistics -> string -> Entry.statistics_entry option @@ -2759,7 +2759,7 @@ sig val reset : solver -> unit (** Assert a constraint (or multiple) into the solver. *) - val assert_ : solver -> Boolean.bool_expr array -> unit + val assert_ : solver -> Boolean.bool_expr list -> unit (** * Assert multiple constraints (cs) into the solver, and track them (in the * unsat) core @@ -2772,7 +2772,7 @@ sig * of the Boolean variables provided using {!assert_and_track} * and the Boolean literals * provided using {!check} with assumptions. *) - val assert_and_track_a : solver -> Boolean.bool_expr array -> Boolean.bool_expr array -> unit + val assert_and_track_a : solver -> Boolean.bool_expr list -> Boolean.bool_expr list -> unit (** * Assert a constraint (c) into the solver, and track it (in the unsat) core * using the Boolean constant p. @@ -2790,14 +2790,14 @@ sig val get_num_assertions : solver -> int (** The set of asserted formulas. *) - val get_assertions : solver -> Boolean.bool_expr array + val get_assertions : solver -> Boolean.bool_expr list (** Checks whether the assertions in the solver are consistent or not. {!Model} {!get_unsat_core} {!Proof} *) - val check : solver -> Boolean.bool_expr array -> status + val check : solver -> Boolean.bool_expr list -> status (** The model of the last Check. @@ -2816,7 +2816,7 @@ sig The unsat core is a subset of Assertions The result is empty if Check was not invoked before, if its results was not UNSATISFIABLE, or if core production is disabled. *) - val get_unsat_core : solver -> AST.ASTVector.ast_vector array + val get_unsat_core : solver -> AST.ast list (** A brief justification of why the last call to Check returned UNKNOWN. *) val get_reason_unknown : solver -> string @@ -2863,7 +2863,7 @@ sig val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs (** Assert a constraints into the fixedpoint solver. *) - val assert_ : fixedpoint -> Boolean.bool_expr array -> unit + val assert_ : fixedpoint -> Boolean.bool_expr list -> unit (** Register predicate as recursive relation. *) val register_relation : fixedpoint -> FuncDecl.func_decl -> unit @@ -2872,7 +2872,7 @@ sig val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit (** Add table fact to the fixedpoint solver. *) - val add_fact : fixedpoint -> FuncDecl.func_decl -> int array -> unit + val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit (** Query the fixedpoint solver. A query is a conjunction of constraints. The constraints may include the recursively defined relations. @@ -2884,7 +2884,7 @@ sig A query is an array of relations. The query is satisfiable if there is an instance of some relation that is non-empty. The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - val query_r : fixedpoint -> FuncDecl.func_decl array -> Solver.status + val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status (** Creates a backtracking point. {!pop} *) @@ -2920,16 +2920,16 @@ sig val to_string : fixedpoint -> string (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol array -> unit + val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit (** Convert benchmark given as set of axioms, rules and queries to a string. *) - val to_string_q : fixedpoint -> Boolean.bool_expr array -> string + val to_string_q : fixedpoint -> Boolean.bool_expr list -> string (** Retrieve set of rules added to fixedpoint context. *) - val get_rules : fixedpoint -> Boolean.bool_expr array + val get_rules : fixedpoint -> Boolean.bool_expr list (** Retrieve set of assertions added to fixedpoint context. *) - val get_assertions : fixedpoint -> Boolean.bool_expr array + val get_assertions : fixedpoint -> Boolean.bool_expr list (** Create a Fixedpoint context. *) val mk_fixedpoint : context -> fixedpoint @@ -2985,7 +2985,7 @@ sig (** Convert a benchmark into an SMT-LIB formatted string. @return A string representation of the benchmark. *) - val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr array -> Boolean.bool_expr -> string + val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr list -> Boolean.bool_expr -> string (** Parse the given string using the SMT-LIB parser. @@ -2994,45 +2994,45 @@ sig don't need to match the names of the sorts and declarations in the arrays in the fourth and sixth argument. This is a useful feature since we can use arbitrary names to reference sorts and declarations. *) - val parse_smtlib_string : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> unit + val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit (** Parse the given file using the SMT-LIB parser. {!parse_smtlib_string} *) - val parse_smtlib_file : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> unit + val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_formulas : context -> int (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_formulas : context -> Boolean.bool_expr array + val get_smtlib_formulas : context -> Boolean.bool_expr list (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_assumptions : context -> int (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_assumptions : context -> Boolean.bool_expr array + val get_smtlib_assumptions : context -> Boolean.bool_expr list (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_decls : context -> int (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_decls : context -> FuncDecl.func_decl array + val get_smtlib_decls : context -> FuncDecl.func_decl list (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_sorts : context -> int (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_sorts : context -> Sort.sort array + val get_smtlib_sorts : context -> Sort.sort list (** Parse the given string using the SMT-LIB2 parser. {!parse_smtlib_string} @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - val parse_smtlib2_string : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> Boolean.bool_expr + val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr (** Parse the given file using the SMT-LIB2 parser. {!parse_smtlib2_string} *) - val parse_smtlib2_file : context -> string -> Symbol.symbol array -> Sort.sort array -> Symbol.symbol array -> FuncDecl.func_decl array -> Boolean.bool_expr + val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr end (** Set a global (or module) parameter, which is shared by all Z3 contexts. From d293b579f376045db72bd30569583bd2cbd2ba41 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 13:25:31 +0000 Subject: [PATCH 404/507] ML API: flat & rich layer in place. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 40 +- src/api/ml/z3.ml | 1458 ++++------------ src/api/ml/z3.mli | 460 ++--- src/api/ml/z3_rich.ml | 3400 +++++++++++++++++++++++++++++++++++++ src/api/ml/z3_rich.mli | 3072 +++++++++++++++++++++++++++++++++ 5 files changed, 7040 insertions(+), 1390 deletions(-) create mode 100644 src/api/ml/z3_rich.ml create mode 100644 src/api/ml/z3_rich.mli diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 31f31d566..823a08fe2 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -26,20 +26,14 @@ exception TestFailedException of string *) let model_converter_test ( ctx : context ) = Printf.printf "ModelConverterTest\n"; - let xr = (arith_expr_of_expr - (Expr.mk_const ctx (Symbol.mk_string ctx "x") - (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in - let yr = (arith_expr_of_expr - (Expr.mk_const ctx (Symbol.mk_string ctx "y") - (sort_of_arith_sort (arith_sort_of_real_sort (Real.mk_sort ctx))))) in + let xr = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Real.mk_sort ctx)) in + let yr = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Real.mk_sort ctx)) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [ (mk_gt ctx xr - (arith_expr_of_real_expr (real_expr_of_rat_num - (Real.mk_numeral_nd ctx 10 1)))) ]) ; + (Goal.assert_ g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; (Goal.assert_ g4 [ (mk_eq ctx - (expr_of_arith_expr yr) - (expr_of_arith_expr (Arithmetic.mk_add ctx [ xr; (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1))) ]) ) ) ] ) ; - (Goal.assert_ g4 [ (mk_gt ctx yr (arith_expr_of_real_expr (real_expr_of_rat_num (Real.mk_numeral_nd ctx 1 1)))) ]) ; + yr + (Arithmetic.mk_add ctx [ xr; (Real.mk_numeral_nd ctx 1 1) ])) ]) ; + (Goal.assert_ g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -83,7 +77,7 @@ let basic_tests ( ctx : context ) = let fname = (mk_string ctx "f") in let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in - let bs = (sort_of_bool_sort (Boolean.mk_sort ctx)) in + let bs = (Boolean.mk_sort ctx) in let domain = [ bs; bs ] in let f = (FuncDecl.mk_func_decl ctx fname domain bs) in let fapp = (mk_app ctx f @@ -123,10 +117,8 @@ let basic_tests ( ctx : context ) = Printf.printf "Test passed.\n" ); (Goal.assert_ g [ (mk_eq ctx - (mk_numeral_int ctx 1 - (sort_of_bitvec_sort (BitVector.mk_sort ctx 32))) - (mk_numeral_int ctx 2 - (sort_of_bitvec_sort (BitVector.mk_sort ctx 32)))) ] ) + (mk_numeral_int ctx 1 (BitVector.mk_sort ctx 32)) + (mk_numeral_int ctx 2 (BitVector.mk_sort ctx 32))) ] ) ; ( let ar = (Tactic.apply (mk_tactic ctx "smt") g None) in @@ -157,10 +149,10 @@ let basic_tests ( ctx : context ) = ); ( let g3 = (mk_goal ctx true true false) in - let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in - let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx)))) in - (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; - (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (sort_of_arith_sort (arith_sort_of_int_sort (Integer.mk_sort ctx))))) ]) ; + let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Integer.mk_sort ctx)) in + let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Integer.mk_sort ctx)) in + (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; + (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; let constr = (mk_eq ctx xc yc) in (Goal.assert_ g3 [ constr ] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in @@ -228,9 +220,9 @@ let _ = let rs = (Real.mk_sort ctx) in Printf.printf "int symbol: %s\n" (Symbol.to_string is); Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string (sort_of_bool_sort bs)); - Printf.printf "int sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_int_sort ints))); - Printf.printf "real sort: %s\n" (Sort.to_string (sort_of_arith_sort (arith_sort_of_real_sort rs))); + Printf.printf "bool sort: %s\n" (Sort.to_string bs); + Printf.printf "int sort: %s\n" (Sort.to_string ints); + Printf.printf "real sort: %s\n" (Sort.to_string rs); basic_tests ctx ; Printf.printf "Disposing...\n"; Gc.full_major () diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 56d319c1a..0676f1a39 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -133,52 +133,34 @@ let mk_context ( cfg : ( string * string ) list ) = module Symbol = struct - (* Symbol types *) - type int_symbol = z3_native_object - type string_symbol = z3_native_object - - type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - + type symbol = z3_native_object let create_i ( ctx : context ) ( no : Z3native.ptr ) = - let res : int_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in + let res : symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + let create_s ( ctx : context ) ( no : Z3native.ptr ) = - let res : string_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in + let res : symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in (z3obj_sno res ctx no) ; (z3obj_create res) ; res let create ( ctx : context ) ( no : Z3native.ptr ) = match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> S_Int (create_i ctx no) - | STRING_SYMBOL -> S_Str (create_s ctx no) + | INT_SYMBOL -> (create_i ctx no) + | STRING_SYMBOL -> (create_s ctx no) - let gc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gc n) - | S_Str(n) -> (z3obj_gc n) - - let gnc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gnc n) - | S_Str(n) -> (z3obj_gnc n) - - let gno ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gno n) - | S_Str(n) -> (z3obj_gno n) + let gc ( x : symbol ) = (z3obj_gc x) + let gnc ( x : symbol ) = (z3obj_gnc x) + let gno ( x : symbol ) = (z3obj_gno x) let symbol_lton ( a : symbol list ) = let f ( e : symbol ) = (gno e) in @@ -187,18 +169,18 @@ struct let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) + let get_int (o : symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) + let get_string (o : symbol ) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) let to_string ( o : symbol ) = match (kind o) with | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) let mk_int ( ctx : context ) ( i : int ) = - S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) let mk_string ( ctx : context ) ( s : string ) = - S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) let mk_ints ( ctx : context ) ( names : int list ) = let f elem = mk_int ( ctx : context ) elem in @@ -353,7 +335,6 @@ open AST module Sort = struct type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> let q = (z3_native_object_of_ast_ptr ctx no) in @@ -373,14 +354,7 @@ struct | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") let ast_of_sort s = match s with Sort(x) -> x - let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x - - let uninterpreted_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - UninterpretedSort(s) - + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) @@ -409,7 +383,7 @@ struct dec_ref = Z3native.dec_ref } in (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; (z3obj_create res) ; - UninterpretedSort(Sort(res)) + Sort(res) let mk_uninterpreted_s ( ctx : context ) ( s : string ) = mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) @@ -713,9 +687,9 @@ and Expr : sig type expr = Expr of AST.ast val expr_of_ptr : context -> Z3native.ptr -> expr - val c_of_expr : expr -> context - val nc_of_expr : expr -> Z3native.ptr - val ptr_of_expr : expr -> Z3native.ptr + val gc : expr -> context + val gnc : expr -> Z3native.ptr + val gno : expr -> Z3native.ptr val expr_lton : expr list -> Z3native.ptr array val ast_of_expr : expr -> AST.ast val expr_of_ast : AST.ast -> expr @@ -762,9 +736,9 @@ sig end = struct type expr = Expr of AST.ast - let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) - let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) - let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + let gc e = match e with Expr(a) -> (z3obj_gc a) + let gnc e = match e with Expr(a) -> (z3obj_gnc a) + let gno e = match e with Expr(a) -> (z3obj_gno a) let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then @@ -802,60 +776,60 @@ end = struct expr_of_ptr ctx o let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> expr_of_ptr (c_of_expr x) (Z3native.simplify (nc_of_expr x) (ptr_of_expr x)) - | Some pp -> expr_of_ptr (c_of_expr x) (Z3native.simplify_ex (nc_of_expr x) (ptr_of_expr x) (z3obj_gno pp)) + | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (gnc x) (gno x)) + | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (gnc x) (gno x) (z3obj_gno pp)) let get_simplify_help ( ctx : context ) = Z3native.simplify_get_help (context_gno ctx) let get_simplify_parameter_descrs ( ctx : context ) = Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (c_of_expr x) (Z3native.get_app_decl (nc_of_expr x) (ptr_of_expr x)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (nc_of_expr x) (ptr_of_expr x)) + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) - let get_num_args ( x : expr ) = Z3native.get_app_num_args (nc_of_expr x) (ptr_of_expr x) + let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = expr_of_ptr (c_of_expr x) (Z3native.get_app_arg (nc_of_expr x) (ptr_of_expr x) i) in + let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (gnc x) (gno x) i) in mk_list f n let update ( x : expr ) ( args : expr list ) = if (List.length args <> (get_num_args x)) then raise (Z3native.Exception "Number of arguments does not match") else - expr_of_ptr (c_of_expr x) (Z3native.update_term (nc_of_expr x) (ptr_of_expr x) (List.length args) (expr_lton args)) + expr_of_ptr (Expr.gc x) (Z3native.update_term (gnc x) (gno x) (List.length args) (expr_lton args)) let substitute ( x : expr ) from to_ = if (List.length from) <> (List.length to_) then raise (Z3native.Exception "Argument sizes do not match") else - expr_of_ptr (c_of_expr x) (Z3native.substitute (nc_of_expr x) (ptr_of_expr x) (List.length from) (expr_lton from) (expr_lton to_)) + expr_of_ptr (Expr.gc x) (Z3native.substitute (gnc x) (gno x) (List.length from) (expr_lton from) (expr_lton to_)) let substitute_one ( x : expr ) from to_ = substitute ( x : expr ) [ from ] [ to_ ] let substitute_vars ( x : expr ) to_ = - expr_of_ptr (c_of_expr x) (Z3native.substitute_vars (nc_of_expr x) (ptr_of_expr x) (List.length to_) (expr_lton to_)) + expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (gnc x) (gno x) (List.length to_) (expr_lton to_)) let translate ( x : expr ) to_ctx = - if (c_of_expr x) == to_ctx then + if (Expr.gc x) == to_ctx then x else - expr_of_ptr to_ctx (Z3native.translate (nc_of_expr x) (ptr_of_expr x) (context_gno to_ctx)) + expr_of_ptr to_ctx (Z3native.translate (gnc x) (gno x) (context_gno to_ctx)) - let to_string ( x : expr ) = Z3native.ast_to_string (nc_of_expr x) (ptr_of_expr x) + let to_string ( x : expr ) = Z3native.ast_to_string (gnc x) (gno x) - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (nc_of_expr x) (ptr_of_expr x)) + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (gnc x) (gno x)) - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (nc_of_expr x) (ptr_of_expr x) + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) - let get_sort ( x : expr ) = sort_of_ptr (c_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)) + let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (nc_of_expr x) - (Z3native.mk_bool_sort (nc_of_expr x)) - (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x))) + (Z3native.is_eq_sort (gnc x) + (Z3native.mk_bool_sort (gnc x)) + (Z3native.get_sort (gnc x) (gno x))) let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && (get_num_args x) == 0 && @@ -901,86 +875,52 @@ open Expr module Boolean = struct - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.ast_of_ptr ctx no) in - BoolExpr(Expr.Expr(a)) - - let bool_expr_of_expr e = - match e with Expr.Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolExpr(e) - - let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - BoolSort(sort_of_ptr ctx no) - - let sort_of_bool_sort s = match s with BoolSort(x) -> x - - let bool_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolSort(s) - - let expr_of_bool_expr e = match e with BoolExpr(x) -> x - - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) - let mk_sort ( ctx : context ) = - BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) + (sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - let s = (match (mk_sort ctx) with BoolSort(q) -> q) in - BoolExpr(Expr.mk_const ctx name s) + (Expr.mk_const ctx name (mk_sort ctx)) let mk_const_s ( ctx : context ) ( name : string ) = mk_const ctx (Symbol.mk_string ctx name) let mk_true ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) + expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) let mk_false ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) + expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) let mk_val ( ctx : context ) ( value : bool ) = if value then mk_true ctx else mk_false ctx let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (ptr_of_expr x) (ptr_of_expr y)) + expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) let mk_distinct ( ctx : context ) ( args : expr list ) = - bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) + expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) - let mk_not ( ctx : context ) ( a : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) + let mk_not ( ctx : context ) ( a : expr ) = + expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + let mk_ite ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( t3 : expr ) = + expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + let mk_iff ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + let mk_implies ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - let mk_and ( ctx : context ) ( args : bool_expr list ) = - let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) + let mk_and ( ctx : context ) ( args : expr list ) = + let f x = (Expr.gno (x)) in + expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - let mk_or ( ctx : context ) ( args : bool_expr list ) = - let f x = (ptr_of_expr (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) + let mk_or ( ctx : context ) ( args : expr list ) = + let f x = (Expr.gno (x)) in + expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) end @@ -998,9 +938,9 @@ struct else Quantifier(e) - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (c_of_expr e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (nc_of_expr e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (ptr_of_expr e) + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) module Pattern = struct @@ -1031,7 +971,7 @@ struct if not (AST.is_var (match x with Expr.Expr(a) -> a)) then raise (Z3native.Exception "Term is not a bound variable.") else - Z3native.get_index_value (nc_of_expr x) (ptr_of_expr x) + Z3native.get_index_value (Expr.gnc x) (Expr.gno x) let is_universal ( x : quantifier ) = Z3native.is_quantifier_forall (gnc x) (gno x) @@ -1067,7 +1007,7 @@ struct mk_list f n let get_body ( x : quantifier ) = - Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) @@ -1087,7 +1027,7 @@ struct (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) @@ -1097,7 +1037,7 @@ struct (List.length nopatterns) (expr_lton nopatterns) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -1105,7 +1045,7 @@ struct (match weight with | None -> 1 | Some(x) -> x) (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true (match weight with | None -> 1 | Some(x) -> x) @@ -1114,7 +1054,7 @@ struct (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length nopatterns) (expr_lton nopatterns) - (ptr_of_expr body))) + (Expr.gno body))) let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (List.length sorts) != (List.length names) then @@ -1125,7 +1065,7 @@ struct (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) @@ -1135,7 +1075,7 @@ struct (List.length nopatterns) (expr_lton nopatterns) (List.length sorts) (sort_lton sorts) (Symbol.symbol_lton names) - (ptr_of_expr body))) + (Expr.gno body))) let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then @@ -1143,7 +1083,7 @@ struct (match weight with | None -> 1 | Some(x) -> x) (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (ptr_of_expr body))) + (Expr.gno body))) else Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false (match weight with | None -> 1 | Some(x) -> x) @@ -1152,7 +1092,7 @@ struct (List.length bound_constants) (expr_lton bound_constants) (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) (List.length nopatterns) (expr_lton nopatterns) - (ptr_of_expr body))) + (Expr.gno body))) let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = if (universal) then @@ -1170,46 +1110,8 @@ end module Array_ = struct - type array_sort = ArraySort of sort - type array_expr = ArrayExpr of expr - - let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (expr_of_ptr ctx no) in - ArrayExpr(e) - - let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - ArraySort(s) - - let sort_of_array_sort s = match s with ArraySort(x) -> x - - let array_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArraySort(s) - - let array_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArrayExpr(e) - - let expr_of_array_expr e = match e with ArrayExpr(x) -> x - - let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) - - let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) - let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) - let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) + sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) @@ -1218,48 +1120,40 @@ struct let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) let is_array ( x : expr ) = - (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == ARRAY_SORT) + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) - let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) - let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) + let get_domain ( x : sort ) = Sort.sort_of_ptr (Sort.gc x) (Z3native.get_array_sort_domain (Sort.gnc x) (Sort.gno x)) + let get_range ( x : sort ) = Sort.sort_of_ptr (Sort.gc x) (Z3native.get_array_sort_range (Sort.gnc x) (Sort.gno x)) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) + (Expr.mk_const ctx name (mk_sort ctx domain range)) let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = mk_const ctx (Symbol.mk_string ctx name) domain range - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (ptr_of_expr i)) + let mk_select ( ctx : context ) ( a : expr ) ( i : expr ) = + expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (Expr.gno a) (Expr.gno i)) - let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (ptr_of_expr i) (ptr_of_expr v)) + let mk_store ( ctx : context ) ( a : expr ) ( i : expr ) ( v : expr ) = + expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (Expr.gno a) (Expr.gno i) (Expr.gno v)) let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (ptr_of_expr v)) + expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = - let m x = (ptr_of_expr (expr_of_array_expr x)) in - array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) + let mk_map ( ctx : context ) ( f : func_decl ) ( args : expr list ) = + let m x = (Expr.gno x) in + expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) - let mk_term_array ( ctx : context ) ( arg : array_expr ) = - array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) + let mk_term_array ( ctx : context ) ( arg : expr ) = + expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (Expr.gno arg)) end module Set = struct - type set_sort = SetSort of sort - - let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - SetSort(s) - - let sort_of_set_sort s = match s with SetSort(x) -> x - let mk_sort ( ctx : context ) ( ty : sort ) = - set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) + sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) @@ -1275,10 +1169,10 @@ struct expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) + expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (ptr_of_expr set) (ptr_of_expr element)) + expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) let mk_union ( ctx : context ) ( args : expr list ) = expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) @@ -1287,53 +1181,37 @@ struct expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) + expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) let mk_complement ( ctx : context ) ( arg : expr ) = - expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (ptr_of_expr arg)) + expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (ptr_of_expr elem) (ptr_of_expr set)) + expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (ptr_of_expr arg1) (ptr_of_expr arg2)) + expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) end module FiniteDomain = struct - type finite_domain_sort = FiniteDomainSort of sort - - let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x - - let finite_domain_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - FiniteDomainSort(s) - - let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in - FiniteDomainSort(s) + (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = mk_sort ctx (Symbol.mk_string ctx name) size - let is_finite_domain ( x : expr ) = - let nc = (nc_of_expr x) in - (Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == FINITE_DOMAIN_SORT) + let nc = (Expr.gnc x) in + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - let get_size ( x : finite_domain_sort ) = - let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in + let get_size ( x : sort ) = + let (r, v) = (Z3native.get_finite_domain_sort_size (Sort.gnc x) (Sort.gno x)) in if r then v else raise (Z3native.Exception "Conversion failed.") end @@ -1341,29 +1219,10 @@ end module Relation = struct - type relation_sort = RelationSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - RelationSort(s) - - let sort_of_relation_sort s = match s with RelationSort(x) -> x - - let relation_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RelationSort(s) - - let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - - let is_relation ( x : expr ) = - let nc = (nc_of_expr x) in - ((Z3native.is_app (nc_of_expr x) (ptr_of_expr x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (ptr_of_expr x))) == RELATION_SORT)) + let nc = (Expr.gnc x) in + ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) @@ -1379,48 +1238,17 @@ struct let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) + let get_arity ( x : sort ) = Z3native.get_relation_arity (Sort.gnc x) (Sort.gno x) - let get_column_sorts ( x : relation_sort ) = + let get_column_sorts ( x : sort ) = let n = get_arity x in - let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in + let f i = (sort_of_ptr (Sort.gc x) (Z3native.get_relation_column (Sort.gnc x) (Sort.gno x) i)) in mk_list f n - end module Datatype = struct - type datatype_sort = DatatypeSort of sort - type datatype_expr = DatatypeExpr of expr - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - DatatypeSort(s) - - let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x - - let datatype_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeSort(s) - - let datatype_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeExpr(e) - - let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x - - let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - module Constructor = struct type constructor = z3_native_object @@ -1517,24 +1345,24 @@ struct ) c - let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) + let get_num_constructors ( x : sort ) = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) - let get_constructors ( x : datatype_sort ) = + let get_constructors ( x : sort ) = let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i) in mk_list f n - let get_recognizers ( x : datatype_sort ) = + let get_recognizers ( x : sort ) = let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) i) in mk_list f n - let get_accessors ( x : datatype_sort ) = + let get_accessors ( x : sort ) = let n = (get_num_constructors x) in let f i = ( - let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let fd = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i) in let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in + let g j = func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) i j) in mk_list g ds ) in mk_list f n @@ -1543,467 +1371,133 @@ end module Enumeration = struct - type enum_sort = EnumSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = - let s = (sort_of_ptr ctx no) in - let res = EnumSort(s) in - res - - let sort_of_enum_sort s = match s with EnumSort(x) -> x - - let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in - sort_of_ptr ctx a (list_of_array b) (list_of_array c) + let (a, _, _) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in + sort_of_ptr ctx a let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - let get_const_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in + let get_const_decls ( x : sort ) = + let n = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) in + let f i = (func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) i)) in mk_list f n - let get_tester_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in + let get_tester_decls ( x : sort ) = + let n = Z3native.get_datatype_sort_num_constructors (Sort.gnc x) (Sort.gno x) in + let f i = (func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) i)) in mk_list f n end module List_ = -struct - type list_sort = ListSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - let res = ListSort(s) in - res - - let sort_of_list_sort s = match s with ListSort(x) -> x - - let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - +struct let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - sort_of_ptr ctx r a b c d e f + let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in + sort_of_ptr ctx r let mk_list_s ( ctx : context ) (name : string) elem_sort = mk_sort ctx (Symbol.mk_string ctx name) elem_sort - let get_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) + let get_nil_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) 0) - let get_is_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) + let get_is_nil_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) 0) - let get_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) + let get_cons_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor (Sort.gnc x) (Sort.gno x) 1) - let get_is_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) + let get_is_cons_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_recognizer (Sort.gnc x) (Sort.gno x) 1) - let get_head_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) + let get_head_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) 1 0) - let get_tail_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) + let get_tail_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_datatype_sort_constructor_accessor (Sort.gnc x) (Sort.gno x) 1 1) - let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] + let nil ( x : sort ) = expr_of_func_app (Sort.gc x) (get_nil_decl x) [] end module Tuple = struct - type tuple_sort = TupleSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - TupleSort(s) - - let sort_of_tuple_sort s = match s with TupleSort(x) -> x - - let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in sort_of_ptr ctx r - let get_mk_decl ( x : tuple_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) + let get_mk_decl ( x : sort ) = + func_decl_of_ptr (Sort.gc x) (Z3native.get_tuple_sort_mk_decl (Sort.gnc x) (Sort.gno x)) - let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) + let get_num_fields ( x : sort ) = Z3native.get_tuple_sort_num_fields (Sort.gnc x) (Sort.gno x) - let get_field_decls ( x : tuple_sort ) = + let get_field_decls ( x : sort ) = let n = get_num_fields x in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in + let f i = func_decl_of_ptr (Sort.gc x) (Z3native.get_tuple_sort_field_decl (Sort.gnc x) (Sort.gno x) i) in mk_list f n end -module rec Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> arith_sort - val expr_of_arith_expr : arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> arith_expr +module Arithmetic = +struct - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end - - val is_int : Expr.expr -> bool - val is_arithmetic_numeral : Expr.expr -> bool - val is_le : Expr.expr -> bool - val is_ge : Expr.expr -> bool - val is_lt : Expr.expr -> bool - val is_gt : Expr.expr -> bool - val is_add : Expr.expr -> bool - val is_sub : Expr.expr -> bool - val is_uminus : Expr.expr -> bool - val is_mul : Expr.expr -> bool - val is_div : Expr.expr -> bool - val is_idiv : Expr.expr -> bool - val is_remainder : Expr.expr -> bool - val is_modulus : Expr.expr -> bool - val is_inttoreal : Expr.expr -> bool - val is_real_to_int : Expr.expr -> bool - val is_real_is_int : Expr.expr -> bool - val is_real : Expr.expr -> bool - val is_int_numeral : Expr.expr -> bool - val is_rat_num : Expr.expr -> bool - val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr list -> arith_expr - val mk_mul : context -> arith_expr list -> arith_expr - val mk_sub : context -> arith_expr list -> arith_expr - val mk_unary_minus : context -> arith_expr -> arith_expr - val mk_div : context -> arith_expr -> arith_expr -> arith_expr - val mk_power : context -> arith_expr -> arith_expr -> arith_expr - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr -end = struct - type arith_sort = ArithSort of sort - type arith_expr = ArithExpr of expr - - let arith_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithExpr(e) - - let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_expr_of_expr (expr_of_ptr ctx no) - - let sort_of_arith_sort s = match s with ArithSort(x) -> x - let expr_of_arith_expr e = match e with ArithExpr(x) -> x - - let arith_sort_of_sort s = match s with Sort(a) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithSort(s) - - let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_sort_of_sort (sort_of_ptr ctx no) - - let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) - let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (c_of_expr e) - let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (nc_of_expr e) - let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (ptr_of_expr e) - - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end = struct - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntExpr(e) - - let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - IntNum(e) - - let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_num_of_int_expr (int_expr_of_ptr ctx no) - - let arith_sort_of_int_sort s = match s with IntSort(x) -> x - let arith_expr_of_int_expr e = match e with IntExpr(x) -> x - let int_expr_of_int_num e = match e with IntNum(x) -> x - - let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntSort(s) - - let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) - - let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) - let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) - let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) - let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) - let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) - let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) - let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) - let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) - let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - + module Integer = + struct let mk_sort ( ctx : context ) = - int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) + sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - let get_int ( x : int_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + let get_int ( x : expr ) = + let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = - IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) + Expr.mk_const ctx name (mk_sort ctx) let mk_int_const_s ( ctx : context ) ( name : string ) = mk_int_const ctx (Symbol.mk_string ctx name) - let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + let mk_mod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + let mk_rem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) let mk_int_numeral_s ( ctx : context ) ( v : string ) = - int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) let mk_int_numeral_i ( ctx : context ) ( v : int ) = - int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) - let mk_int2real ( ctx : context ) ( t : int_expr ) = - Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) + let mk_int2real ( ctx : context ) ( t : expr ) = + (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (Expr.gno t))) - let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) + let mk_int2bv ( ctx : context ) ( n : int ) ( t : expr ) = + (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (Expr.gno t))) end - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : real_sort -> arith_sort - val real_sort_of_arith_sort : arith_sort -> real_sort - val arith_expr_of_real_expr : real_expr -> arith_expr - val real_expr_of_rat_num : rat_num -> real_expr - val real_expr_of_arith_expr : arith_expr -> real_expr - val rat_num_of_real_expr : real_expr -> rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end = struct - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - let arith_sort_of_real_sort s = match s with RealSort(x) -> x - let arith_expr_of_real_expr e = match e with RealExpr(x) -> x - let real_expr_of_rat_num e = match e with RatNum(x) -> x - - let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealExpr(e) - - let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - RatNum(e) - - let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - rat_num_of_real_expr (real_expr_of_ptr ctx no) - - let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealSort(s) - - let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) - let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) - let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) - let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) - let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) - let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) - let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) - let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) - let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - - + module Real = + struct let mk_sort ( ctx : context ) = - real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) + sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - let get_numerator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + let get_numerator ( x : expr ) = + expr_of_ptr (Expr.gc x) (Z3native.get_numerator (Expr.gnc x) (Expr.gno x)) - let get_denominator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + let get_denominator ( x : expr ) = + expr_of_ptr (Expr.gc x) (Z3native.get_denominator (Expr.gnc x) (Expr.gno x)) - let to_decimal_string ( x : rat_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + let to_decimal_string ( x : expr ) ( precision : int ) = + Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = - RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) + Expr.mk_const ctx name (mk_sort ctx) let mk_real_const_s ( ctx : context ) ( name : string ) = mk_real_const ctx (Symbol.mk_string ctx name) @@ -2012,67 +1506,38 @@ end = struct if (den == 0) then raise (Z3native.Exception "Denominator is zero") else - rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) + expr_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) let mk_numeral_s ( ctx : context ) ( v : string ) = - rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) let mk_numeral_i ( ctx : context ) ( v : int ) = - rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) - let mk_is_integer ( ctx : context ) ( t : real_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) + let mk_is_integer ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (Expr.gno t))) - let mk_real2int ( ctx : context ) ( t : real_expr ) = - Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) + let mk_real2int ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (Expr.gno t))) end - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end = struct - type algebraic_num = AlgebraicNum of arith_expr - - let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x - - let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - AlgebraicNum(e) - - let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) - - let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) - let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) - let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - - - let to_upper ( x : algebraic_num ) ( precision : int ) = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + module AlgebraicNumber = + struct + let to_upper ( x : expr ) ( precision : int ) = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) - let to_lower ( x : algebraic_num ) precision = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + let to_lower ( x : expr ) precision = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + let to_decimal_string ( x : expr ) ( precision : int ) = + Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) end let is_int ( x : expr ) = - (Z3native.is_numeral_ast (nc_of_expr x) (nc_of_expr x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == INT_SORT) + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) @@ -2107,224 +1572,55 @@ end = struct let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (nc_of_expr x)))) == REAL_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (nc_of_expr x) (nc_of_expr x) + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - let mk_add ( ctx : context ) ( t : arith_expr list ) = - let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + let mk_add ( ctx : context ) ( t : expr list ) = + let f x = (Expr.gno x) in + (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_mul ( ctx : context ) ( t : arith_expr list ) = - let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + let mk_mul ( ctx : context ) ( t : expr list ) = + let f x = (Expr.gno x) in + (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_sub ( ctx : context ) ( t : arith_expr list ) = - let f x = (ptr_of_expr (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + let mk_sub ( ctx : context ) ( t : expr list ) = + let f x = (Expr.gno x) in + (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) + let mk_unary_minus ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) - let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) + let mk_div ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) + let mk_power ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) + let mk_lt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) + let mk_le ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) + let mk_gt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) + let mk_ge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) end -and BitVector : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - - val mk_sort : context -> int -> bitvec_sort - val is_bv : Expr.expr -> bool - val is_bv_numeral : Expr.expr -> bool - val is_bv_bit1 : Expr.expr -> bool - val is_bv_bit0 : Expr.expr -> bool - val is_bv_uminus : Expr.expr -> bool - val is_bv_add : Expr.expr -> bool - val is_bv_sub : Expr.expr -> bool - val is_bv_mul : Expr.expr -> bool - val is_bv_sdiv : Expr.expr -> bool - val is_bv_udiv : Expr.expr -> bool - val is_bv_SRem : Expr.expr -> bool - val is_bv_urem : Expr.expr -> bool - val is_bv_smod : Expr.expr -> bool - val is_bv_sdiv0 : Expr.expr -> bool - val is_bv_udiv0 : Expr.expr -> bool - val is_bv_srem0 : Expr.expr -> bool - val is_bv_urem0 : Expr.expr -> bool - val is_bv_smod0 : Expr.expr -> bool - val is_bv_ule : Expr.expr -> bool - val is_bv_sle : Expr.expr -> bool - val is_bv_uge : Expr.expr -> bool - val is_bv_sge : Expr.expr -> bool - val is_bv_ult : Expr.expr -> bool - val is_bv_slt : Expr.expr -> bool - val is_bv_ugt : Expr.expr -> bool - val is_bv_sgt : Expr.expr -> bool - val is_bv_and : Expr.expr -> bool - val is_bv_or : Expr.expr -> bool - val is_bv_not : Expr.expr -> bool - val is_bv_xor : Expr.expr -> bool - val is_bv_nand : Expr.expr -> bool - val is_bv_nor : Expr.expr -> bool - val is_bv_xnor : Expr.expr -> bool - val is_bv_concat : Expr.expr -> bool - val is_bv_signextension : Expr.expr -> bool - val is_bv_zeroextension : Expr.expr -> bool - val is_bv_extract : Expr.expr -> bool - val is_bv_repeat : Expr.expr -> bool - val is_bv_reduceor : Expr.expr -> bool - val is_bv_reduceand : Expr.expr -> bool - val is_bv_comp : Expr.expr -> bool - val is_bv_shiftleft : Expr.expr -> bool - val is_bv_shiftrightlogical : Expr.expr -> bool - val is_bv_shiftrightarithmetic : Expr.expr -> bool - val is_bv_rotateleft : Expr.expr -> bool - val is_bv_rotateright : Expr.expr -> bool - val is_bv_rotateleftextended : Expr.expr -> bool - val is_bv_rotaterightextended : Expr.expr -> bool - val is_int_to_bv : Expr.expr -> bool - val is_bv_to_int : Expr.expr -> bool - val is_bv_carry : Expr.expr -> bool - val is_bv_xor3 : Expr.expr -> bool - val get_size : bitvec_sort -> int - val get_int : bitvec_num -> int - val to_string : bitvec_num -> string - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr - val mk_const_s : context -> string -> int -> bitvec_expr - val mk_not : context -> bitvec_expr -> Expr.expr - val mk_redand : context -> bitvec_expr -> Expr.expr - val mk_redor : context -> bitvec_expr -> Expr.expr - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_neg : context -> bitvec_expr -> bitvec_expr - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_numeral : context -> string -> int -> bitvec_num -end = struct - type bitvec_sort = BitVecSort of sort - type bitvec_expr = BitVecExpr of expr - type bitvec_num = BitVecNum of bitvec_expr - - let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x - - let bitvec_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecSort(s) - - let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_sort_of_sort (sort_of_ptr ctx no) - - let bitvec_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecExpr(e) - - let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_expr_of_expr (expr_of_ptr ctx no) - - let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(a)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecNum(e) - - let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) - - let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x - let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x - - - let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) - let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) - let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) - let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (c_of_expr e) - let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (nc_of_expr e) - let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (ptr_of_expr e) - let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) - let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) - let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - - +module BitVector = +struct let mk_sort ( ctx : context ) size = - bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) + sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (nc_of_expr x) (Z3native.get_sort (nc_of_expr x) (ptr_of_expr x)))) == BV_SORT) + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) @@ -2376,112 +1672,112 @@ end = struct let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) - let get_int ( x : bitvec_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + let get_size (x : sort ) = Z3native.get_bv_sort_size (Sort.gnc x) (Sort.gno x) + let get_int ( x : expr ) = + let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) + Expr.mk_const ctx name (mk_sort ctx size) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = mk_const ctx (Symbol.mk_string ctx name) size - let mk_not ( ctx : context ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) - let mk_redand ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) - let mk_redor ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) - let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) - let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) - let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) - let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) - let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) - let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) - let mk_neg ( ctx : context ) ( t : bitvec_expr) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) - let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) - let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) - let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) - let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) - let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) - let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) - let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) - let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) - let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) - let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) - let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) - let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) - let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) - let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) - let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) - let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) - let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) - let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) - let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) - let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) - let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) - let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) - let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) - let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) - let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) - let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) - let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) - let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) - let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) - let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) + let mk_not ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (Expr.gno t)) + let mk_redand ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (Expr.gno t)) + let mk_redor ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (Expr.gno t)) + let mk_and ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_or ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_xor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_nand ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_nor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_xnor ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_neg ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (Expr.gno t)) + let mk_add ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_sub ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_mul ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_udiv ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_sdiv ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_urem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_srem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_smod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_ult ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_slt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_ule ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sle ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_uge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sge ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_ugt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sgt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_concat ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (Expr.gno t)) + let mk_sign_ext ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (Expr.gno t)) + let mk_zero_ext ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (Expr.gno t)) + let mk_repeat ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (Expr.gno t)) + let mk_shl ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_lshr ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_ashr ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_rotate_left ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (Expr.gno t)) + let mk_rotate_right ( ctx : context ) ( i : int ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (Expr.gno t)) + let mk_ext_rotate_left ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_ext_rotate_right ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_bv2int ( ctx : context ) ( t : expr ) ( signed : bool ) = + expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (Expr.gno t) signed) + let mk_add_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = + (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) + let mk_add_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sub_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_sub_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = + (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) + let mk_sdiv_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + let mk_neg_no_overflow ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (Expr.gno t))) + let mk_mul_no_overflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) ( signed : bool) = + (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) + let mk_mul_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx size))) end @@ -2556,8 +1852,8 @@ struct let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in + let assert_ ( x : goal ) ( constraints : expr list ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e) in ignore (List.map f constraints) ; () @@ -2572,7 +1868,7 @@ struct let get_formulas ( x : goal ) = let n = get_size x in - let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + let f i = ((expr_of_ptr (z3obj_gc x) (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in mk_list f n @@ -2749,7 +2045,7 @@ struct exception ModelEvaluationFailedException of string let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (ptr_of_expr t) completion) in + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then raise (ModelEvaluationFailedException "evaluation failed") else @@ -3076,19 +2372,19 @@ struct let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + let assert_ ( x : solver ) ( constraints : expr list ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) - let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = + let assert_and_track_a ( x : solver ) ( cs : expr list ) ( ps : expr list ) = if ((List.length cs) != (List.length ps)) then raise (Z3native.Exception "Argument size mismatch") else - let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in + let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno a) (Expr.gno b)) in ignore (List.iter2 f cs ps) - let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) + let assert_and_track ( x : solver ) ( c : expr ) ( p : expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno c) (Expr.gno p) let get_num_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in @@ -3097,15 +2393,15 @@ struct let get_assertions ( x : solver ) = let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in + let f i = (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in mk_list f n - let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = + let check ( x : solver ) ( assumptions : expr list ) = let r = if ((List.length assumptions) == 0) then lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) else - let f x = (ptr_of_expr (Boolean.expr_of_bool_expr x)) in + let f x = (Expr.gno x) in lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) in match r with @@ -3179,24 +2475,24 @@ struct let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + let assert_ ( x : fixedpoint ) ( constraints : expr list ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) ; () let register_relation ( x : fixedpoint ) ( f : func_decl ) = Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = + let add_rule ( x : fixedpoint ) ( rule : expr ) ( name : Symbol.symbol option ) = match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) (Symbol.gno y) let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) - let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with + let query ( x : fixedpoint ) ( query : expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Expr.gno query))) with | L_TRUE -> Solver.SATISFIABLE | L_FALSE -> Solver.UNSATISFIABLE | _ -> Solver.UNKNOWN @@ -3214,8 +2510,8 @@ struct let pop ( x : fixedpoint ) = Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) + let update_rule ( x : fixedpoint ) ( rule : expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Expr.gno rule) (Symbol.gno name) let get_answer ( x : fixedpoint ) = let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in @@ -3238,27 +2534,27 @@ struct Some (expr_of_ptr (z3obj_gc x) q) let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (ptr_of_expr property) + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = - let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in + let to_string_q ( x : fixedpoint ) ( queries : expr list ) = + let f x = Expr.gno x in Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) let get_rules ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n let get_assertions ( x : fixedpoint ) = let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n let mk_fixedpoint ( ctx : context ) = create ctx @@ -3287,10 +2583,10 @@ end module SMT = struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : expr list ) ( formula : expr ) = Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) - (Boolean.gno formula) + (List.length assumptions) (let f x = Expr.gno (x) in (Array.of_list (List.map f assumptions))) + (Expr.gno formula) let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = let csn = (List.length sort_names) in @@ -3328,14 +2624,14 @@ struct let get_smtlib_formulas ( ctx : context ) = let n = (get_num_smtlib_formulas ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in + let f i =(expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in mk_list f n let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) let get_smtlib_assumptions ( ctx : context ) = let n = (get_num_smtlib_assumptions ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in + let f i = (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in mk_list f n let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) @@ -3360,14 +2656,14 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - + (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = let csn = (List.length sort_names) in let cs = (List.length sorts) in @@ -3376,13 +2672,13 @@ struct if (csn != cs || cdn != cd) then raise (Z3native.Exception "Argument size mismatch") else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) + (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) end diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 9f451c45f..908b3023d 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -70,14 +70,7 @@ end (** Symbols are used to name several term and type constructors *) module Symbol : sig - (** Numbered Symbols *) - type int_symbol - - (** Named Symbols *) - type string_symbol - - (** Symbols *) - type symbol = S_Int of int_symbol | S_Str of string_symbol + type symbol (** The kind of the symbol (int or string) *) val kind : symbol -> Z3enums.symbol_kind @@ -89,10 +82,10 @@ sig val is_string_symbol : symbol -> bool (** The int value of the symbol. *) - val get_int : int_symbol -> int + val get_int : symbol -> int (** The string value of the symbol. *) - val get_string : string_symbol -> string + val get_string : symbol -> string (** A string representation of the symbol. *) val to_string : symbol -> string @@ -251,15 +244,9 @@ end (** The Sort module implements type information for ASTs *) module Sort : sig - (** Sorts *) type sort = Sort of AST.ast - (** Uninterpreted Sorts *) - type uninterpreted_sort = UninterpretedSort of sort - val ast_of_sort : sort -> AST.ast - val sort_of_uninterpreted_sort : uninterpreted_sort -> sort - val uninterpreted_sort_of_sort : sort -> uninterpreted_sort (** Comparison operator. @return True if the two sorts are from the same context @@ -279,10 +266,10 @@ sig val to_string : sort -> string (** Create a new uninterpreted sort. *) - val mk_uninterpreted : context -> Symbol.symbol -> uninterpreted_sort + val mk_uninterpreted : context -> Symbol.symbol -> sort (** Create a new uninterpreted sort. *) - val mk_uninterpreted_s : context -> string -> uninterpreted_sort + val mk_uninterpreted_s : context -> string -> sort end (** Function declarations *) @@ -597,58 +584,50 @@ end (** Boolean expressions *) module Boolean : sig - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - val expr_of_bool_expr : bool_expr -> Expr.expr - val sort_of_bool_sort : bool_sort -> Sort.sort - val bool_sort_of_sort : Sort.sort -> bool_sort - val bool_expr_of_expr : Expr.expr -> bool_expr - (** Create a Boolean sort *) - val mk_sort : context -> bool_sort + val mk_sort : context -> Sort.sort (** Create a Boolean constant. *) - val mk_const : context -> Symbol.symbol -> bool_expr + val mk_const : context -> Symbol.symbol -> Expr.expr (** Create a Boolean constant. *) - val mk_const_s : context -> string -> bool_expr + val mk_const_s : context -> string -> Expr.expr (** The true Term. *) - val mk_true : context -> bool_expr + val mk_true : context -> Expr.expr (** The false Term. *) - val mk_false : context -> bool_expr + val mk_false : context -> Expr.expr (** Creates a Boolean value. *) - val mk_val : context -> bool -> bool_expr + val mk_val : context -> bool -> Expr.expr (** Creates the equality between two expr's. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr + val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr (** Creates a distinct term. *) - val mk_distinct : context -> Expr.expr list -> bool_expr + val mk_distinct : context -> Expr.expr list -> Expr.expr (** Mk an expression representing not(a). *) - val mk_not : context -> bool_expr -> bool_expr + val mk_not : context -> Expr.expr -> Expr.expr (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) - val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr + val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 iff t2. *) - val mk_iff : context -> bool_expr -> bool_expr -> bool_expr + val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 -> t2. *) - val mk_implies : context -> bool_expr -> bool_expr -> bool_expr + val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 xor t2. *) - val mk_xor : context -> bool_expr -> bool_expr -> bool_expr + val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing the AND of args *) - val mk_and : context -> bool_expr list -> bool_expr + val mk_and : context -> Expr.expr list -> Expr.expr (** Create an expression representing the OR of args *) - val mk_or : context -> bool_expr list -> bool_expr + val mk_or : context -> Expr.expr list -> Expr.expr end (** Quantifier expressions *) @@ -731,7 +710,7 @@ sig val get_bound_variable_sorts : quantifier -> Sort.sort list (** The body of the quantifier. *) - val get_body : quantifier -> Boolean.bool_expr + val get_body : quantifier -> Expr.expr (** Creates a new bound variable. *) val mk_bound : context -> int -> Sort.sort -> Expr.expr @@ -761,17 +740,8 @@ end (** Functions to manipulate Array expressions *) module Array_ : sig - type array_sort = ArraySort of Sort.sort - type array_expr = ArrayExpr of Expr.expr - - val sort_of_array_sort : array_sort -> Sort.sort - val array_sort_of_sort : Sort.sort -> array_sort - val expr_of_array_expr : array_expr -> Expr.expr - - val array_expr_of_expr : Expr.expr -> array_expr - (** Create a new array sort. *) - val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort + val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort (** Indicates whether the term is an array store. It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). @@ -802,16 +772,16 @@ sig val is_array : Expr.expr -> bool (** The domain of the array sort. *) - val get_domain : array_sort -> Sort.sort + val get_domain : Sort.sort -> Sort.sort (** The range of the array sort. *) - val get_range : array_sort -> Sort.sort + val get_range : Sort.sort -> Sort.sort (** Create an array constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr + val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> Expr.expr (** Create an array constant. *) - val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr + val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> Expr.expr (** Array read. @@ -823,7 +793,7 @@ sig The sort of the result is range. {!Array_.mk_sort} {!mk_store} *) - val mk_select : context -> array_expr -> Expr.expr -> array_expr + val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr (** Array update. @@ -839,7 +809,7 @@ sig respect to i may be a different value). {!Array_.mk_sort} {!mk_select} *) - val mk_store : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr + val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr (** Create a constant array. @@ -847,7 +817,7 @@ sig produces the value v. {!Array_.mk_sort} {!mk_select} *) - val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr + val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr (** Maps f on the argument arrays. @@ -857,24 +827,20 @@ sig {!Array_.mk_sort} {!mk_select} {!mk_store} *) - val mk_map : context -> FuncDecl.func_decl -> array_expr list -> array_expr + val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr (** Access the array default value. Produces the default range value, for arrays that can be represented as finite maps with a default range value. *) - val mk_term_array : context -> array_expr -> array_expr + val mk_term_array : context -> Expr.expr -> Expr.expr end (** Functions to manipulate Set expressions *) module Set : sig - type set_sort = SetSort of Sort.sort - - val sort_of_set_sort : set_sort -> Sort.sort - (** Create a set type. *) - val mk_sort : context -> Sort.sort -> set_sort + val mk_sort : context -> Sort.sort -> Sort.sort (** Indicates whether the term is set union *) val is_union : Expr.expr -> bool @@ -925,16 +891,11 @@ end (** Functions to manipulate Finite Domain expressions *) module FiniteDomain : sig - type finite_domain_sort = FiniteDomainSort of Sort.sort - - val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort - val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort + (** Create a new finite domain sort. *) + val mk_sort : context -> Symbol.symbol -> int -> Sort.sort (** Create a new finite domain sort. *) - val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort - - (** Create a new finite domain sort. *) - val mk_sort_s : context -> string -> int -> finite_domain_sort + val mk_sort_s : context -> string -> int -> Sort.sort (** Indicates whether the term is of an array sort. *) val is_finite_domain : Expr.expr -> bool @@ -943,18 +904,13 @@ sig val is_lt : Expr.expr -> bool (** The size of the finite domain sort. *) - val get_size : finite_domain_sort -> int + val get_size : Sort.sort -> int end (** Functions to manipulate Relation expressions *) module Relation : sig - type relation_sort = RelationSort of Sort.sort - - val sort_of_relation_sort : relation_sort -> Sort.sort - val relation_sort_of_sort : Sort.sort -> relation_sort - (** Indicates whether the term is of a relation sort. *) val is_relation : Expr.expr -> bool @@ -1034,23 +990,15 @@ sig val is_clone : Expr.expr -> bool (** The arity of the relation sort. *) - val get_arity : relation_sort -> int + val get_arity : Sort.sort -> int (** The sorts of the columns of the relation sort. *) - val get_column_sorts : relation_sort -> relation_sort list + val get_column_sorts : Sort.sort -> Sort.sort list end (** Functions to manipulate Datatype expressions *) module Datatype : sig - type datatype_sort = DatatypeSort of Sort.sort - type datatype_expr = DatatypeExpr of Expr.expr - - val sort_of_datatype_sort : datatype_sort -> Sort.sort - val datatype_sort_of_sort : Sort.sort -> datatype_sort - val expr_of_datatype_expr : datatype_expr -> Expr.expr - val datatype_expr_of_expr : Expr.expr -> datatype_expr - (** Datatype Constructors *) module Constructor : sig @@ -1080,160 +1028,129 @@ sig val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor (** Create a new datatype sort. *) - val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> datatype_sort + val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> Sort.sort (** Create a new datatype sort. *) - val mk_sort_s : context -> string -> Constructor.constructor list -> datatype_sort + val mk_sort_s : context -> string -> Constructor.constructor list -> Sort.sort (** Create mutually recursive datatypes. *) - val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> datatype_sort list + val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> Sort.sort list (** Create mutually recursive data-types. *) - val mk_sorts_s : context -> string list -> Constructor.constructor list list -> datatype_sort list + val mk_sorts_s : context -> string list -> Constructor.constructor list list -> Sort.sort list (** The number of constructors of the datatype sort. *) - val get_num_constructors : datatype_sort -> int + val get_num_constructors : Sort.sort -> int (** The constructors. *) - val get_constructors : datatype_sort -> FuncDecl.func_decl list + val get_constructors : Sort.sort -> FuncDecl.func_decl list (** The recognizers. *) - val get_recognizers : datatype_sort -> FuncDecl.func_decl list + val get_recognizers : Sort.sort -> FuncDecl.func_decl list (** The constructor accessors. *) - val get_accessors : datatype_sort -> FuncDecl.func_decl list list + val get_accessors : Sort.sort -> FuncDecl.func_decl list list end (** Functions to manipulate Enumeration expressions *) module Enumeration : sig - type enum_sort = EnumSort of Sort.sort - - val sort_of_enum_sort : enum_sort -> Sort.sort + (** Create a new enumeration sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort (** Create a new enumeration sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> enum_sort - - (** Create a new enumeration sort. *) - val mk_sort_s : context -> string -> string list -> enum_sort + val mk_sort_s : context -> string -> string list -> Sort.sort (** The function declarations of the constants in the enumeration. *) - val get_const_decls : enum_sort -> FuncDecl.func_decl list + val get_const_decls : Sort.sort -> FuncDecl.func_decl list (** The test predicates for the constants in the enumeration. *) - val get_tester_decls : enum_sort -> FuncDecl.func_decl list + val get_tester_decls : Sort.sort -> FuncDecl.func_decl list end (** Functions to manipulate List expressions *) module List_ : sig - type list_sort = ListSort of Sort.sort - - val sort_of_list_sort : list_sort -> Sort.sort + (** Create a new list sort. *) + val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort (** Create a new list sort. *) - val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort - - (** Create a new list sort. *) - val mk_list_s : context -> string -> Sort.sort -> list_sort + val mk_list_s : context -> string -> Sort.sort -> Sort.sort (** The declaration of the nil function of this list sort. *) - val get_nil_decl : list_sort -> FuncDecl.func_decl + val get_nil_decl : Sort.sort -> FuncDecl.func_decl (** The declaration of the isNil function of this list sort. *) - val get_is_nil_decl : list_sort -> FuncDecl.func_decl + val get_is_nil_decl : Sort.sort -> FuncDecl.func_decl (** The declaration of the cons function of this list sort. *) - val get_cons_decl : list_sort -> FuncDecl.func_decl + val get_cons_decl : Sort.sort -> FuncDecl.func_decl (** The declaration of the isCons function of this list sort. *) - val get_is_cons_decl : list_sort -> FuncDecl.func_decl + val get_is_cons_decl : Sort.sort -> FuncDecl.func_decl (** The declaration of the head function of this list sort. *) - val get_head_decl : list_sort -> FuncDecl.func_decl + val get_head_decl : Sort.sort -> FuncDecl.func_decl (** The declaration of the tail function of this list sort. *) - val get_tail_decl : list_sort -> FuncDecl.func_decl + val get_tail_decl : Sort.sort -> FuncDecl.func_decl (** The empty list. *) - val nil : list_sort -> Expr.expr + val nil : Sort.sort -> Expr.expr end (** Functions to manipulate Tuple expressions *) module Tuple : sig - type tuple_sort = TupleSort of Sort.sort - - val sort_of_tuple_sort : tuple_sort -> Sort.sort - (** Create a new tuple sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> tuple_sort + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> Sort.sort (** The constructor function of the tuple. *) - val get_mk_decl : tuple_sort -> FuncDecl.func_decl + val get_mk_decl : Sort.sort -> FuncDecl.func_decl (** The number of fields in the tuple. *) - val get_num_fields : tuple_sort -> int + val get_num_fields : Sort.sort -> int (** The field declarations. *) - val get_field_decls : tuple_sort -> FuncDecl.func_decl list + val get_field_decls : Sort.sort -> FuncDecl.func_decl list end (** Functions to manipulate arithmetic expressions *) module rec Arithmetic : sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : Arithmetic.arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> Arithmetic.arith_sort - val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr - (** Integer Arithmetic *) module rec Integer : sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val arith_sort_of_int_sort : Arithmetic.Integer.int_sort -> Arithmetic.arith_sort - val int_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Integer.int_sort - val arith_expr_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.arith_expr - val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr - val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr - val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num - (** Create a new integer sort. *) - val mk_sort : context -> int_sort + val mk_sort : context -> Sort.sort (** Retrieve the int value. *) - val get_int : int_num -> int + val get_int : Expr.expr -> int (** Returns a string representation of the numeral. *) - val to_string : int_num -> string + val to_string : Expr.expr -> string (** Creates an integer constant. *) - val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const : context -> Symbol.symbol -> Expr.expr (** Creates an integer constant. *) - val mk_int_const_s : context -> string -> int_expr + val mk_int_const_s : context -> string -> Expr.expr (** Create an expression representing t1 mod t2. The arguments must have int type. *) - val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 rem t2. The arguments must have int type. *) - val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer numeral. *) - val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_s : context -> string -> Expr.expr (** Create an integer numeral. @return A Term with the given value and sort Integer *) - val mk_int_numeral_i : context -> int -> int_num + val mk_int_numeral_i : context -> int -> Expr.expr (** Coerce an integer to a real. @@ -1243,7 +1160,7 @@ sig You can take the floor of a real by creating an auxiliary integer Term k and and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. The argument must be of integer sort. *) - val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2real : context -> Expr.expr -> Expr.expr (** Create an n-bit bit-vector from an integer argument. @@ -1253,94 +1170,78 @@ sig when solving constraints with this function. The argument must be of integer sort. *) - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + val mk_int2bv : context -> int -> Expr.expr -> Expr.expr end (** Real Arithmetic *) and Real : sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - (** Create a real sort. *) - val mk_sort : context -> real_sort + val mk_sort : context -> Sort.sort (** The numerator of a rational numeral. *) - val get_numerator : rat_num -> Integer.int_num + val get_numerator : Expr.expr-> Expr.expr (** The denominator of a rational numeral. *) - val get_denominator : rat_num -> Integer.int_num + val get_denominator : Expr.expr-> Expr.expr (** Returns a string representation in decimal notation. The result has at most as many decimal places as indicated by the int argument.*) - val to_decimal_string : rat_num -> int -> string + val to_decimal_string : Expr.expr-> int -> string (** Returns a string representation of the numeral. *) - val to_string : rat_num -> string + val to_string : Expr.expr-> string (** Creates a real constant. *) - val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const : context -> Symbol.symbol -> Expr.expr (** Creates a real constant. *) - val mk_real_const_s : context -> string -> real_expr + val mk_real_const_s : context -> string -> Expr.expr (** Create a real numeral from a fraction. @return A Term with rational value and sort Real {!mk_numeral_s} *) - val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_nd : context -> int -> int -> Expr.expr (** Create a real numeral. @return A Term with the given value and sort Real *) - val mk_numeral_s : context -> string -> rat_num + val mk_numeral_s : context -> string -> Expr.expr (** Create a real numeral. @return A Term with the given value and sort Real *) - val mk_numeral_i : context -> int -> rat_num + val mk_numeral_i : context -> int -> Expr.expr (** Creates an expression that checks whether a real number is an integer. *) - val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_is_integer : context -> Expr.expr -> Expr.expr (** Coerce a real to an integer. The semantics of this function follows the SMT-LIB standard for the function to_int. The argument must be of real sort. *) - val mk_real2int : context -> real_expr -> Integer.int_expr + val mk_real2int : context -> Expr.expr -> Expr.expr end (** Algebraic Numbers *) and AlgebraicNumber : sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr - val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num - (** Return a upper bound for a given real algebraic number. The interval isolating the number is smaller than 1/10^precision. {!is_algebraic_number} @return A numeral Expr of sort Real *) - val to_upper : algebraic_num -> int -> Real.rat_num + val to_upper : Expr.expr -> int -> Expr.expr (** Return a lower bound for the given real algebraic number. The interval isolating the number is smaller than 1/10^precision. {!is_algebraic_number} @return A numeral Expr of sort Real *) - val to_lower : algebraic_num -> int -> Real.rat_num + val to_lower : Expr.expr -> int -> Expr.expr (** Returns a string representation in decimal notation. The result has at most as many decimal places as the int argument provided.*) - val to_decimal_string : algebraic_num -> int -> string + val to_decimal_string : Expr.expr -> int -> string (** Returns a string representation of the numeral. *) - val to_string : algebraic_num -> string + val to_string : Expr.expr -> string end (** Indicates whether the term is of integer sort. *) @@ -1407,52 +1308,41 @@ sig val is_algebraic_number : Expr.expr -> bool (** Create an expression representing t[0] + t[1] + .... *) - val mk_add : context -> arith_expr list -> arith_expr + val mk_add : context -> Expr.expr list -> Expr.expr (** Create an expression representing t[0] * t[1] * .... *) - val mk_mul : context -> arith_expr list -> arith_expr + val mk_mul : context -> Expr.expr list -> Expr.expr (** Create an expression representing t[0] - t[1] - .... *) - val mk_sub : context -> arith_expr list -> arith_expr + val mk_sub : context -> Expr.expr list -> Expr.expr (** Create an expression representing -t. *) - val mk_unary_minus : context -> arith_expr -> arith_expr + val mk_unary_minus : context -> Expr.expr -> Expr.expr (** Create an expression representing t1 / t2. *) - val mk_div : context -> arith_expr -> arith_expr -> arith_expr + val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 ^ t2. *) - val mk_power : context -> arith_expr -> arith_expr -> arith_expr + val mk_power : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 < t2 *) - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 <= t2 *) - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_le : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 > t2 *) - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing t1 >= t2 *) - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_ge : context -> Expr.expr -> Expr.expr -> Expr.expr end (** Functions to manipulate bit-vector expressions *) and BitVector : sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - (** Create a new bit-vector sort. *) - val mk_sort : context -> int -> bitvec_sort + val mk_sort : context -> int -> Sort.sort (** Indicates whether the terms is of bit-vector sort. *) val is_bv : Expr.expr -> bool @@ -1624,71 +1514,71 @@ sig val is_bv_xor3 : Expr.expr -> bool (** The size of a bit-vector sort. *) - val get_size : bitvec_sort -> int + val get_size : Sort.sort -> int (** Retrieve the int value. *) - val get_int : bitvec_num -> int + val get_int : Expr.expr -> int (** Returns a string representation of the numeral. *) - val to_string : bitvec_num -> string + val to_string : Expr.expr -> string (** Creates a bit-vector constant. *) - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + val mk_const : context -> Symbol.symbol -> int -> Expr.expr (** Creates a bit-vector constant. *) - val mk_const_s : context -> string -> int -> bitvec_expr + val mk_const_s : context -> string -> int -> Expr.expr (** Bitwise negation. The argument must have a bit-vector sort. *) - val mk_not : context -> bitvec_expr -> Expr.expr + val mk_not : context -> Expr.expr -> Expr.expr (** Take conjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) - val mk_redand : context -> bitvec_expr -> Expr.expr + val mk_redand : context -> Expr.expr -> Expr.expr (** Take disjunction of bits in a vector,vector of length 1. The argument must have a bit-vector sort. *) - val mk_redor : context -> bitvec_expr -> Expr.expr + val mk_redor : context -> Expr.expr -> Expr.expr (** Bitwise conjunction. The arguments must have a bit-vector sort. *) - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_and : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise disjunction. The arguments must have a bit-vector sort. *) - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_or : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise XOR. The arguments must have a bit-vector sort. *) - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise NAND. The arguments must have a bit-vector sort. *) - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nand : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise NOR. The arguments must have a bit-vector sort. *) - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise XNOR. The arguments must have a bit-vector sort. *) - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xnor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Standard two's complement unary minus. The arguments must have a bit-vector sort. *) - val mk_neg : context -> bitvec_expr -> bitvec_expr + val mk_neg : context -> Expr.expr -> Expr.expr (** Two's complement addition. The arguments must have the same bit-vector sort. *) - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement subtraction. The arguments must have the same bit-vector sort. *) - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement multiplication. The arguments must have the same bit-vector sort. *) - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned division. @@ -1697,7 +1587,7 @@ sig different from zero. If t2 is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed division. @@ -1709,14 +1599,14 @@ sig If t2 is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned remainder. It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. If t2 is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed remainder. @@ -1725,53 +1615,53 @@ sig If t2 is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed remainder (sign follows divisor). If t2 is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned less-than The arguments must have the same bit-vector sort. *) - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ult : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed less-than The arguments must have the same bit-vector sort. *) - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_slt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned less-than or equal to. The arguments must have the same bit-vector sort. *) - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ule : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed less-than or equal to. The arguments must have the same bit-vector sort. *) - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sle : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned greater than or equal to. The arguments must have the same bit-vector sort. *) - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_uge : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed greater than or equal to. The arguments must have the same bit-vector sort. *) - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sge : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned greater-than. The arguments must have the same bit-vector sort. *) - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ugt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed greater-than. The arguments must have the same bit-vector sort. *) - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sgt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector concatenation. @@ -1779,30 +1669,30 @@ sig @return The result is a bit-vector of size n1+n2, where n1 (n2) is the size of t1 (t2). *) - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector extraction. Extract the bits between two limits from a bitvector of size m to yield a new bitvector of size n, where n = high - low + 1. *) - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + val mk_extract : context -> int -> int -> Expr.expr -> Expr.expr (** Bit-vector sign extension. Sign-extends the given bit-vector to the (signed) equivalent bitvector of size m+i, where \c m is the size of the given bit-vector. *) - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr (** Bit-vector zero extension. Extend the given bit-vector with zeros to the (unsigned) equivalent bitvector of size m+i, where \c m is the size of the given bit-vector. *) - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr (** Bit-vector repetition. *) - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + val mk_repeat : context -> int -> Expr.expr -> Expr.expr (** Shift left. @@ -1811,7 +1701,7 @@ sig NB. The semantics of shift operations varies between environments. This definition does not necessarily capture directly the semantics of the programming language or assembly architecture you are modeling.*) - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_shl : context -> Expr.expr -> Expr.expr -> Expr.expr (** Logical shift right @@ -1822,7 +1712,7 @@ sig programming language or assembly architecture you are modeling. The arguments must have a bit-vector sort. *) - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_lshr : context -> Expr.expr -> Expr.expr -> Expr.expr (** Arithmetic shift right @@ -1835,23 +1725,23 @@ sig programming language or assembly architecture you are modeling. The arguments must have a bit-vector sort. *) - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ashr : context -> Expr.expr -> Expr.expr -> Expr.expr (** Rotate Left. Rotate bits of \c t to the left \c i times. *) - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> int -> Expr.expr -> Expr.expr (** Rotate Right. Rotate bits of \c t to the right \c i times.*) - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> int -> Expr.expr -> Expr.expr (** Rotate Left. Rotate bits of the second argument to the left.*) - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_left : context -> Expr.expr -> Expr.expr -> Expr.expr (** Rotate Right. Rotate bits of the second argument to the right. *) - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_right : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer from the bit-vector argument @@ -1863,50 +1753,50 @@ sig NB. This function is essentially treated as uninterpreted. So you cannot expect Z3 to precisely reflect the semantics of this function when solving constraints with this function.*) - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + val mk_bv2int : context -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise addition does not overflow. The arguments must be of bit-vector sort. *) - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_add_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise addition does not underflow. The arguments must be of bit-vector sort. *) - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_add_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise subtraction does not overflow. The arguments must be of bit-vector sort. *) - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise subtraction does not underflow. The arguments must be of bit-vector sort. *) - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_sub_no_underflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise signed division does not overflow. The arguments must be of bit-vector sort. *) - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sdiv_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise negation does not overflow. The arguments must be of bit-vector sort. *) - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + val mk_neg_no_overflow : context -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise multiplication does not overflow. The arguments must be of bit-vector sort. *) - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_mul_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise multiplication does not underflow. The arguments must be of bit-vector sort. *) - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a bit-vector numeral. *) - val mk_numeral : context -> string -> int -> bitvec_num + val mk_numeral : context -> string -> int -> Expr.expr end (** Functions to manipulate proof expressions *) @@ -2332,7 +2222,7 @@ sig val is_garbage : goal -> bool (** Adds the constraints to the given goal. *) - val assert_ : goal -> Boolean.bool_expr list -> unit + val assert_ : goal -> Expr.expr list -> unit (** Indicates whether the goal contains `false'. *) val is_inconsistent : goal -> bool @@ -2348,7 +2238,7 @@ sig val get_size : goal -> int (** The formulas in the goal. *) - val get_formulas : goal -> Boolean.bool_expr list + val get_formulas : goal -> Expr.expr list (** The number of formulas, subformulas and terms in the goal. *) val get_num_exprs : goal -> int @@ -2759,7 +2649,7 @@ sig val reset : solver -> unit (** Assert a constraint (or multiple) into the solver. *) - val assert_ : solver -> Boolean.bool_expr list -> unit + val assert_ : solver -> Expr.expr list -> unit (** * Assert multiple constraints (cs) into the solver, and track them (in the * unsat) core @@ -2772,7 +2662,7 @@ sig * of the Boolean variables provided using {!assert_and_track} * and the Boolean literals * provided using {!check} with assumptions. *) - val assert_and_track_a : solver -> Boolean.bool_expr list -> Boolean.bool_expr list -> unit + val assert_and_track_a : solver -> Expr.expr list -> Expr.expr list -> unit (** * Assert a constraint (c) into the solver, and track it (in the unsat) core * using the Boolean constant p. @@ -2784,20 +2674,20 @@ sig * of the Boolean variables provided using {!assert_and_track} * and the Boolean literals * provided using {!check} with assumptions. *) - val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit + val assert_and_track : solver -> Expr.expr -> Expr.expr -> unit (** The number of assertions in the solver. *) val get_num_assertions : solver -> int (** The set of asserted formulas. *) - val get_assertions : solver -> Boolean.bool_expr list + val get_assertions : solver -> Expr.expr list (** Checks whether the assertions in the solver are consistent or not. {!Model} {!get_unsat_core} {!Proof} *) - val check : solver -> Boolean.bool_expr list -> status + val check : solver -> Expr.expr list -> status (** The model of the last Check. @@ -2863,13 +2753,13 @@ sig val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs (** Assert a constraints into the fixedpoint solver. *) - val assert_ : fixedpoint -> Boolean.bool_expr list -> unit + val assert_ : fixedpoint -> Expr.expr list -> unit (** Register predicate as recursive relation. *) val register_relation : fixedpoint -> FuncDecl.func_decl -> unit (** Add rule into the fixedpoint solver. *) - val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit + val add_rule : fixedpoint -> Expr.expr -> Symbol.symbol option -> unit (** Add table fact to the fixedpoint solver. *) val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit @@ -2878,7 +2768,7 @@ sig A query is a conjunction of constraints. The constraints may include the recursively defined relations. The query is satisfiable if there is an instance of the query variables and a derivation for it. The query is unsatisfiable if there are no derivations satisfying the query variables. *) - val query : fixedpoint -> Boolean.bool_expr -> Solver.status + val query : fixedpoint -> Expr.expr -> Solver.status (** Query the fixedpoint solver. A query is an array of relations. @@ -2897,7 +2787,7 @@ sig val pop : fixedpoint -> unit (** Update named rule into in the fixedpoint solver. *) - val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit + val update_rule : fixedpoint -> Expr.expr -> Symbol.symbol -> unit (** Retrieve satisfying instance or instances of solver, or definitions for the recursive predicates that show unsatisfiability. *) @@ -2923,13 +2813,13 @@ sig val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit (** Convert benchmark given as set of axioms, rules and queries to a string. *) - val to_string_q : fixedpoint -> Boolean.bool_expr list -> string + val to_string_q : fixedpoint -> Expr.expr list -> string (** Retrieve set of rules added to fixedpoint context. *) - val get_rules : fixedpoint -> Boolean.bool_expr list + val get_rules : fixedpoint -> Expr.expr list (** Retrieve set of assertions added to fixedpoint context. *) - val get_assertions : fixedpoint -> Boolean.bool_expr list + val get_assertions : fixedpoint -> Expr.expr list (** Create a Fixedpoint context. *) val mk_fixedpoint : context -> fixedpoint @@ -2985,7 +2875,7 @@ sig (** Convert a benchmark into an SMT-LIB formatted string. @return A string representation of the benchmark. *) - val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr list -> Boolean.bool_expr -> string + val benchmark_to_smtstring : context -> string -> string -> string -> string -> Expr.expr list -> Expr.expr -> string (** Parse the given string using the SMT-LIB parser. @@ -3004,13 +2894,13 @@ sig val get_num_smtlib_formulas : context -> int (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_formulas : context -> Boolean.bool_expr list + val get_smtlib_formulas : context -> Expr.expr list (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_assumptions : context -> int (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_assumptions : context -> Boolean.bool_expr list + val get_smtlib_assumptions : context -> Expr.expr list (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) val get_num_smtlib_decls : context -> int @@ -3028,11 +2918,11 @@ sig {!parse_smtlib_string} @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr + val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr (** Parse the given file using the SMT-LIB2 parser. {!parse_smtlib2_string} *) - val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr + val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr end (** Set a global (or module) parameter, which is shared by all Z3 contexts. diff --git a/src/api/ml/z3_rich.ml b/src/api/ml/z3_rich.ml new file mode 100644 index 000000000..052ca5e22 --- /dev/null +++ b/src/api/ml/z3_rich.ml @@ -0,0 +1,3400 @@ +(** + The Z3 ML/Ocaml Interface. + + Copyright (C) 2012 Microsoft Corporation + @author CM Wintersteiger (cwinter) 2012-12-17 +*) + +open Z3enums + +(* Some helpers. *) +let null = Z3native.mk_null() +let is_null o = (Z3native.is_null o) + + +(* Internal types *) +type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } +type context = z3_native_context + +type z3_native_object = { + m_ctx : context ; + mutable m_n_obj : Z3native.ptr ; + inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; + dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } + + +(** Internal stuff *) +module Internal = +struct + let dispose_context ctx = + if ctx.m_n_obj_cnt == 0 then ( + (Z3native.del_context ctx.m_n_ctx) + ) else ( + Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; + ) + + let create_context settings = + let cfg = Z3native.mk_config in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_context_rc cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + Z3native.set_internal_error_handler v ; + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> dispose_context o in + Gc.finalise f res; + res + + let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) + let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) + let context_gno ctx = ctx.m_n_ctx + + + let z3obj_gc o = o.m_ctx + let z3obj_gnc o = (context_gno o.m_ctx) + + let z3obj_gno o = o.m_n_obj + let z3obj_sno o ctx no = + (context_add1 ctx) ; + o.inc_ref (context_gno ctx) no ; + ( + if not (is_null o.m_n_obj) then + o.dec_ref (context_gno ctx) o.m_n_obj ; + (context_sub1 ctx) + ) ; + o.m_n_obj <- no + + let z3obj_dispose o = + if not (is_null o.m_n_obj) then + ( + o.dec_ref (z3obj_gnc o) o.m_n_obj ; + (context_sub1 (z3obj_gc o)) + ) ; + o.m_n_obj <- null + + let z3obj_create o = + let f = fun o -> (z3obj_dispose o) in + Gc.finalise f o + + let z3obj_nil_ref x y = () + + let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> + let res : z3_native_object = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res +end + +open Internal + +module Log = +struct + let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) + let close = Z3native.close_log + let append s = Z3native.append_log s +end + + +module Version = +struct + let major = let (x, _, _, _) = Z3native.get_version in x + let minor = let (_, x, _, _) = Z3native.get_version in x + let build = let (_, _, x, _) = Z3native.get_version in x + let revision = let (_, _, _, x) = Z3native.get_version in x + let to_string = + let (mj, mn, bld, rev) = Z3native.get_version in + string_of_int mj ^ "." ^ + string_of_int mn ^ "." ^ + string_of_int bld ^ "." ^ + string_of_int rev ^ "." +end + + +let mk_list ( f : int -> 'a ) ( n : int ) = + let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = + if (i >= n) then + tail + else + (mk_list' f (i+1) n ((f i) :: tail)) + in + mk_list' f 0 n [] + +let list_of_array ( x : _ array ) = + let f i = (Array.get x i) in + mk_list f (Array.length x) + +let mk_context ( cfg : ( string * string ) list ) = + create_context cfg + + +module Symbol = +struct + (* Symbol types *) + type int_symbol = z3_native_object + type string_symbol = z3_native_object + + type symbol = + | S_Int of int_symbol + | S_Str of string_symbol + + + let create_i ( ctx : context ) ( no : Z3native.ptr ) = + let res : int_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let create_s ( ctx : context ) ( no : Z3native.ptr ) = + let res : string_symbol = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let create ( ctx : context ) ( no : Z3native.ptr ) = + match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with + | INT_SYMBOL -> S_Int (create_i ctx no) + | STRING_SYMBOL -> S_Str (create_s ctx no) + + let gc ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gc n) + | S_Str(n) -> (z3obj_gc n) + + let gnc ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gnc n) + | S_Str(n) -> (z3obj_gnc n) + + let gno ( x : symbol ) = + match x with + | S_Int(n) -> (z3obj_gno n) + | S_Str(n) -> (z3obj_gno n) + + let symbol_lton ( a : symbol list ) = + let f ( e : symbol ) = (gno e) in + Array.of_list (List.map f a) + + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) + let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL + let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL + let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) + let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) + let to_string ( o : symbol ) = + match (kind o) with + | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) + | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) + + let mk_int ( ctx : context ) ( i : int ) = + S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) + + let mk_string ( ctx : context ) ( s : string ) = + S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) + + let mk_ints ( ctx : context ) ( names : int list ) = + let f elem = mk_int ( ctx : context ) elem in + (List.map f names) + + let mk_strings ( ctx : context ) ( names : string list ) = + let f elem = mk_string ( ctx : context ) elem in + (List.map f names) +end + + +module AST = +struct + type ast = z3_native_object + + let context_of_ast ( x : ast ) = (z3obj_gc x) + let nc_of_ast ( x : ast ) = (z3obj_gnc x) + let ptr_of_ast ( x : ast ) = (z3obj_gno x) + + let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> + match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with + | FUNC_DECL_AST + | SORT_AST + | QUANTIFIER_AST + | APP_AST + | NUMERAL_AST + | VAR_AST -> z3_native_object_of_ast_ptr ctx no + | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") + + module ASTVector = + struct + type ast_vector = z3_native_object + + let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_vector = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_vector_inc_ref ; + dec_ref = Z3native.ast_vector_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_size ( x : ast_vector ) = + Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) + + let get ( x : ast_vector ) ( i : int ) = + ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) + + let set ( x : ast_vector ) ( i : int ) ( value : ast ) = + Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) + + let resize ( x : ast_vector ) ( new_size : int ) = + Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size + + let push ( x : ast_vector ) ( a : ast ) = + Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) + + let translate ( x : ast_vector ) ( to_ctx : context ) = + ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + + let to_string ( x : ast_vector ) = + Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) + end + + module ASTMap = + struct + type ast_map = z3_native_object + + let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_map = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_map_inc_ref ; + dec_ref = Z3native.ast_map_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let contains ( x : ast_map ) ( key : ast ) = + Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) + + let find ( x : ast_map ) ( key : ast ) = + ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) + + let insert ( x : ast_map ) ( key : ast ) ( value : ast) = + Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) + + let erase ( x : ast_map ) ( key : ast ) = + Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) + + let reset ( x : ast_map ) = + Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) + + let get_size ( x : ast_map ) = + Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) + + let get_keys ( x : ast_map ) = + let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in + let f i = (ASTVector.get av i) in + mk_list f (ASTVector.get_size av) + + let to_string ( x : ast_map ) = + Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) + end + + let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) + let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) + let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) + + let is_expr ( x : ast ) = + match get_ast_kind ( x : ast ) with + | APP_AST + | NUMERAL_AST + | QUANTIFIER_AST + | VAR_AST -> true + | _ -> false + + let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST + let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST + let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST + let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST + + let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) + let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) + + + let ( = ) ( a : ast ) ( b : ast ) = (a == b) || + if (z3obj_gnc a) != (z3obj_gnc b) then + false + else + Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) + + let compare a b = + if (get_id a) < (get_id b) then -1 else + if (get_id a) > (get_id b) then 1 else + 0 + + let ( < ) (a : ast) (b : ast) = (compare a b) + + let translate ( x : ast ) ( to_ctx : context ) = + if (z3obj_gnc x) == (context_gno to_ctx) then + x + else + ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + + let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr + let unwrap_ast ( x : ast ) = (z3obj_gno x) +end + +open AST + + +module Sort = +struct + type sort = Sort of AST.ast + type uninterpreted_sort = UninterpretedSort of sort + + let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> + let q = (z3_native_object_of_ast_ptr ctx no) in + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then + raise (Z3native.Exception "Invalid coercion") + else + match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with + | ARRAY_SORT + | BOOL_SORT + | BV_SORT + | DATATYPE_SORT + | INT_SORT + | REAL_SORT + | UNINTERPRETED_SORT + | FINITE_DOMAIN_SORT + | RELATION_SORT -> Sort(q) + | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") + + let ast_of_sort s = match s with Sort(x) -> x + let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x + + let uninterpreted_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + UninterpretedSort(s) + + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) + let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) + let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) + + let sort_lton ( a : sort list ) = + let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) + + let ( = ) : sort -> sort -> bool = fun a b -> + (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) + + + let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) + let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) + let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) + let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) + + let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; + (z3obj_create res) ; + UninterpretedSort(Sort(res)) + + let mk_uninterpreted_s ( ctx : context ) ( s : string ) = + mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) +end + +open Sort + + +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + val func_decl_of_ptr : context -> Z3native.ptr -> func_decl + val gc : func_decl -> context + val gnc : func_decl -> Z3native.ptr + val gno : func_decl -> Z3native.ptr + module Parameter : + sig + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + val get_kind : parameter -> Z3enums.parameter_kind + val get_int : parameter -> int + val get_float : parameter -> float + val get_symbol : parameter -> Symbol.symbol + val get_sort : parameter -> Sort.sort + val get_ast : parameter -> AST.ast + val get_func_decl : parameter -> func_decl + val get_rational : parameter -> string + end + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + val ( = ) : func_decl -> func_decl -> bool + val to_string : func_decl -> string + val get_id : func_decl -> int + val get_arity : func_decl -> int + val get_domain_size : func_decl -> int + val get_domain : func_decl -> Sort.sort list + val get_range : func_decl -> Sort.sort + val get_decl_kind : func_decl -> Z3enums.decl_kind + val get_name : func_decl -> Symbol.symbol + val get_num_parameters : func_decl -> int + val get_parameters : func_decl -> Parameter.parameter list + val apply : func_decl -> Expr.expr list -> Expr.expr +end = struct + type func_decl = FuncDecl of AST.ast + + let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> + if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + FuncDecl(z3_native_object_of_ast_ptr ctx no) + + let ast_of_func_decl f = match f with FuncDecl(x) -> x + + let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = + let res = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.inc_ref ; + dec_ref = Z3native.dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; + (z3obj_create res) ; + FuncDecl(res) + + let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) + let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) + let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) + + module Parameter = + struct + type parameter = + | P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + let get_kind ( x : parameter ) = + (match x with + | P_Int(_) -> PARAMETER_INT + | P_Dbl(_) -> PARAMETER_DOUBLE + | P_Sym(_) -> PARAMETER_SYMBOL + | P_Srt(_) -> PARAMETER_SORT + | P_Ast(_) -> PARAMETER_AST + | P_Fdl(_) -> PARAMETER_FUNC_DECL + | P_Rat(_) -> PARAMETER_RATIONAL) + + let get_int ( x : parameter ) = + match x with + | P_Int(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an int") + + let get_float ( x : parameter ) = + match x with + | P_Dbl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a double") + + let get_symbol ( x : parameter ) = + match x with + | P_Sym(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a symbol") + + let get_sort ( x : parameter ) = + match x with + | P_Srt(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a sort") + + let get_ast ( x : parameter ) = + match x with + | P_Ast(x) -> x + | _ -> raise (Z3native.Exception "parameter is not an ast") + + let get_func_decl ( x : parameter ) = + match x with + | P_Fdl(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a func_decl") + + let get_rational ( x : parameter ) = + match x with + | P_Rat(x) -> x + | _ -> raise (Z3native.Exception "parameter is not a rational string") + end + + let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = + create_ndr ctx name domain range + + let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = + mk_func_decl ctx (Symbol.mk_string ctx name) domain range + + let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = + create_pdr ctx prefix domain range + + let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + create_ndr ctx name [] range + + let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = + create_ndr ctx (Symbol.mk_string ctx name) [] range + + let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = + create_pdr ctx prefix [] range + + + let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || + if (gnc a) != (gnc b) then + false + else + (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) + + let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) + + let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) + + let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) + + let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) + + let get_domain ( x : func_decl ) = + let n = (get_domain_size x) in + let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in + mk_list f n + + let get_range ( x : func_decl ) = + sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) + + let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) + + let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) + + let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) + + let get_parameters ( x : func_decl ) = + let n = (get_num_parameters x) in + let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with + | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) + | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) + | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) + | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) + | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) + | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) + | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) + ) in + mk_list f n + + let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args +end + + +and Params : +sig + type params = z3_native_object + module ParamDescrs : + sig + type param_descrs + val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs + val validate : param_descrs -> params -> unit + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + val get_names : param_descrs -> Symbol.symbol list + val get_size : param_descrs -> int + val to_string : param_descrs -> string + end + val add_bool : params -> Symbol.symbol -> bool -> unit + val add_int : params -> Symbol.symbol -> int -> unit + val add_double : params -> Symbol.symbol -> float -> unit + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + val add_s_bool : params -> string -> bool -> unit + val add_s_int : params -> string -> int -> unit + val add_s_double : params -> string -> float -> unit + val add_s_symbol : params -> string -> Symbol.symbol -> unit + val mk_params : context -> params + val to_string : params -> string +end = struct + type params = z3_native_object + + module ParamDescrs = + struct + type param_descrs = z3_native_object + + let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let res : param_descrs = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.param_descrs_inc_ref ; + dec_ref = Z3native.param_descrs_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let validate ( x : param_descrs ) ( p : params ) = + Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) + + let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = + (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) + + let get_names ( x : param_descrs ) = + let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in + let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) + let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) + end + + let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = + Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value + + let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = + Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value + + let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value + + let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = + Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) + + let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = + add_bool x (Symbol.mk_string (z3obj_gc x) name) value + + let add_s_int ( x : params) ( name : string ) ( value : int ) = + add_int x (Symbol.mk_string (z3obj_gc x) name) value + + let add_s_double ( x : params ) ( name : string ) ( value : float ) = + add_double x (Symbol.mk_string (z3obj_gc x) name) value + + let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = + add_symbol x (Symbol.mk_string (z3obj_gc x) name) value + + let mk_params ( ctx : context ) = + let res : params = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.params_inc_ref ; + dec_ref = Z3native.params_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; + (z3obj_create res) ; + res + + let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) +end + +(** General expressions (terms) *) +and Expr : +sig + type expr = Expr of AST.ast + val expr_of_ptr : context -> Z3native.ptr -> expr + val gc : expr -> context + val gnc : expr -> Z3native.ptr + val gno : expr -> Z3native.ptr + val expr_lton : expr list -> Z3native.ptr array + val ast_of_expr : expr -> AST.ast + val expr_of_ast : AST.ast -> expr + val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr + val simplify : expr -> Params.params option -> expr + val get_simplify_help : context -> string + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + val get_func_decl : expr -> FuncDecl.func_decl + val get_bool_value : expr -> Z3enums.lbool + val get_num_args : expr -> int + val get_args : expr -> expr list + val update : expr -> expr list -> expr + val substitute : expr -> expr list -> expr list -> expr + val substitute_one : expr -> expr -> expr -> expr + val substitute_vars : expr -> expr list -> expr + val translate : expr -> context -> expr + val to_string : expr -> string + val is_numeral : expr -> bool + val is_well_sorted : expr -> bool + val get_sort : expr -> Sort.sort + val is_bool : expr -> bool + val is_const : expr -> bool + val is_true : expr -> bool + val is_false : expr -> bool + val is_eq : expr -> bool + val is_distinct : expr -> bool + val is_ite : expr -> bool + val is_and : expr -> bool + val is_or : expr -> bool + val is_iff : expr -> bool + val is_xor : expr -> bool + val is_not : expr -> bool + val is_implies : expr -> bool + val is_label : expr -> bool + val is_label_lit : expr -> bool + val is_oeq : expr -> bool + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + val mk_const_s : context -> string -> Sort.sort -> expr + val mk_const_f : context -> FuncDecl.func_decl -> expr + val mk_fresh_const : context -> string -> Sort.sort -> expr + val mk_app : context -> FuncDecl.func_decl -> expr list -> expr + val mk_numeral_string : context -> string -> Sort.sort -> expr + val mk_numeral_int : context -> int -> Sort.sort -> expr +end = struct + type expr = Expr of AST.ast + + let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) + let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) + let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) + + let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> + if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then + Expr(z3_native_object_of_ast_ptr ctx no) + else + let s = Z3native.get_sort (context_gno ctx) no in + let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in + if (Z3native.is_algebraic_number (context_gno ctx) no) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + if (Z3native.is_numeral_ast (context_gno ctx) no) then + if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + Expr(z3_native_object_of_ast_ptr ctx no) + else + raise (Z3native.Exception "Unsupported numeral object") + else + Expr(z3_native_object_of_ast_ptr ctx no) + + let expr_of_ast a = + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Expr(a) + + let ast_of_expr e = match e with Expr(a) -> a + + let expr_lton ( a : expr list ) = + let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) + + let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> + match f with FuncDecl.FuncDecl(fa) -> + let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in + expr_of_ptr ctx o + + let simplify ( x : expr ) ( p : Params.params option ) = match p with + | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (Expr.gnc x) (Expr.gno x)) + | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (Expr.gnc x) (Expr.gno x) (z3obj_gno pp)) + + let get_simplify_help ( ctx : context ) = + Z3native.simplify_get_help (context_gno ctx) + + let get_simplify_parameter_descrs ( ctx : context ) = + Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (Expr.gnc x) (Expr.gno x)) + + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (Expr.gnc x) (Expr.gno x)) + + let get_num_args ( x : expr ) = Z3native.get_app_num_args (Expr.gnc x) (Expr.gno x) + + let get_args ( x : expr ) = let n = (get_num_args x) in + let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (Expr.gnc x) (Expr.gno x) i) in + mk_list f n + + let update ( x : expr ) ( args : expr list ) = + if (List.length args <> (get_num_args x)) then + raise (Z3native.Exception "Number of arguments does not match") + else + expr_of_ptr (Expr.gc x) (Z3native.update_term (Expr.gnc x) (Expr.gno x) (List.length args) (expr_lton args)) + + let substitute ( x : expr ) from to_ = + if (List.length from) <> (List.length to_) then + raise (Z3native.Exception "Argument sizes do not match") + else + expr_of_ptr (Expr.gc x) (Z3native.substitute (Expr.gnc x) (Expr.gno x) (List.length from) (expr_lton from) (expr_lton to_)) + + let substitute_one ( x : expr ) from to_ = + substitute ( x : expr ) [ from ] [ to_ ] + + let substitute_vars ( x : expr ) to_ = + expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (Expr.gnc x) (Expr.gno x) (List.length to_) (expr_lton to_)) + + let translate ( x : expr ) to_ctx = + if (Expr.gc x) == to_ctx then + x + else + expr_of_ptr to_ctx (Z3native.translate (Expr.gnc x) (Expr.gno x) (context_gno to_ctx)) + + let to_string ( x : expr ) = Z3native.ast_to_string (Expr.gnc x) (Expr.gno x) + + let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) + + let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (Expr.gnc x) (Expr.gno x) + + let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)) + + let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (Z3native.is_eq_sort (Expr.gnc x) + (Z3native.mk_bool_sort (Expr.gnc x)) + (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) + + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (get_num_args x) == 0 && + (FuncDecl.get_domain_size (get_func_decl x)) == 0 + + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) + let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) + let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) + + let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = + mk_const ctx (Symbol.mk_string ctx name) range + + let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] + + let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = + expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) + + let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args + + let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) + + let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) +end + +open FuncDecl +open Expr + +module Boolean = +struct + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + + let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let a = (AST.ast_of_ptr ctx no) in + BoolExpr(Expr.Expr(a)) + + let bool_expr_of_expr e = + match e with Expr.Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolExpr(e) + + let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + BoolSort(sort_of_ptr ctx no) + + let sort_of_bool_sort s = match s with BoolSort(x) -> x + + let bool_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BoolSort(s) + + let expr_of_bool_expr e = match e with BoolExpr(x) -> x + + let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) + let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) + let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) + + let mk_sort ( ctx : context ) = + BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) + + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = + let s = (match (mk_sort ctx) with BoolSort(q) -> q) in + BoolExpr(Expr.mk_const ctx name s) + + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) + + let mk_true ( ctx : context ) = + bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) + + let mk_false ( ctx : context ) = + bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) + + let mk_val ( ctx : context ) ( value : bool ) = + if value then mk_true ctx else mk_false ctx + + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + + let mk_distinct ( ctx : context ) ( args : expr list ) = + bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) + + let mk_not ( ctx : context ) ( a : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) + + let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) + + let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) + + let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) + + let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = + bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) + + let mk_and ( ctx : context ) ( args : bool_expr list ) = + let f x = (Expr.gno (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) + + let mk_or ( ctx : context ) ( args : bool_expr list ) = + let f x = (Expr.gno (expr_of_bool_expr x)) in + bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) +end + + +module Quantifier = +struct + type quantifier = Quantifier of expr + + let expr_of_quantifier e = match e with Quantifier(x) -> x + + let quantifier_of_expr e = + match e with Expr.Expr(a) -> + let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.QUANTIFIER_AST) then + raise (Z3native.Exception "Invalid coercion") + else + Quantifier(e) + + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) + let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) + let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) + + module Pattern = + struct + type pattern = Pattern of ast + + let ast_of_pattern e = match e with Pattern(x) -> x + + let pattern_of_ast a = + (* CMW: Unchecked ok? *) + Pattern(a) + + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) + let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) + let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) + + let get_num_terms ( x : pattern ) = + Z3native.get_pattern_num_terms (gnc x) (gno x) + + let get_terms ( x : pattern ) = + let n = (get_num_terms x) in + let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in + mk_list f n + + let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) + end + + let get_index ( x : expr ) = + if not (AST.is_var (match x with Expr.Expr(a) -> a)) then + raise (Z3native.Exception "Term is not a bound variable.") + else + Z3native.get_index_value (Expr.gnc x) (Expr.gno x) + + let is_universal ( x : quantifier ) = + Z3native.is_quantifier_forall (gnc x) (gno x) + + let is_existential ( x : quantifier ) = not (is_universal x) + + let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) + + let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) + + let get_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in + mk_list f n + + let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) + + let get_no_patterns ( x : quantifier ) = + let n = (get_num_patterns x) in + let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in + mk_list f n + + let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) + + let get_bound_variable_names ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in + mk_list f n + + let get_bound_variable_sorts ( x : quantifier ) = + let n = (get_num_bound x) in + let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in + mk_list f n + + let get_body ( x : quantifier ) = + Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) + + let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = + expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) + + let mk_pattern ( ctx : context ) ( terms : expr list ) = + if (List.length terms) == 0 then + raise (Z3native.Exception "Cannot create a pattern from zero terms") + else + Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) + + let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + + let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (Expr.gno body))) + + let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (List.length sorts) != (List.length names) then + raise (Z3native.Exception "Number of sorts does not match number of names") + else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (List.length sorts) (sort_lton sorts) + (Symbol.symbol_lton names) + (Expr.gno body))) + + let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (Expr.gno body))) + else + Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false + (match weight with | None -> 1 | Some(x) -> x) + (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) + (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) + (List.length bound_constants) (expr_lton bound_constants) + (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) + (List.length nopatterns) (expr_lton nopatterns) + (Expr.gno body))) + + let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (universal) then + (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + else + (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) + + let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = + if (universal) then + mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id + else + mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id +end + + +module Array_ = +struct + type array_sort = ArraySort of sort + type array_expr = ArrayExpr of expr + + let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let e = (expr_of_ptr ctx no) in + ArrayExpr(e) + + let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + ArraySort(s) + + let sort_of_array_sort s = match s with ArraySort(x) -> x + + let array_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArraySort(s) + + let array_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.ARRAY_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArrayExpr(e) + + let expr_of_array_expr e = match e with ArrayExpr(x) -> x + + let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) + + let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) + let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) + let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) + + let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = + array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) + + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_array ( x : expr ) = + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) + + let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) + let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) + + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = + ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) + + let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = + mk_const ctx (Symbol.mk_string ctx name) domain range + + let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = + array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) + + let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = + array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) + + let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = + array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) + + let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = + let m x = (Expr.gno (expr_of_array_expr x)) in + array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) + + let mk_term_array ( ctx : context ) ( arg : array_expr ) = + array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) +end + + +module Set = +struct + type set_sort = SetSort of sort + + let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + SetSort(s) + + let sort_of_set_sort s = match s with SetSort(x) -> x + + let mk_sort ( ctx : context ) ( ty : sort ) = + set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) + + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + + + let mk_empty ( ctx : context ) ( domain : sort ) = + (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) + + let mk_full ( ctx : context ) ( domain : sort ) = + expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) + + let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) + + let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = + expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) + + let mk_union ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) + + let mk_intersection ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) + + let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + + let mk_complement ( ctx : context ) ( arg : expr ) = + expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) + + let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = + expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) + + let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = + expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) + +end + + +module FiniteDomain = +struct + type finite_domain_sort = FiniteDomainSort of sort + + let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x + + let finite_domain_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + FiniteDomainSort(s) + + let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in + FiniteDomainSort(s) + + let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_sort ctx (Symbol.mk_string ctx name) size + + + let is_finite_domain ( x : expr ) = + let nc = (Expr.gnc x) in + (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) + + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + + let get_size ( x : finite_domain_sort ) = + let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in + if r then v + else raise (Z3native.Exception "Conversion failed.") +end + + +module Relation = +struct + type relation_sort = RelationSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + RelationSort(s) + + let sort_of_relation_sort s = match s with RelationSort(x) -> x + + let relation_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RelationSort(s) + + let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) + let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) + let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) + + + let is_relation ( x : expr ) = + let nc = (Expr.gnc x) in + ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && + (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) + + let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + + let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) + + let get_column_sorts ( x : relation_sort ) = + let n = get_arity x in + let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in + mk_list f n + +end + + +module Datatype = +struct + type datatype_sort = DatatypeSort of sort + type datatype_expr = DatatypeExpr of expr + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + DatatypeSort(s) + + let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x + + let datatype_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeSort(s) + + let datatype_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.DATATYPE_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + DatatypeExpr(e) + + let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x + + let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) + + module Constructor = + struct + type constructor = z3_native_object + + let _sizes = Hashtbl.create 0 + + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let n = (List.length field_names) in + if n != (List.length sorts) then + raise (Z3native.Exception "Number of field names does not match number of sorts") + else + if n != (List.length sort_refs) then + raise (Z3native.Exception "Number of field names does not match number of sort refs") + else + let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) + (Symbol.gno recognizer) + n + (Symbol.symbol_lton field_names) + (sort_lton sorts) + (Array.of_list sort_refs)) in + let no : constructor = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + (z3obj_sno no ctx ptr) ; + (z3obj_create no) ; + let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f no ; + Hashtbl.add _sizes no n ; + no + + let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x + + let get_constructor_decl ( x : constructor ) = + let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in + func_decl_of_ptr (z3obj_gc x) a + + let get_tester_decl ( x : constructor ) = + let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in + func_decl_of_ptr (z3obj_gc x) b + + let get_accessor_decls ( x : constructor ) = + let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in + let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in + mk_list f (Array.length c) + + end + + module ConstructorList = + struct + type constructor_list = z3_native_object + + let create ( ctx : context ) ( c : Constructor.constructor list ) = + let res : constructor_list = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = z3obj_nil_ref ; + dec_ref = z3obj_nil_ref} in + let f x =(z3obj_gno x) in + (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; + (z3obj_create res) ; + let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in + Gc.finalise f res; + res + end + + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + Constructor.create ctx name recognizer field_names sorts sort_refs + + + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = + let f x = (z3obj_gno x) in + let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in + sort_of_ptr ctx x + + let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = + mk_sort ctx (Symbol.mk_string ctx name) constructors + + let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = + let n = (List.length names) in + let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in + let cla = (Array.of_list (List.map f c)) in + let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in + let g i = (sort_of_ptr ctx (Array.get r i)) in + mk_list g (Array.length r) + + let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = + mk_sorts ctx + ( + let f e = (Symbol.mk_string ctx e) in + List.map f names + ) + c + + let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) + + let get_constructors ( x : datatype_sort ) = + let n = (get_num_constructors x) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + mk_list f n + + let get_recognizers ( x : datatype_sort ) = + let n = (get_num_constructors x) in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in + mk_list f n + + let get_accessors ( x : datatype_sort ) = + let n = (get_num_constructors x) in + let f i = ( + let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in + let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in + let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in + mk_list g ds + ) in + mk_list f n +end + + +module Enumeration = +struct + type enum_sort = EnumSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = + let s = (sort_of_ptr ctx no) in + let res = EnumSort(s) in + res + + let sort_of_enum_sort s = match s with EnumSort(x) -> x + + let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = + let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in + sort_of_ptr ctx a (list_of_array b) (list_of_array c) + + let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = + mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) + + let get_const_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in + mk_list f n + + let get_tester_decls ( x : enum_sort ) = + let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in + let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in + mk_list f n + +end + + +module List_ = +struct + type list_sort = ListSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + let res = ListSort(s) in + res + + let sort_of_list_sort s = match s with ListSort(x) -> x + + let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = + let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in + sort_of_ptr ctx r a b c d e f + + let mk_list_s ( ctx : context ) (name : string) elem_sort = + mk_sort ctx (Symbol.mk_string ctx name) elem_sort + + let get_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) + + let get_is_nil_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) + + let get_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) + + let get_is_cons_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) + + let get_head_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) + + let get_tail_decl ( x : list_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) + + let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] +end + + +module Tuple = +struct + type tuple_sort = TupleSort of sort + + let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let s = (sort_of_ptr ctx no) in + TupleSort(s) + + let sort_of_tuple_sort s = match s with TupleSort(x) -> x + + let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) + + let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = + let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in + sort_of_ptr ctx r + + let get_mk_decl ( x : tuple_sort ) = + func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) + + let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) + + let get_field_decls ( x : tuple_sort ) = + let n = get_num_fields x in + let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in + mk_list f n +end + + +module rec Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr + + val sort_of_arith_sort : arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> arith_sort + val expr_of_arith_expr : arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> arith_expr + + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end + + val is_int : Expr.expr -> bool + val is_arithmetic_numeral : Expr.expr -> bool + val is_le : Expr.expr -> bool + val is_ge : Expr.expr -> bool + val is_lt : Expr.expr -> bool + val is_gt : Expr.expr -> bool + val is_add : Expr.expr -> bool + val is_sub : Expr.expr -> bool + val is_uminus : Expr.expr -> bool + val is_mul : Expr.expr -> bool + val is_div : Expr.expr -> bool + val is_idiv : Expr.expr -> bool + val is_remainder : Expr.expr -> bool + val is_modulus : Expr.expr -> bool + val is_inttoreal : Expr.expr -> bool + val is_real_to_int : Expr.expr -> bool + val is_real_is_int : Expr.expr -> bool + val is_real : Expr.expr -> bool + val is_int_numeral : Expr.expr -> bool + val is_rat_num : Expr.expr -> bool + val is_algebraic_number : Expr.expr -> bool + val mk_add : context -> arith_expr list -> arith_expr + val mk_mul : context -> arith_expr list -> arith_expr + val mk_sub : context -> arith_expr list -> arith_expr + val mk_unary_minus : context -> arith_expr -> arith_expr + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr +end = struct + type arith_sort = ArithSort of sort + type arith_expr = ArithExpr of expr + + let arith_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithExpr(e) + + let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + arith_expr_of_expr (expr_of_ptr ctx no) + + let sort_of_arith_sort s = match s with ArithSort(x) -> x + let expr_of_arith_expr e = match e with ArithExpr(x) -> x + + let arith_sort_of_sort s = match s with Sort(a) -> + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in + if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + ArithSort(s) + + let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + arith_sort_of_sort (sort_of_ptr ctx no) + + let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) + let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) + let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) + let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) + let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) + let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) + + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val int_expr_of_ptr : context -> Z3native.ptr -> int_expr + val int_num_of_ptr : context -> Z3native.ptr -> int_num + + val arith_sort_of_int_sort : Integer.int_sort -> arith_sort + val int_sort_of_arith_sort : arith_sort -> int_sort + val arith_expr_of_int_expr : int_expr -> arith_expr + val int_expr_of_int_num : int_num -> int_expr + val int_expr_of_arith_expr : arith_expr -> int_expr + val int_num_of_int_expr : int_expr -> int_num + + val mk_sort : context -> int_sort + val get_int : int_num -> int + val to_string : int_num -> string + val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_int_const_s : context -> string -> int_expr + val mk_mod : context -> int_expr -> int_expr -> int_expr + val mk_rem : context -> int_expr -> int_expr -> int_expr + val mk_int_numeral_s : context -> string -> int_num + val mk_int_numeral_i : context -> int -> int_num + val mk_int2real : context -> int_expr -> Real.real_expr + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end = struct + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + let int_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntExpr(e) + + let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let int_num_of_int_expr e = + match e with IntExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + IntNum(e) + + let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_num_of_int_expr (int_expr_of_ptr ctx no) + + let arith_sort_of_int_sort s = match s with IntSort(x) -> x + let arith_expr_of_int_expr e = match e with IntExpr(x) -> x + let int_expr_of_int_num e = match e with IntNum(x) -> x + + let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + IntSort(s) + + let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) + + let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) + let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) + let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) + let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) + let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) + let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) + let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) + let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) + let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) + + let mk_sort ( ctx : context ) = + int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) + + let get_int ( x : int_num ) = + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + if r then v + else raise (Z3native.Exception "Conversion failed.") + + let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) + + let mk_int_const_s ( ctx : context ) ( name : string ) = + mk_int_const ctx (Symbol.mk_string ctx name) + + let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) + + let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = + int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) + + let mk_int_numeral_s ( ctx : context ) ( v : string ) = + int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_int_numeral_i ( ctx : context ) ( v : int ) = + int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_int2real ( ctx : context ) ( t : int_expr ) = + Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) + + let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = + BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) + end + + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val real_expr_of_ptr : context -> Z3native.ptr -> real_expr + val rat_num_of_ptr : context -> Z3native.ptr -> rat_num + + val arith_sort_of_real_sort : real_sort -> arith_sort + val real_sort_of_arith_sort : arith_sort -> real_sort + val arith_expr_of_real_expr : real_expr -> arith_expr + val real_expr_of_rat_num : rat_num -> real_expr + val real_expr_of_arith_expr : arith_expr -> real_expr + val rat_num_of_real_expr : real_expr -> rat_num + + val mk_sort : context -> real_sort + val get_numerator : rat_num -> Integer.int_num + val get_denominator : rat_num -> Integer.int_num + val to_decimal_string : rat_num -> int -> string + val to_string : rat_num -> string + val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_real_const_s : context -> string -> real_expr + val mk_numeral_nd : context -> int -> int -> rat_num + val mk_numeral_s : context -> string -> rat_num + val mk_numeral_i : context -> int -> rat_num + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + val mk_real2int : context -> real_expr -> Integer.int_expr + end = struct + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + let arith_sort_of_real_sort s = match s with RealSort(x) -> x + let arith_expr_of_real_expr e = match e with RealExpr(x) -> x + let real_expr_of_rat_num e = match e with RatNum(x) -> x + + let real_expr_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealExpr(e) + + let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) + + let rat_num_of_real_expr e = + match e with RealExpr(ArithExpr(Expr(a))) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + RatNum(e) + + let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + rat_num_of_real_expr (real_expr_of_ptr ctx no) + + let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + RealSort(s) + + let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) + + let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) + let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) + let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) + let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) + let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) + let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) + let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) + let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) + let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) + + + let mk_sort ( ctx : context ) = + real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) + + let get_numerator ( x : rat_num ) = + Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) + + let get_denominator ( x : rat_num ) = + Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) + + let to_decimal_string ( x : rat_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + + let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) + + let mk_real_const_s ( ctx : context ) ( name : string ) = + mk_real_const ctx (Symbol.mk_string ctx name) + + let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + if (den == 0) then + raise (Z3native.Exception "Denominator is zero") + else + rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) + + let mk_numeral_s ( ctx : context ) ( v : string ) = + rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_numeral_i ( ctx : context ) ( v : int ) = + rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) + + let mk_is_integer ( ctx : context ) ( t : real_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) + + let mk_real2int ( ctx : context ) ( t : real_expr ) = + Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) + end + + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : algebraic_num -> arith_expr + val algebraic_num_of_arith_expr : arith_expr -> algebraic_num + + val to_upper : algebraic_num -> int -> Real.rat_num + val to_lower : algebraic_num -> int -> Real.rat_num + val to_decimal_string : algebraic_num -> int -> string + val to_string : algebraic_num -> string + end = struct + type algebraic_num = AlgebraicNum of arith_expr + + let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x + + let algebraic_num_of_arith_expr e = + match e with ArithExpr(Expr(a)) -> + if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + AlgebraicNum(e) + + let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) + + let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) + let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) + let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) + + + let to_upper ( x : algebraic_num ) ( precision : int ) = + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) + + let to_lower ( x : algebraic_num ) precision = + Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) + + let to_decimal_string ( x : algebraic_num ) ( precision : int ) = + Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision + + let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + end + + let is_int ( x : expr ) = + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) + + let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + + let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + + let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + + let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + + let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + + let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + + let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + + let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + + let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + + let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + + let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + + let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + + let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + + let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + + let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + + let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + + let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) + + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) + + let mk_add ( ctx : context ) ( t : arith_expr list ) = + let f x = (Expr.gno (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + + let mk_mul ( ctx : context ) ( t : arith_expr list ) = + let f x = (Expr.gno (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + + let mk_sub ( ctx : context ) ( t : arith_expr list ) = + let f x = (Expr.gno (expr_of_arith_expr x)) in + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + + let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) + + let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) + + let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) + + let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) + + let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) + + let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) + + let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) +end + + +and BitVector : +sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + + val mk_sort : context -> int -> bitvec_sort + val is_bv : Expr.expr -> bool + val is_bv_numeral : Expr.expr -> bool + val is_bv_bit1 : Expr.expr -> bool + val is_bv_bit0 : Expr.expr -> bool + val is_bv_uminus : Expr.expr -> bool + val is_bv_add : Expr.expr -> bool + val is_bv_sub : Expr.expr -> bool + val is_bv_mul : Expr.expr -> bool + val is_bv_sdiv : Expr.expr -> bool + val is_bv_udiv : Expr.expr -> bool + val is_bv_SRem : Expr.expr -> bool + val is_bv_urem : Expr.expr -> bool + val is_bv_smod : Expr.expr -> bool + val is_bv_sdiv0 : Expr.expr -> bool + val is_bv_udiv0 : Expr.expr -> bool + val is_bv_srem0 : Expr.expr -> bool + val is_bv_urem0 : Expr.expr -> bool + val is_bv_smod0 : Expr.expr -> bool + val is_bv_ule : Expr.expr -> bool + val is_bv_sle : Expr.expr -> bool + val is_bv_uge : Expr.expr -> bool + val is_bv_sge : Expr.expr -> bool + val is_bv_ult : Expr.expr -> bool + val is_bv_slt : Expr.expr -> bool + val is_bv_ugt : Expr.expr -> bool + val is_bv_sgt : Expr.expr -> bool + val is_bv_and : Expr.expr -> bool + val is_bv_or : Expr.expr -> bool + val is_bv_not : Expr.expr -> bool + val is_bv_xor : Expr.expr -> bool + val is_bv_nand : Expr.expr -> bool + val is_bv_nor : Expr.expr -> bool + val is_bv_xnor : Expr.expr -> bool + val is_bv_concat : Expr.expr -> bool + val is_bv_signextension : Expr.expr -> bool + val is_bv_zeroextension : Expr.expr -> bool + val is_bv_extract : Expr.expr -> bool + val is_bv_repeat : Expr.expr -> bool + val is_bv_reduceor : Expr.expr -> bool + val is_bv_reduceand : Expr.expr -> bool + val is_bv_comp : Expr.expr -> bool + val is_bv_shiftleft : Expr.expr -> bool + val is_bv_shiftrightlogical : Expr.expr -> bool + val is_bv_shiftrightarithmetic : Expr.expr -> bool + val is_bv_rotateleft : Expr.expr -> bool + val is_bv_rotateright : Expr.expr -> bool + val is_bv_rotateleftextended : Expr.expr -> bool + val is_bv_rotaterightextended : Expr.expr -> bool + val is_int_to_bv : Expr.expr -> bool + val is_bv_to_int : Expr.expr -> bool + val is_bv_carry : Expr.expr -> bool + val is_bv_xor3 : Expr.expr -> bool + val get_size : bitvec_sort -> int + val get_int : bitvec_num -> int + val to_string : bitvec_num -> string + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + val mk_const_s : context -> string -> int -> bitvec_expr + val mk_not : context -> bitvec_expr -> Expr.expr + val mk_redand : context -> bitvec_expr -> Expr.expr + val mk_redor : context -> bitvec_expr -> Expr.expr + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_neg : context -> bitvec_expr -> bitvec_expr + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + val mk_numeral : context -> string -> int -> bitvec_num +end = struct + type bitvec_sort = BitVecSort of sort + type bitvec_expr = BitVecExpr of expr + type bitvec_num = BitVecNum of bitvec_expr + + let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x + + let bitvec_sort_of_sort s = match s with Sort(a) -> + if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecSort(s) + + let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_sort_of_sort (sort_of_ptr ctx no) + + let bitvec_expr_of_expr e = + match e with Expr(a) -> + let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in + let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in + if (q != Z3enums.BV_SORT) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecExpr(e) + + let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_expr_of_expr (expr_of_ptr ctx no) + + let bitvec_num_of_bitvec_expr e = + match e with BitVecExpr(Expr(a)) -> + if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then + raise (Z3native.Exception "Invalid coercion") + else + BitVecNum(e) + + let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) + + let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x + let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x + + + let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) + let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) + let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) + let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) + let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) + let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) + let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) + let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) + let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) + + + let mk_sort ( ctx : context ) size = + bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) + let is_bv ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) + let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) + let get_int ( x : bitvec_num ) = + let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in + if r then v + else raise (Z3native.Exception "Conversion failed.") + let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = + BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) + let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = + mk_const ctx (Symbol.mk_string ctx name) size + let mk_not ( ctx : context ) ( t : bitvec_expr ) = + expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) + let mk_redand ( ctx : context ) ( t : bitvec_expr) = + expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) + let mk_redor ( ctx : context ) ( t : bitvec_expr) = + expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) + let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) + let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) + let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) + let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) + let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) + let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) + let mk_neg ( ctx : context ) ( t : bitvec_expr) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) + let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) + let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) + let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) + let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) + let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) + let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) + let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) + let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) + let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) + let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) + let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) + let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) + let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) + let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) + let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) + let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) + let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) + let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) + let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) + let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) + let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) + let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) + let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) + let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) + let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) + let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) + let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) + let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) + let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = + Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) + let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) + let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) + let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) + let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) + let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) + let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) + let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) + let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = + bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) +end + + +module Proof = +struct + let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) +end + + +module Goal = +struct + type goal = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : goal = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.goal_inc_ref ; + dec_ref = Z3native.goal_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_precision ( x : goal ) = + goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) + + let is_precise ( x : goal ) = + (get_precision x) == GOAL_PRECISE + + let is_underapproximation ( x : goal ) = + (get_precision x) == GOAL_UNDER + + let is_overapproximation ( x : goal ) = + (get_precision x) == GOAL_OVER + + let is_garbage ( x : goal ) = + (get_precision x) == GOAL_UNDER_OVER + + let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = + let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in + ignore (List.map f constraints) ; + () + + let is_inconsistent ( x : goal ) = + Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) + + let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) + + let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) + + let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) + + let get_formulas ( x : goal ) = + let n = get_size x in + let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) + (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in + mk_list f n + + let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) + + let is_decided_sat ( x : goal ) = + Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) + + let is_decided_unsat ( x : goal ) = + Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) + + let translate ( x : goal ) ( to_ctx : context ) = + create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + + let simplify ( x : goal ) ( p : Params.params option ) = + let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in + Z3native.tactic_inc_ref (z3obj_gnc x) tn ; + let arn = match p with + | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) + | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) + in + Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; + let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in + let res = if sg == 0 then + raise (Z3native.Exception "No subgoals") + else + Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in + Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; + Z3native.tactic_dec_ref (z3obj_gnc x) tn ; + create (z3obj_gc x) res + + let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = + create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) + + let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) +end + + +module Model = +struct + type model = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : model = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.model_inc_ref ; + dec_ref = Z3native.model_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + module FuncInterp = + struct + type func_interp = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_interp = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_interp_inc_ref ; + dec_ref = Z3native.func_interp_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + module FuncEntry = + struct + type func_entry = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : func_entry = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.func_entry_inc_ref ; + dec_ref = Z3native.func_entry_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_value ( x : func_entry ) = + expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) + + let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) + + let get_args ( x : func_entry ) = + let n = (get_num_args x) in + let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in + mk_list f n + + let to_string ( x : func_entry ) = + let a = (get_args x) in + let f c p = (p ^ (Expr.to_string c) ^ ", ") in + "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") + end + + let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) + + let get_entries ( x : func_interp ) = + let n = (get_num_entries x) in + let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in + mk_list f n + + let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) + + let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) + + let to_string ( x : func_interp ) = + let f c p = ( + let n = (FuncEntry.get_num_args c) in + p ^ + let g c p = (p ^ (Expr.to_string c) ^ ", ") in + (if n > 1 then "[" else "") ^ + (List.fold_right + g + (FuncEntry.get_args c) + ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) + ) in + List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") + end + + let get_const_interp ( x : model ) ( f : func_decl ) = + if (FuncDecl.get_arity f) != 0 || + (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then + raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") + else + let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in + if (Z3native.is_null np) then + None + else + Some (expr_of_ptr (z3obj_gc x) np) + + let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) + + + let rec get_func_interp ( x : model ) ( f : func_decl ) = + let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in + if (FuncDecl.get_arity f) == 0 then + let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in + if (Z3native.is_null n) then + None + else + match sk with + | ARRAY_SORT -> + if not (Z3native.is_as_array (z3obj_gnc x) n) then + raise (Z3native.Exception "Argument was not an array constant") + else + let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in + get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) + | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); + else + let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in + if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) + + (** The number of constants that have an interpretation in the model. *) + let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) + + let get_const_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) + + let get_func_decls ( x : model ) = + let n = (get_num_consts x) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_decls ( x : model ) = + let n_funcs = (get_num_funcs x) in + let n_consts = (get_num_consts x ) in + let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in + let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in + (mk_list f n_funcs) @ (mk_list g n_consts) + + exception ModelEvaluationFailedException of string + + let eval ( x : model ) ( t : expr ) ( completion : bool ) = + let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in + if not r then + raise (ModelEvaluationFailedException "evaluation failed") + else + expr_of_ptr (z3obj_gc x) v + + let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = + eval x t completion + + let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) + + let get_sorts ( x : model ) = + let n = (get_num_sorts x) in + let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in + mk_list f n + + let sort_universe ( x : model ) ( s : sort ) = + let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n = (AST.ASTVector.get_size n_univ) in + let f i = (AST.ASTVector.get n_univ i) in + mk_list f n + + let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) +end + + +module Probe = +struct + type probe = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : probe = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.probe_inc_ref ; + dec_ref = Z3native.probe_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + + let apply ( x : probe ) ( g : Goal.goal ) = + Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) + + let get_num_probes ( ctx : context ) = + Z3native.get_num_probes (context_gno ctx) + + let get_probe_names ( ctx : context ) = + let n = (get_num_probes ctx) in + let f i = (Z3native.get_probe_name (context_gno ctx) i) in + mk_list f n + + let get_probe_description ( ctx : context ) ( name : string ) = + Z3native.probe_get_descr (context_gno ctx) name + + let mk_probe ( ctx : context ) ( name : string ) = + (create ctx (Z3native.mk_probe (context_gno ctx) name)) + + let const ( ctx : context ) ( v : float ) = + (create ctx (Z3native.probe_const (context_gno ctx) v)) + + let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = + (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) + + let not_ ( ctx : context ) ( p : probe ) = + (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) +end + + +module Tactic = +struct + type tactic = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : tactic = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.tactic_inc_ref ; + dec_ref = Z3native.tactic_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + module ApplyResult = + struct + type apply_result = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : apply_result = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.apply_result_inc_ref ; + dec_ref = Z3native.apply_result_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let get_num_subgoals ( x : apply_result ) = + Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) + + let get_subgoals ( x : apply_result ) = + let n = (get_num_subgoals x) in + let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get_subgoal ( x : apply_result ) ( i : int ) = + Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) + + let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = + Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) + + let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) + end + + let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) + + let get_param_descrs ( x : tactic ) = + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + + let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = + match p with + | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) + | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) + + let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) + + let get_tactic_names ( ctx : context ) = + let n = (get_num_tactics ctx ) in + let f i = (Z3native.get_tactic_name (context_gno ctx) i) in + mk_list f n + + let get_tactic_description ( ctx : context ) ( name : string ) = + Z3native.tactic_get_descr (context_gno ctx) name + + let mk_tactic ( ctx : context ) ( name : string ) = + create ctx (Z3native.mk_tactic (context_gno ctx) name) + + let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = + let f p c = (match p with + | None -> (Some (z3obj_gno c)) + | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in + match (List.fold_left f None ts) with + | None -> + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + | Some(x) -> + let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in + create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) + + let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + + let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = + create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) + + let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = + create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) + + let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = + create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) + + let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = + create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) + + let skip ( ctx : context ) = + create ctx (Z3native.tactic_skip (context_gno ctx)) + + let fail ( ctx : context ) = + create ctx (Z3native.tactic_fail (context_gno ctx)) + + let fail_if ( ctx : context ) ( p : Probe.probe ) = + create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) + + let fail_if_not_decided ( ctx : context ) = + create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) + + let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) + + let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = + using_params ctx t p + + let par_or ( ctx : context ) ( t : tactic list ) = + let f e = (z3obj_gno e) in + create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) + + let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = + create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) + + let interrupt ( ctx : context ) = + Z3native.interrupt (context_gno ctx) +end + + +module Solver = +struct + type solver = z3_native_object + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : solver = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.solver_inc_ref ; + dec_ref = Z3native.solver_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + let string_of_status ( s : status) = match s with + | UNSATISFIABLE -> "unsatisfiable" + | SATISFIABLE -> "satisfiable" + | _ -> "unknown" + + module Statistics = + struct + type statistics = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : statistics = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.stats_inc_ref ; + dec_ref = Z3native.stats_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + + + module Entry = + struct + type statistics_entry = { + mutable m_key : string; + mutable m_is_int : bool ; + mutable m_is_float : bool ; + mutable m_int : int ; + mutable m_float : float } + + let create_si k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = true ; + m_is_float = false ; + m_int = v ; + m_float = 0.0 + } in + res + + let create_sd k v = + let res : statistics_entry = { + m_key = k ; + m_is_int = false ; + m_is_float = true ; + m_int = 0 ; + m_float = v + } in + res + + + let get_key (x : statistics_entry) = x.m_key + let get_int (x : statistics_entry) = x.m_int + let get_float (x : statistics_entry) = x.m_float + let is_int (x : statistics_entry) = x.m_is_int + let is_float (x : statistics_entry) = x.m_is_float + let to_string_value (x : statistics_entry) = + if (is_int x) then + string_of_int (get_int x) + else if (is_float x) then + string_of_float (get_float x) + else + raise (Z3native.Exception "Unknown statistical entry type") + let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) + end + + let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) + + let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) + + let get_entries ( x : statistics ) = + let n = (get_size x ) in + let f i = ( + let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in + if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then + (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) + else + (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + ) in + mk_list f n + + let get_keys ( x : statistics ) = + let n = (get_size x) in + let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in + mk_list f n + + let get ( x : statistics ) ( key : string ) = + let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in + List.fold_left f None (get_entries x) + end + + let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) + + let set_parameters ( x : solver ) ( p : Params.params )= + Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) + + let get_param_descrs ( x : solver ) = + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + + let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) + + let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) + + let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n + + let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) + + let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = + let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + ignore (List.map f constraints) + + let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = + if ((List.length cs) != (List.length ps)) then + raise (Z3native.Exception "Argument size mismatch") + else + let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in + ignore (List.iter2 f cs ps) + + let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = + Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) + + let get_num_assertions ( x : solver ) = + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + (AST.ASTVector.get_size a) + + let get_assertions ( x : solver ) = + let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size a) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in + mk_list f n + + let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = + let r = + if ((List.length assumptions) == 0) then + lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) + else + let f x = (Expr.gno (Boolean.expr_of_bool_expr x)) in + lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) + in + match r with + | L_TRUE -> SATISFIABLE + | L_FALSE -> UNSATISFIABLE + | _ -> UNKNOWN + + let get_model ( x : solver ) = + let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in + if (Z3native.is_null q) then + None + else + Some (Model.create (z3obj_gc x) q) + + let get_proof ( x : solver ) = + let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in + if (Z3native.is_null q) then + None + else + Some (expr_of_ptr (z3obj_gc x) q) + + let get_unsat_core ( x : solver ) = + let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let n = (AST.ASTVector.get_size cn) in + let f i = (AST.ASTVector.get cn i) in + mk_list f n + + let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) + + let get_statistics ( x : solver ) = + (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) + + let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = + match logic with + | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) + | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) + + let mk_solver_s ( ctx : context ) ( logic : string ) = + mk_solver ctx (Some (Symbol.mk_string ctx logic)) + + let mk_simple_solver ( ctx : context ) = + (create ctx (Z3native.mk_simple_solver (context_gno ctx))) + + let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = + (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) + + let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) +end + + +module Fixedpoint = +struct + type fixedpoint = z3_native_object + + let create ( ctx : context ) = + let res : fixedpoint = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.fixedpoint_inc_ref ; + dec_ref = Z3native.fixedpoint_dec_ref } in + (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; + (z3obj_create res) ; + res + + + let get_help ( x : fixedpoint ) = + Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) + + let set_params ( x : fixedpoint ) ( p : Params.params )= + Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) + + let get_param_descrs ( x : fixedpoint ) = + Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) + + let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = + let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in + ignore (List.map f constraints) ; + () + + let register_relation ( x : fixedpoint ) ( f : func_decl ) = + Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) + + let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = + match name with + | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null + | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) + + let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = + Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) + + let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = + match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + let query_r ( x : fixedpoint ) ( relations : func_decl list ) = + let f x = ptr_of_ast (ast_of_func_decl x) in + match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with + | L_TRUE -> Solver.SATISFIABLE + | L_FALSE -> Solver.UNSATISFIABLE + | _ -> Solver.UNKNOWN + + let push ( x : fixedpoint ) = + Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) + + let pop ( x : fixedpoint ) = + Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) + + let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = + Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) + + let get_answer ( x : fixedpoint ) = + let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in + if (Z3native.is_null q) then + None + else + Some (expr_of_ptr (z3obj_gc x) q) + + let get_reason_unknown ( x : fixedpoint ) = + Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) + + let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = + Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) + + let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = + let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in + if (Z3native.is_null q) then + None + else + Some (expr_of_ptr (z3obj_gc x) q) + + let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = + Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) + + let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] + + let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = + Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) + + let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = + let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in + Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) + + let get_rules ( x : fixedpoint ) = + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + mk_list f n + + let get_assertions ( x : fixedpoint ) = + let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let n = (AST.ASTVector.get_size v) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in + mk_list f n + + let mk_fixedpoint ( ctx : context ) = create ctx +end + +module Options = +struct + + let update_param_value ( ctx : context ) ( id : string) ( value : string )= + Z3native.update_param_value (context_gno ctx) id value + + let get_param_value ( ctx : context ) ( id : string ) = + let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in + if not r then + None + else + Some v + + let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = + Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) + + let toggle_warning_messages ( enabled: bool ) = + Z3native.toggle_warning_messages enabled +end + + +module SMT = +struct + let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = + Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes + (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) + (Boolean.gno formula) + + let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Z3native.parse_smtlib_string (context_gno ctx) str + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) + + let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Z3native.parse_smtlib_file (context_gno ctx) file_name + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) + + let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) + + let get_smtlib_formulas ( ctx : context ) = + let n = (get_num_smtlib_formulas ctx ) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in + mk_list f n + + let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) + + let get_smtlib_assumptions ( ctx : context ) = + let n = (get_num_smtlib_assumptions ctx ) in + let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in + mk_list f n + + let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) + + let get_smtlib_decls ( ctx : context ) = + let n = (get_num_smtlib_decls ctx) in + let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in + mk_list f n + + let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) + + let get_smtlib_sorts ( ctx : context ) = + let n = (get_num_smtlib_sorts ctx) in + let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in + mk_list f n + + let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) + + let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = + let csn = (List.length sort_names) in + let cs = (List.length sorts) in + let cdn = (List.length decl_names) in + let cd = (List.length decls) in + if (csn != cs || cdn != cd) then + raise (Z3native.Exception "Argument size mismatch") + else + Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name + cs + (Symbol.symbol_lton sort_names) + (sort_lton sorts) + cd + (Symbol.symbol_lton decl_names) + (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) +end + + +let set_global_param ( id : string ) ( value : string ) = + (Z3native.global_param_set id value) + +let get_global_param ( id : string ) = + let (r, v) = (Z3native.global_param_get id) in + if not r then + None + else + Some v + +let global_param_reset_all = + Z3native.global_param_reset_all diff --git a/src/api/ml/z3_rich.mli b/src/api/ml/z3_rich.mli new file mode 100644 index 000000000..8b6681e11 --- /dev/null +++ b/src/api/ml/z3_rich.mli @@ -0,0 +1,3072 @@ +(** + The Z3 ML/Ocaml Interface. + + Copyright (C) 2012 Microsoft Corporation + @author CM Wintersteiger (cwinter) 2012-12-17 + + NOTE: This is the *rich* version of the interface, using more + type information directly in the type system. Coercion functions + are provided to tran coerce on type into another where applicable. +*) + +(** Context objects. + + Most interactions with Z3 are interpreted in some context; many users will only + require one such object, but power users may require more than one. To start using + Z3, do + + + let ctx = (mk_context []) in + (...) + + + where a list of pairs of strings may be passed to set options on + the context, e.g., like so: + + + let cfg = [("model", "true"); ("...", "...")] in + let ctx = (mk_context cfg) in + (...) + +*) +type context + +(** Create a context object *) +val mk_context : (string * string) list -> context + + +(** Interaction logging for Z3 + Note that this is a global, static log and if multiple Context + objects are created, it logs the interaction with all of them. *) +module Log : +sig + (** Open an interaction log file. + @return True if opening the log file succeeds, false otherwise. *) + (* CMW: "open" seems to be a reserved keyword? *) + val open_ : string -> bool + + (** Closes the interaction log. *) + val close : unit + + (** Appends a user-provided string to the interaction log. *) + val append : string -> unit +end + +(** Version information *) +module Version : +sig + (** The major version. *) + val major : int + + (** The minor version. *) + val minor : int + + (** The build version. *) + val build : int + + (** The revision. *) + val revision : int + + (** A string representation of the version information. *) + val to_string : string +end + +(** Symbols are used to name several term and type constructors *) +module Symbol : +sig + (** Numbered Symbols *) + type int_symbol + + (** Named Symbols *) + type string_symbol + + (** Symbols *) + type symbol = S_Int of int_symbol | S_Str of string_symbol + + (** The kind of the symbol (int or string) *) + val kind : symbol -> Z3enums.symbol_kind + + (** Indicates whether the symbol is of Int kind *) + val is_int_symbol : symbol -> bool + + (** Indicates whether the symbol is of string kind. *) + val is_string_symbol : symbol -> bool + + (** The int value of the symbol. *) + val get_int : int_symbol -> int + + (** The string value of the symbol. *) + val get_string : string_symbol -> string + + (** A string representation of the symbol. *) + val to_string : symbol -> string + + (** Creates a new symbol using an integer. + + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. *) + val mk_int : context -> int -> symbol + + (** Creates a new symbol using a string. *) + val mk_string : context -> string -> symbol + + (** Create a list of symbols. *) + val mk_ints : context -> int list -> symbol list + + (** Create a list of symbols. *) + val mk_strings : context -> string list -> symbol list +end + +(** The abstract syntax tree (AST) module *) +module AST : +sig + type ast + + (** Vectors of ASTs *) + module ASTVector : + sig + type ast_vector + + (** The size of the vector *) + val get_size : ast_vector -> int + + (** + Retrieves the i-th object in the vector. + @return An AST *) + val get : ast_vector -> int -> ast + + (** Sets the i-th object in the vector. *) + val set : ast_vector -> int -> ast -> unit + + (** Resize the vector to a new size. *) + val resize : ast_vector -> int -> unit + + (** Add an ast to the back of the vector. The size + is increased by 1. *) + val push : ast_vector -> ast -> unit + + (** Translates all ASTs in the vector to another context. + @return A new ASTVector *) + val translate : ast_vector -> context -> ast_vector + + (** Retrieves a string representation of the vector. *) + val to_string : ast_vector -> string + end + + (** Map from AST to AST *) + module ASTMap : + sig + type ast_map + + (** Checks whether the map contains a key. + @return True if the key in the map, false otherwise. *) + val contains : ast_map -> ast -> bool + + (** Finds the value associated with the key. + This function signs an error when the key is not a key in the map. *) + val find : ast_map -> ast -> ast + + (** Stores or replaces a new key/value pair in the map. *) + val insert : ast_map -> ast -> ast -> unit + + (** Erases the key from the map.*) + val erase : ast_map -> ast -> unit + + (** Removes all keys from the map. *) + val reset : ast_map -> unit + + (** The size of the map *) + val get_size : ast_map -> int + + (** The keys stored in the map. *) + val get_keys : ast_map -> ast list + + (** Retrieves a string representation of the map.*) + val to_string : ast_map -> string + end + + (** The AST's hash code. + @return A hash code *) + val get_hash_code : ast -> int + + (** A unique identifier for the AST (unique among all ASTs). *) + val get_id : ast -> int + + (** The kind of the AST. *) + val get_ast_kind : ast -> Z3enums.ast_kind + + (** Indicates whether the AST is an Expr *) + val is_expr : ast -> bool + + (** Indicates whether the AST is a bound variable*) + val is_var : ast -> bool + + (** Indicates whether the AST is a Quantifier *) + val is_quantifier : ast -> bool + + (** Indicates whether the AST is a Sort *) + val is_sort : ast -> bool + + (** Indicates whether the AST is a func_decl *) + val is_func_decl : ast -> bool + + (** A string representation of the AST. *) + val to_string : ast -> string + + (** A string representation of the AST in s-expression notation. *) + val to_sexpr : ast -> string + + (** Comparison operator. + @return True if the two ast's are from the same context + and represent the same sort; false otherwise. *) + val ( = ) : ast -> ast -> bool + + (** Object Comparison. + @return Negative if the first ast should be sorted before the second, positive if after else zero. *) + val compare : ast -> ast -> int + + (** Operator < *) + val ( < ) : ast -> ast -> int + + (** Translates (copies) the AST to another context. + @return A copy of the AST which is associated with the other context. *) + val translate : ast -> context -> ast + + (** Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) + and that it must have a correct reference count (see e.g., + Z3native.inc_ref). *) + val wrap_ast : context -> Z3native.z3_ast -> ast + + (** Unwraps an AST. + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + Z3native.inc_ref). + {!wrap_ast} *) + val unwrap_ast : ast -> Z3native.ptr +end + +(** The Sort module implements type information for ASTs *) +module Sort : +sig + (** Sorts *) + type sort = Sort of AST.ast + + (** Uninterpreted Sorts *) + type uninterpreted_sort = UninterpretedSort of sort + + val ast_of_sort : sort -> AST.ast + val sort_of_uninterpreted_sort : uninterpreted_sort -> sort + val uninterpreted_sort_of_sort : sort -> uninterpreted_sort + + (** Comparison operator. + @return True if the two sorts are from the same context + and represent the same sort; false otherwise. *) + val ( = ) : sort -> sort -> bool + + (** Returns a unique identifier for the sort. *) + val get_id : sort -> int + + (** The kind of the sort. *) + val get_sort_kind : sort -> Z3enums.sort_kind + + (** The name of the sort *) + val get_name : sort -> Symbol.symbol + + (** A string representation of the sort. *) + val to_string : sort -> string + + (** Create a new uninterpreted sort. *) + val mk_uninterpreted : context -> Symbol.symbol -> uninterpreted_sort + + (** Create a new uninterpreted sort. *) + val mk_uninterpreted_s : context -> string -> uninterpreted_sort +end + +(** Function declarations *) +module rec FuncDecl : +sig + type func_decl = FuncDecl of AST.ast + + val ast_of_func_decl : FuncDecl.func_decl -> AST.ast + + (** Parameters of Func_Decls *) + module Parameter : + sig + (** Parameters of func_decls *) + type parameter = + P_Int of int + | P_Dbl of float + | P_Sym of Symbol.symbol + | P_Srt of Sort.sort + | P_Ast of AST.ast + | P_Fdl of func_decl + | P_Rat of string + + (** The kind of the parameter. *) + val get_kind : parameter -> Z3enums.parameter_kind + + (** The int value of the parameter.*) + val get_int : parameter -> int + + (** The double value of the parameter.*) + val get_float : parameter -> float + + (** The Symbol.Symbol value of the parameter.*) + val get_symbol : parameter -> Symbol.symbol + + (** The Sort value of the parameter.*) + val get_sort : parameter -> Sort.sort + + (** The AST value of the parameter.*) + val get_ast : parameter -> AST.ast + + (** The FunctionDeclaration value of the parameter.*) + val get_func_decl : parameter -> func_decl + + (** The rational string value of the parameter.*) + val get_rational : parameter -> string + end + + (** Creates a new function declaration. *) + val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl + + (** Creates a new function declaration. *) + val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl + (** Creates a fresh function declaration with a name prefixed with a prefix string. *) + + val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl + + (** Creates a new constant function declaration. *) + val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl + + (** Creates a new constant function declaration. *) + val mk_const_decl_s : context -> string -> Sort.sort -> func_decl + + (** Creates a fresh constant function declaration with a name prefixed with a prefix string. + {!mk_func_decl} + {!mk_func_decl} *) + val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl + + (** Comparison operator. + @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) + val ( = ) : func_decl -> func_decl -> bool + + (** A string representations of the function declaration. *) + val to_string : func_decl -> string + + (** Returns a unique identifier for the function declaration. *) + val get_id : func_decl -> int + + (** The arity of the function declaration *) + val get_arity : func_decl -> int + + (** The size of the domain of the function declaration + {!get_arity} *) + val get_domain_size : func_decl -> int + + (** The domain of the function declaration *) + val get_domain : func_decl -> Sort.sort list + + (** The range of the function declaration *) + val get_range : func_decl -> Sort.sort + + (** The kind of the function declaration. *) + val get_decl_kind : func_decl -> Z3enums.decl_kind + + (** The name of the function declaration*) + val get_name : func_decl -> Symbol.symbol + + (** The number of parameters of the function declaration *) + val get_num_parameters : func_decl -> int + + (** The parameters of the function declaration *) + val get_parameters : func_decl -> Parameter.parameter list + + (** Create expression that applies function to arguments. *) + val apply : func_decl -> Expr.expr list -> Expr.expr +end + +(** Parameter sets (of Solvers, Tactics, ...) + + A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) +and Params : +sig + type params + + (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) + module ParamDescrs : + sig + type param_descrs + + (** Validate a set of parameters. *) + val validate : param_descrs -> params -> unit + + (** Retrieve kind of parameter. *) + val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind + + (** Retrieve all names of parameters. *) + val get_names : param_descrs -> Symbol.symbol list + + (** The size of the ParamDescrs. *) + val get_size : param_descrs -> int + + (** Retrieves a string representation of the ParamDescrs. *) + val to_string : param_descrs -> string + end + + (** Adds a parameter setting. *) + val add_bool : params -> Symbol.symbol -> bool -> unit + + (** Adds a parameter setting. *) + val add_int : params -> Symbol.symbol -> int -> unit + + (** Adds a parameter setting. *) + val add_double : params -> Symbol.symbol -> float -> unit + + (** Adds a parameter setting. *) + val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit + + (** Adds a parameter setting. *) + val add_s_bool : params -> string -> bool -> unit + + (** Adds a parameter setting. *) + val add_s_int : params -> string -> int -> unit + + (** Adds a parameter setting. *) + val add_s_double : params -> string -> float -> unit + + (** Adds a parameter setting. *) + val add_s_symbol : params -> string -> Symbol.symbol -> unit + + (** Creates a new parameter set *) + val mk_params : context -> params + + (** A string representation of the parameter set. *) + val to_string : params -> string +end + +(** General Expressions (terms) *) +and Expr : +sig + type expr = Expr of AST.ast + + val ast_of_expr : Expr.expr -> AST.ast + val expr_of_ast : AST.ast -> Expr.expr + + (** Returns a simplified version of the expression. + {!get_simplify_help} *) + val simplify : Expr.expr -> Params.params option -> expr + + (** A string describing all available parameters to Expr.Simplify. *) + val get_simplify_help : context -> string + + (** Retrieves parameter descriptions for simplifier. *) + val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs + + (** The function declaration of the function that is applied in this expression. *) + val get_func_decl : Expr.expr -> FuncDecl.func_decl + + (** Indicates whether the expression is the true or false expression + or something else (L_UNDEF). *) + val get_bool_value : Expr.expr -> Z3enums.lbool + + (** The number of arguments of the expression. *) + val get_num_args : Expr.expr -> int + + (** The arguments of the expression. *) + val get_args : Expr.expr -> Expr.expr list + + (** Update the arguments of the expression using an array of expressions. + The number of new arguments should coincide with the current number of arguments. *) + val update : Expr.expr -> Expr.expr list -> expr + + (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + + The result is the new expression. The arrays from and to must have size num_exprs. + For every i smaller than num_exprs, we must have that + sort of from[i] must be equal to sort of to[i]. *) + val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr + + (** Substitute every occurrence of from in the expression with to. + {!substitute} *) + val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr + + (** Substitute the free variables in the expression with the expressions in the expr array + + For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) + val substitute_vars : Expr.expr -> Expr.expr list -> expr + + (** Translates (copies) the term to another context. + @return A copy of the term which is associated with the other context *) + val translate : Expr.expr -> context -> expr + + (** Returns a string representation of the expression. *) + val to_string : Expr.expr -> string + + (** Indicates whether the term is a numeral *) + val is_numeral : Expr.expr -> bool + + (** Indicates whether the term is well-sorted. + @return True if the term is well-sorted, false otherwise. *) + val is_well_sorted : Expr.expr -> bool + + (** The Sort of the term. *) + val get_sort : Expr.expr -> Sort.sort + + (** Indicates whether the term has Boolean sort. *) + val is_bool : Expr.expr -> bool + + (** Indicates whether the term represents a constant. *) + val is_const : Expr.expr -> bool + + (** Indicates whether the term is the constant true. *) + val is_true : Expr.expr -> bool + + (** Indicates whether the term is the constant false. *) + val is_false : Expr.expr -> bool + + (** Indicates whether the term is an equality predicate. *) + val is_eq : Expr.expr -> bool + + (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) + val is_distinct : Expr.expr -> bool + + (** Indicates whether the term is a ternary if-then-else term *) + val is_ite : Expr.expr -> bool + + (** Indicates whether the term is an n-ary conjunction *) + val is_and : Expr.expr -> bool + + (** Indicates whether the term is an n-ary disjunction *) + val is_or : Expr.expr -> bool + + (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) + val is_iff : Expr.expr -> bool + + (** Indicates whether the term is an exclusive or *) + val is_xor : Expr.expr -> bool + + (** Indicates whether the term is a negation *) + val is_not : Expr.expr -> bool + + (** Indicates whether the term is an implication *) + val is_implies : Expr.expr -> bool + + (** Indicates whether the term is a label (used by the Boogie Verification condition generator). + The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) + val is_label : Expr.expr -> bool + + (** Indicates whether the term is a label literal (used by the Boogie Verification condition generator). + A label literal has a set of string parameters. It takes no arguments. + let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) + val is_label_lit : Expr.expr -> bool + + (** Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) + val is_oeq : Expr.expr -> bool + + (** Creates a new constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + + (** Creates a new constant. *) + val mk_const_s : context -> string -> Sort.sort -> expr + + (** Creates a constant from the func_decl. *) + val mk_const_f : context -> FuncDecl.func_decl -> expr + + (** Creates a fresh constant with a name prefixed with a string. *) + val mk_fresh_const : context -> string -> Sort.sort -> expr + + (** Create a new function application. *) + val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr + + (** Create a numeral of a given sort. + @return A Term with the goven value and sort *) + val mk_numeral_string : context -> string -> Sort.sort -> expr + + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @return A Term with the given value and sort *) + val mk_numeral_int : context -> int -> Sort.sort -> expr +end + +(** Boolean expressions *) +module Boolean : +sig + type bool_sort = BoolSort of Sort.sort + type bool_expr = BoolExpr of Expr.expr + + val expr_of_bool_expr : bool_expr -> Expr.expr + val sort_of_bool_sort : bool_sort -> Sort.sort + val bool_sort_of_sort : Sort.sort -> bool_sort + val bool_expr_of_expr : Expr.expr -> bool_expr + + (** Create a Boolean sort *) + val mk_sort : context -> bool_sort + + (** Create a Boolean constant. *) + val mk_const : context -> Symbol.symbol -> bool_expr + + (** Create a Boolean constant. *) + val mk_const_s : context -> string -> bool_expr + + (** The true Term. *) + val mk_true : context -> bool_expr + + (** The false Term. *) + val mk_false : context -> bool_expr + + (** Creates a Boolean value. *) + val mk_val : context -> bool -> bool_expr + + (** Creates the equality between two expr's. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr + + (** Creates a distinct term. *) + val mk_distinct : context -> Expr.expr list -> bool_expr + + (** Mk an expression representing not(a). *) + val mk_not : context -> bool_expr -> bool_expr + + (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 iff t2. *) + val mk_iff : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 -> t2. *) + val mk_implies : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing t1 xor t2. *) + val mk_xor : context -> bool_expr -> bool_expr -> bool_expr + + (** Create an expression representing the AND of args *) + val mk_and : context -> bool_expr list -> bool_expr + + (** Create an expression representing the OR of args *) + val mk_or : context -> bool_expr list -> bool_expr +end + +(** Quantifier expressions *) +module Quantifier : +sig + type quantifier = Quantifier of Expr.expr + + val expr_of_quantifier : quantifier -> Expr.expr + val quantifier_of_expr : Expr.expr -> quantifier + + (** Quantifier patterns + + Patterns comprise a list of terms. The list should be + non-empty. If the list comprises of more than one term, it is + also called a multi-pattern. *) + module Pattern : + sig + type pattern = Pattern of AST.ast + + val ast_of_pattern : pattern -> AST.ast + val pattern_of_ast : AST.ast -> pattern + + (** The number of terms in the pattern. *) + val get_num_terms : pattern -> int + + (** The terms in the pattern. *) + val get_terms : pattern -> Expr.expr list + + (** A string representation of the pattern. *) + val to_string : pattern -> string + end + + + (** The de-Burijn index of a bound variable. + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. *) + val get_index : Expr.expr -> int + + (** Indicates whether the quantifier is universal. *) + val is_universal : quantifier -> bool + + (** Indicates whether the quantifier is existential. *) + val is_existential : quantifier -> bool + + (** The weight of the quantifier. *) + val get_weight : quantifier -> int + + (** The number of patterns. *) + val get_num_patterns : quantifier -> int + + (** The patterns. *) + val get_patterns : quantifier -> Pattern.pattern list + + (** The number of no-patterns. *) + val get_num_no_patterns : quantifier -> int + + (** The no-patterns. *) + val get_no_patterns : quantifier -> Pattern.pattern list + + (** The number of bound variables. *) + val get_num_bound : quantifier -> int + + (** The symbols for the bound variables. *) + val get_bound_variable_names : quantifier -> Symbol.symbol list + + (** The sorts of the bound variables. *) + val get_bound_variable_sorts : quantifier -> Sort.sort list + + (** The body of the quantifier. *) + val get_body : quantifier -> Boolean.bool_expr + + (** Creates a new bound variable. *) + val mk_bound : context -> int -> Sort.sort -> Expr.expr + + (** Create a quantifier pattern. *) + val mk_pattern : context -> Expr.expr list -> Pattern.pattern + + (** Create a universal Quantifier. *) + val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a universal Quantifier. *) + val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create an existential Quantifier. *) + val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** Create a Quantifier. *) + val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier +end + +(** Functions to manipulate Array expressions *) +module Array_ : +sig + type array_sort = ArraySort of Sort.sort + type array_expr = ArrayExpr of Expr.expr + + val sort_of_array_sort : array_sort -> Sort.sort + val array_sort_of_sort : Sort.sort -> array_sort + val expr_of_array_expr : array_expr -> Expr.expr + + val array_expr_of_expr : Expr.expr -> array_expr + + (** Create a new array sort. *) + val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort + + (** Indicates whether the term is an array store. + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. *) + val is_store : Expr.expr -> bool + + (** Indicates whether the term is an array select. *) + val is_select : Expr.expr -> bool + + (** Indicates whether the term is a constant array. + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) + val is_constant_array : Expr.expr -> bool + + (** Indicates whether the term is a default array. + For example default(const(v)) = v. The function is unary. *) + val is_default_array : Expr.expr -> bool + + (** Indicates whether the term is an array map. + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) + val is_array_map : Expr.expr -> bool + + (** Indicates whether the term is an as-array term. + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. *) + val is_as_array : Expr.expr -> bool + + (** Indicates whether the term is of an array sort. *) + val is_array : Expr.expr -> bool + + (** The domain of the array sort. *) + val get_domain : array_sort -> Sort.sort + + (** The range of the array sort. *) + val get_range : array_sort -> Sort.sort + + (** Create an array constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr + + (** Create an array constant. *) + val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr + + (** Array read. + + The argument a is the array and i is the index + of the array that gets read. + + The node a must have an array sort [domain -> range], + and i must have the sort domain. + The sort of the result is range. + {!Array_.mk_sort} + {!mk_store} *) + val mk_select : context -> array_expr -> Expr.expr -> array_expr + + (** Array update. + + The node a must have an array sort [domain -> range], + i must have sort domain, + v must have sort range. The sort of the result is [domain -> range]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to a + (with respect to select) + on all indices except for i, where it maps to v + (and the select of a with + respect to i may be a different value). + {!Array_.mk_sort} + {!mk_select} *) + val mk_store : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr + + (** Create a constant array. + + The resulting term is an array, such that a selecton an arbitrary index + produces the value v. + {!Array_.mk_sort} + {!mk_select} *) + val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr + + (** Maps f on the argument arrays. + + Eeach element of args must be of an array sort [domain_i -> range_i]. + The function declaration f must have type range_1 .. range_n -> range. + v must have sort range. The sort of the result is [domain_i -> range]. + {!Array_.mk_sort} + {!mk_select} + {!mk_store} *) + val mk_map : context -> FuncDecl.func_decl -> array_expr list -> array_expr + + (** Access the array default value. + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. *) + val mk_term_array : context -> array_expr -> array_expr +end + +(** Functions to manipulate Set expressions *) +module Set : +sig + type set_sort = SetSort of Sort.sort + + val sort_of_set_sort : set_sort -> Sort.sort + + (** Create a set type. *) + val mk_sort : context -> Sort.sort -> set_sort + + (** Indicates whether the term is set union *) + val is_union : Expr.expr -> bool + + (** Indicates whether the term is set intersection *) + val is_intersect : Expr.expr -> bool + + (** Indicates whether the term is set difference *) + val is_difference : Expr.expr -> bool + + (** Indicates whether the term is set complement *) + val is_complement : Expr.expr -> bool + + (** Indicates whether the term is set subset *) + val is_subset : Expr.expr -> bool + + (** Create an empty set. *) + val mk_empty : context -> Sort.sort -> Expr.expr + + (** Create the full set. *) + val mk_full : context -> Sort.sort -> Expr.expr + + (** Add an element to the set. *) + val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Remove an element from a set. *) + val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Take the union of a list of sets. *) + val mk_union : context -> Expr.expr list -> Expr.expr + + (** Take the intersection of a list of sets. *) + val mk_intersection : context -> Expr.expr list -> Expr.expr + + (** Take the difference between two sets. *) + val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Take the complement of a set. *) + val mk_complement : context -> Expr.expr -> Expr.expr + + (** Check for set membership. *) + val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Check for subsetness of sets. *) + val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr +end + +(** Functions to manipulate Finite Domain expressions *) +module FiniteDomain : +sig + type finite_domain_sort = FiniteDomainSort of Sort.sort + + val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort + val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort + + (** Create a new finite domain sort. *) + val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort + + (** Create a new finite domain sort. *) + val mk_sort_s : context -> string -> int -> finite_domain_sort + + (** Indicates whether the term is of an array sort. *) + val is_finite_domain : Expr.expr -> bool + + (** Indicates whether the term is a less than predicate over a finite domain. *) + val is_lt : Expr.expr -> bool + + (** The size of the finite domain sort. *) + val get_size : finite_domain_sort -> int +end + + +(** Functions to manipulate Relation expressions *) +module Relation : +sig + type relation_sort = RelationSort of Sort.sort + + val sort_of_relation_sort : relation_sort -> Sort.sort + val relation_sort_of_sort : Sort.sort -> relation_sort + + (** Indicates whether the term is of a relation sort. *) + val is_relation : Expr.expr -> bool + + (** Indicates whether the term is an relation store + + Insert a record into a relation. + The function takes n+1 arguments, where the first argument is the relation and the remaining n elements + correspond to the n columns of the relation. *) + val is_store : Expr.expr -> bool + + (** Indicates whether the term is an empty relation *) + val is_empty : Expr.expr -> bool + + (** Indicates whether the term is a test for the emptiness of a relation *) + val is_is_empty : Expr.expr -> bool + + (** Indicates whether the term is a relational join *) + val is_join : Expr.expr -> bool + + (** Indicates whether the term is the union or convex hull of two relations. + The function takes two arguments. *) + val is_union : Expr.expr -> bool + + (** Indicates whether the term is the widening of two relations + The function takes two arguments. *) + val is_widen : Expr.expr -> bool + + (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). + The function takes one argument. *) + val is_project : Expr.expr -> bool + + (** Indicates whether the term is a relation filter + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. *) + val is_filter : Expr.expr -> bool + + (** Indicates whether the term is an intersection of a relation with the negation of another. + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. *) + val is_negation_filter : Expr.expr -> bool + + (** Indicates whether the term is the renaming of a column in a relation + + The function takes one argument. + The parameters contain the renaming as a cycle. *) + val is_rename : Expr.expr -> bool + + (** Indicates whether the term is the complement of a relation *) + val is_complement : Expr.expr -> bool + + (** Indicates whether the term is a relational select + + Check if a record is an element of the relation. + The function takes n+1 arguments, where the first argument is a relation, + and the remaining n arguments correspond to a record. *) + val is_select : Expr.expr -> bool + + (** Indicates whether the term is a relational clone (copy) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind {!is_union} + to perform destructive updates to the first argument. *) + val is_clone : Expr.expr -> bool + + (** The arity of the relation sort. *) + val get_arity : relation_sort -> int + + (** The sorts of the columns of the relation sort. *) + val get_column_sorts : relation_sort -> relation_sort list +end + +(** Functions to manipulate Datatype expressions *) +module Datatype : +sig + type datatype_sort = DatatypeSort of Sort.sort + type datatype_expr = DatatypeExpr of Expr.expr + + val sort_of_datatype_sort : datatype_sort -> Sort.sort + val datatype_sort_of_sort : Sort.sort -> datatype_sort + val expr_of_datatype_expr : datatype_expr -> Expr.expr + val datatype_expr_of_expr : Expr.expr -> datatype_expr + + (** Datatype Constructors *) + module Constructor : + sig + type constructor + + (** The number of fields of the constructor. *) + val get_num_fields : constructor -> int + + (** The function declaration of the constructor. *) + val get_constructor_decl : constructor -> FuncDecl.func_decl + + (** The function declaration of the tester. *) + val get_tester_decl : constructor -> FuncDecl.func_decl + + (** The function declarations of the accessors *) + val get_accessor_decls : constructor -> FuncDecl.func_decl list + end + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + + (** Create a datatype constructor. + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + + (** Create a new datatype sort. *) + val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> datatype_sort + + (** Create a new datatype sort. *) + val mk_sort_s : context -> string -> Constructor.constructor list -> datatype_sort + + (** Create mutually recursive datatypes. *) + val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> datatype_sort list + + (** Create mutually recursive data-types. *) + val mk_sorts_s : context -> string list -> Constructor.constructor list list -> datatype_sort list + + + (** The number of constructors of the datatype sort. *) + val get_num_constructors : datatype_sort -> int + + (** The constructors. *) + val get_constructors : datatype_sort -> FuncDecl.func_decl list + + (** The recognizers. *) + val get_recognizers : datatype_sort -> FuncDecl.func_decl list + + (** The constructor accessors. *) + val get_accessors : datatype_sort -> FuncDecl.func_decl list list +end + +(** Functions to manipulate Enumeration expressions *) +module Enumeration : +sig + type enum_sort = EnumSort of Sort.sort + + val sort_of_enum_sort : enum_sort -> Sort.sort + + (** Create a new enumeration sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> enum_sort + + (** Create a new enumeration sort. *) + val mk_sort_s : context -> string -> string list -> enum_sort + + (** The function declarations of the constants in the enumeration. *) + val get_const_decls : enum_sort -> FuncDecl.func_decl list + + (** The test predicates for the constants in the enumeration. *) + val get_tester_decls : enum_sort -> FuncDecl.func_decl list +end + +(** Functions to manipulate List expressions *) +module List_ : +sig + type list_sort = ListSort of Sort.sort + + val sort_of_list_sort : list_sort -> Sort.sort + + (** Create a new list sort. *) + val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort + + (** Create a new list sort. *) + val mk_list_s : context -> string -> Sort.sort -> list_sort + + (** The declaration of the nil function of this list sort. *) + val get_nil_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the isNil function of this list sort. *) + val get_is_nil_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the cons function of this list sort. *) + val get_cons_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the isCons function of this list sort. *) + val get_is_cons_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the head function of this list sort. *) + val get_head_decl : list_sort -> FuncDecl.func_decl + + (** The declaration of the tail function of this list sort. *) + val get_tail_decl : list_sort -> FuncDecl.func_decl + + (** The empty list. *) + val nil : list_sort -> Expr.expr +end + +(** Functions to manipulate Tuple expressions *) +module Tuple : +sig + type tuple_sort = TupleSort of Sort.sort + + val sort_of_tuple_sort : tuple_sort -> Sort.sort + + (** Create a new tuple sort. *) + val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> tuple_sort + + (** The constructor function of the tuple. *) + val get_mk_decl : tuple_sort -> FuncDecl.func_decl + + (** The number of fields in the tuple. *) + val get_num_fields : tuple_sort -> int + + (** The field declarations. *) + val get_field_decls : tuple_sort -> FuncDecl.func_decl list +end + +(** Functions to manipulate arithmetic expressions *) +module rec Arithmetic : +sig + type arith_sort = ArithSort of Sort.sort + type arith_expr = ArithExpr of Expr.expr + + val sort_of_arith_sort : Arithmetic.arith_sort -> Sort.sort + val arith_sort_of_sort : Sort.sort -> Arithmetic.arith_sort + val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr + val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr + + (** Integer Arithmetic *) + module rec Integer : + sig + type int_sort = IntSort of arith_sort + type int_expr = IntExpr of arith_expr + type int_num = IntNum of int_expr + + val arith_sort_of_int_sort : Arithmetic.Integer.int_sort -> Arithmetic.arith_sort + val int_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Integer.int_sort + val arith_expr_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.arith_expr + val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr + val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr + val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num + + (** Create a new integer sort. *) + val mk_sort : context -> int_sort + + (** Retrieve the int value. *) + val get_int : int_num -> int + + (** Returns a string representation of the numeral. *) + val to_string : int_num -> string + + (** Creates an integer constant. *) + val mk_int_const : context -> Symbol.symbol -> int_expr + + (** Creates an integer constant. *) + val mk_int_const_s : context -> string -> int_expr + + (** Create an expression representing t1 mod t2. + The arguments must have int type. *) + val mk_mod : context -> int_expr -> int_expr -> int_expr + + (** Create an expression representing t1 rem t2. + The arguments must have int type. *) + val mk_rem : context -> int_expr -> int_expr -> int_expr + + (** Create an integer numeral. *) + val mk_int_numeral_s : context -> string -> int_num + + (** Create an integer numeral. + @return A Term with the given value and sort Integer *) + val mk_int_numeral_i : context -> int -> int_num + + (** Coerce an integer to a real. + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term k and + and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + The argument must be of integer sort. *) + val mk_int2real : context -> int_expr -> Real.real_expr + + (** Create an n-bit bit-vector from an integer argument. + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. *) + val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr + end + + (** Real Arithmetic *) + and Real : + sig + type real_sort = RealSort of arith_sort + type real_expr = RealExpr of arith_expr + type rat_num = RatNum of real_expr + + val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort + val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort + val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr + val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr + val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr + val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num + + (** Create a real sort. *) + val mk_sort : context -> real_sort + + (** The numerator of a rational numeral. *) + val get_numerator : rat_num -> Integer.int_num + + (** The denominator of a rational numeral. *) + val get_denominator : rat_num -> Integer.int_num + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as indicated by the int argument.*) + val to_decimal_string : rat_num -> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : rat_num -> string + + (** Creates a real constant. *) + val mk_real_const : context -> Symbol.symbol -> real_expr + + (** Creates a real constant. *) + val mk_real_const_s : context -> string -> real_expr + + (** Create a real numeral from a fraction. + @return A Term with rational value and sort Real + {!mk_numeral_s} *) + val mk_numeral_nd : context -> int -> int -> rat_num + + (** Create a real numeral. + @return A Term with the given value and sort Real *) + val mk_numeral_s : context -> string -> rat_num + + (** Create a real numeral. + @return A Term with the given value and sort Real *) + val mk_numeral_i : context -> int -> rat_num + + (** Creates an expression that checks whether a real number is an integer. *) + val mk_is_integer : context -> real_expr -> Boolean.bool_expr + + (** Coerce a real to an integer. + + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) + val mk_real2int : context -> real_expr -> Integer.int_expr + end + + (** Algebraic Numbers *) + and AlgebraicNumber : + sig + type algebraic_num = AlgebraicNum of arith_expr + + val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr + val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num + + (** Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_upper : algebraic_num -> int -> Real.rat_num + + (** Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_lower : algebraic_num -> int -> Real.rat_num + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as the int argument provided.*) + val to_decimal_string : algebraic_num -> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : algebraic_num -> string + end + + (** Indicates whether the term is of integer sort. *) + val is_int : Expr.expr -> bool + + (** Indicates whether the term is an arithmetic numeral. *) + val is_arithmetic_numeral : Expr.expr -> bool + + (** Indicates whether the term is a less-than-or-equal *) + val is_le : Expr.expr -> bool + + (** Indicates whether the term is a greater-than-or-equal *) + val is_ge : Expr.expr -> bool + + (** Indicates whether the term is a less-than *) + val is_lt : Expr.expr -> bool + + (** Indicates whether the term is a greater-than *) + val is_gt : Expr.expr -> bool + + (** Indicates whether the term is addition (binary) *) + val is_add : Expr.expr -> bool + + (** Indicates whether the term is subtraction (binary) *) + val is_sub : Expr.expr -> bool + + (** Indicates whether the term is a unary minus *) + val is_uminus : Expr.expr -> bool + + (** Indicates whether the term is multiplication (binary) *) + val is_mul : Expr.expr -> bool + + (** Indicates whether the term is division (binary) *) + val is_div : Expr.expr -> bool + + (** Indicates whether the term is integer division (binary) *) + val is_idiv : Expr.expr -> bool + + (** Indicates whether the term is remainder (binary) *) + val is_remainder : Expr.expr -> bool + + (** Indicates whether the term is modulus (binary) *) + val is_modulus : Expr.expr -> bool + + (** Indicates whether the term is a coercion of integer to real (unary) *) + val is_inttoreal : Expr.expr -> bool + + (** Indicates whether the term is a coercion of real to integer (unary) *) + val is_real_to_int : Expr.expr -> bool + + (** Indicates whether the term is a check that tests whether a real is integral (unary) *) + val is_real_is_int : Expr.expr -> bool + + (** Indicates whether the term is of sort real. *) + val is_real : Expr.expr -> bool + + (** Indicates whether the term is an integer numeral. *) + val is_int_numeral : Expr.expr -> bool + + (** Indicates whether the term is a real numeral. *) + val is_rat_num : Expr.expr -> bool + + (** Indicates whether the term is an algebraic number *) + val is_algebraic_number : Expr.expr -> bool + + (** Create an expression representing t[0] + t[1] + .... *) + val mk_add : context -> arith_expr list -> arith_expr + + (** Create an expression representing t[0] * t[1] * .... *) + val mk_mul : context -> arith_expr list -> arith_expr + + (** Create an expression representing t[0] - t[1] - .... *) + val mk_sub : context -> arith_expr list -> arith_expr + + (** Create an expression representing -t. *) + val mk_unary_minus : context -> arith_expr -> arith_expr + + (** Create an expression representing t1 / t2. *) + val mk_div : context -> arith_expr -> arith_expr -> arith_expr + + (** Create an expression representing t1 ^ t2. *) + val mk_power : context -> arith_expr -> arith_expr -> arith_expr + + (** Create an expression representing t1 < t2 *) + val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 <= t2 *) + val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 > t2 *) + val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr + + (** Create an expression representing t1 >= t2 *) + val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr +end + +(** Functions to manipulate bit-vector expressions *) +and BitVector : +sig + type bitvec_sort = BitVecSort of Sort.sort + type bitvec_expr = BitVecExpr of Expr.expr + type bitvec_num = BitVecNum of bitvec_expr + + val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort + val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort + val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr + val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr + val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr + val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num + + (** Create a new bit-vector sort. *) + val mk_sort : context -> int -> bitvec_sort + + (** Indicates whether the terms is of bit-vector sort. *) + val is_bv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector numeral *) + val is_bv_numeral : Expr.expr -> bool + + (** Indicates whether the term is a one-bit bit-vector with value one *) + val is_bv_bit1 : Expr.expr -> bool + + (** Indicates whether the term is a one-bit bit-vector with value zero *) + val is_bv_bit0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unary minus *) + val is_bv_uminus : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector addition (binary) *) + val is_bv_add : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector subtraction (binary) *) + val is_bv_sub : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector multiplication (binary) *) + val is_bv_mul : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed division (binary) *) + val is_bv_sdiv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned division (binary) *) + val is_bv_udiv : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed remainder (binary) *) + val is_bv_SRem : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) + val is_bv_urem : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed modulus *) + val is_bv_smod : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed division by zero *) + val is_bv_sdiv0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned division by zero *) + val is_bv_udiv0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed remainder by zero *) + val is_bv_srem0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector unsigned remainder by zero *) + val is_bv_urem0 : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector signed modulus by zero *) + val is_bv_smod0 : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) + val is_bv_ule : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector less-than-or-equal *) + val is_bv_sle : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) + val is_bv_uge : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) + val is_bv_sge : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector less-than *) + val is_bv_ult : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector less-than *) + val is_bv_slt : Expr.expr -> bool + + (** Indicates whether the term is an unsigned bit-vector greater-than *) + val is_bv_ugt : Expr.expr -> bool + + (** Indicates whether the term is a signed bit-vector greater-than *) + val is_bv_sgt : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise AND *) + val is_bv_and : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise OR *) + val is_bv_or : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NOT *) + val is_bv_not : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise XOR *) + val is_bv_xor : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NAND *) + val is_bv_nand : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise NOR *) + val is_bv_nor : Expr.expr -> bool + + (** Indicates whether the term is a bit-wise XNOR *) + val is_bv_xnor : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector concatenation (binary) *) + val is_bv_concat : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector sign extension *) + val is_bv_signextension : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector zero extension *) + val is_bv_zeroextension : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector extraction *) + val is_bv_extract : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector repetition *) + val is_bv_repeat : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector reduce OR *) + val is_bv_reduceor : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector reduce AND *) + val is_bv_reduceand : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector comparison *) + val is_bv_comp : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector shift left *) + val is_bv_shiftleft : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector logical shift right *) + val is_bv_shiftrightlogical : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector arithmetic shift left *) + val is_bv_shiftrightarithmetic : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate left *) + val is_bv_rotateleft : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate right *) + val is_bv_rotateright : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate left (extended) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) + val is_bv_rotateleftextended : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector rotate right (extended) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) + val is_bv_rotaterightextended : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + + (** Indicates whether the term is a coercion from bit-vector to integer + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + val is_int_to_bv : Expr.expr -> bool + + (** Indicates whether the term is a coercion from integer to bit-vector + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) + val is_bv_to_int : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector carry + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) + val is_bv_carry : Expr.expr -> bool + + (** Indicates whether the term is a bit-vector ternary XOR + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) + val is_bv_xor3 : Expr.expr -> bool + + (** The size of a bit-vector sort. *) + val get_size : bitvec_sort -> int + + (** Retrieve the int value. *) + val get_int : bitvec_num -> int + + (** Returns a string representation of the numeral. *) + val to_string : bitvec_num -> string + + (** Creates a bit-vector constant. *) + val mk_const : context -> Symbol.symbol -> int -> bitvec_expr + + (** Creates a bit-vector constant. *) + val mk_const_s : context -> string -> int -> bitvec_expr + + (** Bitwise negation. + The argument must have a bit-vector sort. *) + val mk_not : context -> bitvec_expr -> Expr.expr + + (** Take conjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) + val mk_redand : context -> bitvec_expr -> Expr.expr + + (** Take disjunction of bits in a vector,vector of length 1. + The argument must have a bit-vector sort. *) + val mk_redor : context -> bitvec_expr -> Expr.expr + + (** Bitwise conjunction. + The arguments must have a bit-vector sort. *) + val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise disjunction. + The arguments must have a bit-vector sort. *) + val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise XOR. + The arguments must have a bit-vector sort. *) + val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise NAND. + The arguments must have a bit-vector sort. *) + val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise NOR. + The arguments must have a bit-vector sort. *) + val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bitwise XNOR. + The arguments must have a bit-vector sort. *) + val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Standard two's complement unary minus. + The arguments must have a bit-vector sort. *) + val mk_neg : context -> bitvec_expr -> bitvec_expr + + (** Two's complement addition. + The arguments must have the same bit-vector sort. *) + val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement subtraction. + The arguments must have the same bit-vector sort. *) + val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement multiplication. + The arguments must have the same bit-vector sort. *) + val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned division. + + + It is defined as the floor of t1/t2 if \c t2 is + different from zero. If t2 is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. *) + val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Signed division. + + It is defined in the following way: + + - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + + - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned remainder. + + It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Signed remainder. + + It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Two's complement signed remainder (sign follows divisor). + + If t2 is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) + val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Unsigned less-than + + The arguments must have the same bit-vector sort. *) + val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed less-than + + The arguments must have the same bit-vector sort. *) + val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned less-than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed less-than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned greater than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed greater than or equal to. + + The arguments must have the same bit-vector sort. *) + val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Unsigned greater-than. + + The arguments must have the same bit-vector sort. *) + val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Two's complement signed greater-than. + + The arguments must have the same bit-vector sort. *) + val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Bit-vector concatenation. + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size n1+n2, where n1 (n2) + is the size of t1 (t2). *) + val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Bit-vector extraction. + + Extract the bits between two limits from a bitvector of + size m to yield a new bitvector of size n, where + n = high - low + 1. *) + val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector sign extension. + + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size m+i, where \c m is the size of the given bit-vector. *) + val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector zero extension. + + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size m+i, where \c m is the size of the + given bit-vector. *) + val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr + + (** Bit-vector repetition. *) + val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr + + (** Shift left. + + It is equivalent to multiplication by 2^x where \c x is the value of third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling.*) + val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Logical shift right + + It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) + val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Arithmetic shift right + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. + + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. + + The arguments must have a bit-vector sort. *) + val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Rotate Left. + Rotate bits of \c t to the left \c i times. *) + val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr + + (** Rotate Right. + Rotate bits of \c t to the right \c i times.*) + val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr + + (** Rotate Left. + Rotate bits of the second argument to the left.*) + val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Rotate Right. + Rotate bits of the second argument to the right. *) + val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr + + (** Create an integer from the bit-vector argument + + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. + So the result is non-negative and in the range [0..2^N-1], where + N are the number of bits in the argument. + If \c is_signed is true, \c t1 is treated as a signed bit-vector. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function.*) + val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr + + (** Create a predicate that checks that the bit-wise addition does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise addition does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise subtraction does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise subtraction does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise signed division does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise negation does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise multiplication does not overflow. + + The arguments must be of bit-vector sort. *) + val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr + + (** Create a predicate that checks that the bit-wise multiplication does not underflow. + + The arguments must be of bit-vector sort. *) + val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr + + (** Create a bit-vector numeral. *) + val mk_numeral : context -> string -> int -> bitvec_num +end + +(** Functions to manipulate proof expressions *) +module Proof : +sig + (** Indicates whether the term is a Proof for the expression 'true'. *) + val is_true : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact asserted by the user. *) + val is_asserted : Expr.expr -> bool + + (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) + val is_goal : Expr.expr -> bool + + (** Indicates whether the term is proof via modus ponens + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). *) + val is_modus_ponens : Expr.expr -> bool + + (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. *) + val is_reflexivity : Expr.expr -> bool + + (** Indicates whether the term is proof by symmetricity of a relation + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. *) + val is_symmetry : Expr.expr -> bool + + (** Indicates whether the term is a proof by transitivity of a relation + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) *) + val is_transitivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by condensed transitivity of a relation + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. *) + val is_Transitivity_star : Expr.expr -> bool + + (** Indicates whether the term is a monotonicity proof object. + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. *) + val is_monotonicity : Expr.expr -> bool + + (** Indicates whether the term is a quant-intro proof + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) + val is_quant_intro : Expr.expr -> bool + + (** Indicates whether the term is a distributivity proof object. + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. *) + val is_distributivity : Expr.expr -> bool + + (** Indicates whether the term is a proof by elimination of AND + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i *) + val is_and_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by eliminiation of not-or + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) *) + val is_or_elimination : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) + val is_rewrite : Expr.expr -> bool + + (** Indicates whether the term is a proof by rewriting + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) + val is_rewrite_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) + val is_pull_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for pulling quantifiers out. + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents *) + val is_pull_quant_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for pushing quantifiers in. + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents *) + val is_push_quant : Expr.expr -> bool + + (** Indicates whether the term is a proof for elimination of unused variables. + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. *) + val is_elim_unused_vars : Expr.expr -> bool + + (** Indicates whether the term is a proof for destructive equality resolution + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. *) + val is_der : Expr.expr -> bool + + (** Indicates whether the term is a proof for quantifier instantiation + + A proof of (or (not (forall (x) (P x))) (P a)) *) + val is_quant_inst : Expr.expr -> bool + + (** Indicates whether the term is a hypthesis marker. + Mark a hypothesis in a natural deduction style proof. *) + val is_hypothesis : Expr.expr -> bool + + (** Indicates whether the term is a proof by lemma + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. *) + val is_lemma : Expr.expr -> bool + + (** Indicates whether the term is a proof by unit resolution + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) + val is_unit_resolution : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-true + + T1: p + [iff-true T1]: (iff p true) *) + val is_iff_true : Expr.expr -> bool + + (** Indicates whether the term is a proof by iff-false + + T1: (not p) + [iff-false T1]: (iff p false) *) + val is_iff_false : Expr.expr -> bool + + (** Indicates whether the term is a proof by commutativity + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. *) + val is_commutativity : Expr.expr -> bool + + (** Indicates whether the term is a proof for Tseitin-like axioms + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). *) + val is_def_axiom : Expr.expr -> bool + + (** Indicates whether the term is a proof for introduction of a name + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) *) + val is_def_intro : Expr.expr -> bool + + (** Indicates whether the term is a proof for application of a definition + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. *) + val is_apply_def : Expr.expr -> bool + + (** Indicates whether the term is a proof iff-oeq + + T1: (iff p q) + [iff~ T1]: (~ p q) *) + val is_iff_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for a positive NNF step + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. *) + val is_nnf_pos : Expr.expr -> bool + + (** Indicates whether the term is a proof for a negative NNF step + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) *) + val is_nnf_neg : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + val is_nnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + val is_cnf_star : Expr.expr -> bool + + (** Indicates whether the term is a proof for a Skolemization step + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. *) + val is_skolemize : Expr.expr -> bool + + (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q *) + val is_modus_ponens_oeq : Expr.expr -> bool + + (** Indicates whether the term is a proof for theory lemma + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) + val is_theory_lemma : Expr.expr -> bool +end + +(** Goals + + A goal (aka problem). A goal is essentially a + of formulas, that can be solved and/or transformed using + tactics and solvers. *) +module Goal : +sig + type goal + + (** The precision of the goal. + + Goals can be transformed using over and under approximations. + An under approximation is applied when the objective is to find a model for a given goal. + An over approximation is applied when the objective is to find a proof for a given goal. *) + val get_precision : goal -> Z3enums.goal_prec + + (** Indicates whether the goal is precise. *) + val is_precise : goal -> bool + + (** Indicates whether the goal is an under-approximation. *) + val is_underapproximation : goal -> bool + + (** Indicates whether the goal is an over-approximation. *) + val is_overapproximation : goal -> bool + + (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) + val is_garbage : goal -> bool + + (** Adds the constraints to the given goal. *) + val assert_ : goal -> Boolean.bool_expr list -> unit + + (** Indicates whether the goal contains `false'. *) + val is_inconsistent : goal -> bool + + (** The depth of the goal. + This tracks how many transformations were applied to it. *) + val get_depth : goal -> int + + (** Erases all formulas from the given goal. *) + val reset : goal -> unit + + (** The number of formulas in the goal. *) + val get_size : goal -> int + + (** The formulas in the goal. *) + val get_formulas : goal -> Boolean.bool_expr list + + (** The number of formulas, subformulas and terms in the goal. *) + val get_num_exprs : goal -> int + + (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) + val is_decided_sat : goal -> bool + + (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) + val is_decided_unsat : goal -> bool + + (** Translates (copies) the Goal to another context.. *) + val translate : goal -> context -> goal + + (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) + val simplify : goal -> Params.params option -> goal + + (** Creates a new Goal. + + Note that the Context must have been created with proof generation support if + the fourth argument is set to true here. *) + val mk_goal : context -> bool -> bool -> bool -> goal + + (** A string representation of the Goal. *) + val to_string : goal -> string +end + +(** Models + + A Model contains interpretations (assignments) of constants and functions. *) +module Model : +sig + type model + + (** Function interpretations + + A function interpretation is represented as a finite map and an 'else'. + Each entry in the finite map represents the value of a function given a set of arguments. *) + module FuncInterp : + sig + type func_interp + + (** Function interpretations entries + + An Entry object represents an element in the finite map used to a function interpretation. *) + module FuncEntry : + sig + type func_entry + + (** Return the (symbolic) value of this entry. + *) + val get_value : func_entry -> Expr.expr + + (** The number of arguments of the entry. + *) + val get_num_args : func_entry -> int + + (** The arguments of the function entry. + *) + val get_args : func_entry -> Expr.expr list + + (** A string representation of the function entry. + *) + val to_string : func_entry -> string + end + + (** The number of entries in the function interpretation. *) + val get_num_entries : func_interp -> int + + (** The entries in the function interpretation *) + val get_entries : func_interp -> FuncEntry.func_entry list + + (** The (symbolic) `else' value of the function interpretation. *) + val get_else : func_interp -> Expr.expr + + (** The arity of the function interpretation *) + val get_arity : func_interp -> int + + (** A string representation of the function interpretation. *) + val to_string : func_interp -> string + end + + (** Retrieves the interpretation (the assignment) of a func_decl in the model. + An expression if the function has an interpretation in the model, null otherwise. *) + val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option + + (** Retrieves the interpretation (the assignment) of an expression in the model. + An expression if the constant has an interpretation in the model, null otherwise. *) + val get_const_interp_e : model -> Expr.expr -> Expr.expr option + + (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. + A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option + + (** The number of constant interpretations in the model. *) + val get_num_consts : model -> int + + (** The function declarations of the constants in the model. *) + val get_const_decls : model -> FuncDecl.func_decl list + + (** The number of function interpretations in the model. *) + val get_num_funcs : model -> int + + (** The function declarations of the function interpretations in the model. *) + val get_func_decls : model -> FuncDecl.func_decl list + + (** All symbols that have an interpretation in the model. *) + val get_decls : model -> FuncDecl.func_decl list + + (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) + exception ModelEvaluationFailedException of string + + (** Evaluates an expression in the current model. + + This function may fail if the argument contains quantifiers, + is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. + In this case a ModelEvaluationFailedException is thrown. + *) + val eval : model -> Expr.expr -> bool -> Expr.expr + + (** Alias for eval. *) + val evaluate : model -> Expr.expr -> bool -> Expr.expr + + (** The number of uninterpreted sorts that the model has an interpretation for. *) + val get_num_sorts : model -> int + + (** The uninterpreted sorts that the model has an interpretation for. + + Z3 also provides an intepretation for uninterpreted sorts used in a formula. + The interpretation for a sort is a finite set of distinct values. We say this finite set is + the "universe" of the sort. + {!get_num_sorts} + {!sort_universe} *) + val get_sorts : model -> Sort.sort list + + (** The finite set of distinct values that represent the interpretation of a sort. + {!get_sorts} + @returns A list of expressions, where each is an element of the universe of the sort *) + val sort_universe : model -> Sort.sort -> AST.ast list + + (** Conversion of models to strings. + A string representation of the model. *) + val to_string : model -> string +end + +(** Probes + + Probes are used to inspect a goal (aka problem) and collect information that may be used to decide + which solver and/or preprocessing step will be used. + The complete list of probes may be obtained using the procedures Context.NumProbes + and Context.ProbeNames. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Probe : +sig + type probe + + (** Execute the probe over the goal. + A probe always produce a double value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + val apply : probe -> Goal.goal -> float + + (** The number of supported Probes. *) + val get_num_probes : context -> int + + (** The names of all supported Probes. *) + val get_probe_names : context -> string list + + (** Returns a string containing a description of the probe with the given name. *) + val get_probe_description : context -> string -> string + + (** Creates a new Probe. *) + val mk_probe : context -> string -> probe + + (** Create a probe that always evaluates to a float value. *) + val const : context -> float -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than the value returned by second argument *) + val lt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than the value returned by second argument *) + val gt : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is less than or equal the value returned by second argument *) + val le : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is greater than or equal the value returned by second argument *) + val ge : context -> probe -> probe -> probe + + + (** Create a probe that evaluates to "true" when the value returned by the first argument + is equal the value returned by second argument *) + val eq : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) + val and_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) + val or_ : context -> probe -> probe -> probe + + (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) + val not_ : context -> probe -> probe +end + +(** Tactics + + Tactics are the basic building block for creating custom solvers for specific problem domains. + The complete list of tactics may be obtained using Context.get_num_tactics + and Context.get_tactic_names. + It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. +*) +module Tactic : +sig + type tactic + + (** Tactic application results + + ApplyResult objects represent the result of an application of a + tactic to a goal. It contains the subgoals that were produced. *) + module ApplyResult : + sig + type apply_result + + (** The number of Subgoals. *) + val get_num_subgoals : apply_result -> int + + (** Retrieves the subgoals from the apply_result. *) + val get_subgoals : apply_result -> Goal.goal list + + (** Retrieves a subgoal from the apply_result. *) + val get_subgoal : apply_result -> int -> Goal.goal + + (** Convert a model for a subgoal into a model for the original + goal g, that the ApplyResult was obtained from. + #return A model for g *) + val convert_model : apply_result -> int -> Model.model -> Model.model + + (** A string representation of the ApplyResult. *) + val to_string : apply_result -> string + end + + (** A string containing a description of parameters accepted by the tactic. *) + val get_help : tactic -> string + + (** Retrieves parameter descriptions for Tactics. *) + val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs + + (** Apply the tactic to the goal. *) + val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result + + (** The number of supported tactics. *) + val get_num_tactics : context -> int + + (** The names of all supported tactics. *) + val get_tactic_names : context -> string list + + (** Returns a string containing a description of the tactic with the given name. *) + val get_tactic_description : context -> string -> string + + (** Creates a new Tactic. *) + val mk_tactic : context -> string -> tactic + + (** Create a tactic that applies one tactic to a Goal and + then another one to every subgoal produced by the first one. *) + val and_then : context -> tactic -> tactic -> tactic list -> tactic + + (** Create a tactic that first applies one tactic to a Goal and + if it fails then returns the result of another tactic applied to the Goal. *) + val or_else : context -> tactic -> tactic -> tactic + + (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). + + If the tactic does not terminate within the timeout, then it fails. *) + val try_for : context -> tactic -> int -> tactic + + (** Create a tactic that applies one tactic to a given goal if the probe + evaluates to true. + + If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) + val when_ : context -> Probe.probe -> tactic -> tactic + + (** Create a tactic that applies a tactic to a given goal if the probe + evaluates to true and another tactic otherwise. *) + val cond : context -> Probe.probe -> tactic -> tactic -> tactic + + (** Create a tactic that keeps applying one tactic until the goal is not + modified anymore or the maximum number of iterations is reached. *) + val repeat : context -> tactic -> int -> tactic + + (** Create a tactic that just returns the given goal. *) + val skip : context -> tactic + + (** Create a tactic always fails. *) + val fail : context -> tactic + + (** Create a tactic that fails if the probe evaluates to false. *) + val fail_if : context -> Probe.probe -> tactic + + (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) + or trivially unsatisfiable (i.e., contains `false'). *) + val fail_if_not_decided : context -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. *) + val using_params : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies a tactic using the given set of parameters. + Alias for UsingParams*) + val with_ : context -> tactic -> Params.params -> tactic + + (** Create a tactic that applies the given tactics in parallel. *) + val par_or : context -> tactic list -> tactic + + (** Create a tactic that applies a tactic to a given goal and then another tactic + to every subgoal produced by the first one. The subgoals are processed in parallel. *) + val par_and_then : context -> tactic -> tactic -> tactic + + (** Interrupt the execution of a Z3 procedure. + This procedure can be used to interrupt: solvers, simplifiers and tactics. *) + val interrupt : context -> unit +end + +(** Solvers *) +module Solver : +sig + type solver + type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE + + val string_of_status : status -> string + + (** Objects that track statistical information about solvers. *) + module Statistics : + sig + type statistics + + (** Statistical data is organized into pairs of \[Key, Entry\], where every + Entry is either a floating point or integer value. + *) + module Entry : + sig + type statistics_entry + + (** The key of the entry. *) + val get_key : statistics_entry -> string + + (** The int-value of the entry. *) + val get_int : statistics_entry -> int + + (** The float-value of the entry. *) + val get_float : statistics_entry -> float + + (** True if the entry is uint-valued. *) + val is_int : statistics_entry -> bool + + (** True if the entry is double-valued. *) + val is_float : statistics_entry -> bool + + (** The string representation of the the entry's value. *) + val to_string_value : statistics_entry -> string + + (** The string representation of the entry (key and value) *) + val to_string : statistics_entry -> string + end + + (** A string representation of the statistical data. *) + val to_string : statistics -> string + + (** The number of statistical data. *) + val get_size : statistics -> int + + (** The data entries. *) + val get_entries : statistics -> Entry.statistics_entry list + + (** The statistical counters. *) + val get_keys : statistics -> string list + + (** The value of a particular statistical counter. *) + val get : statistics -> string -> Entry.statistics_entry option + end + + (** A string that describes all available solver parameters. *) + val get_help : solver -> string + + (** Sets the solver parameters. *) + val set_parameters : solver -> Params.params -> unit + + (** Retrieves parameter descriptions for solver. *) + val get_param_descrs : solver -> Params.ParamDescrs.param_descrs + + (** The current number of backtracking points (scopes). + {!pop} + {!push} *) + val get_num_scopes : solver -> int + + (** Creates a backtracking point. + {!pop} *) + val push : solver -> unit + + (** Backtracks a number of backtracking points. + Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} + {!push} *) + val pop : solver -> int -> unit + + (** Resets the Solver. + This removes all assertions from the solver. *) + val reset : solver -> unit + + (** Assert a constraint (or multiple) into the solver. *) + val assert_ : solver -> Boolean.bool_expr list -> unit + + (** * Assert multiple constraints (cs) into the solver, and track them (in the + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track_a : solver -> Boolean.bool_expr list -> Boolean.bool_expr list -> unit + + (** * Assert a constraint (c) into the solver, and track it (in the unsat) core + * using the Boolean constant p. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) + val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit + + (** The number of assertions in the solver. *) + val get_num_assertions : solver -> int + + (** The set of asserted formulas. *) + val get_assertions : solver -> Boolean.bool_expr list + + (** Checks whether the assertions in the solver are consistent or not. + + {!Model} + {!get_unsat_core} + {!Proof} *) + val check : solver -> Boolean.bool_expr list -> status + + (** The model of the last Check. + + The result is None if Check was not invoked before, + if its results was not SATISFIABLE, or if model production is not enabled. *) + val get_model : solver -> Model.model option + + (** The proof of the last Check. + + The result is null if Check was not invoked before, + if its results was not UNSATISFIABLE, or if proof production is disabled. *) + val get_proof : solver -> Expr.expr option + + (** The unsat core of the last Check. + + The unsat core is a subset of Assertions + The result is empty if Check was not invoked before, + if its results was not UNSATISFIABLE, or if core production is disabled. *) + val get_unsat_core : solver -> AST.ast list + + (** A brief justification of why the last call to Check returned UNKNOWN. *) + val get_reason_unknown : solver -> string + + (** Solver statistics. *) + val get_statistics : solver -> Statistics.statistics + + (** Creates a new (incremental) solver. + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) + val mk_solver : context -> Symbol.symbol option -> solver + + (** Creates a new (incremental) solver. + {!mk_solver} *) + val mk_solver_s : context -> string -> solver + + (** Creates a new (incremental) solver. *) + val mk_simple_solver : context -> solver + + (** Creates a solver that is implemented using the given tactic. + + The solver supports the commands Push and Pop, but it + will always solve each check from scratch. *) + val mk_solver_t : context -> Tactic.tactic -> solver + + (** A string representation of the solver. *) + val to_string : solver -> string +end + +(** Fixedpoint solving *) +module Fixedpoint : +sig + type fixedpoint + + (** A string that describes all available fixedpoint solver parameters. *) + val get_help : fixedpoint -> string + + (** Sets the fixedpoint solver parameters. *) + val set_params : fixedpoint -> Params.params -> unit + + (** Retrieves parameter descriptions for Fixedpoint solver. *) + val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs + + (** Assert a constraints into the fixedpoint solver. *) + val assert_ : fixedpoint -> Boolean.bool_expr list -> unit + + (** Register predicate as recursive relation. *) + val register_relation : fixedpoint -> FuncDecl.func_decl -> unit + + (** Add rule into the fixedpoint solver. *) + val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit + + (** Add table fact to the fixedpoint solver. *) + val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit + + (** Query the fixedpoint solver. + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. *) + val query : fixedpoint -> Boolean.bool_expr -> Solver.status + + (** Query the fixedpoint solver. + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. *) + val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status + + (** Creates a backtracking point. + {!pop} *) + val push : fixedpoint -> unit + + (** Backtrack one backtracking point. + + Note that an exception is thrown if Pop is called without a corresponding Push + {!push} *) + val pop : fixedpoint -> unit + + (** Update named rule into in the fixedpoint solver. *) + val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit + + (** Retrieve satisfying instance or instances of solver, + or definitions for the recursive predicates that show unsatisfiability. *) + val get_answer : fixedpoint -> Expr.expr option + + (** Retrieve explanation why fixedpoint engine returned status Unknown. *) + val get_reason_unknown : fixedpoint -> string + + (** Retrieve the number of levels explored for a given predicate. *) + val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int + + (** Retrieve the cover of a predicate. *) + val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option + + (** Add property about the predicate. + The property is added at level. *) + val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit + + (** Retrieve internal string representation of fixedpoint object. *) + val to_string : fixedpoint -> string + + (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) + val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit + + (** Convert benchmark given as set of axioms, rules and queries to a string. *) + val to_string_q : fixedpoint -> Boolean.bool_expr list -> string + + (** Retrieve set of rules added to fixedpoint context. *) + val get_rules : fixedpoint -> Boolean.bool_expr list + + (** Retrieve set of assertions added to fixedpoint context. *) + val get_assertions : fixedpoint -> Boolean.bool_expr list + + (** Create a Fixedpoint context. *) + val mk_fixedpoint : context -> fixedpoint +end + +(** Global and context options + + Note: This module contains functions that set parameters/options for context + objects as well as functions that set options that are used globally, across + contexts.*) +module Options : +sig + (** Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -ini? + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + {!get_param_value} *) + val update_param_value : context -> string -> string -> unit + + (** Get a configuration parameter. + + Returns None if the parameter value does not exist. + {!update_param_value} *) + val get_param_value : context -> string -> string option + + (** Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) + val set_print_mode : context -> Z3enums.ast_print_mode -> unit + + (** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) + val toggle_warning_messages : bool -> unit +end + +(** Functions for handling SMT and SMT2 expressions and files *) +module SMT : +sig + (** Convert a benchmark into an SMT-LIB formatted string. + + @return A string representation of the benchmark. *) + val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr list -> Boolean.bool_expr -> string + + (** Parse the given string using the SMT-LIB parser. + + The symbol table of the parser can be initialized using the given sorts and declarations. + The symbols in the arrays in the third and fifth argument + don't need to match the names of the sorts and declarations in the arrays in the fourth + and sixth argument. This is a useful feature since we can use arbitrary names to + reference sorts and declarations. *) + val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit + + (** Parse the given file using the SMT-LIB parser. + {!parse_smtlib_string} *) + val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit + + (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_formulas : context -> int + + (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_formulas : context -> Boolean.bool_expr list + + (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_assumptions : context -> int + + (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_assumptions : context -> Boolean.bool_expr list + + (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_decls : context -> int + + (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_decls : context -> FuncDecl.func_decl list + + (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_num_smtlib_sorts : context -> int + + (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + val get_smtlib_sorts : context -> Sort.sort list + + (** Parse the given string using the SMT-LIB2 parser. + + {!parse_smtlib_string} + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) + val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr + + (** Parse the given file using the SMT-LIB2 parser. + {!parse_smtlib2_string} *) + val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr +end + +(** Set a global (or module) parameter, which is shared by all Z3 contexts. + + When a Z3 module is initialized it will use the value of these parameters + when Z3_params objects are not provided. + The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + The character '.' is a delimiter (more later). + The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + This function can be used to set parameters for a specific Z3 module. + This can be done by using .. + For example: + (set_global_param "pp.decimal" "true") + will set the parameter "decimal" in the module "pp" to true. +*) +val set_global_param : string -> string -> unit + +(** Get a global (or module) parameter. + + Returns None if the parameter does not exist. + The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + This function cannot be invoked simultaneously from different threads without synchronization. + The result string stored in param_value is stored in a shared location. +*) +val get_global_param : string -> string option + +(** Restore the value of all global (and module) parameters. + + This command will not affect already created objects (such as tactics and solvers) + {!set_global_param} +*) +val global_param_reset_all : unit From eea13a087f0caec61ec1ef3235944921a07b97e3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 14:17:35 +0000 Subject: [PATCH 405/507] ML API savegame Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 124 +++++++++++++++++++------------------- src/api/ml/z3.ml | 18 +++--- src/api/ml/z3.mli | 23 ++++--- src/api/ml/z3_rich.ml | 43 +++++++------ src/api/ml/z3_rich.mli | 13 ++-- 5 files changed, 107 insertions(+), 114 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 823a08fe2..f7a4cbc00 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -162,70 +162,68 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ) ; - model_converter_test ctx -(* - // Real num/den test. - RatNum rn = ctx.MkReal(42, 43); - Expr inum = rn.Numerator; - Expr iden = rn.Denominator; - Console.WriteLine("Numerator: " + inum + " Denominator: " + iden); - if (inum.ToString() != "42" || iden.ToString() != "43") - throw new TestFailedException(); - - if (rn.ToDecimalString(3) != "0.976?") - throw new TestFailedException(); - - BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); - BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); - BigIntCheck(ctx, ctx.MkReal("-234234333")); - BigIntCheck(ctx, ctx.MkReal("234234333/2")); - - - string bn = "1234567890987654321"; - - if (ctx.MkInt(bn).BigInteger.ToString() != bn) - throw new TestFailedException(); - - if (ctx.MkBV(bn, 128).BigInteger.ToString() != bn) - throw new TestFailedException(); - - if (ctx.MkBV(bn, 32).BigInteger.ToString() == bn) - throw new TestFailedException(); - - // Error handling test. - try - { - IntExpr i = ctx.MkInt("1/2"); - throw new TestFailedException(); // unreachable - } - catch (Z3Exception) - { - } - } -*) + model_converter_test ctx ; + (* Real num/den test. *) + let rn = Real.mk_numeral_nd ctx 42 43 in + let inum = (get_numerator rn) in + let iden = get_denominator rn in + Printf.printf "Numerator: %s Denominator: %s\n" (Real.to_string inum) (Real.to_string iden) ; + if ((Real.to_string inum) <> "42" or (Real.to_string iden) <> "43") then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ; + if ((to_decimal_string rn 3) <> "0.976?") then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ; + if (to_decimal_string (Real.mk_numeral_s ctx "-1231231232/234234333") 5 <> "-5.25640?") then + raise (TestFailedException "") + else if (to_decimal_string (Real.mk_numeral_s ctx "-123123234234234234231232/234234333") 5 <> "-525641278361333.28170?") then + raise (TestFailedException "") + else if (to_decimal_string (Real.mk_numeral_s ctx "-234234333") 5 <> "-234234333") then + raise (TestFailedException "") + else if (to_decimal_string (Real.mk_numeral_s ctx "234234333/2") 5 <> "117117166.5") then + raise (TestFailedException "") + ; + (* Error handling test. *) + try ( + let i = Integer.mk_numeral_s ctx "1/2" in + raise (TestFailedException "") (* unreachable *) + ) + with Z3native.Exception(_) -> ( + Printf.printf "Exception caught, OK.\n" + ) let _ = - if not (Log.open_ "z3.log") then - raise (TestFailedException "Log couldn't be opened.") - else - ( - Printf.printf "Running Z3 version %s\n" Version.to_string ; - let cfg = [("model", "true"); ("proof", "false")] in - let ctx = (mk_context cfg) in - let is = (Symbol.mk_int ctx 42) in - let ss = (Symbol.mk_string ctx "mySymbol") in - let bs = (Boolean.mk_sort ctx) in - let ints = (Integer.mk_sort ctx) in - let rs = (Real.mk_sort ctx) in - Printf.printf "int symbol: %s\n" (Symbol.to_string is); - Printf.printf "string symbol: %s\n" (Symbol.to_string ss); - Printf.printf "bool sort: %s\n" (Sort.to_string bs); - Printf.printf "int sort: %s\n" (Sort.to_string ints); - Printf.printf "real sort: %s\n" (Sort.to_string rs); - basic_tests ctx ; - Printf.printf "Disposing...\n"; - Gc.full_major () - ); - Printf.printf "Exiting.\n"; + try ( + if not (Log.open_ "z3.log") then + raise (TestFailedException "Log couldn't be opened.") + else + ( + Printf.printf "Running Z3 version %s\n" Version.to_string ; + let cfg = [("model", "true"); ("proof", "false")] in + let ctx = (mk_context cfg) in + let is = (Symbol.mk_int ctx 42) in + let ss = (Symbol.mk_string ctx "mySymbol") in + let bs = (Boolean.mk_sort ctx) in + let ints = (Integer.mk_sort ctx) in + let rs = (Real.mk_sort ctx) in + Printf.printf "int symbol: %s\n" (Symbol.to_string is); + Printf.printf "string symbol: %s\n" (Symbol.to_string ss); + Printf.printf "bool sort: %s\n" (Sort.to_string bs); + Printf.printf "int sort: %s\n" (Sort.to_string ints); + Printf.printf "real sort: %s\n" (Sort.to_string rs); + basic_tests ctx ; + Printf.printf "Disposing...\n"; + Gc.full_major () + ); + Printf.printf "Exiting.\n" ; + exit 0 + ) with Z3native.Exception(msg) -> ( + Printf.printf "Z3 EXCEPTION: %s\n" msg ; + exit 1 + ) ;; diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 0676f1a39..e62732924 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -11,7 +11,6 @@ open Z3enums let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) - (* Internal types *) type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } type context = z3_native_context @@ -21,7 +20,6 @@ type z3_native_object = { mutable m_n_obj : Z3native.ptr ; inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - (** Internal stuff *) module Internal = @@ -1455,11 +1453,11 @@ struct let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = Expr.mk_const ctx name (mk_sort ctx) - let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_mod ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) @@ -1467,10 +1465,10 @@ struct let mk_rem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) - let mk_int_numeral_s ( ctx : context ) ( v : string ) = + let mk_numeral_s ( ctx : context ) ( v : string ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx))) - let mk_int_numeral_i ( ctx : context ) ( v : int ) = + let mk_numeral_i ( ctx : context ) ( v : int ) = expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno (mk_sort ctx))) let mk_int2real ( ctx : context ) ( t : expr ) = @@ -1496,11 +1494,11 @@ struct let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = Expr.mk_const ctx name (mk_sort ctx) - let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = if (den == 0) then diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 908b3023d..d7e179cd4 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -30,7 +30,6 @@ type context (** Create a context object *) val mk_context : (string * string) list -> context - (** Interaction logging for Z3 Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) @@ -1117,10 +1116,10 @@ sig end (** Functions to manipulate arithmetic expressions *) -module rec Arithmetic : +module Arithmetic : sig (** Integer Arithmetic *) - module rec Integer : + module Integer : sig (** Create a new integer sort. *) val mk_sort : context -> Sort.sort @@ -1132,10 +1131,10 @@ sig val to_string : Expr.expr -> string (** Creates an integer constant. *) - val mk_int_const : context -> Symbol.symbol -> Expr.expr + val mk_const : context -> Symbol.symbol -> Expr.expr (** Creates an integer constant. *) - val mk_int_const_s : context -> string -> Expr.expr + val mk_const_s : context -> string -> Expr.expr (** Create an expression representing t1 mod t2. The arguments must have int type. *) @@ -1146,11 +1145,11 @@ sig val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer numeral. *) - val mk_int_numeral_s : context -> string -> Expr.expr + val mk_numeral_s : context -> string -> Expr.expr (** Create an integer numeral. @return A Term with the given value and sort Integer *) - val mk_int_numeral_i : context -> int -> Expr.expr + val mk_numeral_i : context -> int -> Expr.expr (** Coerce an integer to a real. @@ -1174,7 +1173,7 @@ sig end (** Real Arithmetic *) - and Real : + module Real : sig (** Create a real sort. *) val mk_sort : context -> Sort.sort @@ -1193,10 +1192,10 @@ sig val to_string : Expr.expr-> string (** Creates a real constant. *) - val mk_real_const : context -> Symbol.symbol -> Expr.expr + val mk_const : context -> Symbol.symbol -> Expr.expr (** Creates a real constant. *) - val mk_real_const_s : context -> string -> Expr.expr + val mk_const_s : context -> string -> Expr.expr (** Create a real numeral from a fraction. @return A Term with rational value and sort Real @@ -1222,7 +1221,7 @@ sig end (** Algebraic Numbers *) - and AlgebraicNumber : + module AlgebraicNumber : sig (** Return a upper bound for a given real algebraic number. The interval isolating the number is smaller than 1/10^precision. @@ -1339,7 +1338,7 @@ sig end (** Functions to manipulate bit-vector expressions *) -and BitVector : +module BitVector : sig (** Create a new bit-vector sort. *) val mk_sort : context -> int -> Sort.sort diff --git a/src/api/ml/z3_rich.ml b/src/api/ml/z3_rich.ml index 052ca5e22..0c2f95b6b 100644 --- a/src/api/ml/z3_rich.ml +++ b/src/api/ml/z3_rich.ml @@ -1,4 +1,4 @@ -(** +\(** The Z3 ML/Ocaml Interface. Copyright (C) 2012 Microsoft Corporation @@ -11,7 +11,6 @@ open Z3enums let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) - (* Internal types *) type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } type context = z3_native_context @@ -1679,12 +1678,12 @@ sig val mk_sort : context -> int_sort val get_int : int_num -> int val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr + val mk_const : context -> Symbol.symbol -> int_expr + val mk_const_s : context -> string -> int_expr val mk_mod : context -> int_expr -> int_expr -> int_expr val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num + val mk_numeral_s : context -> string -> int_num + val mk_numeral_i : context -> int -> int_num val mk_int2real : context -> int_expr -> Real.real_expr val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr end @@ -1709,8 +1708,8 @@ sig val get_denominator : rat_num -> Integer.int_num val to_decimal_string : rat_num -> int -> string val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr + val mk_const : context -> Symbol.symbol -> real_expr + val mk_const_s : context -> string -> real_expr val mk_numeral_nd : context -> int -> int -> rat_num val mk_numeral_s : context -> string -> rat_num val mk_numeral_i : context -> int -> rat_num @@ -1816,12 +1815,12 @@ end = struct val mk_sort : context -> int_sort val get_int : int_num -> int val to_string : int_num -> string - val mk_int_const : context -> Symbol.symbol -> int_expr - val mk_int_const_s : context -> string -> int_expr + val mk_const : context -> Symbol.symbol -> int_expr + val mk_const_s : context -> string -> int_expr val mk_mod : context -> int_expr -> int_expr -> int_expr val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_int_numeral_s : context -> string -> int_num - val mk_int_numeral_i : context -> int -> int_num + val mk_numeral_s : context -> string -> int_num + val mk_numeral_i : context -> int -> int_num val mk_int2real : context -> int_expr -> Real.real_expr val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr end = struct @@ -1884,11 +1883,11 @@ end = struct let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - let mk_int_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) - let mk_int_const_s ( ctx : context ) ( name : string ) = - mk_int_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) @@ -1896,10 +1895,10 @@ end = struct let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) - let mk_int_numeral_s ( ctx : context ) ( v : string ) = + let mk_numeral_s ( ctx : context ) ( v : string ) = int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - let mk_int_numeral_i ( ctx : context ) ( v : int ) = + let mk_numeral_i ( ctx : context ) ( v : int ) = int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) let mk_int2real ( ctx : context ) ( t : int_expr ) = @@ -1930,8 +1929,8 @@ end = struct val get_denominator : rat_num -> Integer.int_num val to_decimal_string : rat_num -> int -> string val to_string : rat_num -> string - val mk_real_const : context -> Symbol.symbol -> real_expr - val mk_real_const_s : context -> string -> real_expr + val mk_const : context -> Symbol.symbol -> real_expr + val mk_const_s : context -> string -> real_expr val mk_numeral_nd : context -> int -> int -> rat_num val mk_numeral_s : context -> string -> rat_num val mk_numeral_i : context -> int -> rat_num @@ -2002,11 +2001,11 @@ end = struct let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - let mk_real_const ( ctx : context ) ( name : Symbol.symbol ) = + let mk_const ( ctx : context ) ( name : Symbol.symbol ) = RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) - let mk_real_const_s ( ctx : context ) ( name : string ) = - mk_real_const ctx (Symbol.mk_string ctx name) + let mk_const_s ( ctx : context ) ( name : string ) = + mk_const ctx (Symbol.mk_string ctx name) let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = if (den == 0) then diff --git a/src/api/ml/z3_rich.mli b/src/api/ml/z3_rich.mli index 8b6681e11..f2ecd326d 100644 --- a/src/api/ml/z3_rich.mli +++ b/src/api/ml/z3_rich.mli @@ -34,7 +34,6 @@ type context (** Create a context object *) val mk_context : (string * string) list -> context - (** Interaction logging for Z3 Note that this is a global, static log and if multiple Context objects are created, it logs the interaction with all of them. *) @@ -1219,10 +1218,10 @@ sig val to_string : int_num -> string (** Creates an integer constant. *) - val mk_int_const : context -> Symbol.symbol -> int_expr + val mk_const : context -> Symbol.symbol -> int_expr (** Creates an integer constant. *) - val mk_int_const_s : context -> string -> int_expr + val mk_const_s : context -> string -> int_expr (** Create an expression representing t1 mod t2. The arguments must have int type. *) @@ -1233,11 +1232,11 @@ sig val mk_rem : context -> int_expr -> int_expr -> int_expr (** Create an integer numeral. *) - val mk_int_numeral_s : context -> string -> int_num + val mk_numeral_s : context -> string -> int_num (** Create an integer numeral. @return A Term with the given value and sort Integer *) - val mk_int_numeral_i : context -> int -> int_num + val mk_numeral_i : context -> int -> int_num (** Coerce an integer to a real. @@ -1291,10 +1290,10 @@ sig val to_string : rat_num -> string (** Creates a real constant. *) - val mk_real_const : context -> Symbol.symbol -> real_expr + val mk_const : context -> Symbol.symbol -> real_expr (** Creates a real constant. *) - val mk_real_const_s : context -> string -> real_expr + val mk_const_s : context -> string -> real_expr (** Create a real numeral from a fraction. @return A Term with rational value and sort Real From 050629536ab7e195bb1fe076e77e8c4043d563bb Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 21 Feb 2013 18:53:29 +0000 Subject: [PATCH 406/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- examples/ml/Makefile | 4 ++-- scripts/update_api.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/ml/Makefile b/examples/ml/Makefile index a7f8e6ee0..818f0cacc 100644 --- a/examples/ml/Makefile +++ b/examples/ml/Makefile @@ -3,5 +3,5 @@ # in the top-level build directory. all: - OCAML_COMPAT=c C:/ocamlw32/bin/ocamlc -g -annot -o ml_example.byte -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cma ml_example.ml - C:/ocamlw32/bin/ocamlopt -g -annot -o ml_example -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cmxa ml_example.ml + source /cygdrive/c/cwinter/.msenv32 ; OCAML_COMPAT=c C:/ocamlw32/bin/ocamlc -g -custom -cclib '-L../../bld_dbg -lz3' -annot -o ml_example.byte -I ../../bld_dbg/api/ml z3.cma ml_example.ml + source /cygdrive/c/cwinter/.msenv32 ; C:/ocamlw32/bin/ocamlopt -g -annot -o ml_example -cclib '-L../../bld_dbg -lz3' -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cmxa ml_example.ml diff --git a/scripts/update_api.py b/scripts/update_api.py index a0b7e6250..44d871348 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1339,9 +1339,10 @@ def mk_ml(): ml_wrapper.write(' // upon errors, but the actual error handling is done by throwing exceptions in the\n') ml_wrapper.write(' // wrappers below.\n') ml_wrapper.write('}\n\n') - ml_wrapper.write('void n_set_internal_error_handler(Z3_context c)\n') + ml_wrapper.write('void n_set_internal_error_handler(value a0)\n') ml_wrapper.write('{\n') - ml_wrapper.write(' Z3_set_error_handler(c, MLErrorHandler);\n') + ml_wrapper.write(' Z3_context _a0 = * (Z3_context*) Data_custom_val(a0);\n') + ml_wrapper.write(' Z3_set_error_handler(_a0, MLErrorHandler);\n') ml_wrapper.write('}\n\n') for name, result, params in _dotnet_decls: ip = inparams(params) From c1e29dabe7858fbbf9eb112028c010d18f4b666c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 26 Feb 2013 19:45:45 +0000 Subject: [PATCH 407/507] ML API: renamed assert_ to add Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 24 ++++++++++++------------ src/api/ml/z3.ml | 8 ++++---- src/api/ml/z3.mli | 8 ++++---- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index f7a4cbc00..c9ed1d948 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -29,11 +29,11 @@ let model_converter_test ( ctx : context ) = let xr = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Real.mk_sort ctx)) in let yr = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Real.mk_sort ctx)) in let g4 = (mk_goal ctx true false false ) in - (Goal.assert_ g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; - (Goal.assert_ g4 [ (mk_eq ctx + (Goal.add g4 [ (mk_gt ctx xr (Real.mk_numeral_nd ctx 10 1)) ]) ; + (Goal.add g4 [ (mk_eq ctx yr (Arithmetic.mk_add ctx [ xr; (Real.mk_numeral_nd ctx 1 1) ])) ]) ; - (Goal.assert_ g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; + (Goal.add g4 [ (mk_gt ctx yr (Real.mk_numeral_nd ctx 1 1)) ]) ; ( let ar = (Tactic.apply (mk_tactic ctx "simplify") g4 None) in if ((get_num_subgoals ar) == 1 && @@ -53,7 +53,7 @@ let model_converter_test ( ctx : context ) = Printf.printf "Test passed.\n" ; let solver = (mk_solver ctx None) in - let f e = (Solver.assert_ solver [ e ]) in + let f e = (Solver.add solver [ e ]) in ignore (List.map f (get_formulas (get_subgoal ar 0))) ; let q = (check solver []) in if q != SATISFIABLE then @@ -88,12 +88,12 @@ let basic_tests ( ctx : context ) = let trivial_eq = (mk_eq ctx fapp fapp) in let nontrivial_eq = (mk_eq ctx fapp fapp2) in let g = (mk_goal ctx true false false) in - (Goal.assert_ g [ trivial_eq ]) ; - (Goal.assert_ g [ nontrivial_eq ]) ; + (Goal.add g [ trivial_eq ]) ; + (Goal.add g [ nontrivial_eq ]) ; Printf.printf "%s\n" ("Goal: " ^ (Goal.to_string g)) ; ( let solver = (mk_solver ctx None) in - (List.iter (fun a -> (Solver.assert_ solver [ a ])) (get_formulas g)) ; + (List.iter (fun a -> (Solver.add solver [ a ])) (get_formulas g)) ; if (check solver []) != SATISFIABLE then raise (TestFailedException "") else @@ -116,7 +116,7 @@ let basic_tests ( ctx : context ) = else Printf.printf "Test passed.\n" ); - (Goal.assert_ g [ (mk_eq ctx + (Goal.add g [ (mk_eq ctx (mk_numeral_int ctx 1 (BitVector.mk_sort ctx 32)) (mk_numeral_int ctx 2 (BitVector.mk_sort ctx 32))) ] ) ; @@ -139,7 +139,7 @@ let basic_tests ( ctx : context ) = ); ( let g2 = (mk_goal ctx true true false) in - (Goal.assert_ g2 [ (Boolean.mk_false ctx) ]) ; + (Goal.add g2 [ (Boolean.mk_false ctx) ]) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g2 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then @@ -151,10 +151,10 @@ let basic_tests ( ctx : context ) = let g3 = (mk_goal ctx true true false) in let xc = (Expr.mk_const ctx (Symbol.mk_string ctx "x") (Integer.mk_sort ctx)) in let yc = (Expr.mk_const ctx (Symbol.mk_string ctx "y") (Integer.mk_sort ctx)) in - (Goal.assert_ g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; - (Goal.assert_ g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; + (Goal.add g3 [ (mk_eq ctx xc (mk_numeral_int ctx 1 (Integer.mk_sort ctx))) ]) ; + (Goal.add g3 [ (mk_eq ctx yc (mk_numeral_int ctx 2 (Integer.mk_sort ctx))) ]) ; let constr = (mk_eq ctx xc yc) in - (Goal.assert_ g3 [ constr ] ) ; + (Goal.add g3 [ constr ] ) ; let ar = (Tactic.apply (mk_tactic ctx "smt") g3 None) in if ((get_num_subgoals ar) == 1 && (not (is_decided_unsat (get_subgoal ar 0)))) then diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index e62732924..8eb5427bb 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1850,7 +1850,7 @@ struct let is_garbage ( x : goal ) = (get_precision x) == GOAL_UNDER_OVER - let assert_ ( x : goal ) ( constraints : expr list ) = + let add ( x : goal ) ( constraints : expr list ) = let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e) in ignore (List.map f constraints) ; () @@ -2370,11 +2370,11 @@ struct let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - let assert_ ( x : solver ) ( constraints : expr list ) = + let add ( x : solver ) ( constraints : expr list ) = let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) - let assert_and_track_a ( x : solver ) ( cs : expr list ) ( ps : expr list ) = + let assert_and_track_l ( x : solver ) ( cs : expr list ) ( ps : expr list ) = if ((List.length cs) != (List.length ps)) then raise (Z3native.Exception "Argument size mismatch") else @@ -2473,7 +2473,7 @@ struct let get_param_descrs ( x : fixedpoint ) = Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - let assert_ ( x : fixedpoint ) ( constraints : expr list ) = + let add ( x : fixedpoint ) ( constraints : expr list ) = let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Expr.gno e)) in ignore (List.map f constraints) ; () diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index d7e179cd4..cde99a90d 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -2221,7 +2221,7 @@ sig val is_garbage : goal -> bool (** Adds the constraints to the given goal. *) - val assert_ : goal -> Expr.expr list -> unit + val add : goal -> Expr.expr list -> unit (** Indicates whether the goal contains `false'. *) val is_inconsistent : goal -> bool @@ -2648,7 +2648,7 @@ sig val reset : solver -> unit (** Assert a constraint (or multiple) into the solver. *) - val assert_ : solver -> Expr.expr list -> unit + val add : solver -> Expr.expr list -> unit (** * Assert multiple constraints (cs) into the solver, and track them (in the * unsat) core @@ -2661,7 +2661,7 @@ sig * of the Boolean variables provided using {!assert_and_track} * and the Boolean literals * provided using {!check} with assumptions. *) - val assert_and_track_a : solver -> Expr.expr list -> Expr.expr list -> unit + val assert_and_track_l : solver -> Expr.expr list -> Expr.expr list -> unit (** * Assert a constraint (c) into the solver, and track it (in the unsat) core * using the Boolean constant p. @@ -2752,7 +2752,7 @@ sig val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs (** Assert a constraints into the fixedpoint solver. *) - val assert_ : fixedpoint -> Expr.expr list -> unit + val add : fixedpoint -> Expr.expr list -> unit (** Register predicate as recursive relation. *) val register_relation : fixedpoint -> FuncDecl.func_decl -> unit From aaa835484f5db085b3e8bac7df6e15ba7bd7f0b3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 3 Jun 2013 18:51:40 +0100 Subject: [PATCH 408/507] Updates to ML API. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 43 ++++++++-------- src/api/ml/z3.mli | 126 ++++++++++++++++++++++++---------------------- 2 files changed, 86 insertions(+), 83 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8eb5427bb..4a8fbaa0a 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -323,8 +323,8 @@ struct else ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + let unwrap_ast ( x : ast ) = (z3obj_gno x) let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr - let unwrap_ast ( x : ast ) = (z3obj_gno x) end open AST @@ -678,6 +678,19 @@ end = struct res let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) + + let update_param_value ( ctx : context ) ( id : string) ( value : string )= + Z3native.update_param_value (context_gno ctx) id value + + let get_param_value ( ctx : context ) ( id : string ) = + let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in + if not r then + None + else + Some v + + let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = + Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) end (** General expressions (terms) *) @@ -1106,7 +1119,7 @@ struct end -module Array_ = +module Array = struct let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) @@ -1389,7 +1402,7 @@ struct end -module List_ = +module List = struct let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in @@ -2558,26 +2571,6 @@ struct let mk_fixedpoint ( ctx : context ) = create ctx end -module Options = -struct - - let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value (context_gno ctx) id value - - let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in - if not r then - None - else - Some v - - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) - - let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages enabled -end - module SMT = struct @@ -2692,3 +2685,7 @@ let get_global_param ( id : string ) = let global_param_reset_all = Z3native.global_param_reset_all + +let toggle_warning_messages ( enabled: bool ) = + Z3native.toggle_warning_messages enabled + diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index cde99a90d..1c4c4e922 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -27,7 +27,20 @@ *) type context -(** Create a context object *) +(** Create a context object + The following parameters can be set: + + - proof (Boolean) Enable proof generation + - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting + - trace (Boolean) Tracing support for VCC + - trace_file_name (String) Trace out file for VCC traces + - timeout (unsigned) default timeout (in milliseconds) used for solvers + - well_sorted_check type checker + - auto_config use heuristics to automatically select solver and configure it + - model model generation for solvers, this parameter can be overwritten when creating a solver + - model_validate validate models produced by solvers + - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver +*) val mk_context : (string * string) list -> context (** Interaction logging for Z3 @@ -220,15 +233,6 @@ sig @return A copy of the AST which is associated with the other context. *) val translate : ast -> context -> ast - (** Wraps an AST. - - This function is used for transitions between native and - managed objects. Note that the native ast that is passed must be a - native object obtained from Z3 (e.g., through {!unwrap_ast}) - and that it must have a correct reference count (see e.g., - Z3native.inc_ref). *) - val wrap_ast : context -> Z3native.z3_ast -> ast - (** Unwraps an AST. This function is used for transitions between native and managed objects. It returns the native pointer to the AST. Note that @@ -238,6 +242,15 @@ sig Z3native.inc_ref). {!wrap_ast} *) val unwrap_ast : ast -> Z3native.ptr + + (** Wraps an AST. + + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) + and that it must have a correct reference count (see e.g., + Z3native.inc_ref). *) + val wrap_ast : context -> Z3native.z3_ast -> ast end (** The Sort module implements type information for ASTs *) @@ -432,6 +445,36 @@ sig (** A string representation of the parameter set. *) val to_string : params -> string + + (** Update a mutable configuration parameter. + + The list of all configuration parameters can be obtained using the Z3 executable: + z3.exe -p + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. + {!get_param_value} *) + val update_param_value : context -> string -> string -> unit + + (** Get a configuration parameter. + + Returns None if the parameter value does not exist. + {!update_param_value} *) + val get_param_value : context -> string -> string option + + (** Selects the format used for pretty-printing expressions. + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) + val set_print_mode : context -> Z3enums.ast_print_mode -> unit end (** General Expressions (terms) *) @@ -737,7 +780,7 @@ sig end (** Functions to manipulate Array expressions *) -module Array_ : +module Array : sig (** Create a new array sort. *) val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort @@ -790,7 +833,7 @@ sig The node a must have an array sort [domain -> range], and i must have the sort domain. The sort of the result is range. - {!Array_.mk_sort} + {!Array.mk_sort} {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -806,7 +849,7 @@ sig on all indices except for i, where it maps to v (and the select of a with respect to i may be a different value). - {!Array_.mk_sort} + {!Array.mk_sort} {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr @@ -814,7 +857,7 @@ sig The resulting term is an array, such that a selecton an arbitrary index produces the value v. - {!Array_.mk_sort} + {!Array.mk_sort} {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr @@ -823,7 +866,7 @@ sig Eeach element of args must be of an array sort [domain_i -> range_i]. The function declaration f must have type range_1 .. range_n -> range. v must have sort range. The sort of the result is [domain_i -> range]. - {!Array_.mk_sort} + {!Array.mk_sort} {!mk_select} {!mk_store} *) val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr @@ -1069,7 +1112,7 @@ sig end (** Functions to manipulate List expressions *) -module List_ : +module List : sig (** Create a new list sort. *) val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort @@ -2824,50 +2867,6 @@ sig val mk_fixedpoint : context -> fixedpoint end -(** Global and context options - - Note: This module contains functions that set parameters/options for context - objects as well as functions that set options that are used globally, across - contexts.*) -module Options : -sig - (** Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - {!get_param_value} *) - val update_param_value : context -> string -> string -> unit - - (** Get a configuration parameter. - - Returns None if the parameter value does not exist. - {!update_param_value} *) - val get_param_value : context -> string -> string option - - (** Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - {!AST.to_string} - {!Quantifier.Pattern.to_string} - {!FuncDecl.to_string} - {!Sort.to_string} *) - val set_print_mode : context -> Z3enums.ast_print_mode -> unit - - (** Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. *) - val toggle_warning_messages : bool -> unit -end - (** Functions for handling SMT and SMT2 expressions and files *) module SMT : sig @@ -2954,4 +2953,11 @@ val get_global_param : string -> string option This command will not affect already created objects (such as tactics and solvers) {!set_global_param} *) + val global_param_reset_all : unit + + (** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) + val toggle_warning_messages : bool -> unit From b81bae76b2ae554e4521cf65c5b71b4e3cfc0b58 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 3 Jun 2013 19:12:00 +0100 Subject: [PATCH 409/507] ML API: refactoring Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 74 +++++++++++------------------ src/api/ml/z3.mli | 115 +++++++++++++++++++--------------------------- 2 files changed, 73 insertions(+), 116 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 4a8fbaa0a..081433f1f 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -7,6 +7,8 @@ open Z3enums +exception Error = Z3native.Exception + (* Some helpers. *) let null = Z3native.mk_null() let is_null o = (Z3native.is_null o) @@ -283,7 +285,7 @@ struct Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) end - let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) + let hash ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) @@ -304,7 +306,7 @@ struct let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - let ( = ) ( a : ast ) ( b : ast ) = (a == b) || + let equal ( a : ast ) ( b : ast ) = (a == b) || if (z3obj_gnc a) != (z3obj_gnc b) then false else @@ -314,8 +316,6 @@ struct if (get_id a) < (get_id b) then -1 else if (get_id a) > (get_id b) then 1 else 0 - - let ( < ) (a : ast) (b : ast) = (compare a b) let translate ( x : ast ) ( to_ctx : context ) = if (z3obj_gnc x) == (context_gno to_ctx) then @@ -361,7 +361,7 @@ struct let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in Array.of_list (List.map f a) - let ( = ) : sort -> sort -> bool = fun a b -> + let equal : sort -> sort -> bool = fun a b -> (a == b) || if (gnc a) != (gnc b) then false @@ -424,7 +424,7 @@ sig val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl val mk_const_decl_s : context -> string -> Sort.sort -> func_decl val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - val ( = ) : func_decl -> func_decl -> bool + val equal : func_decl -> func_decl -> bool val to_string : func_decl -> string val get_id : func_decl -> int val get_arity : func_decl -> int @@ -498,7 +498,7 @@ end = struct let get_float ( x : parameter ) = match x with | P_Dbl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a double") + | _ -> raise (Z3native.Exception "parameter is not a float") let get_symbol ( x : parameter ) = match x with @@ -545,7 +545,7 @@ end = struct create_pdr ctx prefix [] range - let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || + let equal ( a : func_decl ) ( b : func_decl ) = (a == b) || if (gnc a) != (gnc b) then false else @@ -605,12 +605,8 @@ sig end val add_bool : params -> Symbol.symbol -> bool -> unit val add_int : params -> Symbol.symbol -> int -> unit - val add_double : params -> Symbol.symbol -> float -> unit + val add_float : params -> Symbol.symbol -> float -> unit val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - val add_s_bool : params -> string -> bool -> unit - val add_s_int : params -> string -> int -> unit - val add_s_double : params -> string -> float -> unit - val add_s_symbol : params -> string -> Symbol.symbol -> unit val mk_params : context -> params val to_string : params -> string end = struct @@ -650,24 +646,12 @@ end = struct let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = + let add_float ( x : params ) ( name : Symbol.symbol ) ( value : float ) = Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = - add_bool x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_int ( x : params) ( name : string ) ( value : int ) = - add_int x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_double ( x : params ) ( name : string ) ( value : float ) = - add_double x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = - add_symbol x (Symbol.mk_string (z3obj_gc x) name) value - let mk_params ( ctx : context ) = let res : params = { m_ctx = ctx ; m_n_obj = null ; @@ -734,8 +718,6 @@ sig val is_xor : expr -> bool val is_not : expr -> bool val is_implies : expr -> bool - val is_label : expr -> bool - val is_label_lit : expr -> bool val is_oeq : expr -> bool val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val mk_const_s : context -> string -> Sort.sort -> expr @@ -857,8 +839,6 @@ end = struct let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = @@ -1530,20 +1510,20 @@ struct let mk_real2int ( ctx : context ) ( t : expr ) = (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (Expr.gno t))) - end - module AlgebraicNumber = - struct - let to_upper ( x : expr ) ( precision : int ) = - expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) - - let to_lower ( x : expr ) precision = - expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) - - let to_decimal_string ( x : expr ) ( precision : int ) = - Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + module AlgebraicNumber = + struct + let to_upper ( x : expr ) ( precision : int ) = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_upper (Expr.gnc x) (Expr.gno x) precision) + + let to_lower ( x : expr ) precision = + expr_of_ptr (Expr.gc x) (Z3native.get_algebraic_number_lower (Expr.gnc x) (Expr.gno x) precision) + + let to_decimal_string ( x : expr ) ( precision : int ) = + Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision + + let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + end end let is_int ( x : expr ) = @@ -2052,13 +2032,11 @@ struct let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in (mk_list f n_funcs) @ (mk_list g n_consts) - - exception ModelEvaluationFailedException of string - + let eval ( x : model ) ( t : expr ) ( completion : bool ) = let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then - raise (ModelEvaluationFailedException "evaluation failed") + None else expr_of_ptr (z3obj_gc x) v @@ -2353,7 +2331,7 @@ struct if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_sd k (Z3native.stats_get_float_value (z3obj_gnc x) (z3obj_gno x) i)) ) in mk_list f n diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 1c4c4e922..570ff8717 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -5,6 +5,11 @@ @author CM Wintersteiger (cwinter) 2012-12-17 *) +(** General Z3 exceptions + + Many functions in this API may throw an exception; if they do, it is this one.*) +exception Error + (** Context objects. Most interactions with Z3 are interpreted in some context; many users will only @@ -188,7 +193,7 @@ sig (** The AST's hash code. @return A hash code *) - val get_hash_code : ast -> int + val hash : ast -> int (** A unique identifier for the AST (unique among all ASTs). *) val get_id : ast -> int @@ -220,15 +225,12 @@ sig (** Comparison operator. @return True if the two ast's are from the same context and represent the same sort; false otherwise. *) - val ( = ) : ast -> ast -> bool + val equal : ast -> ast -> bool (** Object Comparison. @return Negative if the first ast should be sorted before the second, positive if after else zero. *) val compare : ast -> ast -> int - (** Operator < *) - val ( < ) : ast -> ast -> int - (** Translates (copies) the AST to another context. @return A copy of the AST which is associated with the other context. *) val translate : ast -> context -> ast @@ -263,7 +265,7 @@ sig (** Comparison operator. @return True if the two sorts are from the same context and represent the same sort; false otherwise. *) - val ( = ) : sort -> sort -> bool + val equal : sort -> sort -> bool (** Returns a unique identifier for the sort. *) val get_id : sort -> int @@ -310,7 +312,7 @@ sig (** The int value of the parameter.*) val get_int : parameter -> int - (** The double value of the parameter.*) + (** The float value of the parameter.*) val get_float : parameter -> float (** The Symbol.Symbol value of the parameter.*) @@ -351,7 +353,7 @@ sig (** Comparison operator. @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) - val ( = ) : func_decl -> func_decl -> bool + val equal : func_decl -> func_decl -> bool (** A string representations of the function declaration. *) val to_string : func_decl -> string @@ -423,23 +425,11 @@ sig val add_int : params -> Symbol.symbol -> int -> unit (** Adds a parameter setting. *) - val add_double : params -> Symbol.symbol -> float -> unit + val add_float : params -> Symbol.symbol -> float -> unit (** Adds a parameter setting. *) val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - (** Adds a parameter setting. *) - val add_s_bool : params -> string -> bool -> unit - - (** Adds a parameter setting. *) - val add_s_int : params -> string -> int -> unit - - (** Adds a parameter setting. *) - val add_s_double : params -> string -> float -> unit - - (** Adds a parameter setting. *) - val add_s_symbol : params -> string -> Symbol.symbol -> unit - (** Creates a new parameter set *) val mk_params : context -> params @@ -583,16 +573,7 @@ sig (** Indicates whether the term is an implication *) val is_implies : Expr.expr -> bool - - (** Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) - val is_label : Expr.expr -> bool - - (** Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) - val is_label_lit : Expr.expr -> bool - + (** Indicates whether the term is a binary equivalence modulo namings. This binary predicate is used in proof terms. It captures equisatisfiability and equivalence modulo renamings. *) @@ -1261,29 +1242,29 @@ sig The semantics of this function follows the SMT-LIB standard for the function to_int. The argument must be of real sort. *) val mk_real2int : context -> Expr.expr -> Expr.expr - end - - (** Algebraic Numbers *) - module AlgebraicNumber : - sig - (** Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_upper : Expr.expr -> int -> Expr.expr - - (** Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_lower : Expr.expr -> int -> Expr.expr - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as the int argument provided.*) - val to_decimal_string : Expr.expr -> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string + + (** Algebraic Numbers *) + module AlgebraicNumber : + sig + (** Return a upper bound for a given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_upper : Expr.expr -> int -> Expr.expr + + (** Return a lower bound for the given real algebraic number. + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) + val to_lower : Expr.expr -> int -> Expr.expr + + (** Returns a string representation in decimal notation. + The result has at most as many decimal places as the int argument provided.*) + val to_decimal_string : Expr.expr -> int -> string + + (** Returns a string representation of the numeral. *) + val to_string : Expr.expr -> string + end end (** Indicates whether the term is of integer sort. *) @@ -2389,19 +2370,16 @@ sig (** All symbols that have an interpretation in the model. *) val get_decls : model -> FuncDecl.func_decl list - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - (** Evaluates an expression in the current model. This function may fail if the argument contains quantifiers, is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. In this case a ModelEvaluationFailedException is thrown. *) - val eval : model -> Expr.expr -> bool -> Expr.expr + val eval : model -> Expr.expr -> bool -> Expr.expr option (** Alias for eval. *) - val evaluate : model -> Expr.expr -> bool -> Expr.expr + val evaluate : model -> Expr.expr -> bool -> Expr.expr option (** The number of uninterpreted sorts that the model has an interpretation for. *) val get_num_sorts : model -> int @@ -2438,7 +2416,7 @@ sig type probe (** Execute the probe over the goal. - A probe always produce a double value. + A probe always produce a float value. "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) val apply : probe -> Goal.goal -> float @@ -2637,7 +2615,7 @@ sig (** True if the entry is uint-valued. *) val is_int : statistics_entry -> bool - (** True if the entry is double-valued. *) + (** True if the entry is float-valued. *) val is_float : statistics_entry -> bool (** The string representation of the the entry's value. *) @@ -2954,10 +2932,11 @@ val get_global_param : string -> string option {!set_global_param} *) -val global_param_reset_all : unit - - (** Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. *) - val toggle_warning_messages : bool -> unit +val global_param_reset_all : unit -> unit + +(** Enable/disable printing of warning messages to the console. + + Note that this function is static and effects the behaviour of + all contexts globally. *) +val toggle_warning_messages : bool -> unit + From e40b69d97f2f75477c671cbb7551f3f7272ff224 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 4 Jun 2013 16:46:47 +0100 Subject: [PATCH 410/507] ML API: removing rich layer for now. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3_rich.ml | 3399 ---------------------------------------- src/api/ml/z3_rich.mli | 3071 ------------------------------------ 2 files changed, 6470 deletions(-) delete mode 100644 src/api/ml/z3_rich.ml delete mode 100644 src/api/ml/z3_rich.mli diff --git a/src/api/ml/z3_rich.ml b/src/api/ml/z3_rich.ml deleted file mode 100644 index 0c2f95b6b..000000000 --- a/src/api/ml/z3_rich.ml +++ /dev/null @@ -1,3399 +0,0 @@ -\(** - The Z3 ML/Ocaml Interface. - - Copyright (C) 2012 Microsoft Corporation - @author CM Wintersteiger (cwinter) 2012-12-17 -*) - -open Z3enums - -(* Some helpers. *) -let null = Z3native.mk_null() -let is_null o = (Z3native.is_null o) - -(* Internal types *) -type z3_native_context = { m_n_ctx : Z3native.z3_context; m_n_obj_cnt: int; } -type context = z3_native_context - -type z3_native_object = { - m_ctx : context ; - mutable m_n_obj : Z3native.ptr ; - inc_ref : Z3native.z3_context -> Z3native.ptr -> unit; - dec_ref : Z3native.z3_context -> Z3native.ptr -> unit } - - -(** Internal stuff *) -module Internal = -struct - let dispose_context ctx = - if ctx.m_n_obj_cnt == 0 then ( - (Z3native.del_context ctx.m_n_ctx) - ) else ( - Printf.printf "ERROR: NOT DISPOSING CONTEXT (because it still has %d objects alive)\n" ctx.m_n_obj_cnt; - ) - - let create_context settings = - let cfg = Z3native.mk_config in - let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in - (List.iter f settings) ; - let v = Z3native.mk_context_rc cfg in - Z3native.del_config(cfg) ; - Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; - Z3native.set_internal_error_handler v ; - let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in - let f = fun o -> dispose_context o in - Gc.finalise f res; - res - - let context_add1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt + 1) - let context_sub1 ctx = ignore (ctx.m_n_obj_cnt = ctx.m_n_obj_cnt - 1) - let context_gno ctx = ctx.m_n_ctx - - - let z3obj_gc o = o.m_ctx - let z3obj_gnc o = (context_gno o.m_ctx) - - let z3obj_gno o = o.m_n_obj - let z3obj_sno o ctx no = - (context_add1 ctx) ; - o.inc_ref (context_gno ctx) no ; - ( - if not (is_null o.m_n_obj) then - o.dec_ref (context_gno ctx) o.m_n_obj ; - (context_sub1 ctx) - ) ; - o.m_n_obj <- no - - let z3obj_dispose o = - if not (is_null o.m_n_obj) then - ( - o.dec_ref (z3obj_gnc o) o.m_n_obj ; - (context_sub1 (z3obj_gc o)) - ) ; - o.m_n_obj <- null - - let z3obj_create o = - let f = fun o -> (z3obj_dispose o) in - Gc.finalise f o - - let z3obj_nil_ref x y = () - - let z3_native_object_of_ast_ptr : context -> Z3native.ptr -> z3_native_object = fun ctx no -> - let res : z3_native_object = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res -end - -open Internal - -module Log = -struct - let open_ filename = ((lbool_of_int (Z3native.open_log filename)) == L_TRUE) - let close = Z3native.close_log - let append s = Z3native.append_log s -end - - -module Version = -struct - let major = let (x, _, _, _) = Z3native.get_version in x - let minor = let (_, x, _, _) = Z3native.get_version in x - let build = let (_, _, x, _) = Z3native.get_version in x - let revision = let (_, _, _, x) = Z3native.get_version in x - let to_string = - let (mj, mn, bld, rev) = Z3native.get_version in - string_of_int mj ^ "." ^ - string_of_int mn ^ "." ^ - string_of_int bld ^ "." ^ - string_of_int rev ^ "." -end - - -let mk_list ( f : int -> 'a ) ( n : int ) = - let rec mk_list' ( f : int -> 'a ) ( i : int ) ( n : int ) ( tail : 'a list ) : 'a list = - if (i >= n) then - tail - else - (mk_list' f (i+1) n ((f i) :: tail)) - in - mk_list' f 0 n [] - -let list_of_array ( x : _ array ) = - let f i = (Array.get x i) in - mk_list f (Array.length x) - -let mk_context ( cfg : ( string * string ) list ) = - create_context cfg - - -module Symbol = -struct - (* Symbol types *) - type int_symbol = z3_native_object - type string_symbol = z3_native_object - - type symbol = - | S_Int of int_symbol - | S_Str of string_symbol - - - let create_i ( ctx : context ) ( no : Z3native.ptr ) = - let res : int_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let create_s ( ctx : context ) ( no : Z3native.ptr ) = - let res : string_symbol = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let create ( ctx : context ) ( no : Z3native.ptr ) = - match (symbol_kind_of_int (Z3native.get_symbol_kind (context_gno ctx) no)) with - | INT_SYMBOL -> S_Int (create_i ctx no) - | STRING_SYMBOL -> S_Str (create_s ctx no) - - let gc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gc n) - | S_Str(n) -> (z3obj_gc n) - - let gnc ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gnc n) - | S_Str(n) -> (z3obj_gnc n) - - let gno ( x : symbol ) = - match x with - | S_Int(n) -> (z3obj_gno n) - | S_Str(n) -> (z3obj_gno n) - - let symbol_lton ( a : symbol list ) = - let f ( e : symbol ) = (gno e) in - Array.of_list (List.map f a) - - let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) - let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL - let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL - let get_int (o : int_symbol) = Z3native.get_symbol_int (z3obj_gnc o) (z3obj_gno o) - let get_string (o : string_symbol) = Z3native.get_symbol_string (z3obj_gnc o) (z3obj_gno o) - let to_string ( o : symbol ) = - match (kind o) with - | INT_SYMBOL -> (string_of_int (Z3native.get_symbol_int (gnc o) (gno o))) - | STRING_SYMBOL -> (Z3native.get_symbol_string (gnc o) (gno o)) - - let mk_int ( ctx : context ) ( i : int ) = - S_Int (create_i ctx (Z3native.mk_int_symbol (context_gno ctx) i)) - - let mk_string ( ctx : context ) ( s : string ) = - S_Str (create_s ctx (Z3native.mk_string_symbol (context_gno ctx) s)) - - let mk_ints ( ctx : context ) ( names : int list ) = - let f elem = mk_int ( ctx : context ) elem in - (List.map f names) - - let mk_strings ( ctx : context ) ( names : string list ) = - let f elem = mk_string ( ctx : context ) elem in - (List.map f names) -end - - -module AST = -struct - type ast = z3_native_object - - let context_of_ast ( x : ast ) = (z3obj_gc x) - let nc_of_ast ( x : ast ) = (z3obj_gnc x) - let ptr_of_ast ( x : ast ) = (z3obj_gno x) - - let rec ast_of_ptr : context -> Z3native.ptr -> ast = fun ctx no -> - match (ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) with - | FUNC_DECL_AST - | SORT_AST - | QUANTIFIER_AST - | APP_AST - | NUMERAL_AST - | VAR_AST -> z3_native_object_of_ast_ptr ctx no - | UNKNOWN_AST -> raise (Z3native.Exception "Cannot create asts of type unknown") - - module ASTVector = - struct - type ast_vector = z3_native_object - - let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_vector = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_vector_inc_ref ; - dec_ref = Z3native.ast_vector_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_size ( x : ast_vector ) = - Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) - - let get ( x : ast_vector ) ( i : int ) = - ast_of_ptr (z3obj_gc x) (Z3native.ast_vector_get (z3obj_gnc x) (z3obj_gno x) i) - - let set ( x : ast_vector ) ( i : int ) ( value : ast ) = - Z3native.ast_vector_set (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno value) - - let resize ( x : ast_vector ) ( new_size : int ) = - Z3native.ast_vector_resize (z3obj_gnc x) (z3obj_gno x) new_size - - let push ( x : ast_vector ) ( a : ast ) = - Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) - - let translate ( x : ast_vector ) ( to_ctx : context ) = - ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let to_string ( x : ast_vector ) = - Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) - end - - module ASTMap = - struct - type ast_map = z3_native_object - - let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : ast_map = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.ast_map_inc_ref ; - dec_ref = Z3native.ast_map_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let contains ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_contains (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - - let find ( x : ast_map ) ( key : ast ) = - ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - - let insert ( x : ast_map ) ( key : ast ) ( value : ast) = - Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) - - let erase ( x : ast_map ) ( key : ast ) = - Z3native.ast_map_erase (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) - - let reset ( x : ast_map ) = - Z3native.ast_map_reset (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : ast_map ) = - Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) - - let get_keys ( x : ast_map ) = - let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in - let f i = (ASTVector.get av i) in - mk_list f (ASTVector.get_size av) - - let to_string ( x : ast_map ) = - Z3native.ast_map_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let get_hash_code ( x : ast ) = Z3native.get_ast_hash (z3obj_gnc x) (z3obj_gno x) - let get_id ( x : ast ) = Z3native.get_ast_id (z3obj_gnc x) (z3obj_gno x) - let get_ast_kind ( x : ast ) = (ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc x) (z3obj_gno x))) - - let is_expr ( x : ast ) = - match get_ast_kind ( x : ast ) with - | APP_AST - | NUMERAL_AST - | QUANTIFIER_AST - | VAR_AST -> true - | _ -> false - - let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST - let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST - let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST - let is_func_decl ( x : ast ) = (get_ast_kind x) == FUNC_DECL_AST - - let to_string ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - let to_sexpr ( x : ast ) = Z3native.ast_to_string (z3obj_gnc x) (z3obj_gno x) - - - let ( = ) ( a : ast ) ( b : ast ) = (a == b) || - if (z3obj_gnc a) != (z3obj_gnc b) then - false - else - Z3native.is_eq_ast (z3obj_gnc a) (z3obj_gno a) (z3obj_gno b) - - let compare a b = - if (get_id a) < (get_id b) then -1 else - if (get_id a) > (get_id b) then 1 else - 0 - - let ( < ) (a : ast) (b : ast) = (compare a b) - - let translate ( x : ast ) ( to_ctx : context ) = - if (z3obj_gnc x) == (context_gno to_ctx) then - x - else - ast_of_ptr to_ctx (Z3native.translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let wrap_ast ( ctx : context ) ( ptr : Z3native.ptr ) = ast_of_ptr ctx ptr - let unwrap_ast ( x : ast ) = (z3obj_gno x) -end - -open AST - - -module Sort = -struct - type sort = Sort of AST.ast - type uninterpreted_sort = UninterpretedSort of sort - - let sort_of_ptr : context -> Z3native.ptr -> sort = fun ctx no -> - let q = (z3_native_object_of_ast_ptr ctx no) in - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.SORT_AST) then - raise (Z3native.Exception "Invalid coercion") - else - match (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) no)) with - | ARRAY_SORT - | BOOL_SORT - | BV_SORT - | DATATYPE_SORT - | INT_SORT - | REAL_SORT - | UNINTERPRETED_SORT - | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) - | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") - - let ast_of_sort s = match s with Sort(x) -> x - let sort_of_uninterpreted_sort s = match s with UninterpretedSort(x) -> x - - let uninterpreted_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.UNINTERPRETED_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - UninterpretedSort(s) - - let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) - let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) - let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) - - let sort_lton ( a : sort list ) = - let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let ( = ) : sort -> sort -> bool = fun a b -> - (a == b) || - if (gnc a) != (gnc b) then - false - else - (Z3native.is_eq_sort (gnc a) (gno a) (gno b)) - - - let get_id ( x : sort ) = Z3native.get_sort_id (gnc x) (gno x) - let get_sort_kind ( x : sort ) = (sort_kind_of_int (Z3native.get_sort_kind (gnc x) (gno x))) - let get_name ( x : sort ) = (Symbol.create (gc x) (Z3native.get_sort_name (gnc x) (gno x))) - let to_string ( x : sort ) = Z3native.sort_to_string (gnc x) (gno x) - - let mk_uninterpreted ( ctx : context ) ( s : Symbol.symbol ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_uninterpreted_sort (context_gno ctx) (Symbol.gno s))) ; - (z3obj_create res) ; - UninterpretedSort(Sort(res)) - - let mk_uninterpreted_s ( ctx : context ) ( s : string ) = - mk_uninterpreted ctx (Symbol.mk_string ( ctx : context ) s) -end - -open Sort - - -module rec FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - val ast_of_func_decl : FuncDecl.func_decl -> AST.ast - val func_decl_of_ptr : context -> Z3native.ptr -> func_decl - val gc : func_decl -> context - val gnc : func_decl -> Z3native.ptr - val gno : func_decl -> Z3native.ptr - module Parameter : - sig - type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - val get_kind : parameter -> Z3enums.parameter_kind - val get_int : parameter -> int - val get_float : parameter -> float - val get_symbol : parameter -> Symbol.symbol - val get_sort : parameter -> Sort.sort - val get_ast : parameter -> AST.ast - val get_func_decl : parameter -> func_decl - val get_rational : parameter -> string - end - val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl - val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl - val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl - val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl - val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - val ( = ) : func_decl -> func_decl -> bool - val to_string : func_decl -> string - val get_id : func_decl -> int - val get_arity : func_decl -> int - val get_domain_size : func_decl -> int - val get_domain : func_decl -> Sort.sort list - val get_range : func_decl -> Sort.sort - val get_decl_kind : func_decl -> Z3enums.decl_kind - val get_name : func_decl -> Symbol.symbol - val get_num_parameters : func_decl -> int - val get_parameters : func_decl -> Parameter.parameter list - val apply : func_decl -> Expr.expr list -> Expr.expr -end = struct - type func_decl = FuncDecl of AST.ast - - let func_decl_of_ptr : context -> Z3native.ptr -> func_decl = fun ctx no -> - if ((Z3enums.ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no)) != Z3enums.FUNC_DECL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - FuncDecl(z3_native_object_of_ast_ptr ctx no) - - let ast_of_func_decl f = match f with FuncDecl(x) -> x - - let create_ndr ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_func_decl (context_gno ctx) (Symbol.gno name) (List.length domain) (sort_lton domain) (Sort.gno range))) ; - (z3obj_create res) ; - FuncDecl(res) - - let create_pdr ( ctx : context) ( prefix : string ) ( domain : sort list ) ( range : sort ) = - let res = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.inc_ref ; - dec_ref = Z3native.dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fresh_func_decl (context_gno ctx) prefix (List.length domain) (sort_lton domain) (Sort.gno range))) ; - (z3obj_create res) ; - FuncDecl(res) - - let gc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gc a) - let gnc ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gnc a) - let gno ( x : func_decl ) = match x with FuncDecl(a) -> (z3obj_gno a) - - module Parameter = - struct - type parameter = - | P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - let get_kind ( x : parameter ) = - (match x with - | P_Int(_) -> PARAMETER_INT - | P_Dbl(_) -> PARAMETER_DOUBLE - | P_Sym(_) -> PARAMETER_SYMBOL - | P_Srt(_) -> PARAMETER_SORT - | P_Ast(_) -> PARAMETER_AST - | P_Fdl(_) -> PARAMETER_FUNC_DECL - | P_Rat(_) -> PARAMETER_RATIONAL) - - let get_int ( x : parameter ) = - match x with - | P_Int(x) -> x - | _ -> raise (Z3native.Exception "parameter is not an int") - - let get_float ( x : parameter ) = - match x with - | P_Dbl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a double") - - let get_symbol ( x : parameter ) = - match x with - | P_Sym(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a symbol") - - let get_sort ( x : parameter ) = - match x with - | P_Srt(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a sort") - - let get_ast ( x : parameter ) = - match x with - | P_Ast(x) -> x - | _ -> raise (Z3native.Exception "parameter is not an ast") - - let get_func_decl ( x : parameter ) = - match x with - | P_Fdl(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a func_decl") - - let get_rational ( x : parameter ) = - match x with - | P_Rat(x) -> x - | _ -> raise (Z3native.Exception "parameter is not a rational string") - end - - let mk_func_decl ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort list ) ( range : sort ) = - create_ndr ctx name domain range - - let mk_func_decl_s ( ctx : context ) ( name : string ) ( domain : sort list ) ( range : sort ) = - mk_func_decl ctx (Symbol.mk_string ctx name) domain range - - let mk_fresh_func_decl ( ctx : context ) ( prefix : string ) ( domain : sort list ) ( range : sort ) = - create_pdr ctx prefix domain range - - let mk_const_decl ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - create_ndr ctx name [] range - - let mk_const_decl_s ( ctx : context ) ( name : string ) ( range : sort ) = - create_ndr ctx (Symbol.mk_string ctx name) [] range - - let mk_fresh_const_decl ( ctx : context ) ( prefix : string ) ( range : sort ) = - create_pdr ctx prefix [] range - - - let ( = ) ( a : func_decl ) ( b : func_decl ) = (a == b) || - if (gnc a) != (gnc b) then - false - else - (Z3native.is_eq_func_decl (gnc a) (gno a) (gno b)) - - let to_string ( x : func_decl ) = Z3native.func_decl_to_string (gnc x) (gno x) - - let get_id ( x : func_decl ) = Z3native.get_func_decl_id (gnc x) (gno x) - - let get_arity ( x : func_decl ) = Z3native.get_arity (gnc x) (gno x) - - let get_domain_size ( x : func_decl ) = Z3native.get_domain_size (gnc x) (gno x) - - let get_domain ( x : func_decl ) = - let n = (get_domain_size x) in - let f i = sort_of_ptr (gc x) (Z3native.get_domain (gnc x) (gno x) i) in - mk_list f n - - let get_range ( x : func_decl ) = - sort_of_ptr (gc x) (Z3native.get_range (gnc x) (gno x)) - - let get_decl_kind ( x : func_decl ) = (decl_kind_of_int (Z3native.get_decl_kind (gnc x) (gno x))) - - let get_name ( x : func_decl ) = (Symbol.create (gc x) (Z3native.get_decl_name (gnc x) (gno x))) - - let get_num_parameters ( x : func_decl ) = (Z3native.get_decl_num_parameters (gnc x) (gno x)) - - let get_parameters ( x : func_decl ) = - let n = (get_num_parameters x) in - let f i = (match (parameter_kind_of_int (Z3native.get_decl_parameter_kind (gnc x) (gno x) i)) with - | PARAMETER_INT -> Parameter.P_Int (Z3native.get_decl_int_parameter (gnc x) (gno x) i) - | PARAMETER_DOUBLE -> Parameter.P_Dbl (Z3native.get_decl_double_parameter (gnc x) (gno x) i) - | PARAMETER_SYMBOL-> Parameter.P_Sym (Symbol.create (gc x) (Z3native.get_decl_symbol_parameter (gnc x) (gno x) i)) - | PARAMETER_SORT -> Parameter.P_Srt (sort_of_ptr (gc x) (Z3native.get_decl_sort_parameter (gnc x) (gno x) i)) - | PARAMETER_AST -> Parameter.P_Ast (AST.ast_of_ptr (gc x) (Z3native.get_decl_ast_parameter (gnc x) (gno x) i)) - | PARAMETER_FUNC_DECL -> Parameter.P_Fdl (func_decl_of_ptr (gc x) (Z3native.get_decl_func_decl_parameter (gnc x) (gno x) i)) - | PARAMETER_RATIONAL -> Parameter.P_Rat (Z3native.get_decl_rational_parameter (gnc x) (gno x) i) - ) in - mk_list f n - - let apply ( x : func_decl ) ( args : Expr.expr list ) = Expr.expr_of_func_app (gc x) x args -end - - -and Params : -sig - type params = z3_native_object - module ParamDescrs : - sig - type param_descrs - val param_descrs_of_ptr : context -> Z3native.ptr -> param_descrs - val validate : param_descrs -> params -> unit - val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - val get_names : param_descrs -> Symbol.symbol list - val get_size : param_descrs -> int - val to_string : param_descrs -> string - end - val add_bool : params -> Symbol.symbol -> bool -> unit - val add_int : params -> Symbol.symbol -> int -> unit - val add_double : params -> Symbol.symbol -> float -> unit - val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - val add_s_bool : params -> string -> bool -> unit - val add_s_int : params -> string -> int -> unit - val add_s_double : params -> string -> float -> unit - val add_s_symbol : params -> string -> Symbol.symbol -> unit - val mk_params : context -> params - val to_string : params -> string -end = struct - type params = z3_native_object - - module ParamDescrs = - struct - type param_descrs = z3_native_object - - let param_descrs_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let res : param_descrs = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.param_descrs_inc_ref ; - dec_ref = Z3native.param_descrs_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let validate ( x : param_descrs ) ( p : params ) = - Z3native.params_validate (z3obj_gnc x) (z3obj_gno p) (z3obj_gno x) - - let get_kind ( x : param_descrs ) ( name : Symbol.symbol ) = - (param_kind_of_int (Z3native.param_descrs_get_kind (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name))) - - let get_names ( x : param_descrs ) = - let n = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) in - let f i = Symbol.create (z3obj_gc x) (Z3native.param_descrs_get_name (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_size ( x : param_descrs ) = Z3native.param_descrs_size (z3obj_gnc x) (z3obj_gno x) - let to_string ( x : param_descrs ) = Z3native.param_descrs_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let add_bool ( x : params ) ( name : Symbol.symbol ) ( value : bool ) = - Z3native.params_set_bool (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_int ( x : params ) (name : Symbol.symbol ) ( value : int ) = - Z3native.params_set_uint (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_double ( x : params ) ( name : Symbol.symbol ) ( value : float ) = - Z3native.params_set_double (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) value - - let add_symbol ( x : params ) ( name : Symbol.symbol ) ( value : Symbol.symbol ) = - Z3native.params_set_symbol (z3obj_gnc x) (z3obj_gno x) (Symbol.gno name) (Symbol.gno value) - - let add_s_bool ( x : params ) ( name : string ) ( value : bool ) = - add_bool x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_int ( x : params) ( name : string ) ( value : int ) = - add_int x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_double ( x : params ) ( name : string ) ( value : float ) = - add_double x (Symbol.mk_string (z3obj_gc x) name) value - - let add_s_symbol ( x : params ) ( name : string ) ( value : Symbol.symbol ) = - add_symbol x (Symbol.mk_string (z3obj_gc x) name) value - - let mk_params ( ctx : context ) = - let res : params = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.params_inc_ref ; - dec_ref = Z3native.params_dec_ref } in - (z3obj_sno res ctx (Z3native.mk_params (context_gno ctx))) ; - (z3obj_create res) ; - res - - let to_string ( x : params ) = Z3native.params_to_string (z3obj_gnc x) (z3obj_gno x) -end - -(** General expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - val expr_of_ptr : context -> Z3native.ptr -> expr - val gc : expr -> context - val gnc : expr -> Z3native.ptr - val gno : expr -> Z3native.ptr - val expr_lton : expr list -> Z3native.ptr array - val ast_of_expr : expr -> AST.ast - val expr_of_ast : AST.ast -> expr - val expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr - val simplify : expr -> Params.params option -> expr - val get_simplify_help : context -> string - val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs - val get_func_decl : expr -> FuncDecl.func_decl - val get_bool_value : expr -> Z3enums.lbool - val get_num_args : expr -> int - val get_args : expr -> expr list - val update : expr -> expr list -> expr - val substitute : expr -> expr list -> expr list -> expr - val substitute_one : expr -> expr -> expr -> expr - val substitute_vars : expr -> expr list -> expr - val translate : expr -> context -> expr - val to_string : expr -> string - val is_numeral : expr -> bool - val is_well_sorted : expr -> bool - val get_sort : expr -> Sort.sort - val is_bool : expr -> bool - val is_const : expr -> bool - val is_true : expr -> bool - val is_false : expr -> bool - val is_eq : expr -> bool - val is_distinct : expr -> bool - val is_ite : expr -> bool - val is_and : expr -> bool - val is_or : expr -> bool - val is_iff : expr -> bool - val is_xor : expr -> bool - val is_not : expr -> bool - val is_implies : expr -> bool - val is_label : expr -> bool - val is_label_lit : expr -> bool - val is_oeq : expr -> bool - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - val mk_const_s : context -> string -> Sort.sort -> expr - val mk_const_f : context -> FuncDecl.func_decl -> expr - val mk_fresh_const : context -> string -> Sort.sort -> expr - val mk_app : context -> FuncDecl.func_decl -> expr list -> expr - val mk_numeral_string : context -> string -> Sort.sort -> expr - val mk_numeral_int : context -> int -> Sort.sort -> expr -end = struct - type expr = Expr of AST.ast - - let c_of_expr e = match e with Expr(a) -> (z3obj_gc a) - let nc_of_expr e = match e with Expr(a) -> (z3obj_gnc a) - let ptr_of_expr e = match e with Expr(a) -> (z3obj_gno a) - - let expr_of_ptr : context -> Z3native.ptr -> expr = fun ctx no -> - if ast_kind_of_int (Z3native.get_ast_kind (context_gno ctx) no) == QUANTIFIER_AST then - Expr(z3_native_object_of_ast_ptr ctx no) - else - let s = Z3native.get_sort (context_gno ctx) no in - let sk = (sort_kind_of_int (Z3native.get_sort_kind (context_gno ctx) s)) in - if (Z3native.is_algebraic_number (context_gno ctx) no) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then - Expr(z3_native_object_of_ast_ptr ctx no) - else - raise (Z3native.Exception "Unsupported numeral object") - else - Expr(z3_native_object_of_ast_ptr ctx no) - - let expr_of_ast a = - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.APP_AST && q != VAR_AST && q != QUANTIFIER_AST && q != NUMERAL_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Expr(a) - - let ast_of_expr e = match e with Expr(a) -> a - - let expr_lton ( a : expr list ) = - let f ( e : expr ) = match e with Expr(a) -> (AST.ptr_of_ast a) in - Array.of_list (List.map f a) - - let expr_of_func_app : context -> FuncDecl.func_decl -> expr list -> expr = fun ctx f args -> - match f with FuncDecl.FuncDecl(fa) -> - let o = Z3native.mk_app (context_gno ctx) (AST.ptr_of_ast fa) (List.length args) (expr_lton args) in - expr_of_ptr ctx o - - let simplify ( x : expr ) ( p : Params.params option ) = match p with - | None -> expr_of_ptr (Expr.gc x) (Z3native.simplify (Expr.gnc x) (Expr.gno x)) - | Some pp -> expr_of_ptr (Expr.gc x) (Z3native.simplify_ex (Expr.gnc x) (Expr.gno x) (z3obj_gno pp)) - - let get_simplify_help ( ctx : context ) = - Z3native.simplify_get_help (context_gno ctx) - - let get_simplify_parameter_descrs ( ctx : context ) = - Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (Expr.gnc x) (Expr.gno x)) - - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (Expr.gnc x) (Expr.gno x)) - - let get_num_args ( x : expr ) = Z3native.get_app_num_args (Expr.gnc x) (Expr.gno x) - - let get_args ( x : expr ) = let n = (get_num_args x) in - let f i = expr_of_ptr (Expr.gc x) (Z3native.get_app_arg (Expr.gnc x) (Expr.gno x) i) in - mk_list f n - - let update ( x : expr ) ( args : expr list ) = - if (List.length args <> (get_num_args x)) then - raise (Z3native.Exception "Number of arguments does not match") - else - expr_of_ptr (Expr.gc x) (Z3native.update_term (Expr.gnc x) (Expr.gno x) (List.length args) (expr_lton args)) - - let substitute ( x : expr ) from to_ = - if (List.length from) <> (List.length to_) then - raise (Z3native.Exception "Argument sizes do not match") - else - expr_of_ptr (Expr.gc x) (Z3native.substitute (Expr.gnc x) (Expr.gno x) (List.length from) (expr_lton from) (expr_lton to_)) - - let substitute_one ( x : expr ) from to_ = - substitute ( x : expr ) [ from ] [ to_ ] - - let substitute_vars ( x : expr ) to_ = - expr_of_ptr (Expr.gc x) (Z3native.substitute_vars (Expr.gnc x) (Expr.gno x) (List.length to_) (expr_lton to_)) - - let translate ( x : expr ) to_ctx = - if (Expr.gc x) == to_ctx then - x - else - expr_of_ptr to_ctx (Z3native.translate (Expr.gnc x) (Expr.gno x) (context_gno to_ctx)) - - let to_string ( x : expr ) = Z3native.ast_to_string (Expr.gnc x) (Expr.gno x) - - let is_numeral ( x : expr ) = (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) - - let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (Expr.gnc x) (Expr.gno x) - - let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)) - - let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (Expr.gnc x) - (Z3native.mk_bool_sort (Expr.gnc x)) - (Z3native.get_sort (Expr.gnc x) (Expr.gno x))) - - let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (get_num_args x) == 0 && - (FuncDecl.get_domain_size (get_func_decl x)) == 0 - - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_label ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL) - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) - let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = - expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) - - let mk_const_s ( ctx : context ) ( name : string ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name) range - - let mk_const_f ( ctx : context ) ( f : FuncDecl.func_decl ) = Expr.expr_of_func_app ctx f [] - - let mk_fresh_const ( ctx : context ) ( prefix : string ) ( range : sort ) = - expr_of_ptr ctx (Z3native.mk_fresh_const (context_gno ctx) prefix (Sort.gno range)) - - let mk_app ( ctx : context ) ( f : FuncDecl.func_decl ) ( args : expr list ) = expr_of_func_app ctx f args - - let mk_numeral_string ( ctx : context ) ( v : string ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno ty)) - - let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) -end - -open FuncDecl -open Expr - -module Boolean = -struct - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - let bool_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let a = (AST.ast_of_ptr ctx no) in - BoolExpr(Expr.Expr(a)) - - let bool_expr_of_expr e = - match e with Expr.Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolExpr(e) - - let bool_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - BoolSort(sort_of_ptr ctx no) - - let sort_of_bool_sort s = match s with BoolSort(x) -> x - - let bool_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BOOL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BoolSort(s) - - let expr_of_bool_expr e = match e with BoolExpr(x) -> x - - let gc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.c_of_expr e) - let gnc ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.nc_of_expr e) - let gno ( x : bool_expr ) = match x with BoolExpr(e) -> (Expr.ptr_of_expr e) - - let mk_sort ( ctx : context ) = - BoolSort(sort_of_ptr ctx (Z3native.mk_bool_sort (context_gno ctx))) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - let s = (match (mk_sort ctx) with BoolSort(q) -> q) in - BoolExpr(Expr.mk_const ctx name s) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_true ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_true (context_gno ctx)) - - let mk_false ( ctx : context ) = - bool_expr_of_ptr ctx (Z3native.mk_false (context_gno ctx)) - - let mk_val ( ctx : context ) ( value : bool ) = - if value then mk_true ctx else mk_false ctx - - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - bool_expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) - - let mk_distinct ( ctx : context ) ( args : expr list ) = - bool_expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_not ( ctx : context ) ( a : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) - - let mk_ite ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) ( t3 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_ite (context_gno ctx) (gno t1) (gno t2) (gno t3)) - - let mk_iff ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_iff (context_gno ctx) (gno t1) (gno t2)) - - let mk_implies ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_implies (context_gno ctx) (gno t1) (gno t2)) - - let mk_xor ( ctx : context ) ( t1 : bool_expr ) ( t2 : bool_expr ) = - bool_expr_of_ptr ctx (Z3native.mk_xor (context_gno ctx) (gno t1) (gno t2)) - - let mk_and ( ctx : context ) ( args : bool_expr list ) = - let f x = (Expr.gno (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_and (context_gno ctx) (List.length args) (Array.of_list (List.map f args))) - - let mk_or ( ctx : context ) ( args : bool_expr list ) = - let f x = (Expr.gno (expr_of_bool_expr x)) in - bool_expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) -end - - -module Quantifier = -struct - type quantifier = Quantifier of expr - - let expr_of_quantifier e = match e with Quantifier(x) -> x - - let quantifier_of_expr e = - match e with Expr.Expr(a) -> - let q = (Z3enums.ast_kind_of_int (Z3native.get_ast_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.QUANTIFIER_AST) then - raise (Z3native.Exception "Invalid coercion") - else - Quantifier(e) - - let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) - let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) - let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) - - module Pattern = - struct - type pattern = Pattern of ast - - let ast_of_pattern e = match e with Pattern(x) -> x - - let pattern_of_ast a = - (* CMW: Unchecked ok? *) - Pattern(a) - - let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) - let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) - let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) - - let get_num_terms ( x : pattern ) = - Z3native.get_pattern_num_terms (gnc x) (gno x) - - let get_terms ( x : pattern ) = - let n = (get_num_terms x) in - let f i = (expr_of_ptr (gc x) (Z3native.get_pattern (gnc x) (gno x) i)) in - mk_list f n - - let to_string ( x : pattern ) = Z3native.pattern_to_string (gnc x) (gno x) - end - - let get_index ( x : expr ) = - if not (AST.is_var (match x with Expr.Expr(a) -> a)) then - raise (Z3native.Exception "Term is not a bound variable.") - else - Z3native.get_index_value (Expr.gnc x) (Expr.gno x) - - let is_universal ( x : quantifier ) = - Z3native.is_quantifier_forall (gnc x) (gno x) - - let is_existential ( x : quantifier ) = not (is_universal x) - - let get_weight ( x : quantifier ) = Z3native.get_quantifier_weight (gnc x) (gno x) - - let get_num_patterns ( x : quantifier ) = Z3native.get_quantifier_num_patterns (gnc x) (gno x) - - let get_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_pattern_ast (gnc x) (gno x) i)) in - mk_list f n - - let get_num_no_patterns ( x : quantifier ) = Z3native.get_quantifier_num_no_patterns (gnc x) (gno x) - - let get_no_patterns ( x : quantifier ) = - let n = (get_num_patterns x) in - let f i = Pattern.Pattern (z3_native_object_of_ast_ptr (gc x) (Z3native.get_quantifier_no_pattern_ast (gnc x) (gno x) i)) in - mk_list f n - - let get_num_bound ( x : quantifier ) = Z3native.get_quantifier_num_bound (gnc x) (gno x) - - let get_bound_variable_names ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (Symbol.create (gc x) (Z3native.get_quantifier_bound_name (gnc x) (gno x) i)) in - mk_list f n - - let get_bound_variable_sorts ( x : quantifier ) = - let n = (get_num_bound x) in - let f i = (sort_of_ptr (gc x) (Z3native.get_quantifier_bound_sort (gnc x) (gno x) i)) in - mk_list f n - - let get_body ( x : quantifier ) = - Boolean.bool_expr_of_ptr (gc x) (Z3native.get_quantifier_body (gnc x) (gno x)) - - let mk_bound ( ctx : context ) ( index : int ) ( ty : sort ) = - expr_of_ptr ctx (Z3native.mk_bound (context_gno ctx) index (Sort.gno ty)) - - let mk_pattern ( ctx : context ) ( terms : expr list ) = - if (List.length terms) == 0 then - raise (Z3native.Exception "Cannot create a pattern from zero terms") - else - Pattern.Pattern(z3_native_object_of_ast_ptr ctx (Z3native.mk_pattern (context_gno ctx) (List.length terms) (expr_lton terms))) - - let mk_forall ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (List.length sorts) != (List.length names) then - raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - - let mk_forall_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) true - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (Expr.gno body))) - - let mk_exists ( ctx : context ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (List.length sorts) != (List.length names) then - raise (Z3native.Exception "Number of sorts does not match number of names") - else if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (List.length sorts) (sort_lton sorts) - (Symbol.symbol_lton names) - (Expr.gno body))) - - let mk_exists_const ( ctx : context ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if ((List.length nopatterns) == 0 && quantifier_id == None && skolem_id == None) then - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (Expr.gno body))) - else - Quantifier(expr_of_ptr ctx (Z3native.mk_quantifier_const_ex (context_gno ctx) false - (match weight with | None -> 1 | Some(x) -> x) - (match quantifier_id with | None -> null | Some(x) -> (Symbol.gno x)) - (match skolem_id with | None -> null | Some(x) -> (Symbol.gno x)) - (List.length bound_constants) (expr_lton bound_constants) - (List.length patterns) (let f x = (AST.ptr_of_ast (Pattern.ast_of_pattern x)) in (Array.of_list (List.map f patterns))) - (List.length nopatterns) (expr_lton nopatterns) - (Expr.gno body))) - - let mk_quantifier ( ctx : context ) ( universal : bool ) ( sorts : sort list ) ( names : Symbol.symbol list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (universal) then - (mk_forall ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - else - (mk_exists ctx sorts names body weight patterns nopatterns quantifier_id skolem_id) - - let mk_quantifier ( ctx : context ) ( universal : bool ) ( bound_constants : expr list ) ( body : expr ) ( weight : int option ) ( patterns : Pattern.pattern list ) ( nopatterns : expr list ) ( quantifier_id : Symbol.symbol option ) ( skolem_id : Symbol.symbol option ) = - if (universal) then - mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id - else - mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id -end - - -module Array_ = -struct - type array_sort = ArraySort of sort - type array_expr = ArrayExpr of expr - - let array_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let e = (expr_of_ptr ctx no) in - ArrayExpr(e) - - let array_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - ArraySort(s) - - let sort_of_array_sort s = match s with ArraySort(x) -> x - - let array_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArraySort(s) - - let array_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.ARRAY_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArrayExpr(e) - - let expr_of_array_expr e = match e with ArrayExpr(x) -> x - - let sgc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : array_sort ) = match (x) with ArraySort(Sort(s)) -> (z3obj_gno s) - - let egc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gc e) - let egnc ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gnc e) - let egno ( x : array_expr ) = match (x) with ArrayExpr(Expr(e)) -> (z3obj_gno e) - - let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = - array_sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) - let is_array ( x : expr ) = - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) - - let get_domain ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_domain (sgnc x) (sgno x)) - let get_range ( x : array_sort ) = Sort.sort_of_ptr (sgc x) (Z3native.get_array_sort_range (sgnc x) (sgno x)) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( domain : sort ) ( range : sort ) = - ArrayExpr(Expr.mk_const ctx name (match (mk_sort ctx domain range) with ArraySort(s) -> s)) - - let mk_const_s ( ctx : context ) ( name : string ) ( domain : sort ) ( range : sort ) = - mk_const ctx (Symbol.mk_string ctx name) domain range - - let mk_select ( ctx : context ) ( a : array_expr ) ( i : expr ) = - array_expr_of_ptr ctx (Z3native.mk_select (context_gno ctx) (egno a) (Expr.gno i)) - - let mk_store ( ctx : context ) ( a : array_expr ) ( i : expr ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_store (context_gno ctx) (egno a) (Expr.gno i) (Expr.gno v)) - - let mk_const_array ( ctx : context ) ( domain : sort ) ( v : expr ) = - array_expr_of_ptr ctx (Z3native.mk_const_array (context_gno ctx) (Sort.gno domain) (Expr.gno v)) - - let mk_map ( ctx : context ) ( f : func_decl ) ( args : array_expr list ) = - let m x = (Expr.gno (expr_of_array_expr x)) in - array_expr_of_ptr ctx (Z3native.mk_map (context_gno ctx) (FuncDecl.gno f) (List.length args) (Array.of_list (List.map m args))) - - let mk_term_array ( ctx : context ) ( arg : array_expr ) = - array_expr_of_ptr ctx (Z3native.mk_array_default (context_gno ctx) (egno arg)) -end - - -module Set = -struct - type set_sort = SetSort of sort - - let set_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - SetSort(s) - - let sort_of_set_sort s = match s with SetSort(x) -> x - - let mk_sort ( ctx : context ) ( ty : sort ) = - set_sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) - - - let mk_empty ( ctx : context ) ( domain : sort ) = - (expr_of_ptr ctx (Z3native.mk_empty_set (context_gno ctx) (Sort.gno domain))) - - let mk_full ( ctx : context ) ( domain : sort ) = - expr_of_ptr ctx (Z3native.mk_full_set (context_gno ctx) (Sort.gno domain)) - - let mk_set_add ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_add (context_gno ctx) (Expr.gno set) (Expr.gno element)) - - let mk_del ( ctx : context ) ( set : expr ) ( element : expr ) = - expr_of_ptr ctx (Z3native.mk_set_del (context_gno ctx) (Expr.gno set) (Expr.gno element)) - - let mk_union ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_set_union (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_intersection ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_set_intersect (context_gno ctx) (List.length args) (expr_lton args)) - - let mk_difference ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_difference (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) - - let mk_complement ( ctx : context ) ( arg : expr ) = - expr_of_ptr ctx (Z3native.mk_set_complement (context_gno ctx) (Expr.gno arg)) - - let mk_membership ( ctx : context ) ( elem : expr ) ( set : expr ) = - expr_of_ptr ctx (Z3native.mk_set_member (context_gno ctx) (Expr.gno elem) (Expr.gno set)) - - let mk_subset ( ctx : context ) ( arg1 : expr ) ( arg2 : expr ) = - expr_of_ptr ctx (Z3native.mk_set_subset (context_gno ctx) (Expr.gno arg1) (Expr.gno arg2)) - -end - - -module FiniteDomain = -struct - type finite_domain_sort = FiniteDomainSort of sort - - let sort_of_finite_domain_sort s = match s with FiniteDomainSort(x) -> x - - let finite_domain_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.FINITE_DOMAIN_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - FiniteDomainSort(s) - - let gc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : finite_domain_sort ) = match (x) with FiniteDomainSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - let s = (sort_of_ptr ctx (Z3native.mk_finite_domain_sort (context_gno ctx) (Symbol.gno name) size)) in - FiniteDomainSort(s) - - let mk_sort_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_sort ctx (Symbol.mk_string ctx name) size - - - let is_finite_domain ( x : expr ) = - let nc = (Expr.gnc x) in - (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) - - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) - - let get_size ( x : finite_domain_sort ) = - let (r, v) = (Z3native.get_finite_domain_sort_size (gnc x) (gno x)) in - if r then v - else raise (Z3native.Exception "Conversion failed.") -end - - -module Relation = -struct - type relation_sort = RelationSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - RelationSort(s) - - let sort_of_relation_sort s = match s with RelationSort(x) -> x - - let relation_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.RELATION_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RelationSort(s) - - let gc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gc s) - let gnc ( x : relation_sort ) = match (x) with RelationSort(Sort(s)) -> (z3obj_gnc s) - let gno ( x : relation_sort ) = match (x) with RelationSort(Sort(s))-> (z3obj_gno s) - - - let is_relation ( x : expr ) = - let nc = (Expr.gnc x) in - ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && - (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) - - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) - - let get_arity ( x : relation_sort ) = Z3native.get_relation_arity (gnc x) (gno x) - - let get_column_sorts ( x : relation_sort ) = - let n = get_arity x in - let f i = (sort_of_ptr (gc x) (Z3native.get_relation_column (gnc x) (gno x) i)) in - mk_list f n - -end - - -module Datatype = -struct - type datatype_sort = DatatypeSort of sort - type datatype_expr = DatatypeExpr of expr - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - DatatypeSort(s) - - let sort_of_datatype_sort s = match s with DatatypeSort(x) -> x - - let datatype_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeSort(s) - - let datatype_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.DATATYPE_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - DatatypeExpr(e) - - let expr_of_datatype_expr e = match e with DatatypeExpr(x) -> x - - let sgc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : datatype_sort ) = match (x) with DatatypeSort(Sort(s))-> (z3obj_gno s) - - module Constructor = - struct - type constructor = z3_native_object - - let _sizes = Hashtbl.create 0 - - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = - let n = (List.length field_names) in - if n != (List.length sorts) then - raise (Z3native.Exception "Number of field names does not match number of sorts") - else - if n != (List.length sort_refs) then - raise (Z3native.Exception "Number of field names does not match number of sort refs") - else - let ptr = (Z3native.mk_constructor (context_gno ctx) (Symbol.gno name) - (Symbol.gno recognizer) - n - (Symbol.symbol_lton field_names) - (sort_lton sorts) - (Array.of_list sort_refs)) in - let no : constructor = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - (z3obj_sno no ctx ptr) ; - (z3obj_create no) ; - let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in - Gc.finalise f no ; - Hashtbl.add _sizes no n ; - no - - let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x - - let get_constructor_decl ( x : constructor ) = - let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - func_decl_of_ptr (z3obj_gc x) a - - let get_tester_decl ( x : constructor ) = - let (_, b, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - func_decl_of_ptr (z3obj_gc x) b - - let get_accessor_decls ( x : constructor ) = - let (_, _, c) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in - let f i = func_decl_of_ptr (z3obj_gc x) (Array.get c i) in - mk_list f (Array.length c) - - end - - module ConstructorList = - struct - type constructor_list = z3_native_object - - let create ( ctx : context ) ( c : Constructor.constructor list ) = - let res : constructor_list = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = z3obj_nil_ref ; - dec_ref = z3obj_nil_ref} in - let f x =(z3obj_gno x) in - (z3obj_sno res ctx (Z3native.mk_constructor_list (context_gno ctx) (List.length c) (Array.of_list (List.map f c)))) ; - (z3obj_create res) ; - let f = fun o -> Z3native.del_constructor_list (z3obj_gnc o) (z3obj_gno o) in - Gc.finalise f res; - res - end - - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = - Constructor.create ctx name recognizer field_names sorts sort_refs - - - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = - mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = - let f x = (z3obj_gno x) in - let (x,_) = (Z3native.mk_datatype (context_gno ctx) (Symbol.gno name) (List.length constructors) (Array.of_list (List.map f constructors))) in - sort_of_ptr ctx x - - let mk_sort_s ( ctx : context ) ( name : string ) ( constructors : Constructor.constructor list ) = - mk_sort ctx (Symbol.mk_string ctx name) constructors - - let mk_sorts ( ctx : context ) ( names : Symbol.symbol list ) ( c : Constructor.constructor list list ) = - let n = (List.length names) in - let f e = (AST.ptr_of_ast (ConstructorList.create ctx e)) in - let cla = (Array.of_list (List.map f c)) in - let (r, a) = (Z3native.mk_datatypes (context_gno ctx) n (Symbol.symbol_lton names) cla) in - let g i = (sort_of_ptr ctx (Array.get r i)) in - mk_list g (Array.length r) - - let mk_sorts_s ( ctx : context ) ( names : string list ) ( c : Constructor.constructor list list ) = - mk_sorts ctx - ( - let f e = (Symbol.mk_string ctx e) in - List.map f names - ) - c - - let get_num_constructors ( x : datatype_sort ) = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) - - let get_constructors ( x : datatype_sort ) = - let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in - mk_list f n - - let get_recognizers ( x : datatype_sort ) = - let n = (get_num_constructors x) in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i) in - mk_list f n - - let get_accessors ( x : datatype_sort ) = - let n = (get_num_constructors x) in - let f i = ( - let fd = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i) in - let ds = Z3native.get_domain_size (FuncDecl.gnc fd) (FuncDecl.gno fd) in - let g j = func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) i j) in - mk_list g ds - ) in - mk_list f n -end - - -module Enumeration = -struct - type enum_sort = EnumSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( cdecls : Z3native.z3_func_decl list ) ( tdecls : Z3native.z3_func_decl list ) = - let s = (sort_of_ptr ctx no) in - let res = EnumSort(s) in - res - - let sort_of_enum_sort s = match s with EnumSort(x) -> x - - let sgc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : enum_sort ) = match (x) with EnumSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : enum_sort ) = match (x) with EnumSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( enum_names : Symbol.symbol list ) = - let (a, b, c) = (Z3native.mk_enumeration_sort (context_gno ctx) (Symbol.gno name) (List.length enum_names) (Symbol.symbol_lton enum_names)) in - sort_of_ptr ctx a (list_of_array b) (list_of_array c) - - let mk_sort_s ( ctx : context ) ( name : string ) ( enum_names : string list ) = - mk_sort ctx (Symbol.mk_string ctx name) (Symbol.mk_strings ctx enum_names) - - let get_const_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) i)) in - mk_list f n - - let get_tester_decls ( x : enum_sort ) = - let n = Z3native.get_datatype_sort_num_constructors (sgnc x) (sgno x) in - let f i = (func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) i)) in - mk_list f n - -end - - -module List_ = -struct - type list_sort = ListSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) ( nildecl : Z3native.ptr ) ( is_nildecl : Z3native.ptr ) ( consdecl : Z3native.ptr ) ( is_consdecl : Z3native.ptr ) ( headdecl : Z3native.ptr ) ( taildecl : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - let res = ListSort(s) in - res - - let sort_of_list_sort s = match s with ListSort(x) -> x - - let sgc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : list_sort ) = match (x) with ListSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : list_sort ) = match (x) with ListSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = - let (r, a, b, c, d, e, f) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in - sort_of_ptr ctx r a b c d e f - - let mk_list_s ( ctx : context ) (name : string) elem_sort = - mk_sort ctx (Symbol.mk_string ctx name) elem_sort - - let get_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 0) - - let get_is_nil_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 0) - - let get_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor (sgnc x) (sgno x) 1) - - let get_is_cons_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_recognizer (sgnc x) (sgno x) 1) - - let get_head_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 0) - - let get_tail_decl ( x : list_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_datatype_sort_constructor_accessor (sgnc x) (sgno x) 1 1) - - let nil ( x : list_sort ) = expr_of_func_app (sgc x) (get_nil_decl x) [] -end - - -module Tuple = -struct - type tuple_sort = TupleSort of sort - - let sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - let s = (sort_of_ptr ctx no) in - TupleSort(s) - - let sort_of_tuple_sort s = match s with TupleSort(x) -> x - - let sgc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : tuple_sort ) = match (x) with TupleSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : tuple_sort ) = match (x) with TupleSort(Sort(s))-> (z3obj_gno s) - - let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( field_sorts : sort list ) = - let (r, _, _) = (Z3native.mk_tuple_sort (context_gno ctx) (Symbol.gno name) (List.length field_names) (Symbol.symbol_lton field_names) (sort_lton field_sorts)) in - sort_of_ptr ctx r - - let get_mk_decl ( x : tuple_sort ) = - func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_mk_decl (sgnc x) (sgno x)) - - let get_num_fields ( x : tuple_sort ) = Z3native.get_tuple_sort_num_fields (sgnc x) (sgno x) - - let get_field_decls ( x : tuple_sort ) = - let n = get_num_fields x in - let f i = func_decl_of_ptr (sgc x) (Z3native.get_tuple_sort_field_decl (sgnc x) (sgno x) i) in - mk_list f n -end - - -module rec Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> arith_sort - val expr_of_arith_expr : arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> arith_expr - - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_const : context -> Symbol.symbol -> int_expr - val mk_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_numeral_s : context -> string -> int_num - val mk_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_const : context -> Symbol.symbol -> real_expr - val mk_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end - - val is_int : Expr.expr -> bool - val is_arithmetic_numeral : Expr.expr -> bool - val is_le : Expr.expr -> bool - val is_ge : Expr.expr -> bool - val is_lt : Expr.expr -> bool - val is_gt : Expr.expr -> bool - val is_add : Expr.expr -> bool - val is_sub : Expr.expr -> bool - val is_uminus : Expr.expr -> bool - val is_mul : Expr.expr -> bool - val is_div : Expr.expr -> bool - val is_idiv : Expr.expr -> bool - val is_remainder : Expr.expr -> bool - val is_modulus : Expr.expr -> bool - val is_inttoreal : Expr.expr -> bool - val is_real_to_int : Expr.expr -> bool - val is_real_is_int : Expr.expr -> bool - val is_real : Expr.expr -> bool - val is_int_numeral : Expr.expr -> bool - val is_rat_num : Expr.expr -> bool - val is_algebraic_number : Expr.expr -> bool - val mk_add : context -> arith_expr list -> arith_expr - val mk_mul : context -> arith_expr list -> arith_expr - val mk_sub : context -> arith_expr list -> arith_expr - val mk_unary_minus : context -> arith_expr -> arith_expr - val mk_div : context -> arith_expr -> arith_expr -> arith_expr - val mk_power : context -> arith_expr -> arith_expr -> arith_expr - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr -end = struct - type arith_sort = ArithSort of sort - type arith_expr = ArithExpr of expr - - let arith_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithExpr(e) - - let arith_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_expr_of_expr (expr_of_ptr ctx no) - - let sort_of_arith_sort s = match s with ArithSort(x) -> x - let expr_of_arith_expr e = match e with ArithExpr(x) -> x - - let arith_sort_of_sort s = match s with Sort(a) -> - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) in - if (q != Z3enums.INT_SORT && q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - ArithSort(s) - - let arith_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - arith_sort_of_sort (sort_of_ptr ctx no) - - let sgc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gc s) - let sgnc ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gnc s) - let sgno ( x : arith_sort ) = match (x) with ArithSort(Sort(s)) -> (z3obj_gno s) - let egc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gc e) - let egnc ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gnc e) - let egno ( x : arith_expr ) = match (x) with ArithExpr(e) -> (Expr.gno e) - - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val int_expr_of_ptr : context -> Z3native.ptr -> int_expr - val int_num_of_ptr : context -> Z3native.ptr -> int_num - - val arith_sort_of_int_sort : Integer.int_sort -> arith_sort - val int_sort_of_arith_sort : arith_sort -> int_sort - val arith_expr_of_int_expr : int_expr -> arith_expr - val int_expr_of_int_num : int_num -> int_expr - val int_expr_of_arith_expr : arith_expr -> int_expr - val int_num_of_int_expr : int_expr -> int_num - - val mk_sort : context -> int_sort - val get_int : int_num -> int - val to_string : int_num -> string - val mk_const : context -> Symbol.symbol -> int_expr - val mk_const_s : context -> string -> int_expr - val mk_mod : context -> int_expr -> int_expr -> int_expr - val mk_rem : context -> int_expr -> int_expr -> int_expr - val mk_numeral_s : context -> string -> int_num - val mk_numeral_i : context -> int -> int_num - val mk_int2real : context -> int_expr -> Real.real_expr - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end = struct - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - let int_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntExpr(e) - - let int_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let int_num_of_int_expr e = - match e with IntExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - IntNum(e) - - let int_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_num_of_int_expr (int_expr_of_ptr ctx no) - - let arith_sort_of_int_sort s = match s with IntSort(x) -> x - let arith_expr_of_int_expr e = match e with IntExpr(x) -> x - let int_expr_of_int_num e = match e with IntNum(x) -> x - - let int_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.INT_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - IntSort(s) - - let int_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - int_sort_of_arith_sort (arith_sort_of_sort (Sort.sort_of_ptr ctx no)) - - let sgc ( x : int_sort ) = match (x) with IntSort(s) -> (sgc s) - let sgnc ( x : int_sort ) = match (x) with IntSort(s) -> (sgnc s) - let sgno ( x : int_sort ) = match (x) with IntSort(s) -> (sgno s) - let egc ( x : int_expr ) = match (x) with IntExpr(e) -> (egc e) - let egnc ( x : int_expr ) = match (x) with IntExpr(e) -> (egnc e) - let egno ( x : int_expr ) = match (x) with IntExpr(e) -> (egno e) - let ngc ( x : int_num ) = match (x) with IntNum(e) -> (egc e) - let ngnc ( x : int_num ) = match (x) with IntNum(e) -> (egnc e) - let ngno ( x : int_num ) = match (x) with IntNum(e) -> (egno e) - - let mk_sort ( ctx : context ) = - int_sort_of_ptr ctx (Z3native.mk_int_sort (context_gno ctx)) - - let get_int ( x : int_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in - if r then v - else raise (Z3native.Exception "Conversion failed.") - - let to_string ( x : int_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - IntExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with IntSort(ArithSort(s)) -> s))) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_mod ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_mod (context_gno ctx) (egno t1) (egno t2)) - - let mk_rem ( ctx : context ) ( t1 : int_expr ) ( t2 : int_expr ) = - int_expr_of_ptr ctx (Z3native.mk_rem (context_gno ctx) (egno t1) (egno t2)) - - let mk_numeral_s ( ctx : context ) ( v : string ) = - int_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_numeral_i ( ctx : context ) ( v : int ) = - int_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_int2real ( ctx : context ) ( t : int_expr ) = - Real.real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2real (context_gno ctx) (egno t)))) - - let mk_int2bv ( ctx : context ) ( n : int ) ( t : int_expr ) = - BitVector.bitvec_expr_of_expr (Expr.expr_of_ptr ctx (Z3native.mk_int2bv (context_gno ctx) n (egno t))) - end - - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val real_expr_of_ptr : context -> Z3native.ptr -> real_expr - val rat_num_of_ptr : context -> Z3native.ptr -> rat_num - - val arith_sort_of_real_sort : real_sort -> arith_sort - val real_sort_of_arith_sort : arith_sort -> real_sort - val arith_expr_of_real_expr : real_expr -> arith_expr - val real_expr_of_rat_num : rat_num -> real_expr - val real_expr_of_arith_expr : arith_expr -> real_expr - val rat_num_of_real_expr : real_expr -> rat_num - - val mk_sort : context -> real_sort - val get_numerator : rat_num -> Integer.int_num - val get_denominator : rat_num -> Integer.int_num - val to_decimal_string : rat_num -> int -> string - val to_string : rat_num -> string - val mk_const : context -> Symbol.symbol -> real_expr - val mk_const_s : context -> string -> real_expr - val mk_numeral_nd : context -> int -> int -> rat_num - val mk_numeral_s : context -> string -> rat_num - val mk_numeral_i : context -> int -> rat_num - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - val mk_real2int : context -> real_expr -> Integer.int_expr - end = struct - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - let arith_sort_of_real_sort s = match s with RealSort(x) -> x - let arith_expr_of_real_expr e = match e with RealExpr(x) -> x - let real_expr_of_rat_num e = match e with RatNum(x) -> x - - let real_expr_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealExpr(e) - - let real_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_expr_of_arith_expr (arith_expr_of_expr (Expr.expr_of_ptr ctx no)) - - let rat_num_of_real_expr e = - match e with RealExpr(ArithExpr(Expr(a))) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - RatNum(e) - - let rat_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - rat_num_of_real_expr (real_expr_of_ptr ctx no) - - let real_sort_of_arith_sort s = match s with ArithSort(Sort(a)) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.REAL_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - RealSort(s) - - let real_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - real_sort_of_arith_sort (arith_sort_of_sort (sort_of_ptr ctx no)) - - let sgc ( x : real_sort ) = match (x) with RealSort(s) -> (sgc s) - let sgnc ( x : real_sort ) = match (x) with RealSort(s) -> (sgnc s) - let sgno ( x : real_sort ) = match (x) with RealSort(s) -> (sgno s) - let egc ( x : real_expr ) = match (x) with RealExpr(e) -> (egc e) - let egnc ( x : real_expr ) = match (x) with RealExpr(e) -> (egnc e) - let egno ( x : real_expr ) = match (x) with RealExpr(e) -> (egno e) - let ngc ( x : rat_num ) = match (x) with RatNum(e) -> (egc e) - let ngnc ( x : rat_num ) = match (x) with RatNum(e) -> (egnc e) - let ngno ( x : rat_num ) = match (x) with RatNum(e) -> (egno e) - - - let mk_sort ( ctx : context ) = - real_sort_of_ptr ctx (Z3native.mk_real_sort (context_gno ctx)) - - let get_numerator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_numerator (ngnc x) (ngno x)) - - let get_denominator ( x : rat_num ) = - Integer.int_num_of_ptr (ngc x) (Z3native.get_denominator (ngnc x) (ngno x)) - - let to_decimal_string ( x : rat_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - - let to_string ( x : rat_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - - let mk_const ( ctx : context ) ( name : Symbol.symbol ) = - RealExpr(ArithExpr(Expr.mk_const ctx name (match (mk_sort ctx) with RealSort(ArithSort(s)) -> s))) - - let mk_const_s ( ctx : context ) ( name : string ) = - mk_const ctx (Symbol.mk_string ctx name) - - let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = - if (den == 0) then - raise (Z3native.Exception "Denominator is zero") - else - rat_num_of_ptr ctx (Z3native.mk_real (context_gno ctx) num den) - - let mk_numeral_s ( ctx : context ) ( v : string ) = - rat_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_numeral_i ( ctx : context ) ( v : int ) = - rat_num_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (sgno (mk_sort ctx))) - - let mk_is_integer ( ctx : context ) ( t : real_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_is_int (context_gno ctx) (egno t))) - - let mk_real2int ( ctx : context ) ( t : real_expr ) = - Integer.int_expr_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_real2int (context_gno ctx) (egno t)))) - end - - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : algebraic_num -> arith_expr - val algebraic_num_of_arith_expr : arith_expr -> algebraic_num - - val to_upper : algebraic_num -> int -> Real.rat_num - val to_lower : algebraic_num -> int -> Real.rat_num - val to_decimal_string : algebraic_num -> int -> string - val to_string : algebraic_num -> string - end = struct - type algebraic_num = AlgebraicNum of arith_expr - - let arith_expr_of_algebraic_num e = match e with AlgebraicNum(x) -> x - - let algebraic_num_of_arith_expr e = - match e with ArithExpr(Expr(a)) -> - if (not (Z3native.is_algebraic_number (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - AlgebraicNum(e) - - let algebraic_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - algebraic_num_of_arith_expr (arith_expr_of_expr (expr_of_ptr ctx no)) - - let ngc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egc e) - let ngnc ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egnc e) - let ngno ( x : algebraic_num ) = match (x) with AlgebraicNum(e) -> (egno e) - - - let to_upper ( x : algebraic_num ) ( precision : int ) = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_upper (ngnc x) (ngno x) precision) - - let to_lower ( x : algebraic_num ) precision = - Real.rat_num_of_ptr (ngc x) (Z3native.get_algebraic_number_lower (ngnc x) (ngno x) precision) - - let to_decimal_string ( x : algebraic_num ) ( precision : int ) = - Z3native.get_numeral_decimal_string (ngnc x) (ngno x) precision - - let to_string ( x : algebraic_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - end - - let is_int ( x : expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - - let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - - let mk_add ( ctx : context ) ( t : arith_expr list ) = - let f x = (Expr.gno (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_mul ( ctx : context ) ( t : arith_expr list ) = - let f x = (Expr.gno (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_mul (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_sub ( ctx : context ) ( t : arith_expr list ) = - let f x = (Expr.gno (expr_of_arith_expr x)) in - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) - - let mk_unary_minus ( ctx : context ) ( t : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (egno t))) - - let mk_div ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (egno t1) (egno t2))) - - let mk_power ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - arith_expr_of_expr (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (egno t1) (egno t2))) - - let mk_lt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (egno t1) (egno t2))) - - let mk_le ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_le (context_gno ctx) (egno t1) (egno t2))) - - let mk_gt ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_gt (context_gno ctx) (egno t1) (egno t2))) - - let mk_ge ( ctx : context ) ( t1 : arith_expr ) ( t2 : arith_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_ge (context_gno ctx) (egno t1) (egno t2))) -end - - -and BitVector : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - - val mk_sort : context -> int -> bitvec_sort - val is_bv : Expr.expr -> bool - val is_bv_numeral : Expr.expr -> bool - val is_bv_bit1 : Expr.expr -> bool - val is_bv_bit0 : Expr.expr -> bool - val is_bv_uminus : Expr.expr -> bool - val is_bv_add : Expr.expr -> bool - val is_bv_sub : Expr.expr -> bool - val is_bv_mul : Expr.expr -> bool - val is_bv_sdiv : Expr.expr -> bool - val is_bv_udiv : Expr.expr -> bool - val is_bv_SRem : Expr.expr -> bool - val is_bv_urem : Expr.expr -> bool - val is_bv_smod : Expr.expr -> bool - val is_bv_sdiv0 : Expr.expr -> bool - val is_bv_udiv0 : Expr.expr -> bool - val is_bv_srem0 : Expr.expr -> bool - val is_bv_urem0 : Expr.expr -> bool - val is_bv_smod0 : Expr.expr -> bool - val is_bv_ule : Expr.expr -> bool - val is_bv_sle : Expr.expr -> bool - val is_bv_uge : Expr.expr -> bool - val is_bv_sge : Expr.expr -> bool - val is_bv_ult : Expr.expr -> bool - val is_bv_slt : Expr.expr -> bool - val is_bv_ugt : Expr.expr -> bool - val is_bv_sgt : Expr.expr -> bool - val is_bv_and : Expr.expr -> bool - val is_bv_or : Expr.expr -> bool - val is_bv_not : Expr.expr -> bool - val is_bv_xor : Expr.expr -> bool - val is_bv_nand : Expr.expr -> bool - val is_bv_nor : Expr.expr -> bool - val is_bv_xnor : Expr.expr -> bool - val is_bv_concat : Expr.expr -> bool - val is_bv_signextension : Expr.expr -> bool - val is_bv_zeroextension : Expr.expr -> bool - val is_bv_extract : Expr.expr -> bool - val is_bv_repeat : Expr.expr -> bool - val is_bv_reduceor : Expr.expr -> bool - val is_bv_reduceand : Expr.expr -> bool - val is_bv_comp : Expr.expr -> bool - val is_bv_shiftleft : Expr.expr -> bool - val is_bv_shiftrightlogical : Expr.expr -> bool - val is_bv_shiftrightarithmetic : Expr.expr -> bool - val is_bv_rotateleft : Expr.expr -> bool - val is_bv_rotateright : Expr.expr -> bool - val is_bv_rotateleftextended : Expr.expr -> bool - val is_bv_rotaterightextended : Expr.expr -> bool - val is_int_to_bv : Expr.expr -> bool - val is_bv_to_int : Expr.expr -> bool - val is_bv_carry : Expr.expr -> bool - val is_bv_xor3 : Expr.expr -> bool - val get_size : bitvec_sort -> int - val get_int : bitvec_num -> int - val to_string : bitvec_num -> string - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr - val mk_const_s : context -> string -> int -> bitvec_expr - val mk_not : context -> bitvec_expr -> Expr.expr - val mk_redand : context -> bitvec_expr -> Expr.expr - val mk_redor : context -> bitvec_expr -> Expr.expr - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_neg : context -> bitvec_expr -> bitvec_expr - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - val mk_numeral : context -> string -> int -> bitvec_num -end = struct - type bitvec_sort = BitVecSort of sort - type bitvec_expr = BitVecExpr of expr - type bitvec_num = BitVecNum of bitvec_expr - - let sort_of_bitvec_sort s = match s with BitVecSort(x) -> x - - let bitvec_sort_of_sort s = match s with Sort(a) -> - if ((Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) (z3obj_gno a))) != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecSort(s) - - let bitvec_sort_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_sort_of_sort (sort_of_ptr ctx no) - - let bitvec_expr_of_expr e = - match e with Expr(a) -> - let s = Z3native.get_sort (z3obj_gnc a) (z3obj_gno a) in - let q = (Z3enums.sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc a) s)) in - if (q != Z3enums.BV_SORT) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecExpr(e) - - let bitvec_expr_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_expr_of_expr (expr_of_ptr ctx no) - - let bitvec_num_of_bitvec_expr e = - match e with BitVecExpr(Expr(a)) -> - if (not (Z3native.is_numeral_ast (z3obj_gnc a) (z3obj_gno a))) then - raise (Z3native.Exception "Invalid coercion") - else - BitVecNum(e) - - let bitvec_num_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = - bitvec_num_of_bitvec_expr (bitvec_expr_of_expr (expr_of_ptr ctx no)) - - let expr_of_bitvec_expr e = match e with BitVecExpr(x) -> x - let bitvec_expr_of_bitvec_num e = match e with BitVecNum(x) -> x - - - let sgc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gc s) - let sgnc ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gnc s) - let sgno ( x : bitvec_sort ) = match (x) with BitVecSort(s) -> (Sort.gno s) - let egc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gc e) - let egnc ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gnc e) - let egno ( x : bitvec_expr ) = match (x) with BitVecExpr(e) -> (Expr.gno e) - let ngc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egc e) - let ngnc ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egnc e) - let ngno ( x : bitvec_num ) = match (x) with BitVecNum(e) -> (egno e) - - - let mk_sort ( ctx : context ) size = - bitvec_sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) - let is_bv ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) - let get_size (x : bitvec_sort ) = Z3native.get_bv_sort_size (sgnc x) (sgno x) - let get_int ( x : bitvec_num ) = - let (r, v) = Z3native.get_numeral_int (ngnc x) (ngno x) in - if r then v - else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : bitvec_num ) = Z3native.get_numeral_string (ngnc x) (ngno x) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = - BitVecExpr(Expr.mk_const ctx name (match (BitVector.mk_sort ctx size) with BitVecSort(s) -> s)) - let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = - mk_const ctx (Symbol.mk_string ctx name) size - let mk_not ( ctx : context ) ( t : bitvec_expr ) = - expr_of_ptr ctx (Z3native.mk_bvnot (context_gno ctx) (egno t)) - let mk_redand ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredand (context_gno ctx) (egno t)) - let mk_redor ( ctx : context ) ( t : bitvec_expr) = - expr_of_ptr ctx (Z3native.mk_bvredor (context_gno ctx) (egno t)) - let mk_and ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvand (context_gno ctx) (egno t1) (egno t2)) - let mk_or ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvor (context_gno ctx) (egno t1) (egno t2)) - let mk_xor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxor (context_gno ctx) (egno t1) (egno t2)) - let mk_nand ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnand (context_gno ctx) (egno t1) (egno t2)) - let mk_nor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvnor (context_gno ctx) (egno t1) (egno t2)) - let mk_xnor ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvxnor (context_gno ctx) (egno t1) (egno t2)) - let mk_neg ( ctx : context ) ( t : bitvec_expr) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvneg (context_gno ctx) (egno t)) - let mk_add ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvadd (context_gno ctx) (egno t1) (egno t2)) - let mk_sub ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsub (context_gno ctx) (egno t1) (egno t2)) - let mk_mul ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvmul (context_gno ctx) (egno t1) (egno t2)) - let mk_udiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvudiv (context_gno ctx) (egno t1) (egno t2)) - let mk_sdiv ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsdiv (context_gno ctx) (egno t1) (egno t2)) - let mk_urem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvurem (context_gno ctx) (egno t1) (egno t2)) - let mk_srem ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsrem (context_gno ctx) (egno t1) (egno t2)) - let mk_smod ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvsmod (context_gno ctx) (egno t1) (egno t2)) - let mk_ult ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvult (context_gno ctx) (egno t1) (egno t2))) - let mk_slt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvslt (context_gno ctx) (egno t1) (egno t2))) - let mk_ule ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvule (context_gno ctx) (egno t1) (egno t2))) - let mk_sle ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsle (context_gno ctx) (egno t1) (egno t2))) - let mk_uge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvuge (context_gno ctx) (egno t1) (egno t2))) - let mk_sge ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsge (context_gno ctx) (egno t1) (egno t2))) - let mk_ugt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvugt (context_gno ctx) (egno t1) (egno t2))) - let mk_sgt ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsgt (context_gno ctx) (egno t1) (egno t2))) - let mk_concat ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_concat (context_gno ctx) (egno t1) (egno t2)) - let mk_extract ( ctx : context ) ( high : int ) ( low : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_extract (context_gno ctx) high low (egno t)) - let mk_sign_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_sign_ext (context_gno ctx) i (egno t)) - let mk_zero_ext ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_zero_ext (context_gno ctx) i (egno t)) - let mk_repeat ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_repeat (context_gno ctx) i (egno t)) - let mk_shl ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvshl (context_gno ctx) (egno t1) (egno t2)) - let mk_lshr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvlshr (context_gno ctx) (egno t1) (egno t2)) - let mk_ashr ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_bvashr (context_gno ctx) (egno t1) (egno t2)) - let mk_rotate_left ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_left (context_gno ctx) i (egno t)) - let mk_rotate_right ( ctx : context ) ( i : int ) ( t : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_rotate_right (context_gno ctx) i (egno t)) - let mk_ext_rotate_left ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_left (context_gno ctx) (egno t1) (egno t2)) - let mk_ext_rotate_right ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - bitvec_expr_of_ptr ctx (Z3native.mk_ext_rotate_right (context_gno ctx) (egno t1) (egno t2)) - let mk_bv2int ( ctx : context ) ( t : bitvec_expr ) ( signed : bool ) = - Arithmetic.Integer.int_expr_of_ptr ctx (Z3native.mk_bv2int (context_gno ctx) (egno t) signed) - let mk_add_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_add_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvadd_no_underflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_sub_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsub_no_underflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_sdiv_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvsdiv_no_overflow (context_gno ctx) (egno t1) (egno t2))) - let mk_neg_no_overflow ( ctx : context ) ( t : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvneg_no_overflow (context_gno ctx) (egno t))) - let mk_mul_no_overflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) ( signed : bool) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (egno t1) (egno t2) signed)) - let mk_mul_no_underflow ( ctx : context ) ( t1 : bitvec_expr ) ( t2 : bitvec_expr ) = - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (egno t1) (egno t2))) - let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = - bitvec_num_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (sgno (BitVector.mk_sort ctx size))) -end - - -module Proof = -struct - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) -end - - -module Goal = -struct - type goal = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : goal = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.goal_inc_ref ; - dec_ref = Z3native.goal_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_precision ( x : goal ) = - goal_prec_of_int (Z3native.goal_precision (z3obj_gnc x) (z3obj_gno x)) - - let is_precise ( x : goal ) = - (get_precision x) == GOAL_PRECISE - - let is_underapproximation ( x : goal ) = - (get_precision x) == GOAL_UNDER - - let is_overapproximation ( x : goal ) = - (get_precision x) == GOAL_OVER - - let is_garbage ( x : goal ) = - (get_precision x) == GOAL_UNDER_OVER - - let assert_ ( x : goal ) ( constraints : Boolean.bool_expr list ) = - let f e = Z3native.goal_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e) in - ignore (List.map f constraints) ; - () - - let is_inconsistent ( x : goal ) = - Z3native.goal_inconsistent (z3obj_gnc x) (z3obj_gno x) - - let get_depth ( x : goal ) = Z3native.goal_depth (z3obj_gnc x) (z3obj_gno x) - - let reset ( x : goal ) = Z3native.goal_reset (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : goal ) = Z3native.goal_size (z3obj_gnc x) (z3obj_gno x) - - let get_formulas ( x : goal ) = - let n = get_size x in - let f i = (Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) - (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in - mk_list f n - - let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) - - let is_decided_sat ( x : goal ) = - Z3native.goal_is_decided_sat (z3obj_gnc x) (z3obj_gno x) - - let is_decided_unsat ( x : goal ) = - Z3native.goal_is_decided_unsat (z3obj_gnc x) (z3obj_gno x) - - let translate ( x : goal ) ( to_ctx : context ) = - create to_ctx (Z3native.goal_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) - - let simplify ( x : goal ) ( p : Params.params option ) = - let tn = Z3native.mk_tactic (z3obj_gnc x) "simplify" in - Z3native.tactic_inc_ref (z3obj_gnc x) tn ; - let arn = match p with - | None -> Z3native.tactic_apply (z3obj_gnc x) tn (z3obj_gno x) - | Some(pn) -> Z3native.tactic_apply_ex (z3obj_gnc x) tn (z3obj_gno x) (z3obj_gno pn) - in - Z3native.apply_result_inc_ref (z3obj_gnc x) arn ; - let sg = Z3native.apply_result_get_num_subgoals (z3obj_gnc x) arn in - let res = if sg == 0 then - raise (Z3native.Exception "No subgoals") - else - Z3native.apply_result_get_subgoal (z3obj_gnc x) arn 0 in - Z3native.apply_result_dec_ref (z3obj_gnc x) arn ; - Z3native.tactic_dec_ref (z3obj_gnc x) tn ; - create (z3obj_gc x) res - - let mk_goal ( ctx : context ) ( models : bool ) ( unsat_cores : bool ) ( proofs : bool ) = - create ctx (Z3native.mk_goal (context_gno ctx) models unsat_cores proofs) - - let to_string ( x : goal ) = Z3native.goal_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Model = -struct - type model = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : model = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.model_inc_ref ; - dec_ref = Z3native.model_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module FuncInterp = - struct - type func_interp = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : func_interp = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.func_interp_inc_ref ; - dec_ref = Z3native.func_interp_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module FuncEntry = - struct - type func_entry = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : func_entry = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.func_entry_inc_ref ; - dec_ref = Z3native.func_entry_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_value ( x : func_entry ) = - expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_value (z3obj_gnc x) (z3obj_gno x)) - - let get_num_args ( x : func_entry ) = Z3native.func_entry_get_num_args (z3obj_gnc x) (z3obj_gno x) - - let get_args ( x : func_entry ) = - let n = (get_num_args x) in - let f i = (expr_of_ptr (z3obj_gc x) (Z3native.func_entry_get_arg (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let to_string ( x : func_entry ) = - let a = (get_args x) in - let f c p = (p ^ (Expr.to_string c) ^ ", ") in - "[" ^ List.fold_right f a ((Expr.to_string (get_value x)) ^ "]") - end - - let get_num_entries ( x: func_interp ) = Z3native.func_interp_get_num_entries (z3obj_gnc x) (z3obj_gno x) - - let get_entries ( x : func_interp ) = - let n = (get_num_entries x) in - let f i = (FuncEntry.create (z3obj_gc x) (Z3native.func_interp_get_entry (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let get_else ( x : func_interp ) = expr_of_ptr (z3obj_gc x) (Z3native.func_interp_get_else (z3obj_gnc x) (z3obj_gno x)) - - let get_arity ( x : func_interp ) = Z3native.func_interp_get_arity (z3obj_gnc x) (z3obj_gno x) - - let to_string ( x : func_interp ) = - let f c p = ( - let n = (FuncEntry.get_num_args c) in - p ^ - let g c p = (p ^ (Expr.to_string c) ^ ", ") in - (if n > 1 then "[" else "") ^ - (List.fold_right - g - (FuncEntry.get_args c) - ((if n > 1 then "]" else "") ^ " -> " ^ (Expr.to_string (FuncEntry.get_value c)) ^ ", ")) - ) in - List.fold_right f (get_entries x) ("else -> " ^ (Expr.to_string (get_else x)) ^ "]") - end - - let get_const_interp ( x : model ) ( f : func_decl ) = - if (FuncDecl.get_arity f) != 0 || - (sort_kind_of_int (Z3native.get_sort_kind (FuncDecl.gnc f) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) == ARRAY_SORT then - raise (Z3native.Exception "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp.") - else - let np = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in - if (Z3native.is_null np) then - None - else - Some (expr_of_ptr (z3obj_gc x) np) - - let get_const_interp_e ( x : model ) ( a : expr ) = get_const_interp x (Expr.get_func_decl a) - - - let rec get_func_interp ( x : model ) ( f : func_decl ) = - let sk = (sort_kind_of_int (Z3native.get_sort_kind (z3obj_gnc x) (Z3native.get_range (FuncDecl.gnc f) (FuncDecl.gno f)))) in - if (FuncDecl.get_arity f) == 0 then - let n = Z3native.model_get_const_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) in - if (Z3native.is_null n) then - None - else - match sk with - | ARRAY_SORT -> - if not (Z3native.is_as_array (z3obj_gnc x) n) then - raise (Z3native.Exception "Argument was not an array constant") - else - let fd = Z3native.get_as_array_func_decl (z3obj_gnc x) n in - get_func_interp x (func_decl_of_ptr (z3obj_gc x) fd) - | _ -> raise (Z3native.Exception "Constant functions do not have a function interpretation; use ConstInterp"); - else - let n = (Z3native.model_get_func_interp (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f)) in - if (Z3native.is_null n) then None else Some (FuncInterp.create (z3obj_gc x) n) - - (** The number of constants that have an interpretation in the model. *) - let get_num_consts ( x : model ) = Z3native.model_get_num_consts (z3obj_gnc x) (z3obj_gno x) - - let get_const_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) - - let get_func_decls ( x : model ) = - let n = (get_num_consts x) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_decls ( x : model ) = - let n_funcs = (get_num_funcs x) in - let n_consts = (get_num_consts x ) in - let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in - let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in - (mk_list f n_funcs) @ (mk_list g n_consts) - - exception ModelEvaluationFailedException of string - - let eval ( x : model ) ( t : expr ) ( completion : bool ) = - let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in - if not r then - raise (ModelEvaluationFailedException "evaluation failed") - else - expr_of_ptr (z3obj_gc x) v - - let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = - eval x t completion - - let get_num_sorts ( x : model ) = Z3native.model_get_num_sorts (z3obj_gnc x) (z3obj_gno x) - - let get_sorts ( x : model ) = - let n = (get_num_sorts x) in - let f i = (sort_of_ptr (z3obj_gc x) (Z3native.model_get_sort (z3obj_gnc x) (z3obj_gno x) i)) in - mk_list f n - - let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in - let n = (AST.ASTVector.get_size n_univ) in - let f i = (AST.ASTVector.get n_univ i) in - mk_list f n - - let to_string ( x : model ) = Z3native.model_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Probe = -struct - type probe = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : probe = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.probe_inc_ref ; - dec_ref = Z3native.probe_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - - let apply ( x : probe ) ( g : Goal.goal ) = - Z3native.probe_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) - - let get_num_probes ( ctx : context ) = - Z3native.get_num_probes (context_gno ctx) - - let get_probe_names ( ctx : context ) = - let n = (get_num_probes ctx) in - let f i = (Z3native.get_probe_name (context_gno ctx) i) in - mk_list f n - - let get_probe_description ( ctx : context ) ( name : string ) = - Z3native.probe_get_descr (context_gno ctx) name - - let mk_probe ( ctx : context ) ( name : string ) = - (create ctx (Z3native.mk_probe (context_gno ctx) name)) - - let const ( ctx : context ) ( v : float ) = - (create ctx (Z3native.probe_const (context_gno ctx) v)) - - let lt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_lt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let gt ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_gt (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let le ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_le (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let ge ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_ge (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let eq ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_eq (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let and_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_and (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let or_ ( ctx : context ) ( p1 : probe ) ( p2 : probe ) = - (create ctx (Z3native.probe_or (context_gno ctx) (z3obj_gno p1) (z3obj_gno p2))) - - let not_ ( ctx : context ) ( p : probe ) = - (create ctx (Z3native.probe_not (context_gno ctx) (z3obj_gno p))) -end - - -module Tactic = -struct - type tactic = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : tactic = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.tactic_inc_ref ; - dec_ref = Z3native.tactic_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - module ApplyResult = - struct - type apply_result = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : apply_result = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.apply_result_inc_ref ; - dec_ref = Z3native.apply_result_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let get_num_subgoals ( x : apply_result ) = - Z3native.apply_result_get_num_subgoals (z3obj_gnc x) (z3obj_gno x) - - let get_subgoals ( x : apply_result ) = - let n = (get_num_subgoals x) in - let f i = Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get_subgoal ( x : apply_result ) ( i : int ) = - Goal.create (z3obj_gc x) (Z3native.apply_result_get_subgoal (z3obj_gnc x) (z3obj_gno x) i) - - let convert_model ( x : apply_result ) ( i : int ) ( m : Model.model ) = - Model.create (z3obj_gc x) (Z3native.apply_result_convert_model (z3obj_gnc x) (z3obj_gno x) i (z3obj_gno m)) - - let to_string ( x : apply_result ) = Z3native.apply_result_to_string (z3obj_gnc x) (z3obj_gno x) - end - - let get_help ( x : tactic ) = Z3native.tactic_get_help (z3obj_gnc x) (z3obj_gno x) - - let get_param_descrs ( x : tactic ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.tactic_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let apply ( x : tactic ) ( g : Goal.goal ) ( p : Params.params option ) = - match p with - | None -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g))) - | Some (pn) -> (ApplyResult.create (z3obj_gc x) (Z3native.tactic_apply_ex (z3obj_gnc x) (z3obj_gno x) (z3obj_gno g) (z3obj_gno pn))) - - let get_num_tactics ( ctx : context ) = Z3native.get_num_tactics (context_gno ctx) - - let get_tactic_names ( ctx : context ) = - let n = (get_num_tactics ctx ) in - let f i = (Z3native.get_tactic_name (context_gno ctx) i) in - mk_list f n - - let get_tactic_description ( ctx : context ) ( name : string ) = - Z3native.tactic_get_descr (context_gno ctx) name - - let mk_tactic ( ctx : context ) ( name : string ) = - create ctx (Z3native.mk_tactic (context_gno ctx) name) - - let and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) ( ts : tactic list ) = - let f p c = (match p with - | None -> (Some (z3obj_gno c)) - | Some(x) -> (Some (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno c) x))) in - match (List.fold_left f None ts) with - | None -> - create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - | Some(x) -> - let o = (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t2) x) in - create ctx (Z3native.tactic_and_then (context_gno ctx) (z3obj_gno t1) o) - - let or_else ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_or_else (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - - let try_for ( ctx : context ) ( t : tactic ) ( ms : int ) = - create ctx (Z3native.tactic_try_for (context_gno ctx) (z3obj_gno t) ms) - - let when_ ( ctx : context ) ( p : Probe.probe ) ( t : tactic ) = - create ctx (Z3native.tactic_when (context_gno ctx) (z3obj_gno p) (z3obj_gno t)) - - let cond ( ctx : context ) ( p : Probe.probe ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_cond (context_gno ctx) (z3obj_gno p) (z3obj_gno t1) (z3obj_gno t2)) - - let repeat ( ctx : context ) ( t : tactic ) ( max : int ) = - create ctx (Z3native.tactic_repeat (context_gno ctx) (z3obj_gno t) max) - - let skip ( ctx : context ) = - create ctx (Z3native.tactic_skip (context_gno ctx)) - - let fail ( ctx : context ) = - create ctx (Z3native.tactic_fail (context_gno ctx)) - - let fail_if ( ctx : context ) ( p : Probe.probe ) = - create ctx (Z3native.tactic_fail_if (context_gno ctx) (z3obj_gno p)) - - let fail_if_not_decided ( ctx : context ) = - create ctx (Z3native.tactic_fail_if_not_decided (context_gno ctx)) - - let using_params ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - create ctx (Z3native.tactic_using_params (context_gno ctx) (z3obj_gno t) (z3obj_gno p)) - - let with_ ( ctx : context ) ( t : tactic ) ( p : Params.params ) = - using_params ctx t p - - let par_or ( ctx : context ) ( t : tactic list ) = - let f e = (z3obj_gno e) in - create ctx (Z3native.tactic_par_or (context_gno ctx) (List.length t) (Array.of_list (List.map f t))) - - let par_and_then ( ctx : context ) ( t1 : tactic ) ( t2 : tactic ) = - create ctx (Z3native.tactic_par_and_then (context_gno ctx) (z3obj_gno t1) (z3obj_gno t2)) - - let interrupt ( ctx : context ) = - Z3native.interrupt (context_gno ctx) -end - - -module Solver = -struct - type solver = z3_native_object - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : solver = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.solver_inc_ref ; - dec_ref = Z3native.solver_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - let string_of_status ( s : status) = match s with - | UNSATISFIABLE -> "unsatisfiable" - | SATISFIABLE -> "satisfiable" - | _ -> "unknown" - - module Statistics = - struct - type statistics = z3_native_object - - let create ( ctx : context ) ( no : Z3native.ptr ) = - let res : statistics = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.stats_inc_ref ; - dec_ref = Z3native.stats_dec_ref } in - (z3obj_sno res ctx no) ; - (z3obj_create res) ; - res - - - module Entry = - struct - type statistics_entry = { - mutable m_key : string; - mutable m_is_int : bool ; - mutable m_is_float : bool ; - mutable m_int : int ; - mutable m_float : float } - - let create_si k v = - let res : statistics_entry = { - m_key = k ; - m_is_int = true ; - m_is_float = false ; - m_int = v ; - m_float = 0.0 - } in - res - - let create_sd k v = - let res : statistics_entry = { - m_key = k ; - m_is_int = false ; - m_is_float = true ; - m_int = 0 ; - m_float = v - } in - res - - - let get_key (x : statistics_entry) = x.m_key - let get_int (x : statistics_entry) = x.m_int - let get_float (x : statistics_entry) = x.m_float - let is_int (x : statistics_entry) = x.m_is_int - let is_float (x : statistics_entry) = x.m_is_float - let to_string_value (x : statistics_entry) = - if (is_int x) then - string_of_int (get_int x) - else if (is_float x) then - string_of_float (get_float x) - else - raise (Z3native.Exception "Unknown statistical entry type") - let to_string ( x : statistics_entry ) = (get_key x) ^ ": " ^ (to_string_value x) - end - - let to_string ( x : statistics ) = Z3native.stats_to_string (z3obj_gnc x) (z3obj_gno x) - - let get_size ( x : statistics ) = Z3native.stats_size (z3obj_gnc x) (z3obj_gno x) - - let get_entries ( x : statistics ) = - let n = (get_size x ) in - let f i = ( - let k = Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i in - if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then - (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) - else - (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) - ) in - mk_list f n - - let get_keys ( x : statistics ) = - let n = (get_size x) in - let f i = (Z3native.stats_get_key (z3obj_gnc x) (z3obj_gno x) i) in - mk_list f n - - let get ( x : statistics ) ( key : string ) = - let f p c = (if ((Entry.get_key c) == key) then (Some c) else p) in - List.fold_left f None (get_entries x) - end - - let get_help ( x : solver ) = Z3native.solver_get_help (z3obj_gnc x) (z3obj_gno x) - - let set_parameters ( x : solver ) ( p : Params.params )= - Z3native.solver_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - - let get_param_descrs ( x : solver ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.solver_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let get_num_scopes ( x : solver ) = Z3native.solver_get_num_scopes (z3obj_gnc x) (z3obj_gno x) - - let push ( x : solver ) = Z3native.solver_push (z3obj_gnc x) (z3obj_gno x) - - let pop ( x : solver ) ( n : int ) = Z3native.solver_pop (z3obj_gnc x) (z3obj_gno x) n - - let reset ( x : solver ) = Z3native.solver_reset (z3obj_gnc x) (z3obj_gno x) - - let assert_ ( x : solver ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.solver_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (List.map f constraints) - - let assert_and_track_a ( x : solver ) ( cs : Boolean.bool_expr list ) ( ps : Boolean.bool_expr list ) = - if ((List.length cs) != (List.length ps)) then - raise (Z3native.Exception "Argument size mismatch") - else - let f a b = (Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno a) (Boolean.gno b)) in - ignore (List.iter2 f cs ps) - - let assert_and_track ( x : solver ) ( c : Boolean.bool_expr ) ( p : Boolean.bool_expr ) = - Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Boolean.gno c) (Boolean.gno p) - - let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - (AST.ASTVector.get_size a) - - let get_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size a) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in - mk_list f n - - let check ( x : solver ) ( assumptions : Boolean.bool_expr list ) = - let r = - if ((List.length assumptions) == 0) then - lbool_of_int (Z3native.solver_check (z3obj_gnc x) (z3obj_gno x)) - else - let f x = (Expr.gno (Boolean.expr_of_bool_expr x)) in - lbool_of_int (Z3native.solver_check_assumptions (z3obj_gnc x) (z3obj_gno x) (List.length assumptions) (Array.of_list (List.map f assumptions))) - in - match r with - | L_TRUE -> SATISFIABLE - | L_FALSE -> UNSATISFIABLE - | _ -> UNKNOWN - - let get_model ( x : solver ) = - let q = Z3native.solver_get_model (z3obj_gnc x) (z3obj_gno x) in - if (Z3native.is_null q) then - None - else - Some (Model.create (z3obj_gc x) q) - - let get_proof ( x : solver ) = - let q = Z3native.solver_get_proof (z3obj_gnc x) (z3obj_gno x) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in - let n = (AST.ASTVector.get_size cn) in - let f i = (AST.ASTVector.get cn i) in - mk_list f n - - let get_reason_unknown ( x : solver ) = Z3native.solver_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - let get_statistics ( x : solver ) = - (Statistics.create (z3obj_gc x) (Z3native.solver_get_statistics (z3obj_gnc x) (z3obj_gno x))) - - let mk_solver ( ctx : context ) ( logic : Symbol.symbol option ) = - match logic with - | None -> (create ctx (Z3native.mk_solver (context_gno ctx))) - | Some (x) -> (create ctx (Z3native.mk_solver_for_logic (context_gno ctx) (Symbol.gno x))) - - let mk_solver_s ( ctx : context ) ( logic : string ) = - mk_solver ctx (Some (Symbol.mk_string ctx logic)) - - let mk_simple_solver ( ctx : context ) = - (create ctx (Z3native.mk_simple_solver (context_gno ctx))) - - let mk_solver_t ( ctx : context ) ( t : Tactic.tactic ) = - (create ctx (Z3native.mk_solver_from_tactic (context_gno ctx) (z3obj_gno t))) - - let to_string ( x : solver ) = Z3native.solver_to_string (z3obj_gnc x) (z3obj_gno x) -end - - -module Fixedpoint = -struct - type fixedpoint = z3_native_object - - let create ( ctx : context ) = - let res : fixedpoint = { m_ctx = ctx ; - m_n_obj = null ; - inc_ref = Z3native.fixedpoint_inc_ref ; - dec_ref = Z3native.fixedpoint_dec_ref } in - (z3obj_sno res ctx (Z3native.mk_fixedpoint (context_gno ctx))) ; - (z3obj_create res) ; - res - - - let get_help ( x : fixedpoint ) = - Z3native.fixedpoint_get_help (z3obj_gnc x) (z3obj_gno x) - - let set_params ( x : fixedpoint ) ( p : Params.params )= - Z3native.fixedpoint_set_params (z3obj_gnc x) (z3obj_gno x) (z3obj_gno p) - - let get_param_descrs ( x : fixedpoint ) = - Params.ParamDescrs.param_descrs_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_param_descrs (z3obj_gnc x) (z3obj_gno x)) - - let assert_ ( x : fixedpoint ) ( constraints : Boolean.bool_expr list ) = - let f e = (Z3native.fixedpoint_assert (z3obj_gnc x) (z3obj_gno x) (Boolean.gno e)) in - ignore (List.map f constraints) ; - () - - let register_relation ( x : fixedpoint ) ( f : func_decl ) = - Z3native.fixedpoint_register_relation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) - - let add_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol option ) = - match name with - | None -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) null - | Some(y) -> Z3native.fixedpoint_add_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno y) - - let add_fact ( x : fixedpoint ) ( pred : func_decl ) ( args : int list ) = - Z3native.fixedpoint_add_fact (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno pred) (List.length args) (Array.of_list args) - - let query ( x : fixedpoint ) ( query : Boolean.bool_expr ) = - match (lbool_of_int (Z3native.fixedpoint_query (z3obj_gnc x) (z3obj_gno x) (Boolean.gno query))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN - - let query_r ( x : fixedpoint ) ( relations : func_decl list ) = - let f x = ptr_of_ast (ast_of_func_decl x) in - match (lbool_of_int (Z3native.fixedpoint_query_relations (z3obj_gnc x) (z3obj_gno x) (List.length relations) (Array.of_list (List.map f relations)))) with - | L_TRUE -> Solver.SATISFIABLE - | L_FALSE -> Solver.UNSATISFIABLE - | _ -> Solver.UNKNOWN - - let push ( x : fixedpoint ) = - Z3native.fixedpoint_push (z3obj_gnc x) (z3obj_gno x) - - let pop ( x : fixedpoint ) = - Z3native.fixedpoint_pop (z3obj_gnc x) (z3obj_gno x) - - let update_rule ( x : fixedpoint ) ( rule : Boolean.bool_expr ) ( name : Symbol.symbol ) = - Z3native.fixedpoint_update_rule (z3obj_gnc x) (z3obj_gno x) (Boolean.gno rule) (Symbol.gno name) - - let get_answer ( x : fixedpoint ) = - let q = (Z3native.fixedpoint_get_answer (z3obj_gnc x) (z3obj_gno x)) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let get_reason_unknown ( x : fixedpoint ) = - Z3native.fixedpoint_get_reason_unknown (z3obj_gnc x) (z3obj_gno x) - - let get_num_levels ( x : fixedpoint ) ( predicate : func_decl ) = - Z3native.fixedpoint_get_num_levels (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno predicate) - - let get_cover_delta ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) = - let q = (Z3native.fixedpoint_get_cover_delta (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate)) in - if (Z3native.is_null q) then - None - else - Some (expr_of_ptr (z3obj_gc x) q) - - let add_cover ( x : fixedpoint ) ( level : int ) ( predicate : func_decl ) ( property : expr ) = - Z3native.fixedpoint_add_cover (z3obj_gnc x) (z3obj_gno x) level (FuncDecl.gno predicate) (Expr.gno property) - - let to_string ( x : fixedpoint ) = Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) 0 [||] - - let set_predicate_representation ( x : fixedpoint ) ( f : func_decl ) ( kinds : Symbol.symbol list ) = - Z3native.fixedpoint_set_predicate_representation (z3obj_gnc x) (z3obj_gno x) (FuncDecl.gno f) (List.length kinds) (Symbol.symbol_lton kinds) - - let to_string_q ( x : fixedpoint ) ( queries : Boolean.bool_expr list ) = - let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in - Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) - - let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - mk_list f n - - let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in - let n = (AST.ASTVector.get_size v) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in - mk_list f n - - let mk_fixedpoint ( ctx : context ) = create ctx -end - -module Options = -struct - - let update_param_value ( ctx : context ) ( id : string) ( value : string )= - Z3native.update_param_value (context_gno ctx) id value - - let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in - if not r then - None - else - Some v - - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = - Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) - - let toggle_warning_messages ( enabled: bool ) = - Z3native.toggle_warning_messages enabled -end - - -module SMT = -struct - let benchmark_to_smtstring ( ctx : context ) ( name : string ) ( logic : string ) ( status : string ) ( attributes : string ) ( assumptions : Boolean.bool_expr list ) ( formula : Boolean.bool_expr ) = - Z3native.benchmark_to_smtlib_string (context_gno ctx) name logic status attributes - (List.length assumptions) (let f x = ptr_of_expr (Boolean.expr_of_bool_expr x) in (Array.of_list (List.map f assumptions))) - (Boolean.gno formula) - - let parse_smtlib_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Z3native.parse_smtlib_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - - let parse_smtlib_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Z3native.parse_smtlib_file (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))) - - let get_num_smtlib_formulas ( ctx : context ) = Z3native.get_smtlib_num_formulas (context_gno ctx) - - let get_smtlib_formulas ( ctx : context ) = - let n = (get_num_smtlib_formulas ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_formula (context_gno ctx) i)) in - mk_list f n - - let get_num_smtlib_assumptions ( ctx : context ) = Z3native.get_smtlib_num_assumptions (context_gno ctx) - - let get_smtlib_assumptions ( ctx : context ) = - let n = (get_num_smtlib_assumptions ctx ) in - let f i = Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.get_smtlib_assumption (context_gno ctx) i)) in - mk_list f n - - let get_num_smtlib_decls ( ctx : context ) = Z3native.get_smtlib_num_decls (context_gno ctx) - - let get_smtlib_decls ( ctx : context ) = - let n = (get_num_smtlib_decls ctx) in - let f i = func_decl_of_ptr ctx (Z3native.get_smtlib_decl (context_gno ctx) i) in - mk_list f n - - let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - - let get_smtlib_sorts ( ctx : context ) = - let n = (get_num_smtlib_sorts ctx) in - let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in - mk_list f n - - let parse_smtlib2_string ( ctx : context ) ( str : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) str - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) - - let parse_smtlib2_file ( ctx : context ) ( file_name : string ) ( sort_names : Symbol.symbol list ) ( sorts : sort list ) ( decl_names : Symbol.symbol list ) ( decls : func_decl list ) = - let csn = (List.length sort_names) in - let cs = (List.length sorts) in - let cdn = (List.length decl_names) in - let cd = (List.length decls) in - if (csn != cs || cdn != cd) then - raise (Z3native.Exception "Argument size mismatch") - else - Boolean.bool_expr_of_expr (expr_of_ptr ctx (Z3native.parse_smtlib2_string (context_gno ctx) file_name - cs - (Symbol.symbol_lton sort_names) - (sort_lton sorts) - cd - (Symbol.symbol_lton decl_names) - (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) -end - - -let set_global_param ( id : string ) ( value : string ) = - (Z3native.global_param_set id value) - -let get_global_param ( id : string ) = - let (r, v) = (Z3native.global_param_get id) in - if not r then - None - else - Some v - -let global_param_reset_all = - Z3native.global_param_reset_all diff --git a/src/api/ml/z3_rich.mli b/src/api/ml/z3_rich.mli deleted file mode 100644 index f2ecd326d..000000000 --- a/src/api/ml/z3_rich.mli +++ /dev/null @@ -1,3071 +0,0 @@ -(** - The Z3 ML/Ocaml Interface. - - Copyright (C) 2012 Microsoft Corporation - @author CM Wintersteiger (cwinter) 2012-12-17 - - NOTE: This is the *rich* version of the interface, using more - type information directly in the type system. Coercion functions - are provided to tran coerce on type into another where applicable. -*) - -(** Context objects. - - Most interactions with Z3 are interpreted in some context; many users will only - require one such object, but power users may require more than one. To start using - Z3, do - - - let ctx = (mk_context []) in - (...) - - - where a list of pairs of strings may be passed to set options on - the context, e.g., like so: - - - let cfg = [("model", "true"); ("...", "...")] in - let ctx = (mk_context cfg) in - (...) - -*) -type context - -(** Create a context object *) -val mk_context : (string * string) list -> context - -(** Interaction logging for Z3 - Note that this is a global, static log and if multiple Context - objects are created, it logs the interaction with all of them. *) -module Log : -sig - (** Open an interaction log file. - @return True if opening the log file succeeds, false otherwise. *) - (* CMW: "open" seems to be a reserved keyword? *) - val open_ : string -> bool - - (** Closes the interaction log. *) - val close : unit - - (** Appends a user-provided string to the interaction log. *) - val append : string -> unit -end - -(** Version information *) -module Version : -sig - (** The major version. *) - val major : int - - (** The minor version. *) - val minor : int - - (** The build version. *) - val build : int - - (** The revision. *) - val revision : int - - (** A string representation of the version information. *) - val to_string : string -end - -(** Symbols are used to name several term and type constructors *) -module Symbol : -sig - (** Numbered Symbols *) - type int_symbol - - (** Named Symbols *) - type string_symbol - - (** Symbols *) - type symbol = S_Int of int_symbol | S_Str of string_symbol - - (** The kind of the symbol (int or string) *) - val kind : symbol -> Z3enums.symbol_kind - - (** Indicates whether the symbol is of Int kind *) - val is_int_symbol : symbol -> bool - - (** Indicates whether the symbol is of string kind. *) - val is_string_symbol : symbol -> bool - - (** The int value of the symbol. *) - val get_int : int_symbol -> int - - (** The string value of the symbol. *) - val get_string : string_symbol -> string - - (** A string representation of the symbol. *) - val to_string : symbol -> string - - (** Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. *) - val mk_int : context -> int -> symbol - - (** Creates a new symbol using a string. *) - val mk_string : context -> string -> symbol - - (** Create a list of symbols. *) - val mk_ints : context -> int list -> symbol list - - (** Create a list of symbols. *) - val mk_strings : context -> string list -> symbol list -end - -(** The abstract syntax tree (AST) module *) -module AST : -sig - type ast - - (** Vectors of ASTs *) - module ASTVector : - sig - type ast_vector - - (** The size of the vector *) - val get_size : ast_vector -> int - - (** - Retrieves the i-th object in the vector. - @return An AST *) - val get : ast_vector -> int -> ast - - (** Sets the i-th object in the vector. *) - val set : ast_vector -> int -> ast -> unit - - (** Resize the vector to a new size. *) - val resize : ast_vector -> int -> unit - - (** Add an ast to the back of the vector. The size - is increased by 1. *) - val push : ast_vector -> ast -> unit - - (** Translates all ASTs in the vector to another context. - @return A new ASTVector *) - val translate : ast_vector -> context -> ast_vector - - (** Retrieves a string representation of the vector. *) - val to_string : ast_vector -> string - end - - (** Map from AST to AST *) - module ASTMap : - sig - type ast_map - - (** Checks whether the map contains a key. - @return True if the key in the map, false otherwise. *) - val contains : ast_map -> ast -> bool - - (** Finds the value associated with the key. - This function signs an error when the key is not a key in the map. *) - val find : ast_map -> ast -> ast - - (** Stores or replaces a new key/value pair in the map. *) - val insert : ast_map -> ast -> ast -> unit - - (** Erases the key from the map.*) - val erase : ast_map -> ast -> unit - - (** Removes all keys from the map. *) - val reset : ast_map -> unit - - (** The size of the map *) - val get_size : ast_map -> int - - (** The keys stored in the map. *) - val get_keys : ast_map -> ast list - - (** Retrieves a string representation of the map.*) - val to_string : ast_map -> string - end - - (** The AST's hash code. - @return A hash code *) - val get_hash_code : ast -> int - - (** A unique identifier for the AST (unique among all ASTs). *) - val get_id : ast -> int - - (** The kind of the AST. *) - val get_ast_kind : ast -> Z3enums.ast_kind - - (** Indicates whether the AST is an Expr *) - val is_expr : ast -> bool - - (** Indicates whether the AST is a bound variable*) - val is_var : ast -> bool - - (** Indicates whether the AST is a Quantifier *) - val is_quantifier : ast -> bool - - (** Indicates whether the AST is a Sort *) - val is_sort : ast -> bool - - (** Indicates whether the AST is a func_decl *) - val is_func_decl : ast -> bool - - (** A string representation of the AST. *) - val to_string : ast -> string - - (** A string representation of the AST in s-expression notation. *) - val to_sexpr : ast -> string - - (** Comparison operator. - @return True if the two ast's are from the same context - and represent the same sort; false otherwise. *) - val ( = ) : ast -> ast -> bool - - (** Object Comparison. - @return Negative if the first ast should be sorted before the second, positive if after else zero. *) - val compare : ast -> ast -> int - - (** Operator < *) - val ( < ) : ast -> ast -> int - - (** Translates (copies) the AST to another context. - @return A copy of the AST which is associated with the other context. *) - val translate : ast -> context -> ast - - (** Wraps an AST. - - This function is used for transitions between native and - managed objects. Note that the native ast that is passed must be a - native object obtained from Z3 (e.g., through {!unwrap_ast}) - and that it must have a correct reference count (see e.g., - Z3native.inc_ref). *) - val wrap_ast : context -> Z3native.z3_ast -> ast - - (** Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - Z3native.inc_ref). - {!wrap_ast} *) - val unwrap_ast : ast -> Z3native.ptr -end - -(** The Sort module implements type information for ASTs *) -module Sort : -sig - (** Sorts *) - type sort = Sort of AST.ast - - (** Uninterpreted Sorts *) - type uninterpreted_sort = UninterpretedSort of sort - - val ast_of_sort : sort -> AST.ast - val sort_of_uninterpreted_sort : uninterpreted_sort -> sort - val uninterpreted_sort_of_sort : sort -> uninterpreted_sort - - (** Comparison operator. - @return True if the two sorts are from the same context - and represent the same sort; false otherwise. *) - val ( = ) : sort -> sort -> bool - - (** Returns a unique identifier for the sort. *) - val get_id : sort -> int - - (** The kind of the sort. *) - val get_sort_kind : sort -> Z3enums.sort_kind - - (** The name of the sort *) - val get_name : sort -> Symbol.symbol - - (** A string representation of the sort. *) - val to_string : sort -> string - - (** Create a new uninterpreted sort. *) - val mk_uninterpreted : context -> Symbol.symbol -> uninterpreted_sort - - (** Create a new uninterpreted sort. *) - val mk_uninterpreted_s : context -> string -> uninterpreted_sort -end - -(** Function declarations *) -module rec FuncDecl : -sig - type func_decl = FuncDecl of AST.ast - - val ast_of_func_decl : FuncDecl.func_decl -> AST.ast - - (** Parameters of Func_Decls *) - module Parameter : - sig - (** Parameters of func_decls *) - type parameter = - P_Int of int - | P_Dbl of float - | P_Sym of Symbol.symbol - | P_Srt of Sort.sort - | P_Ast of AST.ast - | P_Fdl of func_decl - | P_Rat of string - - (** The kind of the parameter. *) - val get_kind : parameter -> Z3enums.parameter_kind - - (** The int value of the parameter.*) - val get_int : parameter -> int - - (** The double value of the parameter.*) - val get_float : parameter -> float - - (** The Symbol.Symbol value of the parameter.*) - val get_symbol : parameter -> Symbol.symbol - - (** The Sort value of the parameter.*) - val get_sort : parameter -> Sort.sort - - (** The AST value of the parameter.*) - val get_ast : parameter -> AST.ast - - (** The FunctionDeclaration value of the parameter.*) - val get_func_decl : parameter -> func_decl - - (** The rational string value of the parameter.*) - val get_rational : parameter -> string - end - - (** Creates a new function declaration. *) - val mk_func_decl : context -> Symbol.symbol -> Sort.sort list -> Sort.sort -> func_decl - - (** Creates a new function declaration. *) - val mk_func_decl_s : context -> string -> Sort.sort list -> Sort.sort -> func_decl - (** Creates a fresh function declaration with a name prefixed with a prefix string. *) - - val mk_fresh_func_decl : context -> string -> Sort.sort list -> Sort.sort -> func_decl - - (** Creates a new constant function declaration. *) - val mk_const_decl : context -> Symbol.symbol -> Sort.sort -> func_decl - - (** Creates a new constant function declaration. *) - val mk_const_decl_s : context -> string -> Sort.sort -> func_decl - - (** Creates a fresh constant function declaration with a name prefixed with a prefix string. - {!mk_func_decl} - {!mk_func_decl} *) - val mk_fresh_const_decl : context -> string -> Sort.sort -> func_decl - - (** Comparison operator. - @return True if a and b are from the same context and represent the same func_decl; false otherwise. *) - val ( = ) : func_decl -> func_decl -> bool - - (** A string representations of the function declaration. *) - val to_string : func_decl -> string - - (** Returns a unique identifier for the function declaration. *) - val get_id : func_decl -> int - - (** The arity of the function declaration *) - val get_arity : func_decl -> int - - (** The size of the domain of the function declaration - {!get_arity} *) - val get_domain_size : func_decl -> int - - (** The domain of the function declaration *) - val get_domain : func_decl -> Sort.sort list - - (** The range of the function declaration *) - val get_range : func_decl -> Sort.sort - - (** The kind of the function declaration. *) - val get_decl_kind : func_decl -> Z3enums.decl_kind - - (** The name of the function declaration*) - val get_name : func_decl -> Symbol.symbol - - (** The number of parameters of the function declaration *) - val get_num_parameters : func_decl -> int - - (** The parameters of the function declaration *) - val get_parameters : func_decl -> Parameter.parameter list - - (** Create expression that applies function to arguments. *) - val apply : func_decl -> Expr.expr list -> Expr.expr -end - -(** Parameter sets (of Solvers, Tactics, ...) - - A Params objects represents a configuration in the form of Symbol.symbol/value pairs. *) -and Params : -sig - type params - - (** ParamDescrs describe sets of parameters (of Solvers, Tactics, ...) *) - module ParamDescrs : - sig - type param_descrs - - (** Validate a set of parameters. *) - val validate : param_descrs -> params -> unit - - (** Retrieve kind of parameter. *) - val get_kind : param_descrs -> Symbol.symbol -> Z3enums.param_kind - - (** Retrieve all names of parameters. *) - val get_names : param_descrs -> Symbol.symbol list - - (** The size of the ParamDescrs. *) - val get_size : param_descrs -> int - - (** Retrieves a string representation of the ParamDescrs. *) - val to_string : param_descrs -> string - end - - (** Adds a parameter setting. *) - val add_bool : params -> Symbol.symbol -> bool -> unit - - (** Adds a parameter setting. *) - val add_int : params -> Symbol.symbol -> int -> unit - - (** Adds a parameter setting. *) - val add_double : params -> Symbol.symbol -> float -> unit - - (** Adds a parameter setting. *) - val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit - - (** Adds a parameter setting. *) - val add_s_bool : params -> string -> bool -> unit - - (** Adds a parameter setting. *) - val add_s_int : params -> string -> int -> unit - - (** Adds a parameter setting. *) - val add_s_double : params -> string -> float -> unit - - (** Adds a parameter setting. *) - val add_s_symbol : params -> string -> Symbol.symbol -> unit - - (** Creates a new parameter set *) - val mk_params : context -> params - - (** A string representation of the parameter set. *) - val to_string : params -> string -end - -(** General Expressions (terms) *) -and Expr : -sig - type expr = Expr of AST.ast - - val ast_of_expr : Expr.expr -> AST.ast - val expr_of_ast : AST.ast -> Expr.expr - - (** Returns a simplified version of the expression. - {!get_simplify_help} *) - val simplify : Expr.expr -> Params.params option -> expr - - (** A string describing all available parameters to Expr.Simplify. *) - val get_simplify_help : context -> string - - (** Retrieves parameter descriptions for simplifier. *) - val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs - - (** The function declaration of the function that is applied in this expression. *) - val get_func_decl : Expr.expr -> FuncDecl.func_decl - - (** Indicates whether the expression is the true or false expression - or something else (L_UNDEF). *) - val get_bool_value : Expr.expr -> Z3enums.lbool - - (** The number of arguments of the expression. *) - val get_num_args : Expr.expr -> int - - (** The arguments of the expression. *) - val get_args : Expr.expr -> Expr.expr list - - (** Update the arguments of the expression using an array of expressions. - The number of new arguments should coincide with the current number of arguments. *) - val update : Expr.expr -> Expr.expr list -> expr - - (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. - - The result is the new expression. The arrays from and to must have size num_exprs. - For every i smaller than num_exprs, we must have that - sort of from[i] must be equal to sort of to[i]. *) - val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr - - (** Substitute every occurrence of from in the expression with to. - {!substitute} *) - val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr - - (** Substitute the free variables in the expression with the expressions in the expr array - - For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) - val substitute_vars : Expr.expr -> Expr.expr list -> expr - - (** Translates (copies) the term to another context. - @return A copy of the term which is associated with the other context *) - val translate : Expr.expr -> context -> expr - - (** Returns a string representation of the expression. *) - val to_string : Expr.expr -> string - - (** Indicates whether the term is a numeral *) - val is_numeral : Expr.expr -> bool - - (** Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. *) - val is_well_sorted : Expr.expr -> bool - - (** The Sort of the term. *) - val get_sort : Expr.expr -> Sort.sort - - (** Indicates whether the term has Boolean sort. *) - val is_bool : Expr.expr -> bool - - (** Indicates whether the term represents a constant. *) - val is_const : Expr.expr -> bool - - (** Indicates whether the term is the constant true. *) - val is_true : Expr.expr -> bool - - (** Indicates whether the term is the constant false. *) - val is_false : Expr.expr -> bool - - (** Indicates whether the term is an equality predicate. *) - val is_eq : Expr.expr -> bool - - (** Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). *) - val is_distinct : Expr.expr -> bool - - (** Indicates whether the term is a ternary if-then-else term *) - val is_ite : Expr.expr -> bool - - (** Indicates whether the term is an n-ary conjunction *) - val is_and : Expr.expr -> bool - - (** Indicates whether the term is an n-ary disjunction *) - val is_or : Expr.expr -> bool - - (** Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) *) - val is_iff : Expr.expr -> bool - - (** Indicates whether the term is an exclusive or *) - val is_xor : Expr.expr -> bool - - (** Indicates whether the term is a negation *) - val is_not : Expr.expr -> bool - - (** Indicates whether the term is an implication *) - val is_implies : Expr.expr -> bool - - (** Indicates whether the term is a label (used by the Boogie Verification condition generator). - The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. *) - val is_label : Expr.expr -> bool - - (** Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - A label literal has a set of string parameters. It takes no arguments. - let is_label_lit ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_LABEL_LIT) *) - val is_label_lit : Expr.expr -> bool - - (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) - val is_oeq : Expr.expr -> bool - - (** Creates a new constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - - (** Creates a new constant. *) - val mk_const_s : context -> string -> Sort.sort -> expr - - (** Creates a constant from the func_decl. *) - val mk_const_f : context -> FuncDecl.func_decl -> expr - - (** Creates a fresh constant with a name prefixed with a string. *) - val mk_fresh_const : context -> string -> Sort.sort -> expr - - (** Create a new function application. *) - val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - - (** Create a numeral of a given sort. - @return A Term with the goven value and sort *) - val mk_numeral_string : context -> string -> Sort.sort -> expr - - (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. - @return A Term with the given value and sort *) - val mk_numeral_int : context -> int -> Sort.sort -> expr -end - -(** Boolean expressions *) -module Boolean : -sig - type bool_sort = BoolSort of Sort.sort - type bool_expr = BoolExpr of Expr.expr - - val expr_of_bool_expr : bool_expr -> Expr.expr - val sort_of_bool_sort : bool_sort -> Sort.sort - val bool_sort_of_sort : Sort.sort -> bool_sort - val bool_expr_of_expr : Expr.expr -> bool_expr - - (** Create a Boolean sort *) - val mk_sort : context -> bool_sort - - (** Create a Boolean constant. *) - val mk_const : context -> Symbol.symbol -> bool_expr - - (** Create a Boolean constant. *) - val mk_const_s : context -> string -> bool_expr - - (** The true Term. *) - val mk_true : context -> bool_expr - - (** The false Term. *) - val mk_false : context -> bool_expr - - (** Creates a Boolean value. *) - val mk_val : context -> bool -> bool_expr - - (** Creates the equality between two expr's. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> bool_expr - - (** Creates a distinct term. *) - val mk_distinct : context -> Expr.expr list -> bool_expr - - (** Mk an expression representing not(a). *) - val mk_not : context -> bool_expr -> bool_expr - - (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) - val mk_ite : context -> bool_expr -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing t1 iff t2. *) - val mk_iff : context -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing t1 -> t2. *) - val mk_implies : context -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing t1 xor t2. *) - val mk_xor : context -> bool_expr -> bool_expr -> bool_expr - - (** Create an expression representing the AND of args *) - val mk_and : context -> bool_expr list -> bool_expr - - (** Create an expression representing the OR of args *) - val mk_or : context -> bool_expr list -> bool_expr -end - -(** Quantifier expressions *) -module Quantifier : -sig - type quantifier = Quantifier of Expr.expr - - val expr_of_quantifier : quantifier -> Expr.expr - val quantifier_of_expr : Expr.expr -> quantifier - - (** Quantifier patterns - - Patterns comprise a list of terms. The list should be - non-empty. If the list comprises of more than one term, it is - also called a multi-pattern. *) - module Pattern : - sig - type pattern = Pattern of AST.ast - - val ast_of_pattern : pattern -> AST.ast - val pattern_of_ast : AST.ast -> pattern - - (** The number of terms in the pattern. *) - val get_num_terms : pattern -> int - - (** The terms in the pattern. *) - val get_terms : pattern -> Expr.expr list - - (** A string representation of the pattern. *) - val to_string : pattern -> string - end - - - (** The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. *) - val get_index : Expr.expr -> int - - (** Indicates whether the quantifier is universal. *) - val is_universal : quantifier -> bool - - (** Indicates whether the quantifier is existential. *) - val is_existential : quantifier -> bool - - (** The weight of the quantifier. *) - val get_weight : quantifier -> int - - (** The number of patterns. *) - val get_num_patterns : quantifier -> int - - (** The patterns. *) - val get_patterns : quantifier -> Pattern.pattern list - - (** The number of no-patterns. *) - val get_num_no_patterns : quantifier -> int - - (** The no-patterns. *) - val get_no_patterns : quantifier -> Pattern.pattern list - - (** The number of bound variables. *) - val get_num_bound : quantifier -> int - - (** The symbols for the bound variables. *) - val get_bound_variable_names : quantifier -> Symbol.symbol list - - (** The sorts of the bound variables. *) - val get_bound_variable_sorts : quantifier -> Sort.sort list - - (** The body of the quantifier. *) - val get_body : quantifier -> Boolean.bool_expr - - (** Creates a new bound variable. *) - val mk_bound : context -> int -> Sort.sort -> Expr.expr - - (** Create a quantifier pattern. *) - val mk_pattern : context -> Expr.expr list -> Pattern.pattern - - (** Create a universal Quantifier. *) - val mk_forall : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a universal Quantifier. *) - val mk_forall_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create an existential Quantifier. *) - val mk_exists : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create an existential Quantifier. *) - val mk_exists_const : context -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a Quantifier. *) - val mk_quantifier : context -> Sort.sort list -> Symbol.symbol list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - - (** Create a Quantifier. *) - val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier -end - -(** Functions to manipulate Array expressions *) -module Array_ : -sig - type array_sort = ArraySort of Sort.sort - type array_expr = ArrayExpr of Expr.expr - - val sort_of_array_sort : array_sort -> Sort.sort - val array_sort_of_sort : Sort.sort -> array_sort - val expr_of_array_expr : array_expr -> Expr.expr - - val array_expr_of_expr : Expr.expr -> array_expr - - (** Create a new array sort. *) - val mk_sort : context -> Sort.sort -> Sort.sort -> array_sort - - (** Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. *) - val is_store : Expr.expr -> bool - - (** Indicates whether the term is an array select. *) - val is_select : Expr.expr -> bool - - (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. *) - val is_constant_array : Expr.expr -> bool - - (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. *) - val is_default_array : Expr.expr -> bool - - (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) - val is_array_map : Expr.expr -> bool - - (** Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. *) - val is_as_array : Expr.expr -> bool - - (** Indicates whether the term is of an array sort. *) - val is_array : Expr.expr -> bool - - (** The domain of the array sort. *) - val get_domain : array_sort -> Sort.sort - - (** The range of the array sort. *) - val get_range : array_sort -> Sort.sort - - (** Create an array constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> array_expr - - (** Create an array constant. *) - val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> array_expr - - (** Array read. - - The argument a is the array and i is the index - of the array that gets read. - - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. - {!Array_.mk_sort} - {!mk_store} *) - val mk_select : context -> array_expr -> Expr.expr -> array_expr - - (** Array update. - - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). - {!Array_.mk_sort} - {!mk_select} *) - val mk_store : context -> array_expr -> Expr.expr -> Expr.expr -> array_expr - - (** Create a constant array. - - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. - {!Array_.mk_sort} - {!mk_select} *) - val mk_const_array : context -> Sort.sort -> Expr.expr -> array_expr - - (** Maps f on the argument arrays. - - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. - {!Array_.mk_sort} - {!mk_select} - {!mk_store} *) - val mk_map : context -> FuncDecl.func_decl -> array_expr list -> array_expr - - (** Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. *) - val mk_term_array : context -> array_expr -> array_expr -end - -(** Functions to manipulate Set expressions *) -module Set : -sig - type set_sort = SetSort of Sort.sort - - val sort_of_set_sort : set_sort -> Sort.sort - - (** Create a set type. *) - val mk_sort : context -> Sort.sort -> set_sort - - (** Indicates whether the term is set union *) - val is_union : Expr.expr -> bool - - (** Indicates whether the term is set intersection *) - val is_intersect : Expr.expr -> bool - - (** Indicates whether the term is set difference *) - val is_difference : Expr.expr -> bool - - (** Indicates whether the term is set complement *) - val is_complement : Expr.expr -> bool - - (** Indicates whether the term is set subset *) - val is_subset : Expr.expr -> bool - - (** Create an empty set. *) - val mk_empty : context -> Sort.sort -> Expr.expr - - (** Create the full set. *) - val mk_full : context -> Sort.sort -> Expr.expr - - (** Add an element to the set. *) - val mk_set_add : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Remove an element from a set. *) - val mk_del : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Take the union of a list of sets. *) - val mk_union : context -> Expr.expr list -> Expr.expr - - (** Take the intersection of a list of sets. *) - val mk_intersection : context -> Expr.expr list -> Expr.expr - - (** Take the difference between two sets. *) - val mk_difference : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Take the complement of a set. *) - val mk_complement : context -> Expr.expr -> Expr.expr - - (** Check for set membership. *) - val mk_membership : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Check for subsetness of sets. *) - val mk_subset : context -> Expr.expr -> Expr.expr -> Expr.expr -end - -(** Functions to manipulate Finite Domain expressions *) -module FiniteDomain : -sig - type finite_domain_sort = FiniteDomainSort of Sort.sort - - val sort_of_finite_domain_sort : finite_domain_sort -> Sort.sort - val finite_domain_sort_of_sort : Sort.sort -> finite_domain_sort - - (** Create a new finite domain sort. *) - val mk_sort : context -> Symbol.symbol -> int -> finite_domain_sort - - (** Create a new finite domain sort. *) - val mk_sort_s : context -> string -> int -> finite_domain_sort - - (** Indicates whether the term is of an array sort. *) - val is_finite_domain : Expr.expr -> bool - - (** Indicates whether the term is a less than predicate over a finite domain. *) - val is_lt : Expr.expr -> bool - - (** The size of the finite domain sort. *) - val get_size : finite_domain_sort -> int -end - - -(** Functions to manipulate Relation expressions *) -module Relation : -sig - type relation_sort = RelationSort of Sort.sort - - val sort_of_relation_sort : relation_sort -> Sort.sort - val relation_sort_of_sort : Sort.sort -> relation_sort - - (** Indicates whether the term is of a relation sort. *) - val is_relation : Expr.expr -> bool - - (** Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. *) - val is_store : Expr.expr -> bool - - (** Indicates whether the term is an empty relation *) - val is_empty : Expr.expr -> bool - - (** Indicates whether the term is a test for the emptiness of a relation *) - val is_is_empty : Expr.expr -> bool - - (** Indicates whether the term is a relational join *) - val is_join : Expr.expr -> bool - - (** Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. *) - val is_union : Expr.expr -> bool - - (** Indicates whether the term is the widening of two relations - The function takes two arguments. *) - val is_widen : Expr.expr -> bool - - (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. *) - val is_project : Expr.expr -> bool - - (** Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. *) - val is_filter : Expr.expr -> bool - - (** Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. *) - val is_negation_filter : Expr.expr -> bool - - (** Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. *) - val is_rename : Expr.expr -> bool - - (** Indicates whether the term is the complement of a relation *) - val is_complement : Expr.expr -> bool - - (** Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. *) - val is_select : Expr.expr -> bool - - (** Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind {!is_union} - to perform destructive updates to the first argument. *) - val is_clone : Expr.expr -> bool - - (** The arity of the relation sort. *) - val get_arity : relation_sort -> int - - (** The sorts of the columns of the relation sort. *) - val get_column_sorts : relation_sort -> relation_sort list -end - -(** Functions to manipulate Datatype expressions *) -module Datatype : -sig - type datatype_sort = DatatypeSort of Sort.sort - type datatype_expr = DatatypeExpr of Expr.expr - - val sort_of_datatype_sort : datatype_sort -> Sort.sort - val datatype_sort_of_sort : Sort.sort -> datatype_sort - val expr_of_datatype_expr : datatype_expr -> Expr.expr - val datatype_expr_of_expr : Expr.expr -> datatype_expr - - (** Datatype Constructors *) - module Constructor : - sig - type constructor - - (** The number of fields of the constructor. *) - val get_num_fields : constructor -> int - - (** The function declaration of the constructor. *) - val get_constructor_decl : constructor -> FuncDecl.func_decl - - (** The function declaration of the tester. *) - val get_tester_decl : constructor -> FuncDecl.func_decl - - (** The function declarations of the accessors *) - val get_accessor_decls : constructor -> FuncDecl.func_decl list - end - - (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) - val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor - - (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) - val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor - - (** Create a new datatype sort. *) - val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> datatype_sort - - (** Create a new datatype sort. *) - val mk_sort_s : context -> string -> Constructor.constructor list -> datatype_sort - - (** Create mutually recursive datatypes. *) - val mk_sorts : context -> Symbol.symbol list -> Constructor.constructor list list -> datatype_sort list - - (** Create mutually recursive data-types. *) - val mk_sorts_s : context -> string list -> Constructor.constructor list list -> datatype_sort list - - - (** The number of constructors of the datatype sort. *) - val get_num_constructors : datatype_sort -> int - - (** The constructors. *) - val get_constructors : datatype_sort -> FuncDecl.func_decl list - - (** The recognizers. *) - val get_recognizers : datatype_sort -> FuncDecl.func_decl list - - (** The constructor accessors. *) - val get_accessors : datatype_sort -> FuncDecl.func_decl list list -end - -(** Functions to manipulate Enumeration expressions *) -module Enumeration : -sig - type enum_sort = EnumSort of Sort.sort - - val sort_of_enum_sort : enum_sort -> Sort.sort - - (** Create a new enumeration sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> enum_sort - - (** Create a new enumeration sort. *) - val mk_sort_s : context -> string -> string list -> enum_sort - - (** The function declarations of the constants in the enumeration. *) - val get_const_decls : enum_sort -> FuncDecl.func_decl list - - (** The test predicates for the constants in the enumeration. *) - val get_tester_decls : enum_sort -> FuncDecl.func_decl list -end - -(** Functions to manipulate List expressions *) -module List_ : -sig - type list_sort = ListSort of Sort.sort - - val sort_of_list_sort : list_sort -> Sort.sort - - (** Create a new list sort. *) - val mk_sort : context -> Symbol.symbol -> Sort.sort -> list_sort - - (** Create a new list sort. *) - val mk_list_s : context -> string -> Sort.sort -> list_sort - - (** The declaration of the nil function of this list sort. *) - val get_nil_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the isNil function of this list sort. *) - val get_is_nil_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the cons function of this list sort. *) - val get_cons_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the isCons function of this list sort. *) - val get_is_cons_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the head function of this list sort. *) - val get_head_decl : list_sort -> FuncDecl.func_decl - - (** The declaration of the tail function of this list sort. *) - val get_tail_decl : list_sort -> FuncDecl.func_decl - - (** The empty list. *) - val nil : list_sort -> Expr.expr -end - -(** Functions to manipulate Tuple expressions *) -module Tuple : -sig - type tuple_sort = TupleSort of Sort.sort - - val sort_of_tuple_sort : tuple_sort -> Sort.sort - - (** Create a new tuple sort. *) - val mk_sort : context -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> tuple_sort - - (** The constructor function of the tuple. *) - val get_mk_decl : tuple_sort -> FuncDecl.func_decl - - (** The number of fields in the tuple. *) - val get_num_fields : tuple_sort -> int - - (** The field declarations. *) - val get_field_decls : tuple_sort -> FuncDecl.func_decl list -end - -(** Functions to manipulate arithmetic expressions *) -module rec Arithmetic : -sig - type arith_sort = ArithSort of Sort.sort - type arith_expr = ArithExpr of Expr.expr - - val sort_of_arith_sort : Arithmetic.arith_sort -> Sort.sort - val arith_sort_of_sort : Sort.sort -> Arithmetic.arith_sort - val expr_of_arith_expr : Arithmetic.arith_expr -> Expr.expr - val arith_expr_of_expr : Expr.expr -> Arithmetic.arith_expr - - (** Integer Arithmetic *) - module rec Integer : - sig - type int_sort = IntSort of arith_sort - type int_expr = IntExpr of arith_expr - type int_num = IntNum of int_expr - - val arith_sort_of_int_sort : Arithmetic.Integer.int_sort -> Arithmetic.arith_sort - val int_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Integer.int_sort - val arith_expr_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.arith_expr - val int_expr_of_int_num : Arithmetic.Integer.int_num -> Arithmetic.Integer.int_expr - val int_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Integer.int_expr - val int_num_of_int_expr : Arithmetic.Integer.int_expr -> Arithmetic.Integer.int_num - - (** Create a new integer sort. *) - val mk_sort : context -> int_sort - - (** Retrieve the int value. *) - val get_int : int_num -> int - - (** Returns a string representation of the numeral. *) - val to_string : int_num -> string - - (** Creates an integer constant. *) - val mk_const : context -> Symbol.symbol -> int_expr - - (** Creates an integer constant. *) - val mk_const_s : context -> string -> int_expr - - (** Create an expression representing t1 mod t2. - The arguments must have int type. *) - val mk_mod : context -> int_expr -> int_expr -> int_expr - - (** Create an expression representing t1 rem t2. - The arguments must have int type. *) - val mk_rem : context -> int_expr -> int_expr -> int_expr - - (** Create an integer numeral. *) - val mk_numeral_s : context -> string -> int_num - - (** Create an integer numeral. - @return A Term with the given value and sort Integer *) - val mk_numeral_i : context -> int -> int_num - - (** Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - The argument must be of integer sort. *) - val mk_int2real : context -> int_expr -> Real.real_expr - - (** Create an n-bit bit-vector from an integer argument. - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. *) - val mk_int2bv : context -> int -> int_expr -> BitVector.bitvec_expr - end - - (** Real Arithmetic *) - and Real : - sig - type real_sort = RealSort of arith_sort - type real_expr = RealExpr of arith_expr - type rat_num = RatNum of real_expr - - val arith_sort_of_real_sort : Arithmetic.Real.real_sort -> Arithmetic.arith_sort - val real_sort_of_arith_sort : Arithmetic.arith_sort -> Arithmetic.Real.real_sort - val arith_expr_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.arith_expr - val real_expr_of_rat_num : Arithmetic.Real.rat_num -> Arithmetic.Real.real_expr - val real_expr_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.Real.real_expr - val rat_num_of_real_expr : Arithmetic.Real.real_expr -> Arithmetic.Real.rat_num - - (** Create a real sort. *) - val mk_sort : context -> real_sort - - (** The numerator of a rational numeral. *) - val get_numerator : rat_num -> Integer.int_num - - (** The denominator of a rational numeral. *) - val get_denominator : rat_num -> Integer.int_num - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as indicated by the int argument.*) - val to_decimal_string : rat_num -> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : rat_num -> string - - (** Creates a real constant. *) - val mk_const : context -> Symbol.symbol -> real_expr - - (** Creates a real constant. *) - val mk_const_s : context -> string -> real_expr - - (** Create a real numeral from a fraction. - @return A Term with rational value and sort Real - {!mk_numeral_s} *) - val mk_numeral_nd : context -> int -> int -> rat_num - - (** Create a real numeral. - @return A Term with the given value and sort Real *) - val mk_numeral_s : context -> string -> rat_num - - (** Create a real numeral. - @return A Term with the given value and sort Real *) - val mk_numeral_i : context -> int -> rat_num - - (** Creates an expression that checks whether a real number is an integer. *) - val mk_is_integer : context -> real_expr -> Boolean.bool_expr - - (** Coerce a real to an integer. - - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. *) - val mk_real2int : context -> real_expr -> Integer.int_expr - end - - (** Algebraic Numbers *) - and AlgebraicNumber : - sig - type algebraic_num = AlgebraicNum of arith_expr - - val arith_expr_of_algebraic_num : Arithmetic.AlgebraicNumber.algebraic_num -> Arithmetic.arith_expr - val algebraic_num_of_arith_expr : Arithmetic.arith_expr -> Arithmetic.AlgebraicNumber.algebraic_num - - (** Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_upper : algebraic_num -> int -> Real.rat_num - - (** Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) - val to_lower : algebraic_num -> int -> Real.rat_num - - (** Returns a string representation in decimal notation. - The result has at most as many decimal places as the int argument provided.*) - val to_decimal_string : algebraic_num -> int -> string - - (** Returns a string representation of the numeral. *) - val to_string : algebraic_num -> string - end - - (** Indicates whether the term is of integer sort. *) - val is_int : Expr.expr -> bool - - (** Indicates whether the term is an arithmetic numeral. *) - val is_arithmetic_numeral : Expr.expr -> bool - - (** Indicates whether the term is a less-than-or-equal *) - val is_le : Expr.expr -> bool - - (** Indicates whether the term is a greater-than-or-equal *) - val is_ge : Expr.expr -> bool - - (** Indicates whether the term is a less-than *) - val is_lt : Expr.expr -> bool - - (** Indicates whether the term is a greater-than *) - val is_gt : Expr.expr -> bool - - (** Indicates whether the term is addition (binary) *) - val is_add : Expr.expr -> bool - - (** Indicates whether the term is subtraction (binary) *) - val is_sub : Expr.expr -> bool - - (** Indicates whether the term is a unary minus *) - val is_uminus : Expr.expr -> bool - - (** Indicates whether the term is multiplication (binary) *) - val is_mul : Expr.expr -> bool - - (** Indicates whether the term is division (binary) *) - val is_div : Expr.expr -> bool - - (** Indicates whether the term is integer division (binary) *) - val is_idiv : Expr.expr -> bool - - (** Indicates whether the term is remainder (binary) *) - val is_remainder : Expr.expr -> bool - - (** Indicates whether the term is modulus (binary) *) - val is_modulus : Expr.expr -> bool - - (** Indicates whether the term is a coercion of integer to real (unary) *) - val is_inttoreal : Expr.expr -> bool - - (** Indicates whether the term is a coercion of real to integer (unary) *) - val is_real_to_int : Expr.expr -> bool - - (** Indicates whether the term is a check that tests whether a real is integral (unary) *) - val is_real_is_int : Expr.expr -> bool - - (** Indicates whether the term is of sort real. *) - val is_real : Expr.expr -> bool - - (** Indicates whether the term is an integer numeral. *) - val is_int_numeral : Expr.expr -> bool - - (** Indicates whether the term is a real numeral. *) - val is_rat_num : Expr.expr -> bool - - (** Indicates whether the term is an algebraic number *) - val is_algebraic_number : Expr.expr -> bool - - (** Create an expression representing t[0] + t[1] + .... *) - val mk_add : context -> arith_expr list -> arith_expr - - (** Create an expression representing t[0] * t[1] * .... *) - val mk_mul : context -> arith_expr list -> arith_expr - - (** Create an expression representing t[0] - t[1] - .... *) - val mk_sub : context -> arith_expr list -> arith_expr - - (** Create an expression representing -t. *) - val mk_unary_minus : context -> arith_expr -> arith_expr - - (** Create an expression representing t1 / t2. *) - val mk_div : context -> arith_expr -> arith_expr -> arith_expr - - (** Create an expression representing t1 ^ t2. *) - val mk_power : context -> arith_expr -> arith_expr -> arith_expr - - (** Create an expression representing t1 < t2 *) - val mk_lt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - - (** Create an expression representing t1 <= t2 *) - val mk_le : context -> arith_expr -> arith_expr -> Boolean.bool_expr - - (** Create an expression representing t1 > t2 *) - val mk_gt : context -> arith_expr -> arith_expr -> Boolean.bool_expr - - (** Create an expression representing t1 >= t2 *) - val mk_ge : context -> arith_expr -> arith_expr -> Boolean.bool_expr -end - -(** Functions to manipulate bit-vector expressions *) -and BitVector : -sig - type bitvec_sort = BitVecSort of Sort.sort - type bitvec_expr = BitVecExpr of Expr.expr - type bitvec_num = BitVecNum of bitvec_expr - - val sort_of_bitvec_sort : BitVector.bitvec_sort -> Sort.sort - val bitvec_sort_of_sort : Sort.sort -> BitVector.bitvec_sort - val expr_of_bitvec_expr : BitVector.bitvec_expr -> Expr.expr - val bitvec_expr_of_bitvec_num : BitVector.bitvec_num -> BitVector.bitvec_expr - val bitvec_expr_of_expr : Expr.expr -> BitVector.bitvec_expr - val bitvec_num_of_bitvec_expr : BitVector.bitvec_expr -> BitVector.bitvec_num - - (** Create a new bit-vector sort. *) - val mk_sort : context -> int -> bitvec_sort - - (** Indicates whether the terms is of bit-vector sort. *) - val is_bv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector numeral *) - val is_bv_numeral : Expr.expr -> bool - - (** Indicates whether the term is a one-bit bit-vector with value one *) - val is_bv_bit1 : Expr.expr -> bool - - (** Indicates whether the term is a one-bit bit-vector with value zero *) - val is_bv_bit0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unary minus *) - val is_bv_uminus : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector addition (binary) *) - val is_bv_add : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector subtraction (binary) *) - val is_bv_sub : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector multiplication (binary) *) - val is_bv_mul : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed division (binary) *) - val is_bv_sdiv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned division (binary) *) - val is_bv_udiv : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed remainder (binary) *) - val is_bv_SRem : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned remainder (binary) *) - val is_bv_urem : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed modulus *) - val is_bv_smod : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed division by zero *) - val is_bv_sdiv0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned division by zero *) - val is_bv_udiv0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed remainder by zero *) - val is_bv_srem0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector unsigned remainder by zero *) - val is_bv_urem0 : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector signed modulus by zero *) - val is_bv_smod0 : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector less-than-or-equal *) - val is_bv_ule : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector less-than-or-equal *) - val is_bv_sle : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector greater-than-or-equal *) - val is_bv_uge : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector greater-than-or-equal *) - val is_bv_sge : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector less-than *) - val is_bv_ult : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector less-than *) - val is_bv_slt : Expr.expr -> bool - - (** Indicates whether the term is an unsigned bit-vector greater-than *) - val is_bv_ugt : Expr.expr -> bool - - (** Indicates whether the term is a signed bit-vector greater-than *) - val is_bv_sgt : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise AND *) - val is_bv_and : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise OR *) - val is_bv_or : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NOT *) - val is_bv_not : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise XOR *) - val is_bv_xor : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NAND *) - val is_bv_nand : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise NOR *) - val is_bv_nor : Expr.expr -> bool - - (** Indicates whether the term is a bit-wise XNOR *) - val is_bv_xnor : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector concatenation (binary) *) - val is_bv_concat : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector sign extension *) - val is_bv_signextension : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector zero extension *) - val is_bv_zeroextension : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector extraction *) - val is_bv_extract : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector repetition *) - val is_bv_repeat : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector reduce OR *) - val is_bv_reduceor : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector reduce AND *) - val is_bv_reduceand : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector comparison *) - val is_bv_comp : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector shift left *) - val is_bv_shiftleft : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector logical shift right *) - val is_bv_shiftrightlogical : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector arithmetic shift left *) - val is_bv_shiftrightarithmetic : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate left *) - val is_bv_rotateleft : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate right *) - val is_bv_rotateright : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) - val is_bv_rotateleftextended : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) - val is_bv_rotaterightextended : Expr.expr -> bool - - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - - (** Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - val is_int_to_bv : Expr.expr -> bool - - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - val is_bv_to_int : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) - val is_bv_carry : Expr.expr -> bool - - (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) - val is_bv_xor3 : Expr.expr -> bool - - (** The size of a bit-vector sort. *) - val get_size : bitvec_sort -> int - - (** Retrieve the int value. *) - val get_int : bitvec_num -> int - - (** Returns a string representation of the numeral. *) - val to_string : bitvec_num -> string - - (** Creates a bit-vector constant. *) - val mk_const : context -> Symbol.symbol -> int -> bitvec_expr - - (** Creates a bit-vector constant. *) - val mk_const_s : context -> string -> int -> bitvec_expr - - (** Bitwise negation. - The argument must have a bit-vector sort. *) - val mk_not : context -> bitvec_expr -> Expr.expr - - (** Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) - val mk_redand : context -> bitvec_expr -> Expr.expr - - (** Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) - val mk_redor : context -> bitvec_expr -> Expr.expr - - (** Bitwise conjunction. - The arguments must have a bit-vector sort. *) - val mk_and : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise disjunction. - The arguments must have a bit-vector sort. *) - val mk_or : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise XOR. - The arguments must have a bit-vector sort. *) - val mk_xor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise NAND. - The arguments must have a bit-vector sort. *) - val mk_nand : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise NOR. - The arguments must have a bit-vector sort. *) - val mk_nor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bitwise XNOR. - The arguments must have a bit-vector sort. *) - val mk_xnor : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Standard two's complement unary minus. - The arguments must have a bit-vector sort. *) - val mk_neg : context -> bitvec_expr -> bitvec_expr - - (** Two's complement addition. - The arguments must have the same bit-vector sort. *) - val mk_add : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Two's complement subtraction. - The arguments must have the same bit-vector sort. *) - val mk_sub : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Two's complement multiplication. - The arguments must have the same bit-vector sort. *) - val mk_mul : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Unsigned division. - - - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. *) - val mk_udiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Signed division. - - It is defined in the following way: - - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_sdiv : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Unsigned remainder. - - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_urem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Signed remainder. - - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_srem : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Two's complement signed remainder (sign follows divisor). - - If t2 is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) - val mk_smod : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Unsigned less-than - - The arguments must have the same bit-vector sort. *) - val mk_ult : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed less-than - - The arguments must have the same bit-vector sort. *) - val mk_slt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_ule : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_sle : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_uge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. *) - val mk_sge : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Unsigned greater-than. - - The arguments must have the same bit-vector sort. *) - val mk_ugt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. *) - val mk_sgt : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). *) - val mk_concat : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Bit-vector extraction. - - Extract the bits between two limits from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. *) - val mk_extract : context -> int -> int -> bitvec_expr -> bitvec_expr - - (** Bit-vector sign extension. - - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. *) - val mk_sign_ext : context -> int -> bitvec_expr -> bitvec_expr - - (** Bit-vector zero extension. - - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the - given bit-vector. *) - val mk_zero_ext : context -> int -> bitvec_expr -> bitvec_expr - - (** Bit-vector repetition. *) - val mk_repeat : context -> int -> bitvec_expr -> bitvec_expr - - (** Shift left. - - It is equivalent to multiplication by 2^x where \c x is the value of third argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling.*) - val mk_shl : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Logical shift right - - It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. *) - val mk_lshr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. - - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. - - The arguments must have a bit-vector sort. *) - val mk_ashr : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Rotate Left. - Rotate bits of \c t to the left \c i times. *) - val mk_rotate_left : context -> int -> bitvec_expr -> bitvec_expr - - (** Rotate Right. - Rotate bits of \c t to the right \c i times.*) - val mk_rotate_right : context -> int -> bitvec_expr -> bitvec_expr - - (** Rotate Left. - Rotate bits of the second argument to the left.*) - val mk_ext_rotate_left : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Rotate Right. - Rotate bits of the second argument to the right. *) - val mk_ext_rotate_right : context -> bitvec_expr -> bitvec_expr -> bitvec_expr - - (** Create an integer from the bit-vector argument - - If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where - N are the number of bits in the argument. - If \c is_signed is true, \c t1 is treated as a signed bit-vector. - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function.*) - val mk_bv2int : context -> bitvec_expr -> bool -> Arithmetic.Integer.int_expr - - (** Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_add_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_add_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_sub_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_sub_no_underflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_sdiv_no_overflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_neg_no_overflow : context -> bitvec_expr -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_overflow : context -> bitvec_expr -> bitvec_expr -> bool -> Boolean.bool_expr - - (** Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_underflow : context -> bitvec_expr -> bitvec_expr -> Boolean.bool_expr - - (** Create a bit-vector numeral. *) - val mk_numeral : context -> string -> int -> bitvec_num -end - -(** Functions to manipulate proof expressions *) -module Proof : -sig - (** Indicates whether the term is a Proof for the expression 'true'. *) - val is_true : Expr.expr -> bool - - (** Indicates whether the term is a proof for a fact asserted by the user. *) - val is_asserted : Expr.expr -> bool - - (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) - val is_goal : Expr.expr -> bool - - (** Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). *) - val is_modus_ponens : Expr.expr -> bool - - (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. *) - val is_reflexivity : Expr.expr -> bool - - (** Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. *) - val is_symmetry : Expr.expr -> bool - - (** Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) *) - val is_transitivity : Expr.expr -> bool - - (** Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. *) - val is_Transitivity_star : Expr.expr -> bool - - (** Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. *) - val is_monotonicity : Expr.expr -> bool - - (** Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) - val is_quant_intro : Expr.expr -> bool - - (** Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. *) - val is_distributivity : Expr.expr -> bool - - (** Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i *) - val is_and_elimination : Expr.expr -> bool - - (** Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) *) - val is_or_elimination : Expr.expr -> bool - - (** Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) *) - val is_rewrite : Expr.expr -> bool - - (** Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) - val is_rewrite_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) - val is_pull_quant : Expr.expr -> bool - - (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents *) - val is_pull_quant_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents *) - val is_push_quant : Expr.expr -> bool - - (** Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. *) - val is_elim_unused_vars : Expr.expr -> bool - - (** Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. *) - val is_der : Expr.expr -> bool - - (** Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) *) - val is_quant_inst : Expr.expr -> bool - - (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. *) - val is_hypothesis : Expr.expr -> bool - - (** Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. *) - val is_lemma : Expr.expr -> bool - - (** Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) - val is_unit_resolution : Expr.expr -> bool - - (** Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) *) - val is_iff_true : Expr.expr -> bool - - (** Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) *) - val is_iff_false : Expr.expr -> bool - - (** Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. *) - val is_commutativity : Expr.expr -> bool - - (** Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). *) - val is_def_axiom : Expr.expr -> bool - - (** Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) *) - val is_def_intro : Expr.expr -> bool - - (** Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. *) - val is_apply_def : Expr.expr -> bool - - (** Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) *) - val is_iff_oeq : Expr.expr -> bool - - (** Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. *) - val is_nnf_pos : Expr.expr -> bool - - (** Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) *) - val is_nnf_neg : Expr.expr -> bool - - (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - val is_nnf_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) - val is_cnf_star : Expr.expr -> bool - - (** Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. *) - val is_skolemize : Expr.expr -> bool - - (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q *) - val is_modus_ponens_oeq : Expr.expr -> bool - - (** Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) - val is_theory_lemma : Expr.expr -> bool -end - -(** Goals - - A goal (aka problem). A goal is essentially a - of formulas, that can be solved and/or transformed using - tactics and solvers. *) -module Goal : -sig - type goal - - (** The precision of the goal. - - Goals can be transformed using over and under approximations. - An under approximation is applied when the objective is to find a model for a given goal. - An over approximation is applied when the objective is to find a proof for a given goal. *) - val get_precision : goal -> Z3enums.goal_prec - - (** Indicates whether the goal is precise. *) - val is_precise : goal -> bool - - (** Indicates whether the goal is an under-approximation. *) - val is_underapproximation : goal -> bool - - (** Indicates whether the goal is an over-approximation. *) - val is_overapproximation : goal -> bool - - (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) - val is_garbage : goal -> bool - - (** Adds the constraints to the given goal. *) - val assert_ : goal -> Boolean.bool_expr list -> unit - - (** Indicates whether the goal contains `false'. *) - val is_inconsistent : goal -> bool - - (** The depth of the goal. - This tracks how many transformations were applied to it. *) - val get_depth : goal -> int - - (** Erases all formulas from the given goal. *) - val reset : goal -> unit - - (** The number of formulas in the goal. *) - val get_size : goal -> int - - (** The formulas in the goal. *) - val get_formulas : goal -> Boolean.bool_expr list - - (** The number of formulas, subformulas and terms in the goal. *) - val get_num_exprs : goal -> int - - (** Indicates whether the goal is empty, and it is precise or the product of an under approximation. *) - val is_decided_sat : goal -> bool - - (** Indicates whether the goal contains `false', and it is precise or the product of an over approximation. *) - val is_decided_unsat : goal -> bool - - (** Translates (copies) the Goal to another context.. *) - val translate : goal -> context -> goal - - (** Simplifies the goal. Essentially invokes the `simplify' tactic on the goal. *) - val simplify : goal -> Params.params option -> goal - - (** Creates a new Goal. - - Note that the Context must have been created with proof generation support if - the fourth argument is set to true here. *) - val mk_goal : context -> bool -> bool -> bool -> goal - - (** A string representation of the Goal. *) - val to_string : goal -> string -end - -(** Models - - A Model contains interpretations (assignments) of constants and functions. *) -module Model : -sig - type model - - (** Function interpretations - - A function interpretation is represented as a finite map and an 'else'. - Each entry in the finite map represents the value of a function given a set of arguments. *) - module FuncInterp : - sig - type func_interp - - (** Function interpretations entries - - An Entry object represents an element in the finite map used to a function interpretation. *) - module FuncEntry : - sig - type func_entry - - (** Return the (symbolic) value of this entry. - *) - val get_value : func_entry -> Expr.expr - - (** The number of arguments of the entry. - *) - val get_num_args : func_entry -> int - - (** The arguments of the function entry. - *) - val get_args : func_entry -> Expr.expr list - - (** A string representation of the function entry. - *) - val to_string : func_entry -> string - end - - (** The number of entries in the function interpretation. *) - val get_num_entries : func_interp -> int - - (** The entries in the function interpretation *) - val get_entries : func_interp -> FuncEntry.func_entry list - - (** The (symbolic) `else' value of the function interpretation. *) - val get_else : func_interp -> Expr.expr - - (** The arity of the function interpretation *) - val get_arity : func_interp -> int - - (** A string representation of the function interpretation. *) - val to_string : func_interp -> string - end - - (** Retrieves the interpretation (the assignment) of a func_decl in the model. - An expression if the function has an interpretation in the model, null otherwise. *) - val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option - - (** Retrieves the interpretation (the assignment) of an expression in the model. - An expression if the constant has an interpretation in the model, null otherwise. *) - val get_const_interp_e : model -> Expr.expr -> Expr.expr option - - (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) - val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option - - (** The number of constant interpretations in the model. *) - val get_num_consts : model -> int - - (** The function declarations of the constants in the model. *) - val get_const_decls : model -> FuncDecl.func_decl list - - (** The number of function interpretations in the model. *) - val get_num_funcs : model -> int - - (** The function declarations of the function interpretations in the model. *) - val get_func_decls : model -> FuncDecl.func_decl list - - (** All symbols that have an interpretation in the model. *) - val get_decls : model -> FuncDecl.func_decl list - - (** A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. *) - exception ModelEvaluationFailedException of string - - (** Evaluates an expression in the current model. - - This function may fail if the argument contains quantifiers, - is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. - *) - val eval : model -> Expr.expr -> bool -> Expr.expr - - (** Alias for eval. *) - val evaluate : model -> Expr.expr -> bool -> Expr.expr - - (** The number of uninterpreted sorts that the model has an interpretation for. *) - val get_num_sorts : model -> int - - (** The uninterpreted sorts that the model has an interpretation for. - - Z3 also provides an intepretation for uninterpreted sorts used in a formula. - The interpretation for a sort is a finite set of distinct values. We say this finite set is - the "universe" of the sort. - {!get_num_sorts} - {!sort_universe} *) - val get_sorts : model -> Sort.sort list - - (** The finite set of distinct values that represent the interpretation of a sort. - {!get_sorts} - @returns A list of expressions, where each is an element of the universe of the sort *) - val sort_universe : model -> Sort.sort -> AST.ast list - - (** Conversion of models to strings. - A string representation of the model. *) - val to_string : model -> string -end - -(** Probes - - Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Probe : -sig - type probe - - (** Execute the probe over the goal. - A probe always produce a double value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) - val apply : probe -> Goal.goal -> float - - (** The number of supported Probes. *) - val get_num_probes : context -> int - - (** The names of all supported Probes. *) - val get_probe_names : context -> string list - - (** Returns a string containing a description of the probe with the given name. *) - val get_probe_description : context -> string -> string - - (** Creates a new Probe. *) - val mk_probe : context -> string -> probe - - (** Create a probe that always evaluates to a float value. *) - val const : context -> float -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is less than the value returned by second argument *) - val lt : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is greater than the value returned by second argument *) - val gt : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is less than or equal the value returned by second argument *) - val le : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is greater than or equal the value returned by second argument *) - val ge : context -> probe -> probe -> probe - - - (** Create a probe that evaluates to "true" when the value returned by the first argument - is equal the value returned by second argument *) - val eq : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when both of two probes evaluate to "true". *) - val and_ : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when either of two probes evaluates to "true". *) - val or_ : context -> probe -> probe -> probe - - (** Create a probe that evaluates to "true" when another probe does not evaluate to "true". *) - val not_ : context -> probe -> probe -end - -(** Tactics - - Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using Context.get_num_tactics - and Context.get_tactic_names. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. -*) -module Tactic : -sig - type tactic - - (** Tactic application results - - ApplyResult objects represent the result of an application of a - tactic to a goal. It contains the subgoals that were produced. *) - module ApplyResult : - sig - type apply_result - - (** The number of Subgoals. *) - val get_num_subgoals : apply_result -> int - - (** Retrieves the subgoals from the apply_result. *) - val get_subgoals : apply_result -> Goal.goal list - - (** Retrieves a subgoal from the apply_result. *) - val get_subgoal : apply_result -> int -> Goal.goal - - (** Convert a model for a subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g *) - val convert_model : apply_result -> int -> Model.model -> Model.model - - (** A string representation of the ApplyResult. *) - val to_string : apply_result -> string - end - - (** A string containing a description of parameters accepted by the tactic. *) - val get_help : tactic -> string - - (** Retrieves parameter descriptions for Tactics. *) - val get_param_descrs : tactic -> Params.ParamDescrs.param_descrs - - (** Apply the tactic to the goal. *) - val apply : tactic -> Goal.goal -> Params.params option -> ApplyResult.apply_result - - (** The number of supported tactics. *) - val get_num_tactics : context -> int - - (** The names of all supported tactics. *) - val get_tactic_names : context -> string list - - (** Returns a string containing a description of the tactic with the given name. *) - val get_tactic_description : context -> string -> string - - (** Creates a new Tactic. *) - val mk_tactic : context -> string -> tactic - - (** Create a tactic that applies one tactic to a Goal and - then another one to every subgoal produced by the first one. *) - val and_then : context -> tactic -> tactic -> tactic list -> tactic - - (** Create a tactic that first applies one tactic to a Goal and - if it fails then returns the result of another tactic applied to the Goal. *) - val or_else : context -> tactic -> tactic -> tactic - - (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). - - If the tactic does not terminate within the timeout, then it fails. *) - val try_for : context -> tactic -> int -> tactic - - (** Create a tactic that applies one tactic to a given goal if the probe - evaluates to true. - - If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) - val when_ : context -> Probe.probe -> tactic -> tactic - - (** Create a tactic that applies a tactic to a given goal if the probe - evaluates to true and another tactic otherwise. *) - val cond : context -> Probe.probe -> tactic -> tactic -> tactic - - (** Create a tactic that keeps applying one tactic until the goal is not - modified anymore or the maximum number of iterations is reached. *) - val repeat : context -> tactic -> int -> tactic - - (** Create a tactic that just returns the given goal. *) - val skip : context -> tactic - - (** Create a tactic always fails. *) - val fail : context -> tactic - - (** Create a tactic that fails if the probe evaluates to false. *) - val fail_if : context -> Probe.probe -> tactic - - (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). *) - val fail_if_not_decided : context -> tactic - - (** Create a tactic that applies a tactic using the given set of parameters. *) - val using_params : context -> tactic -> Params.params -> tactic - - (** Create a tactic that applies a tactic using the given set of parameters. - Alias for UsingParams*) - val with_ : context -> tactic -> Params.params -> tactic - - (** Create a tactic that applies the given tactics in parallel. *) - val par_or : context -> tactic list -> tactic - - (** Create a tactic that applies a tactic to a given goal and then another tactic - to every subgoal produced by the first one. The subgoals are processed in parallel. *) - val par_and_then : context -> tactic -> tactic -> tactic - - (** Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. *) - val interrupt : context -> unit -end - -(** Solvers *) -module Solver : -sig - type solver - type status = UNSATISFIABLE | UNKNOWN | SATISFIABLE - - val string_of_status : status -> string - - (** Objects that track statistical information about solvers. *) - module Statistics : - sig - type statistics - - (** Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - *) - module Entry : - sig - type statistics_entry - - (** The key of the entry. *) - val get_key : statistics_entry -> string - - (** The int-value of the entry. *) - val get_int : statistics_entry -> int - - (** The float-value of the entry. *) - val get_float : statistics_entry -> float - - (** True if the entry is uint-valued. *) - val is_int : statistics_entry -> bool - - (** True if the entry is double-valued. *) - val is_float : statistics_entry -> bool - - (** The string representation of the the entry's value. *) - val to_string_value : statistics_entry -> string - - (** The string representation of the entry (key and value) *) - val to_string : statistics_entry -> string - end - - (** A string representation of the statistical data. *) - val to_string : statistics -> string - - (** The number of statistical data. *) - val get_size : statistics -> int - - (** The data entries. *) - val get_entries : statistics -> Entry.statistics_entry list - - (** The statistical counters. *) - val get_keys : statistics -> string list - - (** The value of a particular statistical counter. *) - val get : statistics -> string -> Entry.statistics_entry option - end - - (** A string that describes all available solver parameters. *) - val get_help : solver -> string - - (** Sets the solver parameters. *) - val set_parameters : solver -> Params.params -> unit - - (** Retrieves parameter descriptions for solver. *) - val get_param_descrs : solver -> Params.ParamDescrs.param_descrs - - (** The current number of backtracking points (scopes). - {!pop} - {!push} *) - val get_num_scopes : solver -> int - - (** Creates a backtracking point. - {!pop} *) - val push : solver -> unit - - (** Backtracks a number of backtracking points. - Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} - {!push} *) - val pop : solver -> int -> unit - - (** Resets the Solver. - This removes all assertions from the solver. *) - val reset : solver -> unit - - (** Assert a constraint (or multiple) into the solver. *) - val assert_ : solver -> Boolean.bool_expr list -> unit - - (** * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) - val assert_and_track_a : solver -> Boolean.bool_expr list -> Boolean.bool_expr list -> unit - - (** * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) - val assert_and_track : solver -> Boolean.bool_expr -> Boolean.bool_expr -> unit - - (** The number of assertions in the solver. *) - val get_num_assertions : solver -> int - - (** The set of asserted formulas. *) - val get_assertions : solver -> Boolean.bool_expr list - - (** Checks whether the assertions in the solver are consistent or not. - - {!Model} - {!get_unsat_core} - {!Proof} *) - val check : solver -> Boolean.bool_expr list -> status - - (** The model of the last Check. - - The result is None if Check was not invoked before, - if its results was not SATISFIABLE, or if model production is not enabled. *) - val get_model : solver -> Model.model option - - (** The proof of the last Check. - - The result is null if Check was not invoked before, - if its results was not UNSATISFIABLE, or if proof production is disabled. *) - val get_proof : solver -> Expr.expr option - - (** The unsat core of the last Check. - - The unsat core is a subset of Assertions - The result is empty if Check was not invoked before, - if its results was not UNSATISFIABLE, or if core production is disabled. *) - val get_unsat_core : solver -> AST.ast list - - (** A brief justification of why the last call to Check returned UNKNOWN. *) - val get_reason_unknown : solver -> string - - (** Solver statistics. *) - val get_statistics : solver -> Statistics.statistics - - (** Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. *) - val mk_solver : context -> Symbol.symbol option -> solver - - (** Creates a new (incremental) solver. - {!mk_solver} *) - val mk_solver_s : context -> string -> solver - - (** Creates a new (incremental) solver. *) - val mk_simple_solver : context -> solver - - (** Creates a solver that is implemented using the given tactic. - - The solver supports the commands Push and Pop, but it - will always solve each check from scratch. *) - val mk_solver_t : context -> Tactic.tactic -> solver - - (** A string representation of the solver. *) - val to_string : solver -> string -end - -(** Fixedpoint solving *) -module Fixedpoint : -sig - type fixedpoint - - (** A string that describes all available fixedpoint solver parameters. *) - val get_help : fixedpoint -> string - - (** Sets the fixedpoint solver parameters. *) - val set_params : fixedpoint -> Params.params -> unit - - (** Retrieves parameter descriptions for Fixedpoint solver. *) - val get_param_descrs : fixedpoint -> Params.ParamDescrs.param_descrs - - (** Assert a constraints into the fixedpoint solver. *) - val assert_ : fixedpoint -> Boolean.bool_expr list -> unit - - (** Register predicate as recursive relation. *) - val register_relation : fixedpoint -> FuncDecl.func_decl -> unit - - (** Add rule into the fixedpoint solver. *) - val add_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol option -> unit - - (** Add table fact to the fixedpoint solver. *) - val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit - - (** Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. *) - val query : fixedpoint -> Boolean.bool_expr -> Solver.status - - (** Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. *) - val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status - - (** Creates a backtracking point. - {!pop} *) - val push : fixedpoint -> unit - - (** Backtrack one backtracking point. - - Note that an exception is thrown if Pop is called without a corresponding Push - {!push} *) - val pop : fixedpoint -> unit - - (** Update named rule into in the fixedpoint solver. *) - val update_rule : fixedpoint -> Boolean.bool_expr -> Symbol.symbol -> unit - - (** Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. *) - val get_answer : fixedpoint -> Expr.expr option - - (** Retrieve explanation why fixedpoint engine returned status Unknown. *) - val get_reason_unknown : fixedpoint -> string - - (** Retrieve the number of levels explored for a given predicate. *) - val get_num_levels : fixedpoint -> FuncDecl.func_decl -> int - - (** Retrieve the cover of a predicate. *) - val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option - - (** Add property about the predicate. - The property is added at level. *) - val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit - - (** Retrieve internal string representation of fixedpoint object. *) - val to_string : fixedpoint -> string - - (** Instrument the Datalog engine on which table representation to use for recursive predicate. *) - val set_predicate_representation : fixedpoint -> FuncDecl.func_decl -> Symbol.symbol list -> unit - - (** Convert benchmark given as set of axioms, rules and queries to a string. *) - val to_string_q : fixedpoint -> Boolean.bool_expr list -> string - - (** Retrieve set of rules added to fixedpoint context. *) - val get_rules : fixedpoint -> Boolean.bool_expr list - - (** Retrieve set of assertions added to fixedpoint context. *) - val get_assertions : fixedpoint -> Boolean.bool_expr list - - (** Create a Fixedpoint context. *) - val mk_fixedpoint : context -> fixedpoint -end - -(** Global and context options - - Note: This module contains functions that set parameters/options for context - objects as well as functions that set options that are used globally, across - contexts.*) -module Options : -sig - (** Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -ini? - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - {!get_param_value} *) - val update_param_value : context -> string -> string -> unit - - (** Get a configuration parameter. - - Returns None if the parameter value does not exist. - {!update_param_value} *) - val get_param_value : context -> string -> string option - - (** Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - {!AST.to_string} - {!Quantifier.Pattern.to_string} - {!FuncDecl.to_string} - {!Sort.to_string} *) - val set_print_mode : context -> Z3enums.ast_print_mode -> unit - - (** Enable/disable printing of warning messages to the console. - - Note that this function is static and effects the behaviour of - all contexts globally. *) - val toggle_warning_messages : bool -> unit -end - -(** Functions for handling SMT and SMT2 expressions and files *) -module SMT : -sig - (** Convert a benchmark into an SMT-LIB formatted string. - - @return A string representation of the benchmark. *) - val benchmark_to_smtstring : context -> string -> string -> string -> string -> Boolean.bool_expr list -> Boolean.bool_expr -> string - - (** Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays in the third and fifth argument - don't need to match the names of the sorts and declarations in the arrays in the fourth - and sixth argument. This is a useful feature since we can use arbitrary names to - reference sorts and declarations. *) - val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - - (** Parse the given file using the SMT-LIB parser. - {!parse_smtlib_string} *) - val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - - (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_formulas : context -> int - - (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_formulas : context -> Boolean.bool_expr list - - (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_assumptions : context -> int - - (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_assumptions : context -> Boolean.bool_expr list - - (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_decls : context -> int - - (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_decls : context -> FuncDecl.func_decl list - - (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_num_smtlib_sorts : context -> int - - (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) - val get_smtlib_sorts : context -> Sort.sort list - - (** Parse the given string using the SMT-LIB2 parser. - - {!parse_smtlib_string} - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) - val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr - - (** Parse the given file using the SMT-LIB2 parser. - {!parse_smtlib2_string} *) - val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Boolean.bool_expr -end - -(** Set a global (or module) parameter, which is shared by all Z3 contexts. - - When a Z3 module is initialized it will use the value of these parameters - when Z3_params objects are not provided. - The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. - The character '.' is a delimiter (more later). - The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. - Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". - This function can be used to set parameters for a specific Z3 module. - This can be done by using .. - For example: - (set_global_param "pp.decimal" "true") - will set the parameter "decimal" in the module "pp" to true. -*) -val set_global_param : string -> string -> unit - -(** Get a global (or module) parameter. - - Returns None if the parameter does not exist. - The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. - This function cannot be invoked simultaneously from different threads without synchronization. - The result string stored in param_value is stored in a shared location. -*) -val get_global_param : string -> string option - -(** Restore the value of all global (and module) parameters. - - This command will not affect already created objects (such as tactics and solvers) - {!set_global_param} -*) -val global_param_reset_all : unit From 544a74f03493c73eea98f0414a927401294fd692 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 4 Jun 2013 18:00:48 +0100 Subject: [PATCH 411/507] ML API: bug and build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 28 ++++++++++++++++------------ scripts/update_api.py | 5 ++++- src/api/ml/z3.ml | 27 +++++++++++++++++---------- src/api/ml/z3.mli | 6 +++--- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4082bb2b8..d4221c05e 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1350,26 +1350,30 @@ class MLComponent(Component): mk_dir(os.path.join(BUILD_DIR, sub_dir)) api_src = get_component(API_COMPONENT).to_src_dir for f in filter(lambda f: f.endswith('.ml'), os.listdir(self.src_dir)): - out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) - if IS_WINDOWS: str = str.replace('/','\\') + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) + out.write(str) + for f in filter(lambda f: f.endswith('.mli'), os.listdir(self.src_dir)): + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) for f in filter(lambda f: f.endswith('.c'), os.listdir(self.src_dir)): - out.write('%s/%s: %s/%s\n' % (sub_dir,f,src_dir,f)) - str = '\t%s %s/%s %s/%s\n' % (CP_CMD,src_dir,f,sub_dir,f) - if IS_WINDOWS: str = str.replace('/','\\') + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: - out.write('%s/%s.mli: %s/%s.ml %s\n' % (sub_dir,m,sub_dir,m,prev)) - out.write('\t%s -I %s -i -c %s/%s.ml > %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m,sub_dir,m)) - prev = prev + ' ' + sub_dir + '/' + m + '.mli' + fn = os.path.join(self.src_dir, ('%s.mli' % m)) + if not os.path.exists(fn): + out.write('%s.mli: %s.ml %s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) + out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) + prev = prev + ' ' + os.path.join(sub_dir, m) + '.mli' cmis = '' for m in modules: - out.write('%s/%s.cmi: %s/%s.mli\n' % (sub_dir,m,sub_dir,m)) - out.write('\t%s -I %s -c %s/%s.mli\n' % (OCAMLC,sub_dir,sub_dir,m)) - cmis = cmis + ' ' + sub_dir + '/' + m + '.cmi' + out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) + out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) + cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') diff --git a/scripts/update_api.py b/scripts/update_api.py index 44d871348..77a5bf7f2 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1185,7 +1185,8 @@ def mk_ml(): ip = inparams(params) op = outparams(params) if len(ip) == 0: - ml_native.write(' unit -> ') + ml_native.write(' unit -> ') + ml_i.write(' unit -> ') for p in ip: ml_native.write('%s -> ' % param2ml(p)) ml_i.write('%s -> ' % param2ml(p)) @@ -1233,6 +1234,8 @@ def mk_ml(): ml_native.write(' ') ml_native.write('a%d' % i) i = i + 1 + if len(ip) == 0: + ml_native.write('()') ml_native.write(' = \n') ml_native.write(' ') if result == VOID and len(op) == 0: diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 081433f1f..8b783d25d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -34,7 +34,7 @@ struct ) let create_context settings = - let cfg = Z3native.mk_config in + let cfg = Z3native.mk_config () in let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in (List.iter f settings) ; let v = Z3native.mk_context_rc cfg in @@ -101,12 +101,12 @@ end module Version = struct - let major = let (x, _, _, _) = Z3native.get_version in x - let minor = let (_, x, _, _) = Z3native.get_version in x - let build = let (_, _, x, _) = Z3native.get_version in x - let revision = let (_, _, _, x) = Z3native.get_version in x + let major = let (x, _, _, _) = Z3native.get_version () in x + let minor = let (_, x, _, _) = Z3native.get_version () in x + let build = let (_, _, x, _) = Z3native.get_version () in x + let revision = let (_, _, _, x) = Z3native.get_version () in x let to_string = - let (mj, mn, bld, rev) = Z3native.get_version in + let (mj, mn, bld, rev) = Z3native.get_version () in string_of_int mj ^ "." ^ string_of_int mn ^ "." ^ string_of_int bld ^ "." ^ @@ -609,6 +609,10 @@ sig val add_symbol : params -> Symbol.symbol -> Symbol.symbol -> unit val mk_params : context -> params val to_string : params -> string + + val update_param_value : context -> string -> string -> unit + val get_param_value : context -> string -> string option + val set_print_mode : context -> Z3enums.ast_print_mode -> unit end = struct type params = z3_native_object @@ -1099,7 +1103,7 @@ struct end -module Array = +module Z3Array = struct let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) @@ -1382,7 +1386,7 @@ struct end -module List = +module Z3List = struct let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( elem_sort : sort ) = let (r, _, _, _, _, _, _) = (Z3native.mk_list_sort (context_gno ctx) (Symbol.gno name) (Sort.gno elem_sort)) in @@ -2038,7 +2042,7 @@ struct if not r then None else - expr_of_ptr (z3obj_gc x) v + Some(expr_of_ptr (z3obj_gc x) v) let evaluate ( x : model ) ( t : expr ) ( completion : bool ) = eval x t completion @@ -2331,7 +2335,7 @@ struct if (Z3native.stats_is_uint (z3obj_gnc x) (z3obj_gno x) i) then (Entry.create_si k (Z3native.stats_get_uint_value (z3obj_gnc x) (z3obj_gno x) i)) else - (Entry.create_sd k (Z3native.stats_get_float_value (z3obj_gnc x) (z3obj_gno x) i)) + (Entry.create_sd k (Z3native.stats_get_double_value (z3obj_gnc x) (z3obj_gno x) i)) ) in mk_list f n @@ -2667,3 +2671,6 @@ let global_param_reset_all = let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled + +module Array = Z3Array +module List = Z3List diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 570ff8717..3f83ef6b2 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -8,7 +8,7 @@ (** General Z3 exceptions Many functions in this API may throw an exception; if they do, it is this one.*) -exception Error +exception Error of string (** Context objects. @@ -55,11 +55,11 @@ module Log : sig (** Open an interaction log file. @return True if opening the log file succeeds, false otherwise. *) - (* CMW: "open" seems to be a reserved keyword? *) + (* CMW: "open" is a reserved keyword. *) val open_ : string -> bool (** Closes the interaction log. *) - val close : unit + val close : unit -> unit (** Appends a user-provided string to the interaction log. *) val append : string -> unit From 983a0fb16f7a7c0600e93b2213e7b61c58da5ac9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 21 Oct 2013 11:22:42 +0100 Subject: [PATCH 412/507] ML bindings: list/array are now called z3array/z3list to avoid confusion. Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 4 ---- src/api/ml/z3.mli | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 8b783d25d..ed815d720 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -2670,7 +2670,3 @@ let global_param_reset_all = let toggle_warning_messages ( enabled: bool ) = Z3native.toggle_warning_messages enabled - - -module Array = Z3Array -module List = Z3List diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 3f83ef6b2..ff1898185 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -761,7 +761,7 @@ sig end (** Functions to manipulate Array expressions *) -module Array : +module Z3Array : sig (** Create a new array sort. *) val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort @@ -1093,7 +1093,7 @@ sig end (** Functions to manipulate List expressions *) -module List : +module Z3List : sig (** Create a new list sort. *) val mk_sort : context -> Symbol.symbol -> Sort.sort -> Sort.sort From b889b225a0d59a9abd4927417de91384f033a0c6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 21 Oct 2013 11:25:02 +0100 Subject: [PATCH 413/507] ML cleanup; makefile removed. The example is built by running make examples in the build directory. Signed-off-by: Christoph M. Wintersteiger --- examples/ml/Makefile | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 examples/ml/Makefile diff --git a/examples/ml/Makefile b/examples/ml/Makefile deleted file mode 100644 index 818f0cacc..000000000 --- a/examples/ml/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This is a temporary support file for emacs annotations. -# It does not compile the Z3 ML example; this will be built -# in the top-level build directory. - -all: - source /cygdrive/c/cwinter/.msenv32 ; OCAML_COMPAT=c C:/ocamlw32/bin/ocamlc -g -custom -cclib '-L../../bld_dbg -lz3' -annot -o ml_example.byte -I ../../bld_dbg/api/ml z3.cma ml_example.ml - source /cygdrive/c/cwinter/.msenv32 ; C:/ocamlw32/bin/ocamlopt -g -annot -o ml_example -cclib '-L../../bld_dbg -lz3' -I ../../bld_dbg -I ../../bld_dbg/api/ml z3.cmxa ml_example.ml From c32e1304872f584a69f3ae6b8e410d88e30db7e3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 28 Oct 2013 12:17:58 +0000 Subject: [PATCH 414/507] ML API: bugfix for native function with more than 5 parameters. Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 77a5bf7f2..dd1e46c4f 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1211,9 +1211,11 @@ def mk_ml(): ml_i.write(')') ml_native.write('\n') ml_i.write('\n') - ml_native.write(' = "n_%s"\n' % ml_method_name(name)) if len(ip) > 5: - ml_native.write(' "n_%s_bytecode"\n' % ml_method_name(name)) + ml_native.write(' = "n_%s_bytecode"\n' % ml_method_name(name)) + ml_native.write(' "n_%s"\n' % ml_method_name(name)) + else: + ml_native.write(' = "n_%s"\n' % ml_method_name(name)) ml_native.write('\n') ml_native.write(' end\n\n') ml_i.write('\n(**/**)\n'); From 54b7f8eec3b17ed012324d7a34c8846de32cb560 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 2 Apr 2014 19:08:59 +0100 Subject: [PATCH 415/507] ML API bugfix (Codeplex issue 102) Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 43 ++++++ src/api/ml/z3.ml | 289 +++++++++++++++++++------------------- src/api/ml/z3.mli | 3 + 3 files changed, 192 insertions(+), 143 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index c9ed1d948..0dd227784 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -196,6 +196,48 @@ let basic_tests ( ctx : context ) = Printf.printf "Exception caught, OK.\n" ) +(** + A basic example of how to use quantifiers. +**) +let quantifierExample1 ( ctx : context ) = + Printf.printf "QuantifierExample\n" ; + let is = (Integer.mk_sort ctx) in + let types = [ is; is; is ] in + let names = [ (Symbol.mk_string ctx "x_0"); + (Symbol.mk_string ctx "x_1"); + (Symbol.mk_string ctx "x_2") ] in + let vars = [ (Quantifier.mk_bound ctx 2 (List.nth types 0)); + (Quantifier.mk_bound ctx 2 (List.nth types 1)); + (Quantifier.mk_bound ctx 2 (List.nth types 2)) ] in + let xs = [ (Integer.mk_const ctx (List.nth names 0)); + (Integer.mk_const ctx (List.nth names 1)); + (Integer.mk_const ctx (List.nth names 2)) ] in + + let body_vars = (Boolean.mk_and ctx + [ (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth vars 0) ; (Integer.mk_numeral_i ctx 1)]) + (Integer.mk_numeral_i ctx 2)) ; + (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth vars 1); (Integer.mk_numeral_i ctx 2)]) + (Arithmetic.mk_add ctx [ (List.nth vars 2); (Integer.mk_numeral_i ctx 3)])) ]) in + let body_const = (Boolean.mk_and ctx + [ (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth xs 0); (Integer.mk_numeral_i ctx 1)]) + (Integer.mk_numeral_i ctx 2)) ; + (mk_eq ctx + (Arithmetic.mk_add ctx [ (List.nth xs 1); (Integer.mk_numeral_i ctx 2)]) + (Arithmetic.mk_add ctx [ (List.nth xs 2); (Integer.mk_numeral_i ctx 3)])) ]) in + + let x = (Quantifier.mk_forall ctx types names body_vars (Some 1) [] [] (Some (Symbol.mk_string ctx "Q1")) (Some (Symbol.mk_string ctx "skid1"))) in + Printf.printf "Quantifier X: %s\n" (Quantifier.to_string x) ; + let y = (Quantifier.mk_forall_const ctx xs body_const (Some 1) [] [] (Some (Symbol.mk_string ctx "Q2")) (Some (Symbol.mk_string ctx "skid2"))) in + Printf.printf "Quantifier Y: %s\n" (Quantifier.to_string y) ; + if (is_true (Quantifier.expr_of_quantifier x)) then + raise (TestFailedException "") (* unreachable *) + else if (is_false (Quantifier.expr_of_quantifier x)) then + raise (TestFailedException "") (* unreachable *) + else if (is_const (Quantifier.expr_of_quantifier x)) then + raise (TestFailedException "") (* unreachable *) let _ = try ( @@ -217,6 +259,7 @@ let _ = Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); basic_tests ctx ; + quantifierExample1 ctx ; Printf.printf "Disposing...\n"; Gc.full_major () ); diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index ed815d720..d91d3ca8d 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -297,6 +297,7 @@ struct | VAR_AST -> true | _ -> false + let is_app ( x : ast ) = (get_ast_kind x) == APP_AST let is_var ( x : ast ) = (get_ast_kind x) == VAR_AST let is_quantifier ( x : ast ) = (get_ast_kind x) == QUANTIFIER_AST let is_sort ( x : ast ) = (get_ast_kind x) == SORT_AST @@ -828,22 +829,22 @@ end = struct (Z3native.mk_bool_sort (gnc x)) (Z3native.get_sort (gnc x) (gno x))) - let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_oeq ( x : expr ) = (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) + let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) + let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -1100,6 +1101,8 @@ struct mk_forall_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id else mk_exists_const ctx bound_constants body weight patterns nopatterns quantifier_id skolem_id + + let to_string ( x : quantifier ) = (Expr.to_string (expr_of_quantifier x)) end @@ -1108,12 +1111,12 @@ struct let mk_sort ( ctx : context ) ( domain : sort ) ( range : sort ) = sort_of_ptr ctx (Z3native.mk_array_sort (context_gno ctx) (Sort.gno domain) (Sort.gno range)) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) - let is_constant_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) - let is_default_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) - let is_array_map ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) - let is_as_array ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) + let is_store ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_STORE) + let is_select ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SELECT) + let is_constant_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONST_ARRAY) + let is_default_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_DEFAULT) + let is_array_map ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ARRAY_MAP) + let is_as_array ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_AS_ARRAY) let is_array ( x : expr ) = (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == ARRAY_SORT) @@ -1150,11 +1153,11 @@ struct let mk_sort ( ctx : context ) ( ty : sort ) = sort_of_ptr ctx (Z3native.mk_set_sort (context_gno ctx) (Sort.gno ty)) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) - let is_intersect ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) - let is_difference ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) - let is_subset ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) + let is_union ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_UNION) + let is_intersect ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_INTERSECT) + let is_difference ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_DIFFERENCE) + let is_complement ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_COMPLEMENT) + let is_subset ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SET_SUBSET) let mk_empty ( ctx : context ) ( domain : sort ) = @@ -1203,7 +1206,7 @@ struct (Z3native.is_app (Expr.gnc x) (Expr.gno x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == FINITE_DOMAIN_SORT) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FD_LT) let get_size ( x : sort ) = let (r, v) = (Z3native.get_finite_domain_sort_size (Sort.gnc x) (Sort.gno x)) in @@ -1219,19 +1222,19 @@ struct ((Z3native.is_app (Expr.gnc x) (Expr.gno x)) && (sort_kind_of_int (Z3native.get_sort_kind nc (Z3native.get_sort nc (Expr.gno x))) == RELATION_SORT)) - let is_store ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) - let is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) - let is_is_empty ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) - let is_join ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) - let is_union ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) - let is_widen ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) - let is_project ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) - let is_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) - let is_negation_filter ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) - let is_rename ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) - let is_complement ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) - let is_select ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) - let is_clone ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) + let is_store ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_STORE) + let is_empty ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_EMPTY) + let is_is_empty ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_IS_EMPTY) + let is_join ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_JOIN) + let is_union ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_UNION) + let is_widen ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_WIDEN) + let is_project ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_PROJECT) + let is_filter ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_FILTER) + let is_negation_filter ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_NEGATION_FILTER) + let is_rename ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_RENAME) + let is_complement ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_COMPLEMENT) + let is_select ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_SELECT) + let is_clone ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_RA_CLONE) let get_arity ( x : sort ) = Z3native.get_relation_arity (Sort.gnc x) (Sort.gno x) @@ -1534,37 +1537,37 @@ struct (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - let is_arithmetic_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - let is_le ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - let is_ge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - let is_lt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - let is_gt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - let is_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - let is_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - let is_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - let is_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - let is_div ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - let is_idiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - let is_remainder ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - let is_modulus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - let is_inttoreal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - let is_real_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - let is_real_is_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) let is_real ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) @@ -1616,57 +1619,57 @@ struct sort_of_ptr ctx (Z3native.mk_bv_sort (context_gno ctx) size) let is_bv ( x : expr ) = ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == BV_SORT) - let is_bv_numeral ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) - let is_bv_bit1 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) - let is_bv_bit0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) - let is_bv_uminus ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) - let is_bv_add ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) - let is_bv_sub ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) - let is_bv_mul ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) - let is_bv_sdiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) - let is_bv_udiv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) - let is_bv_SRem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) - let is_bv_urem ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) - let is_bv_smod ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) - let is_bv_sdiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) - let is_bv_udiv0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) - let is_bv_srem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) - let is_bv_urem0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) - let is_bv_smod0 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) - let is_bv_ule ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) - let is_bv_sle ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) - let is_bv_uge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) - let is_bv_sge ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) - let is_bv_ult ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) - let is_bv_slt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) - let is_bv_ugt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) - let is_bv_sgt ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) - let is_bv_and ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) - let is_bv_or ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) - let is_bv_not ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) - let is_bv_xor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) - let is_bv_nand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) - let is_bv_nor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) - let is_bv_xnor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) - let is_bv_concat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) - let is_bv_signextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) - let is_bv_zeroextension ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) - let is_bv_extract ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) - let is_bv_repeat ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) - let is_bv_reduceor ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) - let is_bv_reduceand ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) - let is_bv_comp ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) - let is_bv_shiftleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) - let is_bv_shiftrightlogical ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) - let is_bv_shiftrightarithmetic ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) - let is_bv_rotateleft ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) - let is_bv_rotateright ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) - let is_bv_rotateleftextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) - let is_bv_rotaterightextended ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - let is_int_to_bv ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - let is_bv_to_int ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) - let is_bv_carry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) - let is_bv_xor3 ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) + let is_bv_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNUM) + let is_bv_bit1 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT1) + let is_bv_bit0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BIT0) + let is_bv_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNEG) + let is_bv_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BADD) + let is_bv_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSUB) + let is_bv_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BMUL) + let is_bv_sdiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV) + let is_bv_udiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV) + let is_bv_SRem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM) + let is_bv_urem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM) + let is_bv_smod ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD) + let is_bv_sdiv0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSDIV0) + let is_bv_udiv0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUDIV0) + let is_bv_srem0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSREM0) + let is_bv_urem0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BUREM0) + let is_bv_smod0 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSMOD0) + let is_bv_ule ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULEQ) + let is_bv_sle ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLEQ) + let is_bv_uge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGEQ) + let is_bv_sge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGEQ) + let is_bv_ult ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ULT) + let is_bv_slt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SLT) + let is_bv_ugt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UGT) + let is_bv_sgt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SGT) + let is_bv_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BAND) + let is_bv_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BOR) + let is_bv_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOT) + let is_bv_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXOR) + let is_bv_nand ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNAND) + let is_bv_nor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BNOR) + let is_bv_xnor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BXNOR) + let is_bv_concat ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CONCAT) + let is_bv_signextension ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SIGN_EXT) + let is_bv_zeroextension ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ZERO_EXT) + let is_bv_extract ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXTRACT) + let is_bv_repeat ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REPEAT) + let is_bv_reduceor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDOR) + let is_bv_reduceand ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BREDAND) + let is_bv_comp ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BCOMP) + let is_bv_shiftleft ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BSHL) + let is_bv_shiftrightlogical ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BLSHR) + let is_bv_shiftrightarithmetic ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BASHR) + let is_bv_rotateleft ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_LEFT) + let is_bv_rotateright ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) + let is_bv_rotateleftextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) + let is_bv_rotaterightextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) + let is_int_to_bv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_bv_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_bv_carry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) + let is_bv_xor3 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) let get_size (x : sort ) = Z3native.get_bv_sort_size (Sort.gnc x) (Sort.gno x) let get_int ( x : expr ) = let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in @@ -1778,44 +1781,44 @@ end module Proof = struct - let is_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) - let is_asserted ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) - let is_goal ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) - let is_modus_ponens ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) - let is_reflexivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) - let is_symmetry ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) - let is_transitivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) - let is_Transitivity_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) - let is_monotonicity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) - let is_quant_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) - let is_distributivity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) - let is_and_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) - let is_or_elimination ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) - let is_rewrite ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) - let is_rewrite_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) - let is_pull_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) - let is_pull_quant_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) - let is_push_quant ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) - let is_elim_unused_vars ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) - let is_der ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) - let is_quant_inst ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) - let is_hypothesis ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) - let is_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) - let is_unit_resolution ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) - let is_iff_true ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) - let is_iff_false ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) - let is_commutativity ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) - let is_def_axiom ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) - let is_def_intro ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) - let is_apply_def ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) - let is_iff_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) - let is_nnf_pos ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) - let is_nnf_neg ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) - let is_nnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) - let is_cnf_star ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) - let is_skolemize ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) - let is_modus_ponens_oeq ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) - let is_theory_lemma ( x : expr ) = (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) + let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) + let is_asserted ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) + let is_goal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_modus_ponens ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) + let is_reflexivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) + let is_symmetry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) + let is_transitivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY) + let is_Transitivity_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRANSITIVITY_STAR) + let is_monotonicity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MONOTONICITY) + let is_quant_intro ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INTRO) + let is_distributivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DISTRIBUTIVITY) + let is_and_elimination ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_AND_ELIM) + let is_or_elimination ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NOT_OR_ELIM) + let is_rewrite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE) + let is_rewrite_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REWRITE_STAR) + let is_pull_quant ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT) + let is_pull_quant_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PULL_QUANT_STAR) + let is_push_quant ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_PUSH_QUANT) + let is_elim_unused_vars ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ELIM_UNUSED_VARS) + let is_der ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DER) + let is_quant_inst ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_QUANT_INST) + let is_hypothesis ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_HYPOTHESIS) + let is_lemma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_LEMMA) + let is_unit_resolution ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_UNIT_RESOLUTION) + let is_iff_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_TRUE) + let is_iff_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_FALSE) + let is_commutativity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_COMMUTATIVITY) (* *) + let is_def_axiom ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_AXIOM) + let is_def_intro ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_DEF_INTRO) + let is_apply_def ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_APPLY_DEF) + let is_iff_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_IFF_OEQ) + let is_nnf_pos ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_POS) + let is_nnf_neg ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_NEG) + let is_nnf_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_NNF_STAR) + let is_cnf_star ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_CNF_STAR) + let is_skolemize ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SKOLEMIZE) + let is_modus_ponens_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS_OEQ) + let is_theory_lemma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TH_LEMMA) end diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index ff1898185..5c9c56dbf 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -758,6 +758,9 @@ sig (** Create a Quantifier. *) val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier + + (** A string representation of the quantifier. *) + val to_string : quantifier -> string end (** Functions to manipulate Array expressions *) From ee22d4054201afd40c9a7bf05fe9fb8ca808639f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 2 Apr 2014 19:18:43 +0100 Subject: [PATCH 416/507] ML API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index d91d3ca8d..5f8d96d2a 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -793,7 +793,7 @@ end = struct mk_list f n let update ( x : expr ) ( args : expr list ) = - if (List.length args <> (get_num_args x)) then + if ((AST.is_app (ast_of_expr x)) && (List.length args <> (get_num_args x))) then raise (Z3native.Exception "Number of arguments does not match") else expr_of_ptr (Expr.gc x) (Z3native.update_term (gnc x) (gno x) (List.length args) (expr_lton args)) From 9dc802199503f8f120cb8bf1f5202238ba0e0383 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:17:22 +0100 Subject: [PATCH 417/507] Added facilities for ocamlfind in the ML API build Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 12 +++++++++++- scripts/mk_util.py | 31 ++++++++++++++++++++++++++++--- src/api/ml/README | 6 +++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/examples/ml/README b/examples/ml/README index 3e1eb0d1c..f934aac80 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -1,4 +1,4 @@ -### This is work-in-progress and does not work yet. +### This is work-in-progress. Small example using the Z3 ML bindings. To build the example execute @@ -12,3 +12,13 @@ or LD_LIBRARY_PATH=. ./ml_example.byte for the byte-code version. +If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), +then we can compile this example as follows: + +ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg -verbose +ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg -verbose + +Note that the resulting binaries depend on the shared z3 library, which needs to be +in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was +installed into ocamlfind, the path that should be added is +`ocamlfind printconf destdir`/Z3 \ No newline at end of file diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d4221c05e..f6f95cf7d 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1338,7 +1338,25 @@ class MLComponent(Component): Component.__init__(self, name, path, deps) if lib_name == None: lib_name = name - self.lib_name = lib_name + self.lib_name = lib_name + + def mk_ml_meta(self, ml_meta_in, ml_meta_out, major, minor, build, revision): + ver_pat = re.compile('version = "VERSION"*') + fin = open(ml_meta_in, 'r') + fout = open(ml_meta_out, 'w') + num_updates = 0 + for line in fin: + if ver_pat.match(line): + fout.write('version = "%s.%s.%s.%s"\n' % (major, minor, build, revision)) + num_updates = num_updates + 1 + else: + fout.write(line) + assert num_updates == 1, "unexpected number of version number updates" + fin.close() + fout.close() + if VERBOSE: + print("Updated '%s'" % ml_meta_out) + def mk_makefile(self, out): if is_ml_enabled(): @@ -1377,7 +1395,7 @@ class MLComponent(Component): out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') - out.write('api/ml/z3.cmxa: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') @@ -1385,7 +1403,7 @@ class MLComponent(Component): if DEBUG_MODE: out.write('-g ') out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('api/ml/z3.cma: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) out.write('\n') @@ -1395,6 +1413,13 @@ class MLComponent(Component): out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') out.write('\n') + # Generate META file and package installation commands + self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') + out.write('\tocamlfind remove Z3\n') + out.write('\tocamlfind install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.lib api/ml/libz3ml.lib libz3.lib libz3.dll\n') + out.write('\n') + def main_component(self): return is_ml_enabled() diff --git a/src/api/ml/README b/src/api/ml/README index beee7d864..f697e5ff4 100644 --- a/src/api/ml/README +++ b/src/api/ml/README @@ -5,4 +5,8 @@ We are currently working on a brand new ML API. On Windows, there are no less than four different ports of OCaml. The Z3 build system assumes that either the win32 or the win64 port is installed. This means that OCaml will use `cl' as the underlying C compiler and not the cygwin or -mingw compilers. \ No newline at end of file +mingw compilers. + +By default, a make target called `ocamlfind_install' is added. This installs Z3 +into the ocamlfind package repository such that programs can be compiled via +ocamlfind. \ No newline at end of file From eb72afabfbf89c49be25bd5d1843d6297280b8ef Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:32:06 +0100 Subject: [PATCH 418/507] ML API `or' is deprecated, changed to `||' Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 5f8d96d2a..c037a9263 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -748,7 +748,7 @@ end = struct Expr(z3_native_object_of_ast_ptr ctx no) else if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT or sk == REAL_SORT or sk == BV_SORT) then + if (sk == INT_SORT || sk == REAL_SORT || sk == BV_SORT) then Expr(z3_native_object_of_ast_ptr ctx no) else raise (Z3native.Exception "Unsupported numeral object") From 0465ad3ce6cdccf4e4be9c90954b683c44ec539e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:33:52 +0100 Subject: [PATCH 419/507] ML example; `or' is deprecated, changed to `||' Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 0dd227784..25862b2d7 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -168,7 +168,7 @@ let basic_tests ( ctx : context ) = let inum = (get_numerator rn) in let iden = get_denominator rn in Printf.printf "Numerator: %s Denominator: %s\n" (Real.to_string inum) (Real.to_string iden) ; - if ((Real.to_string inum) <> "42" or (Real.to_string iden) <> "43") then + if ((Real.to_string inum) <> "42" || (Real.to_string iden) <> "43") then raise (TestFailedException "") else Printf.printf "Test passed.\n" From 133890be23c0d02186622fb3781ff6c987b6efae Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:38:29 +0100 Subject: [PATCH 420/507] ML API build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index f6f95cf7d..46229b20c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1417,7 +1417,10 @@ class MLComponent(Component): self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') out.write('\tocamlfind remove Z3\n') - out.write('\tocamlfind install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.lib api/ml/libz3ml.lib libz3.lib libz3.dll\n') + out.write('\tocamlfind install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)') + if IS_WINDOWS: + out.write(' libz3$(LIB_EXT)') + out.write('\n') out.write('\n') From f319a77a4c6c1f8c1620b34424bcbad9931b636c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 15 Apr 2014 18:49:05 +0100 Subject: [PATCH 421/507] ML API build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 46229b20c..418149dbe 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1415,13 +1415,14 @@ class MLComponent(Component): out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') - out.write('\tocamlfind remove Z3\n') - out.write('\tocamlfind install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)') - if IS_WINDOWS: - out.write(' libz3$(LIB_EXT)') - out.write('\n') - out.write('\n') + if OCAMLFIND != '': + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') + out.write('\t%s remove Z3\n' % (OCAMLFIND)) + out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + if IS_WINDOWS: + out.write(' libz3$(LIB_EXT)') + out.write('\n') + out.write('\n') def main_component(self): From 3d9ad51aae97db8a8b2c5ef15163a2c46871ea8c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 12:55:23 +0100 Subject: [PATCH 422/507] ML API refactoring Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 72 ++++++++----------- src/api/ml/z3.mli | 180 +++++++++++++++++++++++----------------------- 2 files changed, 119 insertions(+), 133 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index c037a9263..051a54696 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1,5 +1,5 @@ (** - The Z3 ML/Ocaml Interface. + The Z3 ML/OCaml Interface. Copyright (C) 2012 Microsoft Corporation @author CM Wintersteiger (cwinter) 2012-12-17 @@ -698,7 +698,6 @@ sig val get_simplify_help : context -> string val get_simplify_parameter_descrs : context -> Params.ParamDescrs.param_descrs val get_func_decl : expr -> FuncDecl.func_decl - val get_bool_value : expr -> Z3enums.lbool val get_num_args : expr -> int val get_args : expr -> expr list val update : expr -> expr list -> expr @@ -710,20 +709,7 @@ sig val is_numeral : expr -> bool val is_well_sorted : expr -> bool val get_sort : expr -> Sort.sort - val is_bool : expr -> bool val is_const : expr -> bool - val is_true : expr -> bool - val is_false : expr -> bool - val is_eq : expr -> bool - val is_distinct : expr -> bool - val is_ite : expr -> bool - val is_and : expr -> bool - val is_or : expr -> bool - val is_iff : expr -> bool - val is_xor : expr -> bool - val is_not : expr -> bool - val is_implies : expr -> bool - val is_oeq : expr -> bool val mk_const : context -> Symbol.symbol -> Sort.sort -> expr val mk_const_s : context -> string -> Sort.sort -> expr val mk_const_f : context -> FuncDecl.func_decl -> expr @@ -782,9 +768,7 @@ end = struct let get_simplify_parameter_descrs ( ctx : context ) = Params.ParamDescrs.param_descrs_of_ptr ctx (Z3native.simplify_get_param_descrs (context_gno ctx)) - let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) - - let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) + let get_func_decl ( x : expr ) = FuncDecl.func_decl_of_ptr (Expr.gc x) (Z3native.get_app_decl (gnc x) (gno x)) let get_num_args ( x : expr ) = Z3native.get_app_num_args (gnc x) (gno x) @@ -823,29 +807,11 @@ end = struct let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) - - let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && - (Z3native.is_eq_sort (gnc x) - (Z3native.mk_bool_sort (gnc x)) - (Z3native.get_sort (gnc x) (gno x))) - + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) - let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) - let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) - let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) - let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) - let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) - let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) - let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) - let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) - let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) - let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) - let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OEQ) - let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -888,12 +854,6 @@ struct let mk_val ( ctx : context ) ( value : bool ) = if value then mk_true ctx else mk_false ctx - - let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = - expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) - - let mk_distinct ( ctx : context ) ( args : expr list ) = - expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) let mk_not ( ctx : context ) ( a : expr ) = expr_of_ptr ctx (Z3native.mk_not (context_gno ctx) (gno a)) @@ -917,6 +877,31 @@ struct let mk_or ( ctx : context ) ( args : expr list ) = let f x = (Expr.gno (x)) in expr_of_ptr ctx (Z3native.mk_or (context_gno ctx) (List.length args) (Array.of_list(List.map f args))) + + let mk_eq ( ctx : context ) ( x : expr ) ( y : expr ) = + expr_of_ptr ctx (Z3native.mk_eq (context_gno ctx) (Expr.gno x) (Expr.gno y)) + + let mk_distinct ( ctx : context ) ( args : expr list ) = + expr_of_ptr ctx (Z3native.mk_distinct (context_gno ctx) (List.length args) (expr_lton args)) + + let get_bool_value ( x : expr ) = lbool_of_int (Z3native.get_bool_value (gnc x) (gno x)) + + let is_bool ( x : expr ) = (match x with Expr(a) -> (AST.is_expr a)) && + (Z3native.is_eq_sort (gnc x) + (Z3native.mk_bool_sort (gnc x)) + (Z3native.get_sort (gnc x) (gno x))) + + let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_TRUE) + let is_false ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_FALSE) + let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_EQ) + let is_distinct ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_DISTINCT) + let is_ite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_ITE) + let is_and ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_AND) + let is_or ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_OR) + let is_iff ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IFF) + let is_xor ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_XOR) + let is_not ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_NOT) + let is_implies ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (get_func_decl x) == OP_IMPLIES) end @@ -1784,6 +1769,7 @@ struct let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) let is_asserted ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_ASSERTED) let is_goal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_GOAL) + let is_oeq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_OEQ) let is_modus_ponens ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_MODUS_PONENS) let is_reflexivity ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_REFLEXIVITY) let is_symmetry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_SYMMETRY) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 5c9c56dbf..c554d7564 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1,5 +1,5 @@ (** - The Z3 ML/Ocaml Interface. + The Z3 ML/OCaml Interface. Copyright (C) 2012 Microsoft Corporation @author CM Wintersteiger (cwinter) 2012-12-17 @@ -488,10 +488,6 @@ sig (** The function declaration of the function that is applied in this expression. *) val get_func_decl : Expr.expr -> FuncDecl.func_decl - (** Indicates whether the expression is the true or false expression - or something else (L_UNDEF). *) - val get_bool_value : Expr.expr -> Z3enums.lbool - (** The number of arguments of the expression. *) val get_num_args : Expr.expr -> int @@ -535,11 +531,88 @@ sig (** The Sort of the term. *) val get_sort : Expr.expr -> Sort.sort - (** Indicates whether the term has Boolean sort. *) - val is_bool : Expr.expr -> bool - (** Indicates whether the term represents a constant. *) val is_const : Expr.expr -> bool + + (** Creates a new constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> expr + + (** Creates a new constant. *) + val mk_const_s : context -> string -> Sort.sort -> expr + + (** Creates a constant from the func_decl. *) + val mk_const_f : context -> FuncDecl.func_decl -> expr + + (** Creates a fresh constant with a name prefixed with a string. *) + val mk_fresh_const : context -> string -> Sort.sort -> expr + + (** Create a new function application. *) + val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr + + (** Create a numeral of a given sort. + @return A Term with the given value and sort *) + val mk_numeral_string : context -> string -> Sort.sort -> expr + + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. + It is slightly faster than MakeNumeral since it is not necessary to parse a string. + @return A Term with the given value and sort *) + val mk_numeral_int : context -> int -> Sort.sort -> expr +end + +(** Boolean expressions; Propositional logic and equality *) +module Boolean : +sig + (** Create a Boolean sort *) + val mk_sort : context -> Sort.sort + + (** Create a Boolean constant. *) + val mk_const : context -> Symbol.symbol -> Expr.expr + + (** Create a Boolean constant. *) + val mk_const_s : context -> string -> Expr.expr + + (** The true Term. *) + val mk_true : context -> Expr.expr + + (** The false Term. *) + val mk_false : context -> Expr.expr + + (** Creates a Boolean value. *) + val mk_val : context -> bool -> Expr.expr + + (** Mk an expression representing not(a). *) + val mk_not : context -> Expr.expr -> Expr.expr + + (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 iff t2. *) + val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 -> t2. *) + val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing t1 xor t2. *) + val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create an expression representing the AND of args *) + val mk_and : context -> Expr.expr list -> Expr.expr + + (** Create an expression representing the OR of args *) + val mk_or : context -> Expr.expr list -> Expr.expr + + (** Creates the equality between two expr's. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Creates a distinct term. *) + val mk_distinct : context -> Expr.expr list -> Expr.expr + + (** Indicates whether the expression is the true or false expression + or something else (L_UNDEF). *) + val get_bool_value : Expr.expr -> Z3enums.lbool + + (** Indicates whether the term has Boolean sort. *) + val is_bool : Expr.expr -> bool (** Indicates whether the term is the constant true. *) val is_true : Expr.expr -> bool @@ -573,84 +646,6 @@ sig (** Indicates whether the term is an implication *) val is_implies : Expr.expr -> bool - - (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) - val is_oeq : Expr.expr -> bool - - (** Creates a new constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - - (** Creates a new constant. *) - val mk_const_s : context -> string -> Sort.sort -> expr - - (** Creates a constant from the func_decl. *) - val mk_const_f : context -> FuncDecl.func_decl -> expr - - (** Creates a fresh constant with a name prefixed with a string. *) - val mk_fresh_const : context -> string -> Sort.sort -> expr - - (** Create a new function application. *) - val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - - (** Create a numeral of a given sort. - @return A Term with the goven value and sort *) - val mk_numeral_string : context -> string -> Sort.sort -> expr - - (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. - @return A Term with the given value and sort *) - val mk_numeral_int : context -> int -> Sort.sort -> expr -end - -(** Boolean expressions *) -module Boolean : -sig - (** Create a Boolean sort *) - val mk_sort : context -> Sort.sort - - (** Create a Boolean constant. *) - val mk_const : context -> Symbol.symbol -> Expr.expr - - (** Create a Boolean constant. *) - val mk_const_s : context -> string -> Expr.expr - - (** The true Term. *) - val mk_true : context -> Expr.expr - - (** The false Term. *) - val mk_false : context -> Expr.expr - - (** Creates a Boolean value. *) - val mk_val : context -> bool -> Expr.expr - - (** Creates the equality between two expr's. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Creates a distinct term. *) - val mk_distinct : context -> Expr.expr list -> Expr.expr - - (** Mk an expression representing not(a). *) - val mk_not : context -> Expr.expr -> Expr.expr - - (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) - val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing t1 iff t2. *) - val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing t1 -> t2. *) - val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing t1 xor t2. *) - val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create an expression representing the AND of args *) - val mk_and : context -> Expr.expr list -> Expr.expr - - (** Create an expression representing the OR of args *) - val mk_or : context -> Expr.expr list -> Expr.expr end (** Quantifier expressions *) @@ -817,7 +812,7 @@ sig The node a must have an array sort [domain -> range], and i must have the sort domain. The sort of the result is range. - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -833,7 +828,7 @@ sig on all indices except for i, where it maps to v (and the select of a with respect to i may be a different value). - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr @@ -841,7 +836,7 @@ sig The resulting term is an array, such that a selecton an arbitrary index produces the value v. - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr @@ -850,7 +845,7 @@ sig Eeach element of args must be of an array sort [domain_i -> range_i]. The function declaration f must have type range_1 .. range_n -> range. v must have sort range. The sort of the result is [domain_i -> range]. - {!Array.mk_sort} + {!Z3Array.mk_sort} {!mk_select} {!mk_store} *) val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr @@ -1837,6 +1832,11 @@ sig (** Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. *) val is_goal : Expr.expr -> bool + (** Indicates whether the term is a binary equivalence modulo namings. + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) + val is_oeq : Expr.expr -> bool + (** Indicates whether the term is proof via modus ponens Given a proof for p and a proof for (implies p q), produces a proof for q. From 555a3883b9544dc6603b2067e96f3b009c97e3f9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 13:05:22 +0100 Subject: [PATCH 423/507] ML example doc fix Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ml/README b/examples/ml/README index f934aac80..a14cbeb63 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -15,8 +15,8 @@ for the byte-code version. If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), then we can compile this example as follows: -ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg -verbose -ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg -verbose +ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg +ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg Note that the resulting binaries depend on the shared z3 library, which needs to be in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was From 4687aa208de1071e0516f11a8811153187a016d9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 13:05:50 +0100 Subject: [PATCH 424/507] ML API refactoring (z3native.c -> z3native_stubs.c) Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++--- scripts/update_api.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 418149dbe..ab13bb943 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1392,9 +1392,9 @@ class MLComponent(Component): out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native.c $(CXX_OUT_FLAG)api/ml/z3native$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native$(OBJ_EXT)\n') + out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) diff --git a/scripts/update_api.py b/scripts/update_api.py index dd1e46c4f..0ed9b29ca 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1148,7 +1148,7 @@ def mk_ml(): ml_dir = get_component('ml').src_dir ml_nativef = os.path.join(ml_dir, 'z3native.ml') ml_nativefi = os.path.join(ml_dir, 'z3native.mli') - ml_wrapperf = os.path.join(ml_dir, 'z3native.c') + ml_wrapperf = os.path.join(ml_dir, 'z3native_stubs.c') ml_native = open(ml_nativef, 'w') ml_i = open(ml_nativefi, 'w') ml_native.write('(* Automatically generated file *)\n\n') From ec0b12ecd16742edf1fcfaee41eedd832e952f15 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 13:06:29 +0100 Subject: [PATCH 425/507] ML API refactoring (z3native.c -> z3native_stubs.c) Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 648013ca1..3cd2d3ef3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ *~ *.pyc +*.pyo +# Ignore callgrind files +callgrind.out.* # .hpp files are automatically generated *.hpp .z3-trace @@ -42,7 +45,6 @@ bld_rel_x64/* # Auto generated files. config.log config.status -configure install_tactic.cpp mem_initializer.cpp gparams_register_modules.cpp @@ -54,6 +56,8 @@ src/api/api_log_macros.cpp src/api/dll/api_dll.def src/api/dotnet/Enumerations.cs src/api/dotnet/Native.cs +src/api/dotnet/Properties/AssemblyInfo.cs +src/api/dotnet/Microsoft.Z3.xml src/api/python/z3consts.py src/api/python/z3core.py src/ast/pattern/database.h @@ -61,21 +65,7 @@ src/util/version.h src/api/java/Native.cpp src/api/java/Native.java src/api/java/enumerations/*.java -*.bak -doc/api -doc/code -src/api/ml/z3_native.c -src/api/ml/z3_native.ml -src/api/ml/native.c -src/api/ml/z3.ml -src/api/ml/enumerations.ml -src/api/ml/z3native.c src/api/ml/z3native_stubs.c src/api/ml/z3native.ml src/api/ml/z3enums.ml src/api/ml/z3.mllib -src/api/ml/z3_native.c -src/api/ml/z3_native.ml -src/api/ml/native.c -src/api/ml/z3.ml -src/api/ml/enumerations.ml From 409a40a5627290a04ab6a60df25f58580c87b01c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 14:18:46 +0100 Subject: [PATCH 426/507] ML API: Added get_bit_int and get_ratio Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 4 +- src/api/ml/z3.ml | 101 +++++++++++++++++++++++++-------------------- src/api/ml/z3.mli | 12 ++++-- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ab13bb943..8dcf3dda6 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1553,7 +1553,7 @@ class MLExampleComponent(ExampleComponent): out.write('\t%s ' % OCAMLC) if DEBUG_MODE: out.write('-g ') - out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" z3.cma') + out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3.cma') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') @@ -1564,7 +1564,7 @@ class MLExampleComponent(ExampleComponent): out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: out.write('-g ') - out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" z3.cmxa') + out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3.cmxa') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 051a54696..dda8807c9 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1425,6 +1425,50 @@ end module Arithmetic = struct + let is_int ( x : expr ) = + (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) + + let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) + + let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) + + let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) + + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) + + let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) + + let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) + + let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) + + let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) + + let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) + + let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) + + let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) + + let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) + + let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) + + let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + + let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + + let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) + + let is_real ( x : expr ) = + ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) + + let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) + + let is_rat_numeral ( x : expr ) = (Expr.is_numeral x) && (is_real x) + + let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) module Integer = struct @@ -1435,6 +1479,12 @@ struct let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") + + let get_big_int ( x : expr ) = + if (is_int_numeral x) then + let s = to_string(x) in + (Big_int.big_int_of_string s) + else raise (Z3native.Exception "Conversion failed.") let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) @@ -1474,6 +1524,12 @@ struct let get_denominator ( x : expr ) = expr_of_ptr (Expr.gc x) (Z3native.get_denominator (Expr.gnc x) (Expr.gno x)) + let get_ratio ( x : expr ) = + if (is_rat_numeral x) then + let s = to_string(x) in + (Ratio.ratio_of_string s) + else raise (Z3native.Exception "Conversion failed.") + let to_decimal_string ( x : expr ) ( precision : int ) = Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision @@ -1518,51 +1574,6 @@ struct end end - let is_int ( x : expr ) = - (Z3native.is_numeral_ast (Expr.gnc x) (Expr.gno x)) && - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == INT_SORT) - - let is_arithmetic_numeral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ANUM) - - let is_le ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LE) - - let is_ge ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GE) - - let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_LT) - - let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_GT) - - let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ADD) - - let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_SUB) - - let is_uminus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_UMINUS) - - let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MUL) - - let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_DIV) - - let is_idiv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IDIV) - - let is_remainder ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_REM) - - let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - - let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - - let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) - - let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) - - let is_real ( x : expr ) = - ((sort_kind_of_int (Z3native.get_sort_kind (Expr.gnc x) (Z3native.get_sort (Expr.gnc x) (Expr.gno x)))) == REAL_SORT) - - let is_int_numeral ( x : expr ) = (Expr.is_numeral x) && (is_int x) - - let is_rat_num ( x : expr ) = (Expr.is_numeral x) && (is_real x) - - let is_algebraic_number ( x : expr ) = Z3native.is_algebraic_number (Expr.gnc x) (Expr.gno x) - let mk_add ( ctx : context ) ( t : expr list ) = let f x = (Expr.gno x) in (expr_of_ptr ctx (Z3native.mk_add (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index c554d7564..4122f40f2 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1149,6 +1149,9 @@ sig (** Retrieve the int value. *) val get_int : Expr.expr -> int + (** Get a big_int from an integer numeral *) + val get_big_int : Expr.expr -> Big_int.big_int + (** Returns a string representation of the numeral. *) val to_string : Expr.expr -> string @@ -1201,10 +1204,13 @@ sig val mk_sort : context -> Sort.sort (** The numerator of a rational numeral. *) - val get_numerator : Expr.expr-> Expr.expr + val get_numerator : Expr.expr -> Expr.expr (** The denominator of a rational numeral. *) - val get_denominator : Expr.expr-> Expr.expr + val get_denominator : Expr.expr -> Expr.expr + + (** Get a ratio from a real numeral *) + val get_ratio : Expr.expr -> Ratio.ratio (** Returns a string representation in decimal notation. The result has at most as many decimal places as indicated by the int argument.*) @@ -1323,7 +1329,7 @@ sig val is_int_numeral : Expr.expr -> bool (** Indicates whether the term is a real numeral. *) - val is_rat_num : Expr.expr -> bool + val is_rat_numeral : Expr.expr -> bool (** Indicates whether the term is an algebraic number *) val is_algebraic_number : Expr.expr -> bool From 65ab6d537307c1680844fe1db6cd68e7146f9b66 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 15:33:07 +0100 Subject: [PATCH 427/507] ML API: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8dcf3dda6..f57763ff1 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1393,7 +1393,7 @@ class MLComponent(Component): out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CXX) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): From 05af33ac7d4f0a7eb63d343ee39bf653563a4e46 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:10:18 +0100 Subject: [PATCH 428/507] ML API: ocamlfind installation fixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 4 ++-- scripts/mk_util.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/ml/README b/examples/ml/README index a14cbeb63..31d4b8e2e 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -15,8 +15,8 @@ for the byte-code version. If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), then we can compile this example as follows: -ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg -ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg +ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg ml_example.ml +ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg ml_example.ml Note that the resulting binaries depend on the shared z3 library, which needs to be in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was diff --git a/scripts/mk_util.py b/scripts/mk_util.py index f57763ff1..a0c9213c9 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1419,6 +1419,9 @@ class MLComponent(Component): out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + for m in modules: + out.write(' %s.cmi' % (os.path.join(sub_dir, m))) + out.write(' %s.cmx' % (os.path.join(sub_dir, m))) if IS_WINDOWS: out.write(' libz3$(LIB_EXT)') out.write('\n') From 59371416050c6a2c38d8b893f65f09887114c73e Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:10:29 +0100 Subject: [PATCH 429/507] ML API: bugfix Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 0ed9b29ca..8ce652ed5 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1254,7 +1254,7 @@ def mk_ml(): ml_native.write(' a%d' % i) i = i + 1 ml_native.write(') in\n') - if len(params) > 0 and param_type(params[0]) == CONTEXT: + if name not in Unwrapped and len(params) > 0 and param_type(params[0]) == CONTEXT: ml_native.write(' let err = (error_code_of_int (ML2C.n_get_error_code a0)) in \n') ml_native.write(' if err <> OK then\n') ml_native.write(' raise (Exception (ML2C.n_get_error_msg_ex a0 (int_of_error_code err)))\n') From cc4010591989908ab2f54a2a7fec7f5ec1ca1840 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:12:55 +0100 Subject: [PATCH 430/507] ML API doc fix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.mli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 4122f40f2..8a88a91bb 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -2404,7 +2404,7 @@ sig (** The finite set of distinct values that represent the interpretation of a sort. {!get_sorts} - @returns A list of expressions, where each is an element of the universe of the sort *) + @return A list of expressions, where each is an element of the universe of the sort *) val sort_universe : model -> Sort.sort -> AST.ast list (** Conversion of models to strings. From 83690a8fe3a64cc45f16a444f7b82e0d1c27f9fe Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 16 Apr 2014 16:16:40 +0100 Subject: [PATCH 431/507] ML API doc fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.mli | 220 +++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 8a88a91bb..ff45fb0f2 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -241,7 +241,7 @@ sig AST objects are reference counted and unwrapping an AST disables automatic reference counting, i.e., all references to the IntPtr that is returned must be handled externally and through native calls (see e.g., - Z3native.inc_ref). + [Z3native.inc_ref]). {!wrap_ast} *) val unwrap_ast : ast -> Z3native.ptr @@ -251,7 +251,7 @@ sig managed objects. Note that the native ast that is passed must be a native object obtained from Z3 (e.g., through {!unwrap_ast}) and that it must have a correct reference count (see e.g., - Z3native.inc_ref). *) + [Z3native.inc_ref]). *) val wrap_ast : context -> Z3native.z3_ast -> ast end @@ -439,7 +439,7 @@ sig (** Update a mutable configuration parameter. The list of all configuration parameters can be obtained using the Z3 executable: - z3.exe -p + [z3.exe -p] Only a few configuration parameters are mutable once the context is created. An exception is thrown when trying to modify an immutable parameter. {!get_param_value} *) @@ -479,7 +479,7 @@ sig {!get_simplify_help} *) val simplify : Expr.expr -> Params.params option -> expr - (** A string describing all available parameters to Expr.Simplify. *) + (** A string describing all available parameters to [Expr.Simplify]. *) val get_simplify_help : context -> string (** Retrieves parameter descriptions for simplifier. *) @@ -498,20 +498,20 @@ sig The number of new arguments should coincide with the current number of arguments. *) val update : Expr.expr -> Expr.expr list -> expr - (** Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. + (** Substitute every occurrence of [from[i]] in the expression with [to[i]], for [i] smaller than [num_exprs]. - The result is the new expression. The arrays from and to must have size num_exprs. - For every i smaller than num_exprs, we must have that - sort of from[i] must be equal to sort of to[i]. *) + The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. + For every [i] smaller than [num_exprs], we must have that + sort of [from[i]] must be equal to sort of [to[i]]. *) val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr - (** Substitute every occurrence of from in the expression with to. + (** Substitute every occurrence of [from] in the expression with [to]. {!substitute} *) val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr (** Substitute the free variables in the expression with the expressions in the expr array - For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. *) + For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) val substitute_vars : Expr.expr -> Expr.expr list -> expr (** Translates (copies) the term to another context. @@ -554,7 +554,7 @@ sig val mk_numeral_string : context -> string -> Sort.sort -> expr (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than MakeNumeral since it is not necessary to parse a string. + It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. @return A Term with the given value and sort *) val mk_numeral_int : context -> int -> Sort.sort -> expr end @@ -580,19 +580,19 @@ sig (** Creates a Boolean value. *) val mk_val : context -> bool -> Expr.expr - (** Mk an expression representing not(a). *) + (** Mk an expression representing [not(a)]. *) val mk_not : context -> Expr.expr -> Expr.expr - (** Create an expression representing an if-then-else: ite(t1, t2, t3). *) + (** Create an expression representing an if-then-else: [ite(t1, t2, t3)]. *) val mk_ite : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 iff t2. *) + (** Create an expression representing [t1 iff t2]. *) val mk_iff : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 -> t2. *) + (** Create an expression representing [t1 -> t2]. *) val mk_implies : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 xor t2. *) + (** Create an expression representing [t1 xor t2]. *) val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing the AND of args *) @@ -604,7 +604,7 @@ sig (** Creates the equality between two expr's. *) val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Creates a distinct term. *) + (** Creates a [distinct] term. *) val mk_distinct : context -> Expr.expr list -> Expr.expr (** Indicates whether the expression is the true or false expression @@ -806,45 +806,45 @@ sig (** Array read. - The argument a is the array and i is the index + The argument [a] is the array and [i] is the index of the array that gets read. - The node a must have an array sort [domain -> range], - and i must have the sort domain. - The sort of the result is range. + The node [a] must have an array sort [[domain -> range]], + and [i] must have the sort [domain]. + The sort of the result is [range]. {!Z3Array.mk_sort} {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr (** Array update. - The node a must have an array sort [domain -> range], - i must have sort domain, - v must have sort range. The sort of the result is [domain -> range]. + The node [a] must have an array sort [[domain -> range]], + [i] must have sort [domain], + [v] must have sort range. The sort of the result is [[domain -> range]]. The semantics of this function is given by the theory of arrays described in the SMT-LIB standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to a - (with respect to select) - on all indices except for i, where it maps to v - (and the select of a with - respect to i may be a different value). + The result of this function is an array that is equal to [a] + (with respect to [select]) + on all indices except for [i], where it maps to [v] + (and the [select] of [a] with + respect to [i] may be a different value). {!Z3Array.mk_sort} {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr (** Create a constant array. - The resulting term is an array, such that a selecton an arbitrary index - produces the value v. + The resulting term is an array, such that a [select]on an arbitrary index + produces the value [v]. {!Z3Array.mk_sort} {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr (** Maps f on the argument arrays. - Eeach element of args must be of an array sort [domain_i -> range_i]. - The function declaration f must have type range_1 .. range_n -> range. - v must have sort range. The sort of the result is [domain_i -> range]. + Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. + The function declaration [f] must have type [ range_1 .. range_n -> range]. + [v] must have sort range. The sort of the result is [[domain_i -> range]]. {!Z3Array.mk_sort} {!mk_select} {!mk_store} *) @@ -938,8 +938,8 @@ sig (** Indicates whether the term is an relation store Insert a record into a relation. - The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - correspond to the n columns of the relation. *) + The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements + correspond to the [n] columns of the relation. *) val is_store : Expr.expr -> bool (** Indicates whether the term is an empty relation *) @@ -997,8 +997,8 @@ sig (** Indicates whether the term is a relational select Check if a record is an element of the relation. - The function takes n+1 arguments, where the first argument is a relation, - and the remaining n arguments correspond to a record. *) + The function takes [n+1] arguments, where the first argument is a relation, + and the remaining [n] arguments correspond to a record. *) val is_select : Expr.expr -> bool (** Indicates whether the term is a relational clone (copy) @@ -1161,11 +1161,11 @@ sig (** Creates an integer constant. *) val mk_const_s : context -> string -> Expr.expr - (** Create an expression representing t1 mod t2. + (** Create an expression representing [t1 mod t2]. The arguments must have int type. *) val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 rem t2. + (** Create an expression representing [t1 rem t2]. The arguments must have int type. *) val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1181,8 +1181,8 @@ sig There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - You can take the floor of a real by creating an auxiliary integer Term k and - and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. + You can take the floor of a real by creating an auxiliary integer Term [k] and + and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. The argument must be of integer sort. *) val mk_int2real : context -> Expr.expr -> Expr.expr @@ -1334,34 +1334,34 @@ sig (** Indicates whether the term is an algebraic number *) val is_algebraic_number : Expr.expr -> bool - (** Create an expression representing t[0] + t[1] + .... *) + (** Create an expression representing [t[0] + t[1] + ...]. *) val mk_add : context -> Expr.expr list -> Expr.expr - (** Create an expression representing t[0] * t[1] * .... *) + (** Create an expression representing [t[0] * t[1] * ...]. *) val mk_mul : context -> Expr.expr list -> Expr.expr - (** Create an expression representing t[0] - t[1] - .... *) + (** Create an expression representing [t[0] - t[1] - ...]. *) val mk_sub : context -> Expr.expr list -> Expr.expr - (** Create an expression representing -t. *) + (** Create an expression representing [-t]. *) val mk_unary_minus : context -> Expr.expr -> Expr.expr - (** Create an expression representing t1 / t2. *) + (** Create an expression representing [t1 / t2]. *) val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 ^ t2. *) + (** Create an expression representing [t1 ^ t2]. *) val mk_power : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 < t2 *) + (** Create an expression representing [t1 < t2] *) val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 <= t2 *) + (** Create an expression representing [t1 <= t2] *) val mk_le : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 > t2 *) + (** Create an expression representing [t1 > t2] *) val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr - (** Create an expression representing t1 >= t2 *) + (** Create an expression representing [t1 >= t2] *) val mk_ge : context -> Expr.expr -> Expr.expr -> Expr.expr end @@ -1610,8 +1610,8 @@ sig (** Unsigned division. - It is defined as the floor of t1/t2 if \c t2 is - different from zero. If t2 is zero, then the result + It is defined as the floor of [t1/t2] if \c t2 is + different from zero. If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1620,33 +1620,33 @@ sig It is defined in the following way: - - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. + - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. - - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. + - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. - If t2 is zero, then the result is undefined. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned remainder. - It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - If t2 is zero, then the result is undefined. + It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed remainder. - It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. + It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - If t2 is zero, then the result is undefined. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed remainder (sign follows divisor). - If t2 is zero, then the result is undefined. + If [t2] is zero, then the result is undefined. The arguments must have the same bit-vector sort. *) val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr @@ -1694,27 +1694,27 @@ sig The arguments must have a bit-vector sort. @return - The result is a bit-vector of size n1+n2, where n1 (n2) - is the size of t1 (t2). *) + The result is a bit-vector of size [n1+n2], where [n1] ([n2]) + is the size of [t1] ([t2]). *) val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector extraction. Extract the bits between two limits from a bitvector of - size m to yield a new bitvector of size n, where - n = high - low + 1. *) + size [m] to yield a new bitvector of size [n], where + [n = high - low + 1]. *) val mk_extract : context -> int -> int -> Expr.expr -> Expr.expr (** Bit-vector sign extension. Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size m+i, where \c m is the size of the given bit-vector. *) + size [m+i], where \c m is the size of the given bit-vector. *) val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr (** Bit-vector zero extension. Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size m+i, where \c m is the size of the + bitvector of size [m+i], where \c m is the size of the given bit-vector. *) val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr @@ -1723,7 +1723,7 @@ sig (** Shift left. - It is equivalent to multiplication by 2^x where \c x is the value of third argument. + It is equivalent to multiplication by [2^x] where \c x is the value of third argument. NB. The semantics of shift operations varies between environments. This definition does not necessarily capture directly the semantics of the @@ -1732,7 +1732,7 @@ sig (** Logical shift right - It is equivalent to unsigned division by 2^x where \c x is the value of the third argument. + It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. NB. The semantics of shift operations varies between environments. This definition does not necessarily capture directly the semantics of the @@ -1773,7 +1773,7 @@ sig (** Create an integer from the bit-vector argument If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - So the result is non-negative and in the range [0..2^N-1], where + So the result is non-negative and in the range [[0..2^N-1]], where N are the number of bits in the argument. If \c is_signed is true, \c t1 is treated as a signed bit-vector. @@ -2353,15 +2353,15 @@ sig end (** Retrieves the interpretation (the assignment) of a func_decl in the model. - An expression if the function has an interpretation in the model, null otherwise. *) + @return An expression if the function has an interpretation in the model, null otherwise. *) val get_const_interp : model -> FuncDecl.func_decl -> Expr.expr option (** Retrieves the interpretation (the assignment) of an expression in the model. - An expression if the constant has an interpretation in the model, null otherwise. *) + @return An expression if the constant has an interpretation in the model, null otherwise. *) val get_const_interp_e : model -> Expr.expr -> Expr.expr option (** Retrieves the interpretation (the assignment) of a non-constant func_decl in the model. - A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) + @return A FunctionInterpretation if the function has an interpretation in the model, null otherwise. *) val get_func_interp : model -> FuncDecl.func_decl -> FuncInterp.func_interp option (** The number of constant interpretations in the model. *) @@ -2383,11 +2383,11 @@ sig This function may fail if the argument contains quantifiers, is partial (MODEL_PARTIAL enabled), or if it is not well-sorted. - In this case a ModelEvaluationFailedException is thrown. + In this case a [ModelEvaluationFailedException] is thrown. *) val eval : model -> Expr.expr -> bool -> Expr.expr option - (** Alias for eval. *) + (** Alias for [eval]. *) val evaluate : model -> Expr.expr -> bool -> Expr.expr option (** The number of uninterpreted sorts that the model has an interpretation for. *) @@ -2408,7 +2408,7 @@ sig val sort_universe : model -> Sort.sort -> AST.ast list (** Conversion of models to strings. - A string representation of the model. *) + @return A string representation of the model. *) val to_string : model -> string end @@ -2416,17 +2416,17 @@ end Probes are used to inspect a goal (aka problem) and collect information that may be used to decide which solver and/or preprocessing step will be used. - The complete list of probes may be obtained using the procedures Context.NumProbes - and Context.ProbeNames. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + The complete list of probes may be obtained using the procedures [Context.NumProbes] + and [Context.ProbeNames]. + It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. *) module Probe : sig type probe (** Execute the probe over the goal. - A probe always produce a float value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + @return A probe always produce a float value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) val apply : probe -> Goal.goal -> float (** The number of supported Probes. *) @@ -2478,9 +2478,9 @@ end (** Tactics Tactics are the basic building block for creating custom solvers for specific problem domains. - The complete list of tactics may be obtained using Context.get_num_tactics - and Context.get_tactic_names. - It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. + The complete list of tactics may be obtained using [Context.get_num_tactics] + and [Context.get_tactic_names]. + It may also be obtained using the command [(help-tactics)] in the SMT 2.0 front-end. *) module Tactic : sig @@ -2504,8 +2504,8 @@ sig val get_subgoal : apply_result -> int -> Goal.goal (** Convert a model for a subgoal into a model for the original - goal g, that the ApplyResult was obtained from. - #return A model for g *) + goal [g], that the ApplyResult was obtained from. + #return A model for [g] *) val convert_model : apply_result -> int -> Model.model -> Model.model (** A string representation of the ApplyResult. *) @@ -2549,7 +2549,7 @@ sig (** Create a tactic that applies one tactic to a given goal if the probe evaluates to true. - If the probe evaluates to false, then the new tactic behaves like the skip tactic. *) + If the probe evaluates to false, then the new tactic behaves like the [skip] tactic. *) val when_ : context -> Probe.probe -> tactic -> tactic (** Create a tactic that applies a tactic to a given goal if the probe @@ -2577,7 +2577,7 @@ sig val using_params : context -> tactic -> Params.params -> tactic (** Create a tactic that applies a tactic using the given set of parameters. - Alias for UsingParams*) + Alias for [UsingParams]*) val with_ : context -> tactic -> Params.params -> tactic (** Create a tactic that applies the given tactics in parallel. *) @@ -2718,26 +2718,26 @@ sig {!Proof} *) val check : solver -> Expr.expr list -> status - (** The model of the last Check. + (** The model of the last [Check]. - The result is None if Check was not invoked before, - if its results was not SATISFIABLE, or if model production is not enabled. *) + The result is [None] if [Check] was not invoked before, + if its results was not [SATISFIABLE], or if model production is not enabled. *) val get_model : solver -> Model.model option - (** The proof of the last Check. + (** The proof of the last [Check]. - The result is null if Check was not invoked before, - if its results was not UNSATISFIABLE, or if proof production is disabled. *) + The result is [null] if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if proof production is disabled. *) val get_proof : solver -> Expr.expr option - (** The unsat core of the last Check. + (** The unsat core of the last [Check]. - The unsat core is a subset of Assertions - The result is empty if Check was not invoked before, - if its results was not UNSATISFIABLE, or if core production is disabled. *) + The unsat core is a subset of [Assertions] + The result is empty if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if core production is disabled. *) val get_unsat_core : solver -> AST.ast list - (** A brief justification of why the last call to Check returned UNKNOWN. *) + (** A brief justification of why the last call to [Check] returned [UNKNOWN]. *) val get_reason_unknown : solver -> string (** Solver statistics. *) @@ -2759,7 +2759,7 @@ sig (** Creates a solver that is implemented using the given tactic. - The solver supports the commands Push and Pop, but it + The solver supports the commands [Push] and [Pop], but it will always solve each check from scratch. *) val mk_solver_t : context -> Tactic.tactic -> solver @@ -2811,7 +2811,7 @@ sig (** Backtrack one backtracking point. - Note that an exception is thrown if Pop is called without a corresponding Push + Note that an exception is thrown if Pop is called without a corresponding [Push] {!push} *) val pop : fixedpoint -> unit @@ -2875,28 +2875,28 @@ sig {!parse_smtlib_string} *) val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit - (** The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_formulas : context -> int - (** The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_formulas : context -> Expr.expr list - (** The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_assumptions : context -> int - (** The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The assumptions parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_assumptions : context -> Expr.expr list - (** The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_decls : context -> int - (** The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_decls : context -> FuncDecl.func_decl list - (** The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The number of SMTLIB sorts parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_num_smtlib_sorts : context -> int - (** The sort declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. *) + (** The sort declarations parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) val get_smtlib_sorts : context -> Sort.sort list (** Parse the given string using the SMT-LIB2 parser. From e7345f5ea809049d56705635208ffac8b93ab87a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 17 Apr 2014 15:06:32 +0100 Subject: [PATCH 432/507] ML API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index dda8807c9..e2fa01478 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1482,7 +1482,7 @@ struct let get_big_int ( x : expr ) = if (is_int_numeral x) then - let s = to_string(x) in + let s = (Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x)) in (Big_int.big_int_of_string s) else raise (Z3native.Exception "Conversion failed.") @@ -1526,7 +1526,7 @@ struct let get_ratio ( x : expr ) = if (is_rat_numeral x) then - let s = to_string(x) in + let s = (Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x)) in (Ratio.ratio_of_string s) else raise (Z3native.Exception "Conversion failed.") From a73a66b79c64971109ab3425654a8299ff1332bf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 22 Apr 2014 11:49:47 +0100 Subject: [PATCH 433/507] ML API bugfix Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index e2fa01478..dafd255f8 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -119,7 +119,7 @@ let mk_list ( f : int -> 'a ) ( n : int ) = if (i >= n) then tail else - (mk_list' f (i+1) n ((f i) :: tail)) + (f i) :: (mk_list' f (i+1) n tail) in mk_list' f 0 n [] From 9160925c28fbcc3586dc15dad249096f06bec148 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Apr 2014 15:15:59 +0100 Subject: [PATCH 434/507] ML API: added Expr.equal and Expr.compare Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 6 ++++++ src/api/ml/z3.mli | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index dafd255f8..3f40b288c 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -717,6 +717,8 @@ sig val mk_app : context -> FuncDecl.func_decl -> expr list -> expr val mk_numeral_string : context -> string -> Sort.sort -> expr val mk_numeral_int : context -> int -> Sort.sort -> expr + val equal : expr -> expr -> bool + val compare : expr -> expr -> int end = struct type expr = Expr of AST.ast @@ -830,6 +832,10 @@ end = struct let mk_numeral_int ( ctx : context ) ( v : int ) ( ty : sort ) = expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) + + let equal ( a : expr ) ( b : expr ) = AST.equal (ast_of_expr a) (ast_of_expr b) + + let compare a b = AST.compare (ast_of_expr a) (ast_of_expr b) end open FuncDecl diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index ff45fb0f2..84f230d95 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -554,9 +554,17 @@ sig val mk_numeral_string : context -> string -> Sort.sort -> expr (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. - It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. - @return A Term with the given value and sort *) + It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. + @return A Term with the given value and sort *) val mk_numeral_int : context -> int -> Sort.sort -> expr + + (** Comparison operator. + @return True if the two expr's are equal; false otherwise. *) + val equal : expr -> expr -> bool + + (** Object Comparison. + @return Negative if the first expr should be sorted before the second, positive if after, else zero. *) + val compare : expr -> expr -> int end (** Boolean expressions; Propositional logic and equality *) From 5e2a7e06fd21ce14e3ff33042fbec7562307d3a4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 23 Apr 2014 15:25:08 +0100 Subject: [PATCH 435/507] ML API: added constructors for ast_map and ast_vector Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 31 ++++++++++++++++++++++--------- src/api/ml/z3.mli | 20 ++++++++++++-------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 3f40b288c..b48681b87 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -214,7 +214,7 @@ struct struct type ast_vector = z3_native_object - let ast_vector_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; inc_ref = Z3native.ast_vector_inc_ref ; @@ -223,6 +223,8 @@ struct (z3obj_create res) ; res + let mk_ast_vector ( ctx : context ) = (create ctx (Z3native.mk_ast_vector (context_gno ctx))) + let get_size ( x : ast_vector ) = Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) @@ -239,7 +241,7 @@ struct Z3native.ast_vector_push (z3obj_gnc x) (z3obj_gno x) (z3obj_gno a) let translate ( x : ast_vector ) ( to_ctx : context ) = - ast_vector_of_ptr to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) + create to_ctx (Z3native.ast_vector_translate (z3obj_gnc x) (z3obj_gno x) (context_gno to_ctx)) let to_string ( x : ast_vector ) = Z3native.ast_vector_to_string (z3obj_gnc x) (z3obj_gno x) @@ -248,7 +250,18 @@ struct module ASTMap = struct type ast_map = z3_native_object + + let create ( ctx : context ) ( no : Z3native.ptr ) = + let res : ast_map = { m_ctx = ctx ; + m_n_obj = null ; + inc_ref = Z3native.ast_map_inc_ref ; + dec_ref = Z3native.ast_map_dec_ref } in + (z3obj_sno res ctx no) ; + (z3obj_create res) ; + res + let mk_ast_map ( ctx : context ) = (create ctx (Z3native.mk_ast_map (context_gno ctx))) + let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_map = { m_ctx = ctx ; m_n_obj = null ; @@ -277,7 +290,7 @@ struct Z3native.ast_map_size (z3obj_gnc x) (z3obj_gno x) let get_keys ( x : ast_map ) = - let av = ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in + let av = ASTVector.create (z3obj_gc x) (Z3native.ast_map_keys (z3obj_gnc x) (z3obj_gno x)) in let f i = (ASTVector.get av i) in mk_list f (ASTVector.get_size av) @@ -2061,7 +2074,7 @@ struct mk_list f n let sort_universe ( x : model ) ( s : sort ) = - let n_univ = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in + let n_univ = AST.ASTVector.create (z3obj_gc x) (Z3native.model_get_sort_universe (z3obj_gnc x) (z3obj_gno x) (Sort.gno s)) in let n = (AST.ASTVector.get_size n_univ) in let f i = (AST.ASTVector.get n_univ i) in mk_list f n @@ -2386,11 +2399,11 @@ struct Z3native.solver_assert_and_track (z3obj_gnc x) (z3obj_gno x) (Expr.gno c) (Expr.gno p) let get_num_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in (AST.ASTVector.get_size a) let get_assertions ( x : solver ) = - let a = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in + let a = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_assertions (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size a) in let f i = (expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get a i))) in mk_list f n @@ -2423,7 +2436,7 @@ struct Some (expr_of_ptr (z3obj_gc x) q) let get_unsat_core ( x : solver ) = - let cn = AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in + let cn = AST.ASTVector.create (z3obj_gc x) (Z3native.solver_get_unsat_core (z3obj_gnc x) (z3obj_gno x)) in let n = (AST.ASTVector.get_size cn) in let f i = (AST.ASTVector.get cn i) in mk_list f n @@ -2545,13 +2558,13 @@ struct Z3native.fixedpoint_to_string (z3obj_gnc x) (z3obj_gno x) (List.length queries) (Array.of_list (List.map f queries)) let get_rules ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_rules (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n let get_assertions ( x : fixedpoint ) = - let v = (AST.ASTVector.ast_vector_of_ptr (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in + let v = (AST.ASTVector.create (z3obj_gc x) (Z3native.fixedpoint_get_assertions (z3obj_gnc x) (z3obj_gno x))) in let n = (AST.ASTVector.get_size v) in let f i =(expr_of_ptr (z3obj_gc x) (z3obj_gno (AST.ASTVector.get v i))) in mk_list f n diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 84f230d95..4347c7431 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -107,10 +107,9 @@ sig (** A string representation of the symbol. *) val to_string : symbol -> string - (** Creates a new symbol using an integer. - - Not all integers can be passed to this function. - The legal range of unsigned integers is 0 to 2^30-1. *) + (** Creates a new symbol using an integer. + Not all integers can be passed to this function. + The legal range of unsigned integers is 0 to 2^30-1. *) val mk_int : context -> int -> symbol (** Creates a new symbol using a string. *) @@ -132,12 +131,14 @@ sig module ASTVector : sig type ast_vector + + (** Create an empty AST vector *) + val mk_ast_vector : context -> ast_vector (** The size of the vector *) val get_size : ast_vector -> int - (** - Retrieves the i-th object in the vector. + (** Retrieves the i-th object in the vector. @return An AST *) val get : ast_vector -> int -> ast @@ -162,7 +163,10 @@ sig (** Map from AST to AST *) module ASTMap : sig - type ast_map + type ast_map + + (** Create an empty mapping from AST to AST *) + val mk_ast_map : context -> ast_map (** Checks whether the map contains a key. @return True if the key in the map, false otherwise. *) @@ -2297,7 +2301,7 @@ sig (** Creates a new Goal. - Note that the Context must have been created with proof generation support if + Note that the Context must have been created with proof generation support if the fourth argument is set to true here. *) val mk_goal : context -> bool -> bool -> bool -> goal From a8f703e0344812ee94b037bda9a17802415ff03d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 18:50:11 +0100 Subject: [PATCH 436/507] ML API bugfix. Thanks to Martin Neuhaeusser for reporting this one! Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index b48681b87..bdcf1a26b 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -2045,7 +2045,7 @@ struct let get_num_funcs ( x : model ) = Z3native.model_get_num_funcs (z3obj_gnc x) (z3obj_gno x) let get_func_decls ( x : model ) = - let n = (get_num_consts x) in + let n = (get_num_funcs x) in let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in mk_list f n From 7ec8c81c3369613a3baf5272b1973344997a9927 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 18:59:03 +0100 Subject: [PATCH 437/507] ML API fix for datatype construction (Issue #121). Thanks to Elarnon for reporting this one! Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 12 ++++++++---- src/api/ml/z3.mli | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index bdcf1a26b..f34ce0ca7 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -374,6 +374,10 @@ struct let sort_lton ( a : sort list ) = let f ( e : sort ) = match e with Sort(a) -> (AST.ptr_of_ast a) in Array.of_list (List.map f a) + + let sort_option_lton ( a : sort option list ) = + let f ( e : sort option ) = match e with None -> null | Some(Sort(a)) -> (AST.ptr_of_ast a) in + Array.of_list (List.map f a) let equal : sort -> sort -> bool = fun a b -> (a == b) || @@ -1257,7 +1261,7 @@ struct let _sizes = Hashtbl.create 0 - let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = let n = (List.length field_names) in if n != (List.length sorts) then raise (Z3native.Exception "Number of field names does not match number of sorts") @@ -1269,7 +1273,7 @@ struct (Symbol.gno recognizer) n (Symbol.symbol_lton field_names) - (sort_lton sorts) + (sort_option_lton sorts) (Array.of_list sort_refs)) in let no : constructor = { m_ctx = ctx ; m_n_obj = null ; @@ -1316,11 +1320,11 @@ struct res end - let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let mk_constructor ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = Constructor.create ctx name recognizer field_names sorts sort_refs - let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort list ) ( sort_refs : int list ) = + let mk_constructor_s ( ctx : context ) ( name : string ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = mk_constructor ctx (Symbol.mk_string ctx name) recognizer field_names sorts sort_refs let mk_sort ( ctx : context ) ( name : Symbol.symbol ) ( constructors : Constructor.constructor list ) = diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 4347c7431..1342bb4bc 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1053,12 +1053,12 @@ sig (** Create a datatype constructor. if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a datatype constructor. if the corresponding sort reference is 0, then the value in sort_refs should be an index referring to one of the recursive datatypes that is declared. *) - val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort list -> int list -> Constructor.constructor + val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a new datatype sort. *) val mk_sort : context -> Symbol.symbol -> Constructor.constructor list -> Sort.sort From 84b7644305c64475c0aedb72f202c384342a6155 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 19:16:16 +0100 Subject: [PATCH 438/507] ML API bugfix (Issue #119). Thanks to user Elarnon for reporting this! Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 8ce652ed5..fba194bac 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -1464,7 +1464,7 @@ def mk_ml(): for p in params: if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) - ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) + ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s_val, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) elif is_out_param(p): ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) i = i + 1 From 94a8c271d4fb3c47086dacc27ae789e80867d951 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 24 Jul 2014 19:29:06 +0100 Subject: [PATCH 439/507] ML API bugfix for datatype module (Issue #120). Thanks to user Elarnon for reporting this! Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/z3.ml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index f34ce0ca7..013101398 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -277,7 +277,7 @@ struct let find ( x : ast_map ) ( key : ast ) = ast_of_ptr (z3obj_gc x) (Z3native.ast_map_find (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key)) - let insert ( x : ast_map ) ( key : ast ) ( value : ast) = + let insert ( x : ast_map ) ( key : ast ) ( value : ast ) = Z3native.ast_map_insert (z3obj_gnc x) (z3obj_gno x) (z3obj_gno key) (z3obj_gno value) let erase ( x : ast_map ) ( key : ast ) = @@ -1259,7 +1259,13 @@ struct struct type constructor = z3_native_object - let _sizes = Hashtbl.create 0 + module FieldNumTable = Hashtbl.Make(struct + type t = AST.ast + let equal x y = AST.compare x y = 0 + let hash = AST.hash + end) + + let _field_nums = FieldNumTable.create 0 let create ( ctx : context ) ( name : Symbol.symbol ) ( recognizer : Symbol.symbol ) ( field_names : Symbol.symbol list ) ( sorts : sort option list ) ( sort_refs : int list ) = let n = (List.length field_names) in @@ -1283,10 +1289,10 @@ struct (z3obj_create no) ; let f = fun o -> Z3native.del_constructor (z3obj_gnc o) (z3obj_gno o) in Gc.finalise f no ; - Hashtbl.add _sizes no n ; + FieldNumTable.add _field_nums no n ; no - let get_num_fields ( x : constructor ) = Hashtbl.find _sizes x + let get_num_fields ( x : constructor ) = FieldNumTable.find _field_nums x let get_constructor_decl ( x : constructor ) = let (a, _, _) = (Z3native.query_constructor (z3obj_gnc x) (z3obj_gno x) (get_num_fields x)) in From fa4dab48522f4d9e96f4f7456cc57c9208cf622f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 14 Aug 2014 18:58:52 +0100 Subject: [PATCH 440/507] ML API: added .cmxs to the distribution. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index a0c9213c9..bf1f5e471 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1402,7 +1402,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('\t%s ' % (OCAMLOPT)) + if DEBUG_MODE: + out.write('-g ') + out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1410,15 +1415,15 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L../.. -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('ml: api/ml/z3.cmxa api/ml/z3.cma\n') + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa\n') + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) - out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) for m in modules: out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) From fe0b579426cdb98ebe6f24324eb98fc0b8cddb0c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:02:00 +0100 Subject: [PATCH 441/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index bf1f5e471..784d47cee 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1402,12 +1402,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('-shared -o %s %s -linkall\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1415,7 +1415,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From a1bb307dd18bb02ba375e570805b36bbe5107f15 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:09:01 +0100 Subject: [PATCH 442/507] ML API: bugfixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 784d47cee..3e9bd8eb2 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1402,7 +1402,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: @@ -1415,7 +1415,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib -lz3ml -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From 7bd8dda766fa01a23b83367b27335d744af0c9e8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:18:40 +0100 Subject: [PATCH 443/507] ML API: bugfixes --- scripts/mk_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 3e9bd8eb2..ef01ccc10 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1402,12 +1402,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-shared -o %s %s -linkall\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + out.write('-shared -cclib "-L%s -lz3ml" -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir,'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1415,7 +1415,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-Lapi/ml -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From 8cd74a825d8c148566848835924dccb15c3982f6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 19 Aug 2014 19:32:33 +0100 Subject: [PATCH 444/507] ML API: Undoing earlier changes. Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ef01ccc10..bf1f5e471 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1402,12 +1402,12 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('\t%s ' % (OCAMLOPT)) if DEBUG_MODE: out.write('-g ') - out.write('-shared -cclib "-L%s -lz3ml" -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir,'z3.cmxa'))) + out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) @@ -1415,7 +1415,7 @@ class MLComponent(Component): out.write('\t%s ' % (OCAMLC)) if DEBUG_MODE: out.write('-g ') - out.write('-cclib "-L%s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir,sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) out.write('\n') # Generate META file and package installation commands From 42f12ed75216d891550b879a987ef5e9036ee47a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 19:39:13 +0000 Subject: [PATCH 445/507] ML API: added interpolation, bugfixes. Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 10 +- src/api/ml/z3.ml | 121 ++-- src/api/ml/z3.mli | 1386 +++++++++++++++++++++-------------------- 3 files changed, 806 insertions(+), 711 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index fba194bac..4669b78fc 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -334,6 +334,8 @@ def param2ml(p): return "ptr" elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY: return "%s array" % type2ml(param_type(p)) + elif k == OUT_MANAGED_ARRAY: + return "%s array" % type2ml(param_type(p)); else: return type2ml(param_type(p)) @@ -1067,7 +1069,7 @@ def ml_method_name(name): return name[3:] # Remove Z3_ def is_out_param(p): - if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: + if param_kind(p) == OUT or param_kind(p) == INOUT or param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT_MANAGED_ARRAY: return True else: return False @@ -1411,6 +1413,8 @@ def mk_ml(): type2str(param_type(param)), type2str(param_type(param)), param_array_capacity_pos(param))) + elif k == OUT_MANAGED_ARRAY: + ml_wrapper.write(' %s * _a%s = 0;\n' % (type2str(param_type(param)), i)) elif k == IN_ARRAY or k == INOUT_ARRAY: t = param_type(param) ts = type2str(t) @@ -1449,7 +1453,7 @@ def mk_ml(): else: ml_wrapper.write(', ') k = param_kind(param) - if k == OUT or k == INOUT: + if k == OUT or k == INOUT or k == OUT_MANAGED_ARRAY: ml_wrapper.write('&_a%s' % i) else: ml_wrapper.write('_a%i' % i) @@ -1465,6 +1469,8 @@ def mk_ml(): if param_kind(p) == OUT_ARRAY or param_kind(p) == INOUT_ARRAY: ml_wrapper.write(' _a%s_val = caml_alloc(_a%s, 0);\n' % (i, param_array_capacity_pos(p))) ml_wrapper.write(' for (_i = 0; _i < _a%s; _i++) { value t; %s Store_field(_a%s_val, _i, t); }\n' % (param_array_capacity_pos(p), ml_set_wrap(param_type(p), 't', '_a' + str(i) + '[_i]'), i)) + elif param_kind(p) == OUT_MANAGED_ARRAY: + ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) elif is_out_param(p): ml_wrapper.write(' %s\n' % ml_set_wrap(param_type(p), "_a" + str(i) + "_val", "_a" + str(i) )) i = i + 1 diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 013101398..2b54a1113 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -165,7 +165,7 @@ struct let symbol_lton ( a : symbol list ) = let f ( e : symbol ) = (gno e) in Array.of_list (List.map f a) - + let kind ( o : symbol ) = (symbol_kind_of_int (Z3native.get_symbol_kind (gnc o) (gno o))) let is_int_symbol ( o : symbol ) = (kind o) == INT_SYMBOL let is_string_symbol ( o : symbol ) = (kind o) == STRING_SYMBOL @@ -213,7 +213,7 @@ struct module ASTVector = struct type ast_vector = z3_native_object - + let create ( ctx : context ) ( no : Z3native.ptr ) = let res : ast_vector = { m_ctx = ctx ; m_n_obj = null ; @@ -224,7 +224,7 @@ struct res let mk_ast_vector ( ctx : context ) = (create ctx (Z3native.mk_ast_vector (context_gno ctx))) - + let get_size ( x : ast_vector ) = Z3native.ast_vector_size (z3obj_gnc x) (z3obj_gno x) @@ -259,7 +259,7 @@ struct (z3obj_sno res ctx no) ; (z3obj_create res) ; res - + let mk_ast_map ( ctx : context ) = (create ctx (Z3native.mk_ast_map (context_gno ctx))) let astmap_of_ptr ( ctx : context ) ( no : Z3native.ptr ) = @@ -330,7 +330,7 @@ struct if (get_id a) < (get_id b) then -1 else if (get_id a) > (get_id b) then 1 else 0 - + let translate ( x : ast ) ( to_ctx : context ) = if (z3obj_gnc x) == (context_gno to_ctx) then x @@ -366,7 +366,7 @@ struct | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") let ast_of_sort s = match s with Sort(x) -> x - + let gc ( x : sort ) = (match x with Sort(a) -> (z3obj_gc a)) let gnc ( x : sort ) = (match x with Sort(a) -> (z3obj_gnc a)) let gno ( x : sort ) = (match x with Sort(a) -> (z3obj_gno a)) @@ -378,7 +378,7 @@ struct let sort_option_lton ( a : sort option list ) = let f ( e : sort option ) = match e with None -> null | Some(Sort(a)) -> (AST.ptr_of_ast a) in Array.of_list (List.map f a) - + let equal : sort -> sort -> bool = fun a b -> (a == b) || if (gnc a) != (gnc b) then @@ -629,7 +629,6 @@ sig val to_string : params -> string val update_param_value : context -> string -> string -> unit - val get_param_value : context -> string -> string option val set_print_mode : context -> Z3enums.ast_print_mode -> unit end = struct type params = z3_native_object @@ -688,13 +687,6 @@ end = struct let update_param_value ( ctx : context ) ( id : string) ( value : string )= Z3native.update_param_value (context_gno ctx) id value - let get_param_value ( ctx : context ) ( id : string ) = - let (r, v) = (Z3native.get_param_value (context_gno ctx) id) in - if not r then - None - else - Some v - let set_print_mode ( ctx : context ) ( value : ast_print_mode ) = Z3native.set_ast_print_mode (context_gno ctx) (int_of_ast_print_mode value) end @@ -826,11 +818,11 @@ end = struct let is_well_sorted ( x : expr ) = Z3native.is_well_sorted (gnc x) (gno x) let get_sort ( x : expr ) = sort_of_ptr (Expr.gc x) (Z3native.get_sort (gnc x) (gno x)) - + let is_const ( x : expr ) = (match x with Expr(a) -> (AST.is_app a)) && (get_num_args x) == 0 && (FuncDecl.get_domain_size (get_func_decl x)) == 0 - + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( range : sort ) = expr_of_ptr ctx (Z3native.mk_const (context_gno ctx) (Symbol.gno name) (Sort.gno range)) @@ -851,7 +843,7 @@ end = struct expr_of_ptr ctx (Z3native.mk_int (context_gno ctx) v (Sort.gno ty)) let equal ( a : expr ) ( b : expr ) = AST.equal (ast_of_expr a) (ast_of_expr b) - + let compare a b = AST.compare (ast_of_expr a) (ast_of_expr b) end @@ -941,7 +933,7 @@ struct raise (Z3native.Exception "Invalid coercion") else Quantifier(e) - + let gc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gc e) let gnc ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gnc e) let gno ( x : quantifier ) = match (x) with Quantifier(e) -> (Expr.gno e) @@ -949,13 +941,13 @@ struct module Pattern = struct type pattern = Pattern of ast - + let ast_of_pattern e = match e with Pattern(x) -> x let pattern_of_ast a = - (* CMW: Unchecked ok? *) + (* CMW: Unchecked ok? *) Pattern(a) - + let gc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gc a) let gnc ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gnc a) let gno ( x : pattern ) = match (x) with Pattern(a) -> (z3obj_gno a) @@ -1258,11 +1250,11 @@ struct module Constructor = struct type constructor = z3_native_object - + module FieldNumTable = Hashtbl.Make(struct - type t = AST.ast - let equal x y = AST.compare x y = 0 - let hash = AST.hash + type t = AST.ast + let equal x y = AST.compare x y = 0 + let hash = AST.hash end) let _field_nums = FieldNumTable.create 0 @@ -1291,7 +1283,7 @@ struct Gc.finalise f no ; FieldNumTable.add _field_nums no n ; no - + let get_num_fields ( x : constructor ) = FieldNumTable.find _field_nums x let get_constructor_decl ( x : constructor ) = @@ -1613,16 +1605,16 @@ struct let mk_sub ( ctx : context ) ( t : expr list ) = let f x = (Expr.gno x) in - (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) + (expr_of_ptr ctx (Z3native.mk_sub (context_gno ctx) (List.length t) (Array.of_list (List.map f t)))) let mk_unary_minus ( ctx : context ) ( t : expr ) = - (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) + (expr_of_ptr ctx (Z3native.mk_unary_minus (context_gno ctx) (Expr.gno t))) let mk_div ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + (expr_of_ptr ctx (Z3native.mk_div (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) let mk_power ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = - (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) + (expr_of_ptr ctx (Z3native.mk_power (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) let mk_lt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = (expr_of_ptr ctx (Z3native.mk_lt (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) @@ -1893,7 +1885,7 @@ struct let get_formulas ( x : goal ) = let n = get_size x in let f i = ((expr_of_ptr (z3obj_gc x) - (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in + (Z3native.goal_formula (z3obj_gnc x) (z3obj_gno x) i))) in mk_list f n let get_num_exprs ( x : goal ) = Z3native.goal_num_exprs (z3obj_gnc x) (z3obj_gno x) @@ -2065,7 +2057,7 @@ struct let f i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_func_decl (z3obj_gnc x) (z3obj_gno x) i) in let g i = func_decl_of_ptr (z3obj_gc x) (Z3native.model_get_const_decl (z3obj_gnc x) (z3obj_gno x) i) in (mk_list f n_funcs) @ (mk_list g n_consts) - + let eval ( x : model ) ( t : expr ) ( completion : bool ) = let (r, v) = (Z3native.model_eval (z3obj_gnc x) (z3obj_gno x) (Expr.gno t) completion) in if not r then @@ -2316,7 +2308,7 @@ struct mutable m_is_float : bool ; mutable m_int : int ; mutable m_float : float } - + let create_si k v = let res : statistics_entry = { m_key = k ; @@ -2644,7 +2636,7 @@ struct mk_list f n let get_num_smtlib_sorts ( ctx : context ) = Z3native.get_smtlib_num_sorts (context_gno ctx) - + let get_smtlib_sorts ( ctx : context ) = let n = (get_num_smtlib_sorts ctx) in let f i = (sort_of_ptr ctx (Z3native.get_smtlib_sort (context_gno ctx) i)) in @@ -2683,6 +2675,65 @@ struct (let f x = FuncDecl.gno x in (Array.of_list (List.map f decls))))) end +module Interpolation = +struct + let mk_interpolant ( ctx : context ) ( a : expr ) = + (expr_of_ptr ctx (Z3native.mk_interpolant (context_gno ctx) (Expr.gno a))) + + let mk_interpolation_context ( settings : ( string * string ) list ) = + let cfg = Z3native.mk_config () in + let f e = (Z3native.set_param_value cfg (fst e) (snd e)) in + (List.iter f settings) ; + let v = Z3native.mk_interpolation_context cfg in + Z3native.del_config(cfg) ; + Z3native.set_ast_print_mode v (int_of_ast_print_mode PRINT_SMTLIB2_COMPLIANT) ; + Z3native.set_internal_error_handler v ; + let res = { m_n_ctx = v; m_n_obj_cnt = 0 } in + let f = fun o -> dispose_context o in + Gc.finalise f res; + res + + let get_interpolant ( ctx : context ) ( pf : expr ) ( pat: expr ) ( p : Params.params ) = + (ASTVector.create ctx (Z3native.get_interpolant (context_gno ctx) (Expr.gno pf) (Expr.gno pat) (z3obj_gno p))) + + let compute_interpolant ( ctx : context ) ( pat : expr ) ( p : Params.params ) = + let (r, interp, model) = (Z3native.compute_interpolant (context_gno ctx) (Expr.gno pat) (z3obj_gno p)) in + match (lbool_of_int r) with + | L_TRUE -> ((ASTVector.create ctx interp), (Model.create ctx model)) + | _ -> raise (Z3native.Exception "Error computing interpolant.") + + let get_interpolation_profile ( ctx : context ) = + (Z3native.interpolation_profile (context_gno ctx)) + + let read_interpolation_problem ( ctx : context ) ( filename : string ) = + let (r, num, cnsts, parents, error, num_theory, theory) = (Z3native.read_interpolation_problem (context_gno ctx) filename) in + match r with + | 0 -> raise (Z3native.Exception "Interpolation problem could not be read.") + | _ -> + let f1 i = (expr_of_ptr ctx (Array.get cnsts i)) in + let f2 i = (Array.get parents i) in + let f3 i = (expr_of_ptr ctx (Array.get theory i)) in + ((mk_list f1 num), + (mk_list f2 num), + (mk_list f3 num_theory)) + + let check_interpolant ( ctx : context ) ( num : int ) ( cnsts : Expr.expr list ) ( parents : int list ) ( interps : Expr.expr list ) ( num_theory : int ) ( theory : Expr.expr list ) = + let (r, str) = (Z3native.check_interpolant (context_gno ctx) + num + (let f x = Expr.gno x in (Array.of_list (List.map f cnsts))) + (Array.of_list parents) + (let f x = Expr.gno x in (Array.of_list (List.map f interps))) + num_theory + (let f x = Expr.gno x in (Array.of_list (List.map f theory)))) in + match (lbool_of_int r) with + | L_UNDEF -> raise (Z3native.Exception "Interpolant could not be verified.") + | L_FALSE -> raise (Z3native.Exception "Interpolant could not be verified.") + | _ -> () + + let write_interpolation_problem ( ctx : context ) ( num : int ) ( cnsts : Expr.expr list ) ( parents : int list ) ( filename : string ) ( num_theory : int ) ( theory : Expr.expr list ) = + (Z3native.write_interpolation_problem (context_gno ctx) num (expr_lton cnsts) (Array.of_list parents) filename num_theory (expr_lton theory)) ; + () +end let set_global_param ( id : string ) ( value : string ) = (Z3native.global_param_set id value) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 1342bb4bc..b2f0939d0 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -149,11 +149,11 @@ sig val resize : ast_vector -> int -> unit (** Add an ast to the back of the vector. The size - is increased by 1. *) + is increased by 1. *) val push : ast_vector -> ast -> unit (** Translates all ASTs in the vector to another context. - @return A new ASTVector *) + @return A new ASTVector *) val translate : ast_vector -> context -> ast_vector (** Retrieves a string representation of the vector. *) @@ -196,7 +196,7 @@ sig end (** The AST's hash code. - @return A hash code *) + @return A hash code *) val hash : ast -> int (** A unique identifier for the AST (unique among all ASTs). *) @@ -227,34 +227,34 @@ sig val to_sexpr : ast -> string (** Comparison operator. - @return True if the two ast's are from the same context - and represent the same sort; false otherwise. *) + @return True if the two ast's are from the same context + and represent the same sort; false otherwise. *) val equal : ast -> ast -> bool (** Object Comparison. - @return Negative if the first ast should be sorted before the second, positive if after else zero. *) + @return Negative if the first ast should be sorted before the second, positive if after else zero. *) val compare : ast -> ast -> int (** Translates (copies) the AST to another context. - @return A copy of the AST which is associated with the other context. *) + @return A copy of the AST which is associated with the other context. *) val translate : ast -> context -> ast (** Unwraps an AST. - This function is used for transitions between native and - managed objects. It returns the native pointer to the AST. Note that - AST objects are reference counted and unwrapping an AST disables automatic - reference counting, i.e., all references to the IntPtr that is returned - must be handled externally and through native calls (see e.g., - [Z3native.inc_ref]). - {!wrap_ast} *) + This function is used for transitions between native and + managed objects. It returns the native pointer to the AST. Note that + AST objects are reference counted and unwrapping an AST disables automatic + reference counting, i.e., all references to the IntPtr that is returned + must be handled externally and through native calls (see e.g., + [Z3native.inc_ref]). + {!wrap_ast} *) val unwrap_ast : ast -> Z3native.ptr (** Wraps an AST. - This function is used for transitions between native and - managed objects. Note that the native ast that is passed must be a - native object obtained from Z3 (e.g., through {!unwrap_ast}) - and that it must have a correct reference count (see e.g., + This function is used for transitions between native and + managed objects. Note that the native ast that is passed must be a + native object obtained from Z3 (e.g., through {!unwrap_ast}) + and that it must have a correct reference count (see e.g., [Z3native.inc_ref]). *) val wrap_ast : context -> Z3native.z3_ast -> ast end @@ -267,8 +267,8 @@ sig val ast_of_sort : sort -> AST.ast (** Comparison operator. - @return True if the two sorts are from the same context - and represent the same sort; false otherwise. *) + @return True if the two sorts are from the same context + and represent the same sort; false otherwise. *) val equal : sort -> sort -> bool (** Returns a unique identifier for the sort. *) @@ -441,33 +441,26 @@ sig val to_string : params -> string (** Update a mutable configuration parameter. - - The list of all configuration parameters can be obtained using the Z3 executable: - [z3.exe -p] - Only a few configuration parameters are mutable once the context is created. - An exception is thrown when trying to modify an immutable parameter. - {!get_param_value} *) + + The list of all configuration parameters can be obtained using the Z3 executable: + [z3.exe -p] + Only a few configuration parameters are mutable once the context is created. + An exception is thrown when trying to modify an immutable parameter. *) val update_param_value : context -> string -> string -> unit - - (** Get a configuration parameter. - - Returns None if the parameter value does not exist. - {!update_param_value} *) - val get_param_value : context -> string -> string option - + (** Selects the format used for pretty-printing expressions. - - The default mode for pretty printing expressions is to produce - SMT-LIB style output where common subexpressions are printed - at each occurrence. The mode is called PRINT_SMTLIB_FULL. - To print shared common subexpressions only once, - use the PRINT_LOW_LEVEL mode. - To print in way that conforms to SMT-LIB standards and uses let - expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. - {!AST.to_string} - {!Quantifier.Pattern.to_string} - {!FuncDecl.to_string} - {!Sort.to_string} *) + + The default mode for pretty printing expressions is to produce + SMT-LIB style output where common subexpressions are printed + at each occurrence. The mode is called PRINT_SMTLIB_FULL. + To print shared common subexpressions only once, + use the PRINT_LOW_LEVEL mode. + To print in way that conforms to SMT-LIB standards and uses let + expressions to share common sub-expressions use PRINT_SMTLIB_COMPLIANT. + {!AST.to_string} + {!Quantifier.Pattern.to_string} + {!FuncDecl.to_string} + {!Sort.to_string} *) val set_print_mode : context -> Z3enums.ast_print_mode -> unit end @@ -480,7 +473,7 @@ sig val expr_of_ast : AST.ast -> Expr.expr (** Returns a simplified version of the expression. - {!get_simplify_help} *) + {!get_simplify_help} *) val simplify : Expr.expr -> Params.params option -> expr (** A string describing all available parameters to [Expr.Simplify]. *) @@ -503,23 +496,23 @@ sig val update : Expr.expr -> Expr.expr list -> expr (** Substitute every occurrence of [from[i]] in the expression with [to[i]], for [i] smaller than [num_exprs]. - - The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. - For every [i] smaller than [num_exprs], we must have that - sort of [from[i]] must be equal to sort of [to[i]]. *) + + The result is the new expression. The arrays [from] and [to] must have size [num_exprs]. + For every [i] smaller than [num_exprs], we must have that + sort of [from[i]] must be equal to sort of [to[i]]. *) val substitute : Expr.expr -> Expr.expr list -> Expr.expr list -> expr (** Substitute every occurrence of [from] in the expression with [to]. - {!substitute} *) + {!substitute} *) val substitute_one : Expr.expr -> Expr.expr -> Expr.expr -> expr (** Substitute the free variables in the expression with the expressions in the expr array - For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) + For every [i] smaller than [num_exprs], the variable with de-Bruijn index [i] is replaced with term [to[i]]. *) val substitute_vars : Expr.expr -> Expr.expr list -> expr (** Translates (copies) the term to another context. - @return A copy of the term which is associated with the other context *) + @return A copy of the term which is associated with the other context *) val translate : Expr.expr -> context -> expr (** Returns a string representation of the expression. *) @@ -529,7 +522,7 @@ sig val is_numeral : Expr.expr -> bool (** Indicates whether the term is well-sorted. - @return True if the term is well-sorted, false otherwise. *) + @return True if the term is well-sorted, false otherwise. *) val is_well_sorted : Expr.expr -> bool (** The Sort of the term. *) @@ -537,26 +530,26 @@ sig (** Indicates whether the term represents a constant. *) val is_const : Expr.expr -> bool - + (** Creates a new constant. *) val mk_const : context -> Symbol.symbol -> Sort.sort -> expr - + (** Creates a new constant. *) val mk_const_s : context -> string -> Sort.sort -> expr - + (** Creates a constant from the func_decl. *) val mk_const_f : context -> FuncDecl.func_decl -> expr - + (** Creates a fresh constant with a name prefixed with a string. *) val mk_fresh_const : context -> string -> Sort.sort -> expr - + (** Create a new function application. *) val mk_app : context -> FuncDecl.func_decl -> Expr.expr list -> expr - + (** Create a numeral of a given sort. - @return A Term with the given value and sort *) + @return A Term with the given value and sort *) val mk_numeral_string : context -> string -> Sort.sort -> expr - + (** Create a numeral of a given sort. This function can be use to create numerals that fit in a machine integer. It is slightly faster than [MakeNumeral] since it is not necessary to parse a string. @return A Term with the given value and sort *) @@ -692,21 +685,21 @@ sig (** The de-Burijn index of a bound variable. - - Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - the meaning of de-Bruijn indices by indicating the compilation process from - non-de-Bruijn formulas to de-Bruijn format. - - abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - abs1(x, x, n) = b_n - abs1(y, x, n) = y - abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - - The last line is significant: the index of a bound variable is different depending - on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its - index. *) + + Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain + the meaning of de-Bruijn indices by indicating the compilation process from + non-de-Bruijn formulas to de-Bruijn format. + + abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + abs1(x, x, n) = b_n + abs1(y, x, n) = y + abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + + The last line is significant: the index of a bound variable is different depending + on the scope in which it appears. The deeper ( x : expr ) appears, the higher is its + index. *) val get_index : Expr.expr -> int (** Indicates whether the quantifier is universal. *) @@ -723,19 +716,19 @@ sig (** The patterns. *) val get_patterns : quantifier -> Pattern.pattern list - - (** The number of no-patterns. *) + + (** The number of no-patterns. *) val get_num_no_patterns : quantifier -> int (** The no-patterns. *) val get_no_patterns : quantifier -> Pattern.pattern list - (** The number of bound variables. *) - val get_num_bound : quantifier -> int - - (** The symbols for the bound variables. *) + (** The number of bound variables. *) + val get_num_bound : quantifier -> int + + (** The symbols for the bound variables. *) val get_bound_variable_names : quantifier -> Symbol.symbol list - + (** The sorts of the bound variables. *) val get_bound_variable_sorts : quantifier -> Sort.sort list @@ -767,7 +760,7 @@ sig val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier (** A string representation of the quantifier. *) - val to_string : quantifier -> string + val to_string : quantifier -> string end (** Functions to manipulate Array expressions *) @@ -777,28 +770,28 @@ sig val mk_sort : context -> Sort.sort -> Sort.sort -> Sort.sort (** Indicates whether the term is an array store. - It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - Array store takes at least 3 arguments. *) + It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). + Array store takes at least 3 arguments. *) val is_store : Expr.expr -> bool (** Indicates whether the term is an array select. *) val is_select : Expr.expr -> bool (** Indicates whether the term is a constant array. - For example, select(const(v),i) = v holds for every v and i. The function is unary. *) + For example, select(const(v),i) = v holds for every v and i. The function is unary. *) val is_constant_array : Expr.expr -> bool (** Indicates whether the term is a default array. - For example default(const(v)) = v. The function is unary. *) + For example default(const(v)) = v. The function is unary. *) val is_default_array : Expr.expr -> bool (** Indicates whether the term is an array map. - It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) + It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. *) val is_array_map : Expr.expr -> bool (** Indicates whether the term is an as-array term. - An as-array term is n array value that behaves as the function graph of the - function passed as parameter. *) + An as-array term is n array value that behaves as the function graph of the + function passed as parameter. *) val is_as_array : Expr.expr -> bool (** Indicates whether the term is of an array sort. *) @@ -806,66 +799,66 @@ sig (** The domain of the array sort. *) val get_domain : Sort.sort -> Sort.sort - + (** The range of the array sort. *) val get_range : Sort.sort -> Sort.sort - + (** Create an array constant. *) val mk_const : context -> Symbol.symbol -> Sort.sort -> Sort.sort -> Expr.expr - + (** Create an array constant. *) val mk_const_s : context -> string -> Sort.sort -> Sort.sort -> Expr.expr - + (** Array read. - - The argument [a] is the array and [i] is the index - of the array that gets read. - - The node [a] must have an array sort [[domain -> range]], - and [i] must have the sort [domain]. - The sort of the result is [range]. - {!Z3Array.mk_sort} - {!mk_store} *) + + The argument [a] is the array and [i] is the index + of the array that gets read. + + The node [a] must have an array sort [[domain -> range]], + and [i] must have the sort [domain]. + The sort of the result is [range]. + {!Z3Array.mk_sort} + {!mk_store} *) val mk_select : context -> Expr.expr -> Expr.expr -> Expr.expr (** Array update. - - The node [a] must have an array sort [[domain -> range]], - [i] must have sort [domain], - [v] must have sort range. The sort of the result is [[domain -> range]]. - The semantics of this function is given by the theory of arrays described in the SMT-LIB - standard. See http://smtlib.org for more details. - The result of this function is an array that is equal to [a] - (with respect to [select]) - on all indices except for [i], where it maps to [v] - (and the [select] of [a] with - respect to [i] may be a different value). - {!Z3Array.mk_sort} - {!mk_select} *) + + The node [a] must have an array sort [[domain -> range]], + [i] must have sort [domain], + [v] must have sort range. The sort of the result is [[domain -> range]]. + The semantics of this function is given by the theory of arrays described in the SMT-LIB + standard. See http://smtlib.org for more details. + The result of this function is an array that is equal to [a] + (with respect to [select]) + on all indices except for [i], where it maps to [v] + (and the [select] of [a] with + respect to [i] may be a different value). + {!Z3Array.mk_sort} + {!mk_select} *) val mk_store : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr (** Create a constant array. - - The resulting term is an array, such that a [select]on an arbitrary index - produces the value [v]. - {!Z3Array.mk_sort} - {!mk_select} *) + + The resulting term is an array, such that a [select]on an arbitrary index + produces the value [v]. + {!Z3Array.mk_sort} + {!mk_select} *) val mk_const_array : context -> Sort.sort -> Expr.expr -> Expr.expr (** Maps f on the argument arrays. - - Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. - The function declaration [f] must have type [ range_1 .. range_n -> range]. - [v] must have sort range. The sort of the result is [[domain_i -> range]]. - {!Z3Array.mk_sort} - {!mk_select} - {!mk_store} *) + + Eeach element of [args] must be of an array sort [[domain_i -> range_i]]. + The function declaration [f] must have type [ range_1 .. range_n -> range]. + [v] must have sort range. The sort of the result is [[domain_i -> range]]. + {!Z3Array.mk_sort} + {!mk_select} + {!mk_store} *) val mk_map : context -> FuncDecl.func_decl -> Expr.expr list -> Expr.expr (** Access the array default value. - - Produces the default range value, for arrays that can be represented as - finite maps with a default range value. *) + + Produces the default range value, for arrays that can be represented as + finite maps with a default range value. *) val mk_term_array : context -> Expr.expr -> Expr.expr end @@ -948,10 +941,10 @@ sig val is_relation : Expr.expr -> bool (** Indicates whether the term is an relation store - - Insert a record into a relation. - The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements - correspond to the [n] columns of the relation. *) + + Insert a record into a relation. + The function takes [n+1] arguments, where the first argument is the relation and the remaining [n] elements + correspond to the [n] columns of the relation. *) val is_store : Expr.expr -> bool (** Indicates whether the term is an empty relation *) @@ -964,62 +957,62 @@ sig val is_join : Expr.expr -> bool (** Indicates whether the term is the union or convex hull of two relations. - The function takes two arguments. *) + The function takes two arguments. *) val is_union : Expr.expr -> bool (** Indicates whether the term is the widening of two relations - The function takes two arguments. *) + The function takes two arguments. *) val is_widen : Expr.expr -> bool (** Indicates whether the term is a projection of columns (provided as numbers in the parameters). - The function takes one argument. *) + The function takes one argument. *) val is_project : Expr.expr -> bool (** Indicates whether the term is a relation filter - - Filter (restrict) a relation with respect to a predicate. - The first argument is a relation. - The second argument is a predicate with free de-Brujin indices - corresponding to the columns of the relation. - So the first column in the relation has index 0. *) + + Filter (restrict) a relation with respect to a predicate. + The first argument is a relation. + The second argument is a predicate with free de-Brujin indices + corresponding to the columns of the relation. + So the first column in the relation has index 0. *) val is_filter : Expr.expr -> bool (** Indicates whether the term is an intersection of a relation with the negation of another. - - Intersect the first relation with respect to negation - of the second relation (the function takes two arguments). - Logically, the specification can be described by a function - - target = filter_by_negation(pos, neg, columns) - - where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with - ( x : expr ) on the columns c1, d1, .., cN, dN. *) + + Intersect the first relation with respect to negation + of the second relation (the function takes two arguments). + Logically, the specification can be described by a function + + target = filter_by_negation(pos, neg, columns) + + where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that + target are elements in ( x : expr ) in pos, such that there is no y in neg that agrees with + ( x : expr ) on the columns c1, d1, .., cN, dN. *) val is_negation_filter : Expr.expr -> bool (** Indicates whether the term is the renaming of a column in a relation - - The function takes one argument. - The parameters contain the renaming as a cycle. *) + + The function takes one argument. + The parameters contain the renaming as a cycle. *) val is_rename : Expr.expr -> bool (** Indicates whether the term is the complement of a relation *) val is_complement : Expr.expr -> bool (** Indicates whether the term is a relational select - - Check if a record is an element of the relation. - The function takes [n+1] arguments, where the first argument is a relation, - and the remaining [n] arguments correspond to a record. *) + + Check if a record is an element of the relation. + The function takes [n+1] arguments, where the first argument is a relation, + and the remaining [n] arguments correspond to a record. *) val is_select : Expr.expr -> bool (** Indicates whether the term is a relational clone (copy) - - Create a fresh copy (clone) of a relation. - The function is logically the identity, but - in the context of a register machine allows - for terms of kind {!is_union} - to perform destructive updates to the first argument. *) + + Create a fresh copy (clone) of a relation. + The function is logically the identity, but + in the context of a register machine allows + for terms of kind {!is_union} + to perform destructive updates to the first argument. *) val is_clone : Expr.expr -> bool (** The arity of the relation sort. *) @@ -1039,25 +1032,25 @@ sig (** The number of fields of the constructor. *) val get_num_fields : constructor -> int - + (** The function declaration of the constructor. *) val get_constructor_decl : constructor -> FuncDecl.func_decl (** The function declaration of the tester. *) val get_tester_decl : constructor -> FuncDecl.func_decl - + (** The function declarations of the accessors *) val get_accessor_decls : constructor -> FuncDecl.func_decl list end (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) val mk_constructor : context -> Symbol.symbol -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a datatype constructor. - if the corresponding sort reference is 0, then the value in sort_refs should be an index - referring to one of the recursive datatypes that is declared. *) + if the corresponding sort reference is 0, then the value in sort_refs should be an index + referring to one of the recursive datatypes that is declared. *) val mk_constructor_s : context -> string -> Symbol.symbol -> Symbol.symbol list -> Sort.sort option list -> int list -> Constructor.constructor (** Create a new datatype sort. *) @@ -1078,7 +1071,7 @@ sig (** The constructors. *) val get_constructors : Sort.sort -> FuncDecl.func_decl list - + (** The recognizers. *) val get_recognizers : Sort.sort -> FuncDecl.func_decl list @@ -1174,38 +1167,38 @@ sig val mk_const_s : context -> string -> Expr.expr (** Create an expression representing [t1 mod t2]. - The arguments must have int type. *) + The arguments must have int type. *) val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing [t1 rem t2]. - The arguments must have int type. *) + The arguments must have int type. *) val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer numeral. *) val mk_numeral_s : context -> string -> Expr.expr (** Create an integer numeral. - @return A Term with the given value and sort Integer *) + @return A Term with the given value and sort Integer *) val mk_numeral_i : context -> int -> Expr.expr (** Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term [k] and - and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. - The argument must be of integer sort. *) + + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term [k] and + and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. + The argument must be of integer sort. *) val mk_int2real : context -> Expr.expr -> Expr.expr (** Create an n-bit bit-vector from an integer argument. - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. *) + + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. *) val mk_int2bv : context -> int -> Expr.expr -> Expr.expr end @@ -1238,16 +1231,16 @@ sig val mk_const_s : context -> string -> Expr.expr (** Create a real numeral from a fraction. - @return A Term with rational value and sort Real - {!mk_numeral_s} *) + @return A Term with rational value and sort Real + {!mk_numeral_s} *) val mk_numeral_nd : context -> int -> int -> Expr.expr (** Create a real numeral. - @return A Term with the given value and sort Real *) + @return A Term with the given value and sort Real *) val mk_numeral_s : context -> string -> Expr.expr (** Create a real numeral. - @return A Term with the given value and sort Real *) + @return A Term with the given value and sort Real *) val mk_numeral_i : context -> int -> Expr.expr (** Creates an expression that checks whether a real number is an integer. *) @@ -1255,8 +1248,8 @@ sig (** Coerce a real to an integer. - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. *) + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) val mk_real2int : context -> Expr.expr -> Expr.expr (** Algebraic Numbers *) @@ -1522,34 +1515,34 @@ sig val is_bv_rotateright : Expr.expr -> bool (** Indicates whether the term is a bit-vector rotate left (extended) - Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) + Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. *) val is_bv_rotateleftextended : Expr.expr -> bool (** Indicates whether the term is a bit-vector rotate right (extended) - Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) + Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) val is_bv_rotaterightextended : Expr.expr -> bool - + (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) (** Indicates whether the term is a coercion from bit-vector to integer - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) val is_int_to_bv : Expr.expr -> bool (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) + This function is not supported by the decision procedures. Only the most + rudimentary simplification rules are applied to this function. *) val is_bv_to_int : Expr.expr -> bool (** Indicates whether the term is a bit-vector carry - Compute the carry bit in a full-adder. The meaning is given by the - equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) + Compute the carry bit in a full-adder. The meaning is given by the + equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) *) val is_bv_carry : Expr.expr -> bool - + (** Indicates whether the term is a bit-vector ternary XOR - The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) + The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) *) val is_bv_xor3 : Expr.expr -> bool (** The size of a bit-vector sort. *) @@ -1557,7 +1550,7 @@ sig (** Retrieve the int value. *) val get_int : Expr.expr -> int - + (** Returns a string representation of the numeral. *) val to_string : Expr.expr -> string @@ -1568,146 +1561,145 @@ sig val mk_const_s : context -> string -> int -> Expr.expr (** Bitwise negation. - The argument must have a bit-vector sort. *) + The argument must have a bit-vector sort. *) val mk_not : context -> Expr.expr -> Expr.expr (** Take conjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) + The argument must have a bit-vector sort. *) val mk_redand : context -> Expr.expr -> Expr.expr (** Take disjunction of bits in a vector,vector of length 1. - The argument must have a bit-vector sort. *) + The argument must have a bit-vector sort. *) val mk_redor : context -> Expr.expr -> Expr.expr (** Bitwise conjunction. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_and : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise disjunction. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_or : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise XOR. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_xor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise NAND. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_nand : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise NOR. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_nor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bitwise XNOR. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_xnor : context -> Expr.expr -> Expr.expr -> Expr.expr (** Standard two's complement unary minus. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_neg : context -> Expr.expr -> Expr.expr (** Two's complement addition. - The arguments must have the same bit-vector sort. *) + The arguments must have the same bit-vector sort. *) val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement subtraction. - The arguments must have the same bit-vector sort. *) + The arguments must have the same bit-vector sort. *) val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement multiplication. - The arguments must have the same bit-vector sort. *) + The arguments must have the same bit-vector sort. *) val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned division. - - - It is defined as the floor of [t1/t2] if \c t2 is - different from zero. If [t2] is zero, then the result - is undefined. - The arguments must have the same bit-vector sort. *) + + It is defined as the floor of [t1/t2] if \c t2 is + different from zero. If [t2] is zero, then the result + is undefined. + The arguments must have the same bit-vector sort. *) val mk_udiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed division. - - It is defined in the following way: + + It is defined in the following way: - - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. + - The \c floor of [t1/t2] if \c t2 is different from zero, and [t1*t2 >= 0]. - - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. + - The \c ceiling of [t1/t2] if \c t2 is different from zero, and [t1*t2 < 0]. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_sdiv : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned remainder. - - It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + + It is defined as [t1 - (t1 /u t2) * t2], where [/u] represents unsigned division. + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_urem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Signed remainder. - - It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. - The most significant bit (sign) of the result is equal to the most significant bit of \c t1. + + It is defined as [t1 - (t1 /s t2) * t2], where [/s] represents signed division. + The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_srem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed remainder (sign follows divisor). - - If [t2] is zero, then the result is undefined. - The arguments must have the same bit-vector sort. *) + + If [t2] is zero, then the result is undefined. + The arguments must have the same bit-vector sort. *) val mk_smod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned less-than - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_ult : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed less-than - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_slt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned less-than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_ule : context -> Expr.expr -> Expr.expr -> Expr.expr - + (** Two's complement signed less-than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_sle : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned greater than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_uge : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed greater than or equal to. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_sge : context -> Expr.expr -> Expr.expr -> Expr.expr (** Unsigned greater-than. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_ugt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Two's complement signed greater-than. - - The arguments must have the same bit-vector sort. *) + + The arguments must have the same bit-vector sort. *) val mk_sgt : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector concatenation. - - The arguments must have a bit-vector sort. - @return - The result is a bit-vector of size [n1+n2], where [n1] ([n2]) - is the size of [t1] ([t2]). *) + + The arguments must have a bit-vector sort. + @return + The result is a bit-vector of size [n1+n2], where [n1] ([n2]) + is the size of [t1] ([t2]). *) val mk_concat : context -> Expr.expr -> Expr.expr -> Expr.expr (** Bit-vector extraction. @@ -1719,17 +1711,17 @@ sig (** Bit-vector sign extension. - Sign-extends the given bit-vector to the (signed) equivalent bitvector of - size [m+i], where \c m is the size of the given bit-vector. *) + Sign-extends the given bit-vector to the (signed) equivalent bitvector of + size [m+i], where \c m is the size of the given bit-vector. *) val mk_sign_ext : context -> int -> Expr.expr -> Expr.expr (** Bit-vector zero extension. - Extend the given bit-vector with zeros to the (unsigned) equivalent - bitvector of size [m+i], where \c m is the size of the - given bit-vector. *) + Extend the given bit-vector with zeros to the (unsigned) equivalent + bitvector of size [m+i], where \c m is the size of the + given bit-vector. *) val mk_zero_ext : context -> int -> Expr.expr -> Expr.expr - + (** Bit-vector repetition. *) val mk_repeat : context -> int -> Expr.expr -> Expr.expr @@ -1743,27 +1735,27 @@ sig val mk_shl : context -> Expr.expr -> Expr.expr -> Expr.expr (** Logical shift right - - It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. + + It is equivalent to unsigned division by [2^x] where \c x is the value of the third argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_lshr : context -> Expr.expr -> Expr.expr -> Expr.expr (** Arithmetic shift right - - It is like logical shift right except that the most significant - bits of the result always copy the most significant bit of the - second argument. + + It is like logical shift right except that the most significant + bits of the result always copy the most significant bit of the + second argument. - NB. The semantics of shift operations varies between environments. This - definition does not necessarily capture directly the semantics of the - programming language or assembly architecture you are modeling. + NB. The semantics of shift operations varies between environments. This + definition does not necessarily capture directly the semantics of the + programming language or assembly architecture you are modeling. - The arguments must have a bit-vector sort. *) + The arguments must have a bit-vector sort. *) val mk_ashr : context -> Expr.expr -> Expr.expr -> Expr.expr (** Rotate Left. @@ -1783,7 +1775,7 @@ sig val mk_ext_rotate_right : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer from the bit-vector argument - + If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. So the result is non-negative and in the range [[0..2^N-1]], where N are the number of bits in the argument. @@ -1795,45 +1787,45 @@ sig val mk_bv2int : context -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise addition does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_add_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise addition does not underflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_add_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise subtraction does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_sub_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise subtraction does not underflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_sub_no_underflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise signed division does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_sdiv_no_overflow : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise negation does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_neg_no_overflow : context -> Expr.expr -> Expr.expr (** Create a predicate that checks that the bit-wise multiplication does not overflow. - - The arguments must be of bit-vector sort. *) + + The arguments must be of bit-vector sort. *) val mk_mul_no_overflow : context -> Expr.expr -> Expr.expr -> bool -> Expr.expr (** Create a predicate that checks that the bit-wise multiplication does not underflow. - - The arguments must be of bit-vector sort. *) - val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr + The arguments must be of bit-vector sort. *) + val mk_mul_no_underflow : context -> Expr.expr -> Expr.expr -> Expr.expr + (** Create a bit-vector numeral. *) val mk_numeral : context -> string -> int -> Expr.expr end @@ -1851,389 +1843,389 @@ sig val is_goal : Expr.expr -> bool (** Indicates whether the term is a binary equivalence modulo namings. - This binary predicate is used in proof terms. - It captures equisatisfiability and equivalence modulo renamings. *) + This binary predicate is used in proof terms. + It captures equisatisfiability and equivalence modulo renamings. *) val is_oeq : Expr.expr -> bool (** Indicates whether the term is proof via modus ponens - - Given a proof for p and a proof for (implies p q), produces a proof for q. - T1: p - T2: (implies p q) - [mp T1 T2]: q - The second antecedents may also be a proof for (iff p q). *) + + Given a proof for p and a proof for (implies p q), produces a proof for q. + T1: p + T2: (implies p q) + [mp T1 T2]: q + The second antecedents may also be a proof for (iff p q). *) val is_modus_ponens : Expr.expr -> bool (** Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - This proof object has no antecedents. - The only reflexive relations that are used are - equivalence modulo namings, equality and equivalence. - That is, R is either '~', '=' or 'iff'. *) + This proof object has no antecedents. + The only reflexive relations that are used are + equivalence modulo namings, equality and equivalence. + That is, R is either '~', '=' or 'iff'. *) val is_reflexivity : Expr.expr -> bool (** Indicates whether the term is proof by symmetricity of a relation - - Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - T1: (R t s) - [symmetry T1]: (R s t) - T1 is the antecedent of this proof object. *) + + Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). + T1: (R t s) + [symmetry T1]: (R s t) + T1 is the antecedent of this proof object. *) val is_symmetry : Expr.expr -> bool (** Indicates whether the term is a proof by transitivity of a relation - - Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - for (R t u). - T1: (R t s) - T2: (R s u) - [trans T1 T2]: (R t u) *) + + Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof + for (R t u). + T1: (R t s) + T2: (R s u) + [trans T1 T2]: (R t u) *) val is_transitivity : Expr.expr -> bool (** Indicates whether the term is a proof by condensed transitivity of a relation - - Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - It combines several symmetry and transitivity proofs. - Example: - T1: (R a b) - T2: (R c b) - T3: (R c d) - [trans* T1 T2 T3]: (R a d) - R must be a symmetric and transitive relation. - - Assuming that this proof object is a proof for (R s t), then - a proof checker must check if it is possible to prove (R s t) - using the antecedents, symmetry and transitivity. That is, - if there is a path from s to t, if we view every - antecedent (R a b) as an edge between a and b. *) + + Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. + It combines several symmetry and transitivity proofs. + Example: + T1: (R a b) + T2: (R c b) + T3: (R c d) + [trans* T1 T2 T3]: (R a d) + R must be a symmetric and transitive relation. + + Assuming that this proof object is a proof for (R s t), then + a proof checker must check if it is possible to prove (R s t) + using the antecedents, symmetry and transitivity. That is, + if there is a path from s to t, if we view every + antecedent (R a b) as an edge between a and b. *) val is_Transitivity_star : Expr.expr -> bool (** Indicates whether the term is a monotonicity proof object. - - T1: (R t_1 s_1) - ... - Tn: (R t_n s_n) - [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - Remark: if t_i == s_i, then the antecedent Ti is suppressed. - That is, reflexivity proofs are supressed to save space. *) + + T1: (R t_1 s_1) + ... + Tn: (R t_n s_n) + [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) + Remark: if t_i == s_i, then the antecedent Ti is suppressed. + That is, reflexivity proofs are supressed to save space. *) val is_monotonicity : Expr.expr -> bool (** Indicates whether the term is a quant-intro proof - - Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - T1: (~ p q) - [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) + + Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). + T1: (~ p q) + [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) *) val is_quant_intro : Expr.expr -> bool (** Indicates whether the term is a distributivity proof object. - - Given that f (= or) distributes over g (= and), produces a proof for - (= (f a (g c d)) - (g (f a c) (f a d))) - If f and g are associative, this proof also justifies the following equality: - (= (f (g a b) (g c d)) - (g (f a c) (f a d) (f b c) (f b d))) - where each f and g can have arbitrary number of arguments. - - This proof object has no antecedents. - Remark. This rule is used by the CNF conversion pass and - instantiated by f = or, and g = and. *) + + Given that f (= or) distributes over g (= and), produces a proof for + (= (f a (g c d)) + (g (f a c) (f a d))) + If f and g are associative, this proof also justifies the following equality: + (= (f (g a b) (g c d)) + (g (f a c) (f a d) (f b c) (f b d))) + where each f and g can have arbitrary number of arguments. + + This proof object has no antecedents. + Remark. This rule is used by the CNF conversion pass and + instantiated by f = or, and g = and. *) val is_distributivity : Expr.expr -> bool (** Indicates whether the term is a proof by elimination of AND - - Given a proof for (and l_1 ... l_n), produces a proof for l_i - T1: (and l_1 ... l_n) - [and-elim T1]: l_i *) + + Given a proof for (and l_1 ... l_n), produces a proof for l_i + T1: (and l_1 ... l_n) + [and-elim T1]: l_i *) val is_and_elimination : Expr.expr -> bool (** Indicates whether the term is a proof by eliminiation of not-or - - Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - T1: (not (or l_1 ... l_n)) - [not-or-elim T1]: (not l_i) *) + + Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + T1: (not (or l_1 ... l_n)) + [not-or-elim T1]: (not l_i) *) val is_or_elimination : Expr.expr -> bool (** Indicates whether the term is a proof by rewriting - - A proof for a local rewriting step (= t s). - The head function symbol of t is interpreted. - - This proof object has no antecedents. - The conclusion of a rewrite rule is either an equality (= t s), - an equivalence (iff t s), or equi-satisfiability (~ t s). - Remark: if f is bool, then = is iff. - - Examples: - (= (+ ( x : expr ) 0) x) - (= (+ ( x : expr ) 1 2) (+ 3 x)) - (iff (or ( x : expr ) false) x) *) + + A proof for a local rewriting step (= t s). + The head function symbol of t is interpreted. + + This proof object has no antecedents. + The conclusion of a rewrite rule is either an equality (= t s), + an equivalence (iff t s), or equi-satisfiability (~ t s). + Remark: if f is bool, then = is iff. + + Examples: + (= (+ ( x : expr ) 0) x) + (= (+ ( x : expr ) 1 2) (+ 3 x)) + (iff (or ( x : expr ) false) x) *) val is_rewrite : Expr.expr -> bool (** Indicates whether the term is a proof by rewriting - - A proof for rewriting an expression t into an expression s. - This proof object is used if the parameter PROOF_MODE is 1. - This proof object can have n antecedents. - The antecedents are proofs for equalities used as substitution rules. - The object is also used in a few cases if the parameter PROOF_MODE is 2. - The cases are: - - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - - When converting bit-vectors to Booleans (BIT2BOOL=true) - - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) + + A proof for rewriting an expression t into an expression s. + This proof object is used if the parameter PROOF_MODE is 1. + This proof object can have n antecedents. + The antecedents are proofs for equalities used as substitution rules. + The object is also used in a few cases if the parameter PROOF_MODE is 2. + The cases are: + - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) + - When converting bit-vectors to Booleans (BIT2BOOL=true) + - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) *) val is_rewrite_star : Expr.expr -> bool (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) + + A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. *) val is_pull_quant : Expr.expr -> bool (** Indicates whether the term is a proof for pulling quantifiers out. - - A proof for (iff P Q) where Q is in prenex normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object has no antecedents *) + + A proof for (iff P Q) where Q is in prenex normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object has no antecedents *) val is_pull_quant_star : Expr.expr -> bool (** Indicates whether the term is a proof for pushing quantifiers in. - - A proof for: - (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - ... - (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - This proof object has no antecedents *) + + A proof for: + (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) + (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) + ... + (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) + This proof object has no antecedents *) val is_push_quant : Expr.expr -> bool (** Indicates whether the term is a proof for elimination of unused variables. - - A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - (forall (x_1 ... x_n) p[x_1 ... x_n])) - - It is used to justify the elimination of unused variables. - This proof object has no antecedents. *) + + A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) + (forall (x_1 ... x_n) p[x_1 ... x_n])) + + It is used to justify the elimination of unused variables. + This proof object has no antecedents. *) val is_elim_unused_vars : Expr.expr -> bool (** Indicates whether the term is a proof for destructive equality resolution - - A proof for destructive equality resolution: - (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) - if ( x : expr ) does not occur in t. - - This proof object has no antecedents. - - Several variables can be eliminated simultaneously. *) + + A proof for destructive equality resolution: + (iff (forall (x) (or (not (= ( x : expr ) t)) P[x])) P[t]) + if ( x : expr ) does not occur in t. + + This proof object has no antecedents. + + Several variables can be eliminated simultaneously. *) val is_der : Expr.expr -> bool - + (** Indicates whether the term is a proof for quantifier instantiation - - A proof of (or (not (forall (x) (P x))) (P a)) *) + + A proof of (or (not (forall (x) (P x))) (P a)) *) val is_quant_inst : Expr.expr -> bool (** Indicates whether the term is a hypthesis marker. - Mark a hypothesis in a natural deduction style proof. *) + Mark a hypothesis in a natural deduction style proof. *) val is_hypothesis : Expr.expr -> bool (** Indicates whether the term is a proof by lemma - - T1: false - [lemma T1]: (or (not l_1) ... (not l_n)) - - This proof object has one antecedent: a hypothetical proof for false. - It converts the proof in a proof for (or (not l_1) ... (not l_n)), - when T1 contains the hypotheses: l_1, ..., l_n. *) + + T1: false + [lemma T1]: (or (not l_1) ... (not l_n)) + + This proof object has one antecedent: a hypothetical proof for false. + It converts the proof in a proof for (or (not l_1) ... (not l_n)), + when T1 contains the hypotheses: l_1, ..., l_n. *) val is_lemma : Expr.expr -> bool (** Indicates whether the term is a proof by unit resolution - - T1: (or l_1 ... l_n l_1' ... l_m') - T2: (not l_1) - ... - T(n+1): (not l_n) - [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) + + T1: (or l_1 ... l_n l_1' ... l_m') + T2: (not l_1) + ... + T(n+1): (not l_n) + [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') *) val is_unit_resolution : Expr.expr -> bool (** Indicates whether the term is a proof by iff-true - - T1: p - [iff-true T1]: (iff p true) *) + + T1: p + [iff-true T1]: (iff p true) *) val is_iff_true : Expr.expr -> bool (** Indicates whether the term is a proof by iff-false - - T1: (not p) - [iff-false T1]: (iff p false) *) + + T1: (not p) + [iff-false T1]: (iff p false) *) val is_iff_false : Expr.expr -> bool (** Indicates whether the term is a proof by commutativity - - [comm]: (= (f a b) (f b a)) - - f is a commutative operator. - - This proof object has no antecedents. - Remark: if f is bool, then = is iff. *) + + [comm]: (= (f a b) (f b a)) + + f is a commutative operator. + + This proof object has no antecedents. + Remark: if f is bool, then = is iff. *) val is_commutativity : Expr.expr -> bool (** Indicates whether the term is a proof for Tseitin-like axioms - - Proof object used to justify Tseitin's like axioms: - - (or (not (and p q)) p) - (or (not (and p q)) q) - (or (not (and p q r)) p) - (or (not (and p q r)) q) - (or (not (and p q r)) r) - ... - (or (and p q) (not p) (not q)) - (or (not (or p q)) p q) - (or (or p q) (not p)) - (or (or p q) (not q)) - (or (not (iff p q)) (not p) q) - (or (not (iff p q)) p (not q)) - (or (iff p q) (not p) (not q)) - (or (iff p q) p q) - (or (not (ite a b c)) (not a) b) - (or (not (ite a b c)) a c) - (or (ite a b c) (not a) (not b)) - (or (ite a b c) a (not c)) - (or (not (not a)) (not a)) - (or (not a) a) - - This proof object has no antecedents. - Note: all axioms are propositional tautologies. - Note also that 'and' and 'or' can take multiple arguments. - You can recover the propositional tautologies by - unfolding the Boolean connectives in the axioms a small - bounded number of steps (=3). *) + + Proof object used to justify Tseitin's like axioms: + + (or (not (and p q)) p) + (or (not (and p q)) q) + (or (not (and p q r)) p) + (or (not (and p q r)) q) + (or (not (and p q r)) r) + ... + (or (and p q) (not p) (not q)) + (or (not (or p q)) p q) + (or (or p q) (not p)) + (or (or p q) (not q)) + (or (not (iff p q)) (not p) q) + (or (not (iff p q)) p (not q)) + (or (iff p q) (not p) (not q)) + (or (iff p q) p q) + (or (not (ite a b c)) (not a) b) + (or (not (ite a b c)) a c) + (or (ite a b c) (not a) (not b)) + (or (ite a b c) a (not c)) + (or (not (not a)) (not a)) + (or (not a) a) + + This proof object has no antecedents. + Note: all axioms are propositional tautologies. + Note also that 'and' and 'or' can take multiple arguments. + You can recover the propositional tautologies by + unfolding the Boolean connectives in the axioms a small + bounded number of steps (=3). *) val is_def_axiom : Expr.expr -> bool (** Indicates whether the term is a proof for introduction of a name - - Introduces a name for a formula/term. - Suppose e is an expression with free variables x, and def-intro - introduces the name n(x). The possible cases are: - - When e is of Boolean type: - [def-intro]: (and (or n (not e)) (or (not n) e)) - - or: - [def-intro]: (or (not n) e) - when e only occurs positively. - - When e is of the form (ite cond th el): - [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - - Otherwise: - [def-intro]: (= n e) *) + + Introduces a name for a formula/term. + Suppose e is an expression with free variables x, and def-intro + introduces the name n(x). The possible cases are: + + When e is of Boolean type: + [def-intro]: (and (or n (not e)) (or (not n) e)) + + or: + [def-intro]: (or (not n) e) + when e only occurs positively. + + When e is of the form (ite cond th el): + [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) + + Otherwise: + [def-intro]: (= n e) *) val is_def_intro : Expr.expr -> bool (** Indicates whether the term is a proof for application of a definition - - [apply-def T1]: F ~ n - F is 'equivalent' to n, given that T1 is a proof that - n is a name for F. *) + + [apply-def T1]: F ~ n + F is 'equivalent' to n, given that T1 is a proof that + n is a name for F. *) val is_apply_def : Expr.expr -> bool (** Indicates whether the term is a proof iff-oeq - - T1: (iff p q) - [iff~ T1]: (~ p q) *) + + T1: (iff p q) + [iff~ T1]: (~ p q) *) val is_iff_oeq : Expr.expr -> bool (** Indicates whether the term is a proof for a positive NNF step - - Proof for a (positive) NNF step. Example: - - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - (and (or r_1 r_2') (or r_1' r_2))) - - The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - (a) When creating the NNF of a positive force quantifier. - The quantifier is retained (unless the bound variables are eliminated). - Example - T1: q ~ q_new - [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - - (b) When recursively creating NNF over Boolean formulas, where the top-level - connective is changed during NNF conversion. The relevant Boolean connectives - for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - NNF_NEG furthermore handles the case where negation is pushed - over Boolean connectives 'and' and 'or'. *) + + Proof for a (positive) NNF step. Example: + + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) + (and (or r_1 r_2') (or r_1' r_2))) + + The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: + (a) When creating the NNF of a positive force quantifier. + The quantifier is retained (unless the bound variables are eliminated). + Example + T1: q ~ q_new + [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) + + (b) When recursively creating NNF over Boolean formulas, where the top-level + connective is changed during NNF conversion. The relevant Boolean connectives + for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + NNF_NEG furthermore handles the case where negation is pushed + over Boolean connectives 'and' and 'or'. *) val is_nnf_pos : Expr.expr -> bool (** Indicates whether the term is a proof for a negative NNF step - - Proof for a (negative) NNF step. Examples: - - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - ... - Tn: (not s_n) ~ r_n - [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - and - T1: (not s_1) ~ r_1 - T2: (not s_2) ~ r_2 - T3: s_1 ~ r_1' - T4: s_2 ~ r_2' - [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - (and (or r_1 r_2) (or r_1' r_2'))) *) + + Proof for a (negative) NNF step. Examples: + + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + ... + Tn: (not s_n) ~ r_n + [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) + and + T1: (not s_1) ~ r_1 + T2: (not s_2) ~ r_2 + T3: s_1 ~ r_1' + T4: s_2 ~ r_2' + [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) + (and (or r_1 r_2) (or r_1' r_2'))) *) val is_nnf_neg : Expr.expr -> bool (** Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - - A proof for (~ P Q) where Q is in negation normal form. - - This proof object is only used if the parameter PROOF_MODE is 1. - - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + + A proof for (~ P Q) where Q is in negation normal form. + + This proof object is only used if the parameter PROOF_MODE is 1. + + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) val is_nnf_star : Expr.expr -> bool (** Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - - A proof for (~ P Q) where Q is in conjunctive normal form. - This proof object is only used if the parameter PROOF_MODE is 1. - This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) + + A proof for (~ P Q) where Q is in conjunctive normal form. + This proof object is only used if the parameter PROOF_MODE is 1. + This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. *) val is_cnf_star : Expr.expr -> bool (** Indicates whether the term is a proof for a Skolemization step - - Proof for: - - [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) - [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) - - This proof object has no antecedents. *) + + Proof for: + + [sk]: (~ (not (forall ( x : expr ) (p ( x : expr ) y))) (not (p (sk y) y))) + [sk]: (~ (exists ( x : expr ) (p ( x : expr ) y)) (p (sk y) y)) + + This proof object has no antecedents. *) val is_skolemize : Expr.expr -> bool (** Indicates whether the term is a proof by modus ponens for equi-satisfiability. - - Modus ponens style rule for equi-satisfiability. - T1: p - T2: (~ p q) - [mp~ T1 T2]: q *) + + Modus ponens style rule for equi-satisfiability. + T1: p + T2: (~ p q) + [mp~ T1 T2]: q *) val is_modus_ponens_oeq : Expr.expr -> bool (** Indicates whether the term is a proof for theory lemma - - Generic proof for theory lemmas. - - The theory lemma function comes with one or more parameters. - The first parameter indicates the name of the theory. - For the theory of arithmetic, additional parameters provide hints for - checking the theory lemma. - The hints for arithmetic are: - - farkas - followed by rational coefficients. Multiply the coefficients to the - inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - - triangle-eq - Indicates a lemma related to the equivalence: - (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) + + Generic proof for theory lemmas. + + The theory lemma function comes with one or more parameters. + The first parameter indicates the name of the theory. + For the theory of arithmetic, additional parameters provide hints for + checking the theory lemma. + The hints for arithmetic are: + - farkas - followed by rational coefficients. Multiply the coefficients to the + inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. + - triangle-eq - Indicates a lemma related to the equivalence: + (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) + - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. *) val is_theory_lemma : Expr.expr -> bool end @@ -2265,12 +2257,12 @@ sig (** Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). *) val is_garbage : goal -> bool - (** Adds the constraints to the given goal. *) + (** Adds the constraints to the given goal. *) val add : goal -> Expr.expr list -> unit - + (** Indicates whether the goal contains `false'. *) val is_inconsistent : goal -> bool - + (** The depth of the goal. This tracks how many transformations were applied to it. *) val get_depth : goal -> int @@ -2300,7 +2292,7 @@ sig val simplify : goal -> Params.params option -> goal (** Creates a new Goal. - + Note that the Context must have been created with proof generation support if the fourth argument is set to true here. *) val mk_goal : context -> bool -> bool -> bool -> goal @@ -2323,7 +2315,7 @@ sig module FuncInterp : sig type func_interp - + (** Function interpretations entries An Entry object represents an element in the finite map used to a function interpretation. *) @@ -2418,7 +2410,7 @@ sig {!get_sorts} @return A list of expressions, where each is an element of the universe of the sort *) val sort_universe : model -> Sort.sort -> AST.ast list - + (** Conversion of models to strings. @return A string representation of the model. *) val to_string : model -> string @@ -2437,8 +2429,8 @@ sig type probe (** Execute the probe over the goal. - @return A probe always produce a float value. - "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) + @return A probe always produce a float value. + "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. *) val apply : probe -> Goal.goal -> float (** The number of supported Probes. *) @@ -2546,21 +2538,21 @@ sig val mk_tactic : context -> string -> tactic (** Create a tactic that applies one tactic to a Goal and - then another one to every subgoal produced by the first one. *) + then another one to every subgoal produced by the first one. *) val and_then : context -> tactic -> tactic -> tactic list -> tactic (** Create a tactic that first applies one tactic to a Goal and - if it fails then returns the result of another tactic applied to the Goal. *) + if it fails then returns the result of another tactic applied to the Goal. *) val or_else : context -> tactic -> tactic -> tactic (** Create a tactic that applies one tactic to a goal for some time (in milliseconds). - - If the tactic does not terminate within the timeout, then it fails. *) + + If the tactic does not terminate within the timeout, then it fails. *) val try_for : context -> tactic -> int -> tactic (** Create a tactic that applies one tactic to a given goal if the probe evaluates to true. - + If the probe evaluates to false, then the new tactic behaves like the [skip] tactic. *) val when_ : context -> Probe.probe -> tactic -> tactic @@ -2569,7 +2561,7 @@ sig val cond : context -> Probe.probe -> tactic -> tactic -> tactic (** Create a tactic that keeps applying one tactic until the goal is not - modified anymore or the maximum number of iterations is reached. *) + modified anymore or the maximum number of iterations is reached. *) val repeat : context -> tactic -> int -> tactic (** Create a tactic that just returns the given goal. *) @@ -2582,14 +2574,14 @@ sig val fail_if : context -> Probe.probe -> tactic (** Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - or trivially unsatisfiable (i.e., contains `false'). *) + or trivially unsatisfiable (i.e., contains `false'). *) val fail_if_not_decided : context -> tactic (** Create a tactic that applies a tactic using the given set of parameters. *) val using_params : context -> tactic -> Params.params -> tactic (** Create a tactic that applies a tactic using the given set of parameters. - Alias for [UsingParams]*) + Alias for [UsingParams]*) val with_ : context -> tactic -> Params.params -> tactic (** Create a tactic that applies the given tactics in parallel. *) @@ -2600,7 +2592,7 @@ sig val par_and_then : context -> tactic -> tactic -> tactic (** Interrupt the execution of a Z3 procedure. - This procedure can be used to interrupt: solvers, simplifiers and tactics. *) + This procedure can be used to interrupt: solvers, simplifiers and tactics. *) val interrupt : context -> unit end @@ -2618,8 +2610,8 @@ sig type statistics (** Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. - *) + Entry is either a floating point or integer value. + *) module Entry : sig type statistics_entry @@ -2641,7 +2633,7 @@ sig (** The string representation of the the entry's value. *) val to_string_value : statistics_entry -> string - + (** The string representation of the entry (key and value) *) val to_string : statistics_entry -> string end @@ -2672,49 +2664,49 @@ sig val get_param_descrs : solver -> Params.ParamDescrs.param_descrs (** The current number of backtracking points (scopes). - {!pop} - {!push} *) + {!pop} + {!push} *) val get_num_scopes : solver -> int (** Creates a backtracking point. - {!pop} *) + {!pop} *) val push : solver -> unit (** Backtracks a number of backtracking points. - Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} - {!push} *) + Note that an exception is thrown if the integer is not smaller than {!get_num_scopes} + {!push} *) val pop : solver -> int -> unit (** Resets the Solver. - This removes all assertions from the solver. *) + This removes all assertions from the solver. *) val reset : solver -> unit (** Assert a constraint (or multiple) into the solver. *) val add : solver -> Expr.expr list -> unit (** * Assert multiple constraints (cs) into the solver, and track them (in the - * unsat) core - * using the Boolean constants in ps. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) + * unsat) core + * using the Boolean constants in ps. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) val assert_and_track_l : solver -> Expr.expr list -> Expr.expr list -> unit (** * Assert a constraint (c) into the solver, and track it (in the unsat) core - * using the Boolean constant p. - * - * This API is an alternative to {!check} with assumptions for - * extracting unsat cores. - * Both APIs can be used in the same solver. The unsat core will contain a - * combination - * of the Boolean variables provided using {!assert_and_track} - * and the Boolean literals - * provided using {!check} with assumptions. *) + * using the Boolean constant p. + * + * This API is an alternative to {!check} with assumptions for + * extracting unsat cores. + * Both APIs can be used in the same solver. The unsat core will contain a + * combination + * of the Boolean variables provided using {!assert_and_track} + * and the Boolean literals + * provided using {!check} with assumptions. *) val assert_and_track : solver -> Expr.expr -> Expr.expr -> unit (** The number of assertions in the solver. *) @@ -2724,29 +2716,29 @@ sig val get_assertions : solver -> Expr.expr list (** Checks whether the assertions in the solver are consistent or not. - - {!Model} - {!get_unsat_core} - {!Proof} *) + + {!Model} + {!get_unsat_core} + {!Proof} *) val check : solver -> Expr.expr list -> status (** The model of the last [Check]. - - The result is [None] if [Check] was not invoked before, - if its results was not [SATISFIABLE], or if model production is not enabled. *) + + The result is [None] if [Check] was not invoked before, + if its results was not [SATISFIABLE], or if model production is not enabled. *) val get_model : solver -> Model.model option (** The proof of the last [Check]. - - The result is [null] if [Check] was not invoked before, - if its results was not [UNSATISFIABLE], or if proof production is disabled. *) + + The result is [null] if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if proof production is disabled. *) val get_proof : solver -> Expr.expr option (** The unsat core of the last [Check]. - - The unsat core is a subset of [Assertions] - The result is empty if [Check] was not invoked before, - if its results was not [UNSATISFIABLE], or if core production is disabled. *) + + The unsat core is a subset of [Assertions] + The result is empty if [Check] was not invoked before, + if its results was not [UNSATISFIABLE], or if core production is disabled. *) val get_unsat_core : solver -> AST.ast list (** A brief justification of why the last call to [Check] returned [UNKNOWN]. *) @@ -2756,23 +2748,23 @@ sig val get_statistics : solver -> Statistics.statistics (** Creates a new (incremental) solver. - - This solver also uses a set of builtin tactics for handling the first - check-sat command, and check-sat commands that take more than a given - number of milliseconds to be solved. *) + + This solver also uses a set of builtin tactics for handling the first + check-sat command, and check-sat commands that take more than a given + number of milliseconds to be solved. *) val mk_solver : context -> Symbol.symbol option -> solver (** Creates a new (incremental) solver. - {!mk_solver} *) + {!mk_solver} *) val mk_solver_s : context -> string -> solver (** Creates a new (incremental) solver. *) val mk_simple_solver : context -> solver (** Creates a solver that is implemented using the given tactic. - - The solver supports the commands [Push] and [Pop], but it - will always solve each check from scratch. *) + + The solver supports the commands [Push] and [Pop], but it + will always solve each check from scratch. *) val mk_solver_t : context -> Tactic.tactic -> solver (** A string representation of the solver. *) @@ -2806,32 +2798,32 @@ sig val add_fact : fixedpoint -> FuncDecl.func_decl -> int list -> unit (** Query the fixedpoint solver. - A query is a conjunction of constraints. The constraints may include the recursively defined relations. - The query is satisfiable if there is an instance of the query variables and a derivation for it. - The query is unsatisfiable if there are no derivations satisfying the query variables. *) + A query is a conjunction of constraints. The constraints may include the recursively defined relations. + The query is satisfiable if there is an instance of the query variables and a derivation for it. + The query is unsatisfiable if there are no derivations satisfying the query variables. *) val query : fixedpoint -> Expr.expr -> Solver.status (** Query the fixedpoint solver. - A query is an array of relations. - The query is satisfiable if there is an instance of some relation that is non-empty. - The query is unsatisfiable if there are no derivations satisfying any of the relations. *) + A query is an array of relations. + The query is satisfiable if there is an instance of some relation that is non-empty. + The query is unsatisfiable if there are no derivations satisfying any of the relations. *) val query_r : fixedpoint -> FuncDecl.func_decl list -> Solver.status (** Creates a backtracking point. - {!pop} *) + {!pop} *) val push : fixedpoint -> unit (** Backtrack one backtracking point. - Note that an exception is thrown if Pop is called without a corresponding [Push] - {!push} *) + Note that an exception is thrown if Pop is called without a corresponding [Push] + {!push} *) val pop : fixedpoint -> unit (** Update named rule into in the fixedpoint solver. *) val update_rule : fixedpoint -> Expr.expr -> Symbol.symbol -> unit (** Retrieve satisfying instance or instances of solver, - or definitions for the recursive predicates that show unsatisfiability. *) + or definitions for the recursive predicates that show unsatisfiability. *) val get_answer : fixedpoint -> Expr.expr option (** Retrieve explanation why fixedpoint engine returned status Unknown. *) @@ -2844,7 +2836,7 @@ sig val get_cover_delta : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr option (** Add property about the predicate. - The property is added at level. *) + The property is added at level. *) val add_cover : fixedpoint -> int -> FuncDecl.func_decl -> Expr.expr -> unit (** Retrieve internal string representation of fixedpoint object. *) @@ -2871,7 +2863,7 @@ module SMT : sig (** Convert a benchmark into an SMT-LIB formatted string. - @return A string representation of the benchmark. *) + @return A string representation of the benchmark. *) val benchmark_to_smtstring : context -> string -> string -> string -> string -> Expr.expr list -> Expr.expr -> string (** Parse the given string using the SMT-LIB parser. @@ -2884,7 +2876,7 @@ sig val parse_smtlib_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit (** Parse the given file using the SMT-LIB parser. - {!parse_smtlib_string} *) + {!parse_smtlib_string} *) val parse_smtlib_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> unit (** The number of SMTLIB formulas parsed by the last call to [ParseSMTLIBString] or [ParseSMTLIBFile]. *) @@ -2913,15 +2905,61 @@ sig (** Parse the given string using the SMT-LIB2 parser. - {!parse_smtlib_string} - @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) + {!parse_smtlib_string} + @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. *) val parse_smtlib2_string : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr (** Parse the given file using the SMT-LIB2 parser. - {!parse_smtlib2_string} *) + {!parse_smtlib2_string} *) val parse_smtlib2_file : context -> string -> Symbol.symbol list -> Sort.sort list -> Symbol.symbol list -> FuncDecl.func_decl list -> Expr.expr end +(** Interpolation *) +module Interpolation : +sig + + (** Create an AST node marking a formula position for interpolation. + The expression must have Boolean sort. *) + val mk_interpolant : context -> Expr.expr -> Expr.expr + + (** The interpolation context is suitable for generation of interpolants. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val mk_interpolation_context : (string * string) list -> context + + (** Gets an interpolant. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> AST.ASTVector.ast_vector + + (** Computes an interpolant. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val compute_interpolant : context -> Expr.expr -> Params.params -> (AST.ASTVector.ast_vector * Model.model) + + (** Retrieves an interpolation profile. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val get_interpolation_profile : context -> string + + (** Read an interpolation problem from file. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val read_interpolation_problem : context -> string -> (Expr.expr list * int list * Expr.expr list) + + (** Check the correctness of an interpolant. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val check_interpolant : context -> int -> Expr.expr list -> int list -> Expr.expr list -> int -> Expr.expr list -> unit + + (** Write an interpolation problem to file suitable for reading with + Z3_read_interpolation_problem. + For more information on interpolation please refer + too the C/C++ API, which is well documented. *) + val write_interpolation_problem : context -> int -> Expr.expr list -> int list -> string -> int -> Expr.expr list -> unit + +end + (** Set a global (or module) parameter, which is shared by all Z3 contexts. When a Z3 module is initialized it will use the value of these parameters @@ -2939,9 +2977,9 @@ end val set_global_param : string -> string -> unit (** Get a global (or module) parameter. - + Returns None if the parameter does not exist. - The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + The caller must invoke #Z3_global_param_del_value to delete the value returned at param_value. This function cannot be invoked simultaneously from different threads without synchronization. The result string stored in param_value is stored in a shared location. *) From 5092ceec7d04476e668d26690a54a38c8f246111 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 20:21:30 +0000 Subject: [PATCH 446/507] ML API: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index bf1f5e471..ad60fa1e1 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1379,6 +1379,10 @@ class MLComponent(Component): out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) + for f in filter(lambda f: f=='META', os.listdir(self.src_dir)): + out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) + str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) + out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: @@ -1421,7 +1425,7 @@ class MLComponent(Component): # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs\n') + out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/META\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) for m in modules: From b85c3e12f4fbf2b3f16531972577b07acaae1d51 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 20:31:16 +0000 Subject: [PATCH 447/507] ML API build fix --- scripts/mk_util.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ad60fa1e1..d42e6af29 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1379,10 +1379,6 @@ class MLComponent(Component): out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) - for f in filter(lambda f: f=='META', os.listdir(self.src_dir)): - out.write('%s: %s\n' % (os.path.join(sub_dir,f),os.path.join(src_dir,f))) - str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) - out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! prev = '' for m in modules: From 93d74129508b159aeeeb687fb9780257df44ced4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 2 Dec 2014 22:00:58 +0000 Subject: [PATCH 448/507] ML API build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index d42e6af29..b1b3445ec 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1392,9 +1392,14 @@ class MLComponent(Component): out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('api/ml/z3native_stubs$(OBJ_EXT): %s/z3native_stubs.c\n' % (sub_dir)); out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') + out.write('api/ml/libz3mldyn$(SO_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) + out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) for mlfile in get_ml_files(self.src_dir): out.write(' %s' % os.path.join(sub_dir, mlfile)) From 40c6be0baa6010a628408d5959ee385d4fa11d66 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 13:45:49 +0000 Subject: [PATCH 449/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 98 ++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b1b3445ec..5e412c892 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1384,58 +1384,80 @@ class MLComponent(Component): for m in modules: fn = os.path.join(self.src_dir, ('%s.mli' % m)) if not os.path.exists(fn): - out.write('%s.mli: %s.ml %s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) + out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) prev = prev + ' ' + os.path.join(sub_dir, m) + '.mli' cmis = '' for m in modules: - out.write('%s.cmi: %s.mli\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m))) + out.write('%s.cmi: %s.mli%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m), cmis)) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - out.write('api/ml/z3native_stubs$(OBJ_EXT): %s/z3native_stubs.c\n' % (sub_dir)); - out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) - out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') - out.write('api/ml/libz3mldyn$(SO_EXT): api/ml/z3native_stubs.c %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s/z3native_stubs.c $(CXX_OUT_FLAG)api/ml/z3native_stubs$(OBJ_EXT)\n' % (OCAML_LIB, api_src, sub_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) + + out.write('%s: %s %s\n' % + (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), + os.path.join(sub_dir, 'z3native_stubs.c'), + get_component(Z3_DLL_COMPONENT).dll_name+'$(SO_EXT)')); + out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % + (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) - out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(sub_dir, mlfile)) - out.write('\n') - out.write('\t%s ' % (OCAMLOPT)) - if DEBUG_MODE: - out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - out.write('\t%s ' % (OCAMLOPT)) - if DEBUG_MODE: - out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(sub_dir, mlfile)) - out.write('\n') - out.write('\t%s ' % (OCAMLC)) - if DEBUG_MODE: - out.write('-g ') - out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) - out.write('ml: %s %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) - out.write('\n') + # out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + # out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') + + # out.write('api/ml/libz3ml$(SO_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) + # out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) + + + # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + + # for mlfile in get_ml_files(self.src_dir): + # out.write(' %s' % os.path.join(sub_dir, mlfile)) + # out.write('\n') + # out.write('\t%s ' % (OCAMLOPT)) + # if DEBUG_MODE: + # out.write('-g ') + # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + + # out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + # out.write('\t%s ' % (OCAMLOPT)) + # if DEBUG_MODE: + # out.write('-g ') + # out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) + # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + # for mlfile in get_ml_files(self.src_dir): + # out.write(' %s' % os.path.join(sub_dir, mlfile)) + # out.write('\n') + # out.write('\t%s ' % (OCAMLC)) + # if DEBUG_MODE: + # out.write('-g ') + # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + + out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) + for m in modules: + out.write(' %s.cmi' % (os.path.join(sub_dir, m))) + out.write(' %s.cmx' % (os.path.join(sub_dir, m))) + out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + out.write('%s/z3native_stubs.o\n' % (sub_dir)) + out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) + for m in modules: + out.write(' ' + m) + out.write('z3native_stubs$(OBJ_EXT) ; cd -' ) + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) + #out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('ocamlfind_install: api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/META\n') + out.write('\nocamlfind_install: api/ml/z3.cmxa api/ml/META\n') out.write('\t%s remove Z3\n' % (OCAMLFIND)) - out.write('\t%s install Z3 api/ml/META api/ml/z3.cma api/ml/z3.cmxa api/ml/z3.cmxs api/ml/z3$(LIB_EXT) api/ml/libz3ml$(LIB_EXT) libz3$(SO_EXT)' % (OCAMLFIND)) + out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) for m in modules: + out.write(' %s.cma' % (os.path.join(sub_dir, m))) + out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) + out.write(' %s.cmxx' % (os.path.join(sub_dir, m))) out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - if IS_WINDOWS: - out.write(' libz3$(LIB_EXT)') - out.write('\n') - out.write('\n') + out.write(' %s' % ((os.path.join(sub_dir, 'libz3$(LIB_EXT)')))) + out.write(' %s' % ((os.path.join(sub_dir, 'dllz3$(SO_EXT)')))) + out.write('\n\n') def main_component(self): From 2ee4409962405dbef86874398ad4197332b5cd73 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 13:51:17 +0000 Subject: [PATCH 450/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5e412c892..bd60feaa8 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1440,8 +1440,9 @@ class MLComponent(Component): out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: out.write(' ' + m) - out.write('z3native_stubs$(OBJ_EXT) ; cd -' ) - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) + out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) + # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) #out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) From ceabafa01cdbb66c6b6c465fd62e5c8c6f87d774 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 14:11:19 +0000 Subject: [PATCH 451/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index bd60feaa8..38cbb32f5 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1434,8 +1434,8 @@ class MLComponent(Component): out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) for m in modules: out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) + # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) out.write('%s/z3native_stubs.o\n' % (sub_dir)) out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: @@ -1453,11 +1453,15 @@ class MLComponent(Component): for m in modules: out.write(' %s.cma' % (os.path.join(sub_dir, m))) out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) - out.write(' %s.cmxx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) + out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) + out.write(' %s.cmi' % (os.path.join(sub_dir, m))) out.write(' %s' % ((os.path.join(sub_dir, 'libz3$(LIB_EXT)')))) - out.write(' %s' % ((os.path.join(sub_dir, 'dllz3$(SO_EXT)')))) + out.write(' %s' % ((os.path.join(sub_dir, 'dllz3')))) + if IS_WINDOWS: + out.write('.lib') + else: + out.write('.so') # .so also on OSX! out.write('\n\n') From 4c28085022419176c3b4cd4b8227a283ee024cae Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 14:14:14 +0000 Subject: [PATCH 452/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 38cbb32f5..24c9def9c 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1436,7 +1436,7 @@ class MLComponent(Component): out.write(' %s.cmi' % (os.path.join(sub_dir, m))) # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) - out.write('%s/z3native_stubs.o\n' % (sub_dir)) + out.write(' %s/z3native_stubs.o\n' % (sub_dir)) out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: out.write(' ' + m) From 198c6ef930d3684fca1ed15aee7cd327bb653a7a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 14:18:03 +0000 Subject: [PATCH 453/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 24c9def9c..3f53266e2 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1439,7 +1439,7 @@ class MLComponent(Component): out.write(' %s/z3native_stubs.o\n' % (sub_dir)) out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) for m in modules: - out.write(' ' + m) + out.write(' %s.ml' % m) out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) From d47f143591f3fe7e9f0ada321841b292e393c3fc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 15:03:10 +0000 Subject: [PATCH 454/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 3f53266e2..0625e9c68 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1436,28 +1436,28 @@ class MLComponent(Component): out.write(' %s.cmi' % (os.path.join(sub_dir, m))) # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) - out.write(' %s/z3native_stubs.o\n' % (sub_dir)) - out.write('\tcd %s ; ocamlmklib -verbose -o z3' % (sub_dir)) + out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) + out.write('\tcd %s ; ocamlmklib -o z3ml' % (sub_dir)) for m in modules: out.write(' %s.ml' % m) out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) #out.write('\n') # Generate META file and package installation commands self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('\nocamlfind_install: api/ml/z3.cmxa api/ml/META\n') + out.write('\nocamlfind_install: %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'META'))) out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) for m in modules: out.write(' %s.cma' % (os.path.join(sub_dir, m))) out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) + #out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - out.write(' %s' % ((os.path.join(sub_dir, 'libz3$(LIB_EXT)')))) - out.write(' %s' % ((os.path.join(sub_dir, 'dllz3')))) + out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) + out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) if IS_WINDOWS: out.write('.lib') else: From ea9fc43544bdf2f9b24bbfca92a923561869d35f Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 15:38:15 +0000 Subject: [PATCH 455/507] ML API: build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 0625e9c68..ce8abd4ce 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1422,14 +1422,19 @@ class MLComponent(Component): # if DEBUG_MODE: # out.write('-g ') # out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cma'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - # for mlfile in get_ml_files(self.src_dir): - # out.write(' %s' % os.path.join(sub_dir, mlfile)) - # out.write('\n') - # out.write('\t%s ' % (OCAMLC)) - # if DEBUG_MODE: - # out.write('-g ') - # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cma -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) + out.write('%s: %s %s$(SO_EXT) %s' % ( + os.path.join(sub_dir, 'z3.cma'), + os.path.join(sub_dir, 'libz3ml$(LIB_EXT)'), + get_component(Z3_DLL_COMPONENT).dll_name, cmis)) + for mlfile in get_ml_files(self.src_dir): + out.write(' %s' % os.path.join(sub_dir, mlfile)) + out.write('\n') + out.write('\t%s ' % (OCAMLC)) + if DEBUG_MODE: + out.write('-g ') + out.write('-I %s -a -o %s -linkall' % (sub_dir, os.path.join(sub_dir, 'z3.cma'))) + for m in modules: + out.write(' %s.ml' % (os.path.join(sub_dir, m))) out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) for m in modules: From 93a20d90740c2112fb5cac5f11ebbe2097503762 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 19:22:23 +0000 Subject: [PATCH 456/507] ML API: build fixes --- scripts/mk_util.py | 94 +++++++++++++++++----------------------------- src/api/ml/META | 6 +-- src/api/ml/z3.ml | 2 +- 3 files changed, 38 insertions(+), 64 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index ce8abd4ce..b674d106f 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1380,19 +1380,25 @@ class MLComponent(Component): str = '\t%s %s %s\n' % (CP_CMD,os.path.join(src_dir,f),os.path.join(sub_dir,f)) out.write(str) modules = ["z3enums", "z3native", "z3"] # dependencies in this order! - prev = '' + mls = '' + mlis = '' + cmis = '' + archives = '' + for m in modules: fn = os.path.join(self.src_dir, ('%s.mli' % m)) if not os.path.exists(fn): - out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),prev)) + out.write('%s.mli: %s.ml%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),mlis)) out.write('\t%s -I %s -i -c %s.ml > %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir, m),os.path.join(sub_dir, m))) - prev = prev + ' ' + os.path.join(sub_dir, m) + '.mli' - cmis = '' - for m in modules: out.write('%s.cmi: %s.mli%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m), cmis)) out.write('\t%s -I %s -c %s.mli\n' % (OCAMLC,sub_dir,os.path.join(sub_dir,m))) + out.write('%s.cma: %s.ml %s.cmi%s\n' % (os.path.join(sub_dir,m),os.path.join(sub_dir,m),os.path.join(sub_dir,m), archives)) + out.write('\t%s -a -o %s.ml -o %s.cma\n' % (OCAMLC,os.path.join(sub_dir,m), os.path.join(sub_dir,m))) + mlis = mlis + ' ' + os.path.join(sub_dir, m) + '.mli' cmis = cmis + ' ' + os.path.join(sub_dir,m) + '.cmi' - + archives = archives + ' ' + os.path.join(sub_dir,m) + '.cma' + mls = mls + ' ' + os.path.join(sub_dir, m) + '.ml' + out.write('%s: %s %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'), os.path.join(sub_dir, 'z3native_stubs.c'), @@ -1400,73 +1406,43 @@ class MLComponent(Component): out.write('\t$(CC) $(CXXFLAGS) -I %s -I %s %s $(CXX_OUT_FLAG)%s$(OBJ_EXT)\n' % (OCAML_LIB, api_src, os.path.join(sub_dir, 'z3native_stubs.c'), os.path.join(sub_dir, 'z3native_stubs'))) - # out.write('api/ml/libz3ml$(LIB_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - # out.write('\t$(AR) $(AR_FLAGS) $(AR_OUTFLAG)api/ml/libz3ml$(LIB_EXT) api/ml/z3native_stubs$(OBJ_EXT)\n') - - # out.write('api/ml/libz3ml$(SO_EXT): api/ml/z3native_stubs$(OBJ_EXT) %s$(SO_EXT)\n' % get_component(Z3_DLL_COMPONENT).dll_name) - # out.write('\t$(SLINK) $(SLINK_OUT_FLAG)api/ml/libz3ml$(SO_EXT) $(SLINK_FLAGS) -I %s -I %s api/ml/z3native_stubs$(OBJ_EXT) %s$(LIB_EXT)\n' % (OCAML_LIB, api_src, get_component(Z3_DLL_COMPONENT).dll_name)) - - - # out.write('%s: api/ml/libz3ml$(LIB_EXT) %s$(SO_EXT) %s' % (os.path.join(sub_dir, 'z3.cmxa'), get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - - # for mlfile in get_ml_files(self.src_dir): - # out.write(' %s' % os.path.join(sub_dir, mlfile)) - # out.write('\n') - # out.write('\t%s ' % (OCAMLOPT)) - # if DEBUG_MODE: - # out.write('-g ') - # out.write('-cclib "-L %s -lz3ml" -I %s %s/z3enums.ml %s/z3native.ml %s/z3.ml -a -o api/ml/z3.cmxa -linkall\n' % (sub_dir, sub_dir,sub_dir,sub_dir,sub_dir)) - - # out.write('%s: %s\n' % (os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - # out.write('\t%s ' % (OCAMLOPT)) - # if DEBUG_MODE: - # out.write('-g ') - # out.write('-cclib "-L %s -lz3ml" -shared -o %s %s -linkall\n' % (sub_dir, os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cmxa'))) - out.write('%s: %s %s$(SO_EXT) %s' % ( - os.path.join(sub_dir, 'z3.cma'), - os.path.join(sub_dir, 'libz3ml$(LIB_EXT)'), - get_component(Z3_DLL_COMPONENT).dll_name, cmis)) - for mlfile in get_ml_files(self.src_dir): - out.write(' %s' % os.path.join(sub_dir, mlfile)) - out.write('\n') - out.write('\t%s ' % (OCAMLC)) - if DEBUG_MODE: - out.write('-g ') - out.write('-I %s -a -o %s -linkall' % (sub_dir, os.path.join(sub_dir, 'z3.cma'))) - for m in modules: - out.write(' %s.ml' % (os.path.join(sub_dir, m))) - - out.write('%s:' % (os.path.join(sub_dir, "z3.cmxa"))) - for m in modules: - out.write(' %s.cmi' % (os.path.join(sub_dir, m))) - # out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - # out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + out.write('%s: %s %s %s$(SO_EXT)' % ( + os.path.join(sub_dir, "z3ml.cmxa"), + cmis, + archives, + get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tcd %s ; ocamlmklib -o z3ml' % (sub_dir)) + out.write('\tcd %s ; ocamlmklib -o z3ml -ldopt \'-L../.. -lz3\' ' % (sub_dir)) for m in modules: out.write(' %s.ml' % m) out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') - out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3.cmxa'))) - # , os.path.join(sub_dir, 'z3.cmxs'), os.path.join(sub_dir, 'z3.cma'))) - #out.write('\n') - # Generate META file and package installation commands + out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': - out.write('\nocamlfind_install: %s %s\n' % (os.path.join(sub_dir, 'z3.cmxa'), os.path.join(sub_dir, 'META'))) + out.write('\nocamlfind_install: %s %s %s\n' % ( + get_component(Z3_DLL_COMPONENT).dll_name)+'$(SO_EXT)', + os.path.join(sub_dir, 'z3ml.cmxa'), + os.path.join(sub_dir, 'META'))) out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) for m in modules: out.write(' %s.cma' % (os.path.join(sub_dir, m))) - out.write(' %s.cmxa' % (os.path.join(sub_dir, m))) out.write(' %s.cmx' % (os.path.join(sub_dir, m))) - #out.write(' %s.cmxs' % (os.path.join(sub_dir, m))) out.write(' %s.cmi' % (os.path.join(sub_dir, m))) + out.write(' %s.cmo' % (os.path.join(sub_dir, m))) + out.write(' %s.ml' % (os.path.join(sub_dir, m))) + out.write(' %s.mli' % (os.path.join(sub_dir, m))) + out.write(' %s$(OBJ_EXT)' % (os.path.join(sub_dir, m))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.a')))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cma')))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cmxa')))) out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) if IS_WINDOWS: out.write('.lib') else: out.write('.so') # .so also on OSX! + out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name) + '$(SO_EXT)')))) out.write('\n\n') @@ -1591,25 +1567,25 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: api/ml/z3.cma ') + out.write('ml_example.byte: api/ml/z3ml.cma ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLC) if DEBUG_MODE: out.write('-g ') - out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3.cma') + out.write('-custom -o ml_example.byte -I api/ml -cclib "-L. -lz3" nums.cma z3ml.cma') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') - out.write('ml_example$(EXE_EXT): api/ml/z3.cmxa ml_example.byte') + out.write('ml_example$(EXE_EXT): api/ml/z3ml.cmxa ml_example.byte') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') out.write('\t%s ' % OCAMLOPT) if DEBUG_MODE: out.write('-g ') - out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3.cmxa') + out.write('-o ml_example$(EXE_EXT) -I api/ml -cclib "-L. -lz3" nums.cmxa z3ml.cmxa') for mlfile in get_ml_files(self.ex_dir): out.write(' %s/%s' % (self.to_ex_dir, mlfile)) out.write('\n') diff --git a/src/api/ml/META b/src/api/ml/META index 635de613c..8634b53b1 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -4,8 +4,6 @@ description = "Z3 Theorem Prover (OCaml API)" requires = "num" archive(byte) = "z3ml.cma" archive(native) = "z3ml.cmxa" -archive(byte,plugin) = "z3ml.cma" -archive(native,plugin) = "z3ml.cmxa" -archive(byte,toploop) = "z3ml.cma" -archive(native,toploop) = "z3ml.cmxa" +archive(byte, plugin) = "z3ml.cma" +archive(native, plugin) = "z3ml.cmxs" linkopts = "-cclib -lz3" diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 2b54a1113..350457525 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -110,7 +110,7 @@ struct string_of_int mj ^ "." ^ string_of_int mn ^ "." ^ string_of_int bld ^ "." ^ - string_of_int rev ^ "." + string_of_int rev end From 05f42b0073d50c20dff4a3fa229d09897ba580c5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 4 Dec 2014 19:42:03 +0000 Subject: [PATCH 457/507] ML API: build fixes? --- scripts/mk_util.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b674d106f..4ccf23932 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1412,16 +1412,18 @@ class MLComponent(Component): archives, get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tcd %s ; ocamlmklib -o z3ml -ldopt \'-L../.. -lz3\' ' % (sub_dir)) + out.write('\tocamlmklib -o %s -I %s -ldopt \'-L. -lz3\' ' % ( + os.path.join(sub_dir, 'z3ml'), + sub_dir)) for m in modules: - out.write(' %s.ml' % m) - out.write(' z3native_stubs$(OBJ_EXT) ; cd -\n') + out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) + out.write(' z3native_stubs$(OBJ_EXT)\n') out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': out.write('\nocamlfind_install: %s %s %s\n' % ( - get_component(Z3_DLL_COMPONENT).dll_name)+'$(SO_EXT)', - os.path.join(sub_dir, 'z3ml.cmxa'), + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)', + os.path.join(sub_dir, 'z3ml.cmxa'), os.path.join(sub_dir, 'META'))) out.write('\t%s remove Z3\n' % (OCAMLFIND)) out.write('\t%s install Z3 %s' % (OCAMLFIND, (os.path.join(sub_dir, 'META')))) @@ -1442,7 +1444,7 @@ class MLComponent(Component): out.write('.lib') else: out.write('.so') # .so also on OSX! - out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name) + '$(SO_EXT)')))) + out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') out.write('\n\n') From 5c67b596857524db527fad2aa0361c948f434305 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 5 Dec 2014 16:40:40 +0000 Subject: [PATCH 458/507] ML API: Windows build fixes Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4ccf23932..8c6d35a0a 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1412,12 +1412,10 @@ class MLComponent(Component): archives, get_component(Z3_DLL_COMPONENT).dll_name)) out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) - out.write('\tocamlmklib -o %s -I %s -ldopt \'-L. -lz3\' ' % ( - os.path.join(sub_dir, 'z3ml'), - sub_dir)) + out.write('\tocamlmklib -o %s -I %s -ldopt \"-L. -lz3\" ' % (os.path.join(sub_dir, 'z3ml'), sub_dir)) for m in modules: out.write(' %s' % (os.path.join(sub_dir, m+'.ml'))) - out.write(' z3native_stubs$(OBJ_EXT)\n') + out.write(' %s\n' % (os.path.join(sub_dir, 'z3native_stubs$(OBJ_EXT)'))) out.write('ml: %s\n' % (os.path.join(sub_dir, 'z3ml.cmxa'))) self.mk_ml_meta(os.path.join('src/api/ml/META'), os.path.join(BUILD_DIR, sub_dir, 'META'), VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) if OCAMLFIND != '': @@ -1435,13 +1433,13 @@ class MLComponent(Component): out.write(' %s.ml' % (os.path.join(sub_dir, m))) out.write(' %s.mli' % (os.path.join(sub_dir, m))) out.write(' %s$(OBJ_EXT)' % (os.path.join(sub_dir, m))) - out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.a')))) + out.write(' %s' % ((os.path.join(sub_dir, 'z3ml$(LIB_EXT)')))) out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cma')))) out.write(' %s' % ((os.path.join(sub_dir, 'z3ml.cmxa')))) out.write(' %s' % ((os.path.join(sub_dir, 'libz3ml$(LIB_EXT)')))) out.write(' %s' % ((os.path.join(sub_dir, 'dllz3ml')))) if IS_WINDOWS: - out.write('.lib') + out.write('.dll') else: out.write('.so') # .so also on OSX! out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') @@ -1569,7 +1567,7 @@ class MLExampleComponent(ExampleComponent): def mk_makefile(self, out): if ML_ENABLED: - out.write('ml_example.byte: api/ml/z3ml.cma ') + out.write('ml_example.byte: api/ml/z3ml.cmxa ') for mlfile in get_ml_files(self.ex_dir): out.write(' %s' % os.path.join(self.to_ex_dir, mlfile)) out.write('\n') From 011b700c20aadf000fceb5da9b4630f8939b033a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 6 Dec 2014 18:14:26 +0000 Subject: [PATCH 459/507] ML API: build fix --- src/api/ml/META | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/api/ml/META b/src/api/ml/META index 8634b53b1..635de613c 100644 --- a/src/api/ml/META +++ b/src/api/ml/META @@ -4,6 +4,8 @@ description = "Z3 Theorem Prover (OCaml API)" requires = "num" archive(byte) = "z3ml.cma" archive(native) = "z3ml.cmxa" -archive(byte, plugin) = "z3ml.cma" -archive(native, plugin) = "z3ml.cmxs" +archive(byte,plugin) = "z3ml.cma" +archive(native,plugin) = "z3ml.cmxa" +archive(byte,toploop) = "z3ml.cma" +archive(native,toploop) = "z3ml.cmxa" linkopts = "-cclib -lz3" From 10c153bfe46fa74d58995dc392ac1ef89de9bc76 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 6 Dec 2014 18:21:27 +0000 Subject: [PATCH 460/507] ML API: build fix --- examples/ml/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ml/README b/examples/ml/README index 31d4b8e2e..b7aa187fa 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -15,10 +15,10 @@ for the byte-code version. If Z3 was installed into the ocamlfind package repository (see src/api/ml/README), then we can compile this example as follows: -ocamlfind ocamlc -o ml_example.byte -custom -package Z3 -linkpkg ml_example.ml +ocamlfind ocamlc -o ml_example.byte -package Z3 -linkpkg ml_example.ml ocamlfind ocamlopt -o ml_example -package Z3 -linkpkg ml_example.ml Note that the resulting binaries depend on the shared z3 library, which needs to be in the PATH (Windows), LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (OSX). If Z3 was installed into ocamlfind, the path that should be added is -`ocamlfind printconf destdir`/Z3 \ No newline at end of file +`ocamlfind printconf destdir`/Z3 From bb310144175221fd1dd7d885d139ec65b14b03b0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 6 Dec 2014 18:37:09 +0000 Subject: [PATCH 461/507] ML API: build fix Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 8c6d35a0a..86035b94b 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -1443,6 +1443,8 @@ class MLComponent(Component): else: out.write('.so') # .so also on OSX! out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(SO_EXT)') + if IS_WINDOWS: + out.write(' ' + get_component(Z3_DLL_COMPONENT).dll_name + '$(LIB_EXT)') out.write('\n\n') From e754aa1c1169b61904b3fce21aeb286ce641aec4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 16 Jan 2015 19:25:21 +0000 Subject: [PATCH 462/507] Minor adjustments after rebasing ml-ng onto unstable. Signed-off-by: Christoph M. Wintersteiger --- .gitignore | 5 +++++ scripts/mk_util.py | 9 ++++++--- src/api/ml/README-test-win | 23 ----------------------- 3 files changed, 11 insertions(+), 26 deletions(-) delete mode 100644 src/api/ml/README-test-win diff --git a/.gitignore b/.gitignore index 3cd2d3ef3..93194fc1b 100644 --- a/.gitignore +++ b/.gitignore @@ -68,4 +68,9 @@ src/api/java/enumerations/*.java src/api/ml/z3native_stubs.c src/api/ml/z3native.ml src/api/ml/z3enums.ml +src/api/ml/z3native.mli +src/api/ml/z3enums.mli src/api/ml/z3.mllib +*.bak +doc/api +doc/code diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 86035b94b..5f2b846a0 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -357,6 +357,7 @@ def check_ml(): rmf('hello.cmo') rmf('hello.cmx') rmf('a.out') + rmf('hello.o') find_ml_lib() find_ocaml_find() @@ -384,6 +385,8 @@ def find_ml_lib(): OCAML_LIB = line[:-1] if is_verbose(): print 'OCAML_LIB=%s' % OCAML_LIB + t.close() + rmf('output') return def is64(): @@ -1737,10 +1740,10 @@ def mk_config(): # End of Windows VS config.mk if is_verbose(): print('64-bit: %s' % is64()) - print('ML API: %s' % is_ml_enabled()) if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) + print('ML API: %s' % is_ml_enabled()) if is_ml_enabled(): print('OCaml Compiler: %s' % OCAMLC) print('OCaml Native: %s' % OCAMLOPT) @@ -1859,11 +1862,11 @@ def mk_config(): print('64-bit: %s' % is64()) if GPROF: print('gprof: enabled') - print('Python version: %s' % distutils.sysconfig.get_python_version()) - print('ML API: %s' % is_ml_enabled()) + print('Python version: %s' % distutils.sysconfig.get_python_version()) if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) + print('ML API: %s' % is_ml_enabled()) if is_ml_enabled(): print('Ocaml Compiler: %s' % OCAMLC) print('Ocaml Native: %s' % OCAMLOPT) diff --git a/src/api/ml/README-test-win b/src/api/ml/README-test-win deleted file mode 100644 index 0e8b73ccd..000000000 --- a/src/api/ml/README-test-win +++ /dev/null @@ -1,23 +0,0 @@ -This directory contains scripts to build the test application using -OCaml. You also need CamlIDL to be able to generate the OCaml API. - -- To download OCaml: - http://caml.inria.fr/ocaml/ - -- To download CamlIDL: - http://forge.ocamlcore.org/projects/camlidl/ - -- One must build the OCaml library before compiling the example. - Go to directory ../ocaml - -- Use 'build-test.cmd' to build the test application using the OCaml compiler. - -Remark: The OCaml and C compiler tool chains must be configured in your environment. -Running from the Visual Studio Command Prompt configures the Microsoft C compiler. - -- The script 'exec.cmd' adds the bin directory to the path. So, - test_mlapi.exe can find z3.dll. - - - - From c9fa77cc70e1d7cd0953743d12202f93fd3b9387 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Jan 2015 15:29:50 +0000 Subject: [PATCH 463/507] ML API: fixed Python 3.4 issues in the build scripts Signed-off-by: Christoph M. Wintersteiger --- scripts/mk_util.py | 14 +++++++------- scripts/update_api.py | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 5f2b846a0..49ff79824 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -344,12 +344,12 @@ def check_ml(): t.add('print_string "Hello world!\n";;') t.commit() if is_verbose(): - print "Testing %s..." % OCAMLC + print ('Testing %s...' % OCAMLC) r = exec_cmd([OCAMLC, '-o', 'a.out', 'hello.ml']) if r != 0: raise MKException('Failed testing ocamlc compiler. Set environment variable OCAMLC with the path to the Ocaml compiler') if is_verbose(): - print "Testing %s..." % OCAMLOPT + print ('Testing %s...' % OCAMLOPT) r = exec_cmd([OCAMLOPT, '-o', 'a.out', 'hello.ml']) if r != 0: raise MKException('Failed testing ocamlopt compiler. Set environment variable OCAMLOPT with the path to the Ocaml native compiler. Note that ocamlopt may require flexlink to be in your path.') @@ -364,7 +364,7 @@ def check_ml(): def find_ocaml_find(): global OCAMLFIND if is_verbose(): - print "Testing %s..." % OCAMLFIND + print ('Testing %s...' % OCAMLFIND) r = exec_cmd([OCAMLFIND, 'printconf']) if r != 0: OCAMLFIND='' @@ -372,7 +372,7 @@ def find_ocaml_find(): def find_ml_lib(): global OCAML_LIB if is_verbose(): - print "Finding OCAML_LIB..." + print ('Finding OCAML_LIB...') t = TempFile('output') null = open(os.devnull, 'wb') try: @@ -384,7 +384,7 @@ def find_ml_lib(): for line in t: OCAML_LIB = line[:-1] if is_verbose(): - print 'OCAML_LIB=%s' % OCAML_LIB + print ('OCAML_LIB=%s' % OCAML_LIB) t.close() rmf('output') return @@ -2810,7 +2810,7 @@ def mk_z3consts_ml(api_files): linenum = linenum + 1 efile.write('end\n') if VERBOSE: - print "Generated '%s/z3enums.ml'" % ('%s' % gendir) + print ('Generated "%s/z3enums.ml"' % ('%s' % gendir)) efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') efile.write('(* Automatically generated file *)\n\n') efile.write('(** The enumeration types of Z3. *)\n\n') @@ -2880,7 +2880,7 @@ def mk_z3consts_ml(api_files): idx = idx + 1 linenum = linenum + 1 if VERBOSE: - print "Generated '%s/z3enums.mli'" % ('%s' % gendir) + print ('Generated "%s/z3enums.mli"' % ('%s' % gendir)) def mk_gui_str(id): return '4D2F40D8-E5F9-473B-B548-%012d' % id diff --git a/scripts/update_api.py b/scripts/update_api.py index 4669b78fc..a70214971 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -276,7 +276,7 @@ def param2dotnet(p): elif k == OUT_ARRAY: return "[Out] %s[]" % type2dotnet(param_type(p)) elif k == OUT_MANAGED_ARRAY: - return "[Out] out %s[]" % type2dotnet(param_type(p)) + return "[Out] out %s[]" % type2dotnet(param_type(p)) else: return type2dotnet(param_type(p)) @@ -1517,7 +1517,7 @@ def mk_ml(): ml_wrapper.write('}\n') ml_wrapper.write('#endif\n') if is_verbose(): - print "Generated '%s'" % ml_nativef + print ('Generated "%s"' % ml_nativef) # Collect API(...) commands from def def_APIs(): From ed0fa9324592293e97f8a0da267cc3eb384a1e03 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Jan 2015 17:35:19 +0000 Subject: [PATCH 464/507] Minor adjustments after rebase Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 2 +- scripts/mk_util.py | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 25862b2d7..33334930e 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -190,7 +190,7 @@ let basic_tests ( ctx : context ) = (* Error handling test. *) try ( let i = Integer.mk_numeral_s ctx "1/2" in - raise (TestFailedException "") (* unreachable *) + raise (TestFailedException (to_string i)) (* unreachable *) ) with Z3native.Exception(_) -> ( Printf.printf "Exception caught, OK.\n" diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 49ff79824..30c305047 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -357,14 +357,13 @@ def check_ml(): rmf('hello.cmo') rmf('hello.cmx') rmf('a.out') - rmf('hello.o') find_ml_lib() find_ocaml_find() def find_ocaml_find(): global OCAMLFIND if is_verbose(): - print ('Testing %s...' % OCAMLFIND) + print ("Testing %s..." % OCAMLFIND) r = exec_cmd([OCAMLFIND, 'printconf']) if r != 0: OCAMLFIND='' @@ -1743,7 +1742,6 @@ def mk_config(): if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) - print('ML API: %s' % is_ml_enabled()) if is_ml_enabled(): print('OCaml Compiler: %s' % OCAMLC) print('OCaml Native: %s' % OCAMLOPT) @@ -1866,11 +1864,10 @@ def mk_config(): if is_java_enabled(): print('JNI Bindings: %s' % JNI_HOME) print('Java Compiler: %s' % JAVAC) - print('ML API: %s' % is_ml_enabled()) if is_ml_enabled(): - print('Ocaml Compiler: %s' % OCAMLC) - print('Ocaml Native: %s' % OCAMLOPT) - print('Ocaml Library: %s' % OCAML_LIB) + print('OCaml Compiler: %s' % OCAMLC) + print('OCaml Native: %s' % OCAMLOPT) + print('OCaml Library: %s' % OCAML_LIB) def mk_install(out): out.write('install: ') @@ -2437,9 +2434,6 @@ def mk_bindings(api_files): if is_java_enabled(): check_java() mk_z3consts_java(api_files) - if is_ml_enabled(): - check_ml() - mk_z3consts_ml(api_files) _execfile(os.path.join('scripts', 'update_api.py'), g) # HACK cp_z3py_to_build() if is_ml_enabled(): @@ -2808,7 +2802,6 @@ def mk_z3consts_ml(api_files): decls[words[1]] = idx idx = idx + 1 linenum = linenum + 1 - efile.write('end\n') if VERBOSE: print ('Generated "%s/z3enums.ml"' % ('%s' % gendir)) efile = open('%s.mli' % os.path.join(gendir, "z3enums"), 'w') From d8f90802c0933be09377e30fec724e24252c2253 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Jan 2015 18:14:22 +0000 Subject: [PATCH 465/507] Added FPA setup to default kernel setup Signed-off-by: Christoph M. Wintersteiger --- src/smt/smt_setup.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index 68e960fb8..d17e4b803 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -813,6 +813,7 @@ namespace smt { setup_AUFLIA(false); setup_datatypes(); setup_bv(); + setup_fpa(); return; } From a8d8e3e9e59b1f726399462bde034edae1e63aaf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Jan 2015 18:16:51 +0000 Subject: [PATCH 466/507] formatting Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index 2fbf42cca..d53bc5de3 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -266,7 +266,7 @@ def param2dotnet(p): elif k == OUT_ARRAY: return "[Out] %s[]" % type2dotnet(param_type(p)) elif k == OUT_MANAGED_ARRAY: - return "[Out] out %s[]" % type2dotnet(param_type(p)) + return "[Out] out %s[]" % type2dotnet(param_type(p)) else: return type2dotnet(param_type(p)) From d20c7bc9eeaf952fd40f4604dac3c1a748507f56 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Mon, 19 Jan 2015 18:19:43 +0000 Subject: [PATCH 467/507] Added is_qfaufbv_probe and is_qfauflia_probe. Potential performance disruption for some users: Changed default_tactic to call the respective tactics, where previously they would have run the default 'smt' tactic. Signed-off-by: Christoph M. Wintersteiger --- src/tactic/arith/probe_arith.cpp | 75 +++++++++++++++++++++++++ src/tactic/arith/probe_arith.h | 2 + src/tactic/portfolio/default_tactic.cpp | 6 +- src/tactic/probe.cpp | 38 +++++++++++++ src/tactic/probe.h | 2 + 5 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/tactic/arith/probe_arith.cpp b/src/tactic/arith/probe_arith.cpp index 45fc868ac..770281923 100644 --- a/src/tactic/arith/probe_arith.cpp +++ b/src/tactic/arith/probe_arith.cpp @@ -198,11 +198,75 @@ struct is_non_qflira_functor { } }; +struct is_non_qfauflira_functor { + struct found {}; + ast_manager & m; + arith_util m_arith_util; + array_util m_array_util; + bool m_int; + bool m_real; + + is_non_qfauflira_functor(ast_manager & _m, bool _int, bool _real) : + m(_m), m_arith_util(_m), m_array_util(_m), m_int(_int), m_real(_real) {} + + void operator()(var *) { throw found(); } + + void operator()(quantifier *) { throw found(); } + + bool compatible_sort(app * n) const { + if (m.is_bool(n)) + return true; + if (m_int && m_arith_util.is_int(n)) + return true; + if (m_real && m_arith_util.is_real(n)) + return true; + if (m_array_util.is_array(n)) + return true; + return false; + } + + void operator()(app * n) { + if (!compatible_sort(n)) + throw found(); + family_id fid = n->get_family_id(); + if (fid == m.get_basic_family_id()) + return; + if (fid == m_arith_util.get_family_id()) { + switch (n->get_decl_kind()) { + case OP_LE: case OP_GE: case OP_LT: case OP_GT: + case OP_ADD: case OP_NUM: + return; + case OP_MUL: + if (n->get_num_args() != 2) + throw found(); + if (!m_arith_util.is_numeral(n->get_arg(0))) + throw found(); + return; + case OP_TO_REAL: + if (!m_real) + throw found(); + break; + default: + throw found(); + } + return; + } + if (is_uninterp(n)) + return; + throw found(); + } +}; + static bool is_qflia(goal const & g) { is_non_qflira_functor p(g.m(), true, false); return !test(g, p); } +static bool is_qfauflia(goal const & g) { + is_non_qfauflira_functor p(g.m(), true, false); + return !test(g, p); +} + class is_qflia_probe : public probe { public: virtual result operator()(goal const & g) { @@ -210,6 +274,13 @@ public: } }; +class is_qfauflia_probe : public probe { +public: + virtual result operator()(goal const & g) { + return is_qfauflia(g); + } +}; + static bool is_qflra(goal const & g) { is_non_qflira_functor p(g.m(), false, true); return !test(g, p); @@ -289,6 +360,10 @@ probe * mk_is_qflia_probe() { return alloc(is_qflia_probe); } +probe * mk_is_qfauflia_probe() { + return alloc(is_qfauflia_probe); +} + probe * mk_is_qflra_probe() { return alloc(is_qflra_probe); } diff --git a/src/tactic/arith/probe_arith.h b/src/tactic/arith/probe_arith.h index 17e9efb28..83179098d 100644 --- a/src/tactic/arith/probe_arith.h +++ b/src/tactic/arith/probe_arith.h @@ -33,6 +33,7 @@ probe * mk_arith_max_degree_probe(); */ probe * mk_is_qflia_probe(); +probe * mk_is_qfauflia_probe(); probe * mk_is_qflra_probe(); probe * mk_is_qflira_probe(); probe * mk_is_ilp_probe(); @@ -40,6 +41,7 @@ probe * mk_is_mip_probe(); /* ADD_PROBE("is-qflia", "true if the goal is in QF_LIA.", "mk_is_qflia_probe()") + ADD_PROBE("is-qfauflia", "true if the goal is in QF_AUFLIA.", "mk_is_qfauflia_probe()") ADD_PROBE("is-qflra", "true if the goal is in QF_LRA.", "mk_is_qflra_probe()") ADD_PROBE("is-qflira", "true if the goal is in QF_LIRA.", "mk_is_qflira_probe()") ADD_PROBE("is-ilp", "true if the goal is ILP.", "mk_is_ilp_probe()") diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 9ecc16ecf..4bd82b969 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -28,10 +28,14 @@ Notes: #include"probe_arith.h" #include"quant_tactics.h" #include"qffpa_tactic.h" +#include"qfaufbv_tactic.h" +#include"qfauflia_tactic.h" tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * st = using_params(and_then(mk_simplify_tactic(m), cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), + cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m), + cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), @@ -39,7 +43,7 @@ tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { cond(mk_is_nra_probe(), mk_nra_tactic(m), cond(mk_is_lira_probe(), mk_lira_tactic(m, p), cond(mk_is_qffpabv_probe(), mk_qffpa_tactic(m, p), - mk_smt_tactic()))))))))), + mk_smt_tactic()))))))))))), p); return st; } diff --git a/src/tactic/probe.cpp b/src/tactic/probe.cpp index 1a696dc78..30a62fb5c 100644 --- a/src/tactic/probe.cpp +++ b/src/tactic/probe.cpp @@ -316,6 +316,44 @@ probe * mk_is_qfbv_probe() { return alloc(is_qfbv_probe); } +struct is_non_qfaufbv_predicate { + struct found {}; + ast_manager & m; + bv_util m_bv_util; + array_util m_array_util; + + is_non_qfaufbv_predicate(ast_manager & _m) : m(_m), m_bv_util(_m), m_array_util(_m) {} + + void operator()(var *) { throw found(); } + + void operator()(quantifier *) { throw found(); } + + void operator()(app * n) { + if (!m.is_bool(n) && !m_bv_util.is_bv(n) && !m_array_util.is_array(n)) + throw found(); + family_id fid = n->get_family_id(); + if (fid == m.get_basic_family_id()) + return; + if (fid == m_bv_util.get_family_id() || fid == m_array_util.get_family_id()) + return; + if (is_uninterp(n)) + return; + + throw found(); + } +}; + +class is_qfaufbv_probe : public probe { +public: + virtual result operator()(goal const & g) { + return !test(g); + } +}; + +probe * mk_is_qfaufbv_probe() { + return alloc(is_qfaufbv_probe); +} + class num_consts_probe : public probe { bool m_bool; // If true, track only boolean constants. Otherwise, track only non boolean constants. char const * m_family; // (Ignored if m_bool == true), if != 0 and m_bool == true, then track only constants of the given family. diff --git a/src/tactic/probe.h b/src/tactic/probe.h index 2f61b340f..0cf8122e4 100644 --- a/src/tactic/probe.h +++ b/src/tactic/probe.h @@ -111,10 +111,12 @@ probe * mk_div(probe * p1, probe * p2); probe * mk_is_propositional_probe(); probe * mk_is_qfbv_probe(); +probe * mk_is_qfaufbv_probe(); /* ADD_PROBE("is-propositional", "true if the goal is in propositional logic.", "mk_is_propositional_probe()") ADD_PROBE("is-qfbv", "true if the goal is in QF_BV.", "mk_is_qfbv_probe()") + ADD_PROBE("is-qfaufbv", "true if the goal is in QF_AUFBV.", "mk_is_qfaufbv_probe()") */ #endif From 074ff311c072a8c240b515a54b9be2f705d9edd1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 20 Jan 2015 15:19:31 +0000 Subject: [PATCH 468/507] BV-SLS final integration. Signed-off-by: Christoph M. Wintersteiger --- versions/z3-crsat-0.01.txt | 12 ------------ versions/z3-gsat-0.01.txt | 10 ---------- versions/z3-gsat-res-0.01.txt | 10 ---------- versions/z3-wsat-0.01.txt | 14 -------------- versions/z3-wsat-0.01b.txt | 14 -------------- versions/z3-wsat-0.01c.txt | 12 ------------ versions/z3-wsat-0.01d.txt | 11 ----------- versions/z3-wsat-0.01e.txt | 11 ----------- versions/z3-wsat-0.02.txt | 13 ------------- versions/z3-wsat-res-0.01.txt | 13 ------------- 10 files changed, 120 deletions(-) delete mode 100644 versions/z3-crsat-0.01.txt delete mode 100644 versions/z3-gsat-0.01.txt delete mode 100644 versions/z3-gsat-res-0.01.txt delete mode 100644 versions/z3-wsat-0.01.txt delete mode 100644 versions/z3-wsat-0.01b.txt delete mode 100644 versions/z3-wsat-0.01c.txt delete mode 100644 versions/z3-wsat-0.01d.txt delete mode 100644 versions/z3-wsat-0.01e.txt delete mode 100644 versions/z3-wsat-0.02.txt delete mode 100644 versions/z3-wsat-res-0.01.txt diff --git a/versions/z3-crsat-0.01.txt b/versions/z3-crsat-0.01.txt deleted file mode 100644 index 49e1a1525..000000000 --- a/versions/z3-crsat-0.01.txt +++ /dev/null @@ -1,12 +0,0 @@ -More focused (_FOCUS_ == 2) WalkSAT version. -Variables are chosen among candidates in only one unsatisfied bit-vector term. -Flip rate slightly slower; probably due to larger hash-table and recursive formula structure. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 1 -#define _FOCUS_ 3 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-gsat-0.01.txt b/versions/z3-gsat-0.01.txt deleted file mode 100644 index eb806a67f..000000000 --- a/versions/z3-gsat-0.01.txt +++ /dev/null @@ -1,10 +0,0 @@ -Basic GSAT version. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 0 -#define _FOCUS_ 0 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-gsat-res-0.01.txt b/versions/z3-gsat-res-0.01.txt deleted file mode 100644 index 6a211f2bc..000000000 --- a/versions/z3-gsat-res-0.01.txt +++ /dev/null @@ -1,10 +0,0 @@ -Basic GSAT version corresponding to Christoph's original code. -Restarts after 100 plateaus. - -#define _CNF_ 0 -#define _BFS_ 0 -#define _FOCUS_ 0 -#define _RESTARTS_ 1 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01.txt b/versions/z3-wsat-0.01.txt deleted file mode 100644 index fec38518d..000000000 --- a/versions/z3-wsat-0.01.txt +++ /dev/null @@ -1,14 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion. -Flip rate increased by roughly 10%-300%. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 1 -#define _FOCUS_ 1 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 - -BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file diff --git a/versions/z3-wsat-0.01b.txt b/versions/z3-wsat-0.01b.txt deleted file mode 100644 index 8bcf2ffeb..000000000 --- a/versions/z3-wsat-0.01b.txt +++ /dev/null @@ -1,14 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion. -Chooses a random top level assertion instead of using a BFS approach (_BFS_ == 0). -No restarts. - -#define _CNF_ 0 -#define _BFS_ 0 -#define _FOCUS_ 1 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 - -BUGGY VERSION! Uses wrong value for modulo operation in assertion selection. \ No newline at end of file diff --git a/versions/z3-wsat-0.01c.txt b/versions/z3-wsat-0.01c.txt deleted file mode 100644 index 223560e08..000000000 --- a/versions/z3-wsat-0.01c.txt +++ /dev/null @@ -1,12 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion. -AND is scored by average; OR is scored by inverse multiplication. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 1 -#define _FOCUS_ 1 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 1 -#define _SCORE_OR_MUL_ 1 \ No newline at end of file diff --git a/versions/z3-wsat-0.01d.txt b/versions/z3-wsat-0.01d.txt deleted file mode 100644 index 072191370..000000000 --- a/versions/z3-wsat-0.01d.txt +++ /dev/null @@ -1,11 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion with MINIMAL top_score. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 2 -#define _FOCUS_ 1 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.01e.txt b/versions/z3-wsat-0.01e.txt deleted file mode 100644 index b018c5e0d..000000000 --- a/versions/z3-wsat-0.01e.txt +++ /dev/null @@ -1,11 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion with MAXIMAL top_score. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 3 -#define _FOCUS_ 1 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file diff --git a/versions/z3-wsat-0.02.txt b/versions/z3-wsat-0.02.txt deleted file mode 100644 index 34dcb157c..000000000 --- a/versions/z3-wsat-0.02.txt +++ /dev/null @@ -1,13 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion. -Score function reduced to 0/1. -No restarts. - -#define _CNF_ 0 -#define _BFS_ 1 -#define _FOCUS_ 1 -#define _RESTARTS_ 0 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 -#define _WEIGHTED_DIST_ 1 \ No newline at end of file diff --git a/versions/z3-wsat-res-0.01.txt b/versions/z3-wsat-res-0.01.txt deleted file mode 100644 index 575180a59..000000000 --- a/versions/z3-wsat-res-0.01.txt +++ /dev/null @@ -1,13 +0,0 @@ -Basic WalkSAT version. -Variables are chosen among candidates in only ONE top level assertion. -Flip rate increased by roughly 10%-300% compared to GSAT. -Restarts after 100 plateaus. -Fps slightly decreased due to restarts. - -#define _CNF_ 0 -#define _BFS_ 1 -#define _FOCUS_ 1 -#define _RESTARTS_ 1 -#define _TIMELIMIT_ 300 -#define _SCORE_AND_AVG_ 0 -#define _SCORE_OR_MUL_ 0 \ No newline at end of file From 0746ede53733c6a4191dd588cba14ec83236e490 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 20 Jan 2015 15:59:25 +0000 Subject: [PATCH 469/507] BV SLS: Final adjustments Signed-off-by: Christoph M. Wintersteiger --- src/tactic/portfolio/smt_strategic_solver.cpp | 5 +--- src/tactic/sls/sls_tactic.cpp | 3 +-- src/tactic/sls/sls_tactic.h | 2 +- src/tactic/smtlogics/qfbv_tactic.cpp | 26 ------------------- 4 files changed, 3 insertions(+), 33 deletions(-) diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index f63b4fd8c..586c3a349 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -37,14 +37,11 @@ Notes: #include"horn_tactic.h" #include"smt_solver.h" -#include"sls_tactic.h" - tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) { if (logic=="QF_UF") return mk_qfuf_tactic(m, p); else if (logic=="QF_BV") - // return mk_qfbv_tactic(m, p); - return mk_qfbv_sls_tactic(m, p); + return mk_qfbv_tactic(m, p); else if (logic=="QF_IDL") return mk_qfidl_tactic(m, p); else if (logic=="QF_LIA") diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 9bbed20bb..b06a047f7 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -158,8 +158,7 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { } tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { - tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m)); - //tactic * t = and_then(mk_simplify_tactic(m), mk_nnf_tactic(m, p), mk_sls_tactic(m)); + tactic * t = and_then(mk_preamble(m, p), mk_sls_tactic(m, p)); t->updt_params(p); return t; } diff --git a/src/tactic/sls/sls_tactic.h b/src/tactic/sls/sls_tactic.h index 50b8f0d5b..82ac1ce88 100644 --- a/src/tactic/sls/sls_tactic.h +++ b/src/tactic/sls/sls_tactic.h @@ -23,8 +23,8 @@ Notes: class ast_manager; class tactic; -tactic * mk_sls_tactic(ast_manager & m, params_ref const & p = params_ref()); tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p = params_ref()); + /* ADD_TACTIC("qfbv-sls", "(try to) solve using stochastic local search for QF_BV.", "mk_qfbv_sls_tactic(m, p)") */ diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index 3b4da2f2d..ac53ca0c8 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -93,32 +93,6 @@ tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) { mk_sat_tactic(m)); #endif - /* use full sls - tactic * st = using_params(and_then(preamble_st, - cond(mk_is_qfbv_probe(), - cond(mk_is_qfbv_eq_probe(), - and_then(mk_bv1_blaster_tactic(m), - using_params(mk_smt_tactic(), solver_p)), - and_then(mk_nnf_tactic(m, p), mk_sls_tactic(m))), - mk_smt_tactic())), - main_p);*/ - - /* use pure dpll - tactic * st = using_params(and_then(mk_simplify_tactic(m), - cond(mk_is_qfbv_probe(), - and_then(mk_bit_blaster_tactic(m), - when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)), - and_then(using_params(and_then(mk_simplify_tactic(m), - mk_solve_eqs_tactic(m)), - local_ctx_p), - if_no_proofs(cond(mk_produce_unsat_cores_probe(), - mk_aig_tactic(), - using_params(mk_aig_tactic(), - big_aig_p))))), - new_sat), - mk_smt_tactic())), - main_p);*/ - tactic * st = using_params(and_then(preamble_st, // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function // symbols. In this case, we should not use From 237577acc8e0d4fae8e57b4e48c3c086e70c23d1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 20 Jan 2015 15:59:54 +0000 Subject: [PATCH 470/507] Bumping version to 4.4 Added to release notes Signed-off-by: Christoph M. Wintersteiger --- RELEASE_NOTES | 8 ++++++-- scripts/mk_project.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index ad2dcaf00..f185983a3 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,9 +1,13 @@ RELEASE NOTES -Version 4.3.3 +Version 4.4 ============= -- Fixed bug in floating point models +- New feature: Stochastic local search engine for bit-vector formulas (see the qfbv-sls tactic). + See also: Froehlich, Biere, Wintersteiger, Hamadi: Stochastic Local Search + for Satisfiability Modulo Theories, AAAI 2015. + +- Fixed various bugs reported by Marc Brockschmidt, Venkatesh-Prasad Ranganath, Enric Carbonell, Morgan Deters, Tom Ball, and Codeplex users rsas, clockish, Heizmann. Version 4.3.2 ============= diff --git a/scripts/mk_project.py b/scripts/mk_project.py index b30bba609..225ef6413 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -9,7 +9,7 @@ from mk_util import * # Z3 Project definition def init_project_def(): - set_version(4, 3, 3, 0) + set_version(4, 4, 0, 0) add_lib('util', []) add_lib('polynomial', ['util'], 'math/polynomial') add_lib('sat', ['util']) From 5e6ea4e5704babcf6502d8deb925f29134df3767 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Tue, 20 Jan 2015 19:03:49 +0000 Subject: [PATCH 471/507] added --x86 build flag --- scripts/mk_util.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4641a7b1b..96bc1c273 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -59,6 +59,7 @@ VERBOSE=True DEBUG_MODE=False SHOW_CPPS = True VS_X64 = False +LINUX_X64 = True ONLY_MAKEFILES = False Z3PY_SRC_DIR=None VS_PROJ = False @@ -334,7 +335,8 @@ def check_java(): raise MKException("Failed to detect jni.h. Possible solution: set JNI_HOME with the path to JDK.") def is64(): - return sys.maxsize >= 2**32 + global LINUX_X64 + return LINUX_X64 and sys.maxsize >= 2**32 def check_ar(): if is_verbose(): @@ -450,6 +452,8 @@ def display_help(exit_code): print(" -t, --trace enable tracing in release mode.") if IS_WINDOWS: print(" -x, --x64 create 64 binary when using Visual Studio.") + else: + print(" --x86 force 32-bit x86 build on x64 systems.") print(" -m, --makefiles generate only makefiles.") if IS_WINDOWS: print(" -v, --vsproj generate Visual Studio Project Files.") @@ -477,12 +481,13 @@ def display_help(exit_code): def parse_options(): global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH + global LINUX_X64 try: options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:df:sxhmcvtnp:gj', ['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof', - 'githash=']) + 'githash=', 'x86']) except: print("ERROR: Invalid command line option") display_help(1) @@ -501,6 +506,8 @@ def parse_options(): if not IS_WINDOWS: raise MKException('x64 compilation mode can only be specified when using Visual Studio') VS_X64 = True + elif opt in ('--x86'): + LINUX_X64=False elif opt in ('-h', '--help'): display_help(0) elif opt in ('-m', '--onlymakefiles'): @@ -1593,6 +1600,10 @@ def mk_config(): CPPFLAGS = '%s -D_AMD64_' % CPPFLAGS if sysname == 'Linux': CPPFLAGS = '%s -D_USE_THREAD_LOCAL' % CPPFLAGS + elif not LINUX_X64: + CXXFLAGS = '%s -m32' % CXXFLAGS + LDFLAGS = '%s -m32' % LDFLAGS + SLIBFLAGS = '%s -m32' % SLIBFLAGS if DEBUG_MODE: CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS if TRACE or DEBUG_MODE: From 83023c72116670742c8e6b1f470e08d1b80de158 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 13:02:18 +0000 Subject: [PATCH 472/507] build fixes Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_tracker.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 89ef57871..798a03761 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -20,6 +20,8 @@ Notes: #ifndef _SLS_TRACKER_H_ #define _SLS_TRACKER_H_ +#include + #include"for_each_expr.h" #include"ast_smt2_pp.h" #include"bv_decl_plugin.h" @@ -39,7 +41,7 @@ class sls_tracker { mpz m_zero, m_one, m_two; struct value_score { - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), touched(1), score_prune(0.0), has_pos_occ(0), has_neg_occ(0) { }; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), score_prune(0.0), has_pos_occ(0), has_neg_occ(0), touched(1) {}; ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; From 71e5f03b441cec399dae25cd15f6dd5fc4b657f8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 13:04:05 +0000 Subject: [PATCH 473/507] build fix --- src/tactic/sls/sls_tracker.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/sls/sls_tracker.h b/src/tactic/sls/sls_tracker.h index 798a03761..87c0f962c 100644 --- a/src/tactic/sls/sls_tracker.h +++ b/src/tactic/sls/sls_tracker.h @@ -41,7 +41,7 @@ class sls_tracker { mpz m_zero, m_one, m_two; struct value_score { - value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), distance(0), score_prune(0.0), has_pos_occ(0), has_neg_occ(0), touched(1) {}; + value_score() : m(0), value(unsynch_mpz_manager::mk_z(0)), score(0.0), score_prune(0.0), has_pos_occ(0), has_neg_occ(0), distance(0), touched(1) {}; ~value_score() { if (m) m->del(value); } unsynch_mpz_manager * m; mpz value; From e20dc9f9a474e1228795c07cf6a1c8c522ba70c5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 13:35:25 +0000 Subject: [PATCH 474/507] typo Signed-off-by: Christoph M. Wintersteiger --- src/smt/smt_case_split_queue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/smt/smt_case_split_queue.cpp b/src/smt/smt_case_split_queue.cpp index 7a03224cf..5a4a6ff25 100644 --- a/src/smt/smt_case_split_queue.cpp +++ b/src/smt/smt_case_split_queue.cpp @@ -1091,7 +1091,7 @@ namespace smt { case_split_queue * mk_case_split_queue(context & ctx, smt_params & p) { if (p.m_relevancy_lvl < 2 && (p.m_case_split_strategy == CS_RELEVANCY || p.m_case_split_strategy == CS_RELEVANCY_ACTIVITY || p.m_case_split_strategy == CS_RELEVANCY_GOAL)) { - warning_msg("relevacy must be enabled to use option CASE_SPLIT=3, 4 or 5"); + warning_msg("relevancy must be enabled to use option CASE_SPLIT=3, 4 or 5"); p.m_case_split_strategy = CS_ACTIVITY; } if (p.m_auto_config && (p.m_case_split_strategy == CS_RELEVANCY || p.m_case_split_strategy == CS_RELEVANCY_ACTIVITY || From ae792f18917d34ad02279999bbdf29d132f94a97 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 13:47:32 +0000 Subject: [PATCH 475/507] avoid spurious warning message Signed-off-by: Christoph M. Wintersteiger --- src/smt/smt_model_checker.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index 7053d63ec..163003c01 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -282,6 +282,7 @@ namespace smt { if (!m_fparams) { m_fparams = alloc(smt_params, m_context->get_fparams()); m_fparams->m_relevancy_lvl = 0; // no relevancy since the model checking problems are quantifier free + m_fparams->m_case_split_strategy = CS_ACTIVITY; // avoid warning messages about smt.case_split >= 3. } if (!m_aux_context) { symbol logic; From 052baaabe40d321aea5ec644cefa58ee36788305 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 14:22:35 +0000 Subject: [PATCH 476/507] FPA API bugfixes Signed-off-by: Christoph M. Wintersteiger --- scripts/update_api.py | 2 +- src/ast/fpa/fpa2bv_converter.cpp | 34 +++++++++++++++++++++----------- src/util/mpf.cpp | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/scripts/update_api.py b/scripts/update_api.py index a47835904..499cc1a32 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -267,7 +267,7 @@ def param2dotnet(p): elif k == OUT_ARRAY: return "[Out] %s[]" % type2dotnet(param_type(p)) elif k == OUT_MANAGED_ARRAY: - return "[Out] out %s[]" % type2dotnet(param_type(p)) + return "[Out] out %s[]" % type2dotnet(param_type(p)) else: return type2dotnet(param_type(p)) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 1f7ea1186..110311c4c 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2982,12 +2982,11 @@ void fpa2bv_converter::mk_is_rm(expr * e, BV_RM_VAL rm, expr_ref & result) { case BV_RM_TIES_TO_AWAY: case BV_RM_TIES_TO_EVEN: case BV_RM_TO_NEGATIVE: - case BV_RM_TO_POSITIVE: return m_simp.mk_eq(e, rm_num, result); + case BV_RM_TO_POSITIVE: case BV_RM_TO_ZERO: + return m_simp.mk_eq(e, rm_num, result); default: - rm_num = m_bv_util.mk_numeral(BV_RM_TO_POSITIVE, 3); - expr_ref r(m); r = m_bv_util.mk_ule(e, rm_num); - return m_simp.mk_not(r, result); + UNREACHABLE(); } } @@ -3182,7 +3181,7 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #ifdef Z3DEBUG - return; + // return; // CMW: This works only for quantifier-free formulas. expr_ref new_e(m); new_e = m.mk_fresh_const(prefix, m.get_sort(e)); @@ -3485,9 +3484,14 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & mk_is_rm(rm, BV_RM_TO_POSITIVE, rm_is_to_pos); m_simp.mk_or(rm_is_to_zero, rm_is_to_neg, rm_zero_or_neg); m_simp.mk_or(rm_is_to_zero, rm_is_to_pos, rm_zero_or_pos); + dbg_decouple("fpa2bv_rnd_rm_is_to_zero", rm_is_to_zero); + dbg_decouple("fpa2bv_rnd_rm_is_to_neg", rm_is_to_neg); + dbg_decouple("fpa2bv_rnd_rm_is_to_pos", rm_is_to_pos); + expr_ref sgn_is_zero(m); m_simp.mk_eq(sgn, m_bv_util.mk_numeral(0, 1), sgn_is_zero); + dbg_decouple("fpa2bv_rnd_sgn_is_zero", sgn_is_zero); expr_ref max_sig(m), max_exp(m), inf_sig(m), inf_exp(m); max_sig = m_bv_util.mk_numeral(fu().fm().m_powers2.m1(sbits-1, false), sbits-1); @@ -3497,22 +3501,30 @@ void fpa2bv_converter::round(sort * s, expr_ref & rm, expr_ref & sgn, expr_ref & inf_exp = top_exp; dbg_decouple("fpa2bv_rnd_max_exp", max_exp); + dbg_decouple("fpa2bv_rnd_max_sig", max_sig); + dbg_decouple("fpa2bv_rnd_inf_sig", inf_sig); + dbg_decouple("fpa2bv_rnd_inf_exp", inf_exp); expr_ref ovfl_exp(m), max_inf_exp_neg(m), max_inf_exp_pos(m), n_d_check(m), n_d_exp(m); - m_simp.mk_ite(rm_zero_or_neg, max_exp, inf_exp, max_inf_exp_neg); - m_simp.mk_ite(rm_zero_or_pos, max_exp, inf_exp, max_inf_exp_pos); - m_simp.mk_ite(sgn_is_zero, max_inf_exp_neg, max_inf_exp_pos, ovfl_exp); + m_simp.mk_ite(rm_zero_or_pos, max_exp, inf_exp, max_inf_exp_neg); + m_simp.mk_ite(rm_zero_or_neg, max_exp, inf_exp, max_inf_exp_pos); + m_simp.mk_ite(sgn_is_zero, max_inf_exp_pos, max_inf_exp_neg, ovfl_exp); t_sig = m_bv_util.mk_extract(sbits-1, sbits-1, sig); m_simp.mk_eq(t_sig, nil_1, n_d_check); m_simp.mk_ite(n_d_check, bot_exp /* denormal */, biased_exp, n_d_exp); m_simp.mk_ite(OVF, ovfl_exp, n_d_exp, exp); expr_ref max_inf_sig_neg(m), max_inf_sig_pos(m), ovfl_sig(m), rest_sig(m); - m_simp.mk_ite(rm_zero_or_neg, max_sig, inf_sig, max_inf_sig_neg); - m_simp.mk_ite(rm_zero_or_pos, max_sig, inf_sig, max_inf_sig_pos); - m_simp.mk_ite(sgn_is_zero, max_inf_sig_neg, max_inf_sig_pos, ovfl_sig); + m_simp.mk_ite(rm_zero_or_pos, max_sig, inf_sig, max_inf_sig_neg); + m_simp.mk_ite(rm_zero_or_neg, max_sig, inf_sig, max_inf_sig_pos); + m_simp.mk_ite(sgn_is_zero, max_inf_sig_pos, max_inf_sig_neg, ovfl_sig); rest_sig = m_bv_util.mk_extract(sbits-2, 0, sig); m_simp.mk_ite(OVF, ovfl_sig, rest_sig, sig); + + dbg_decouple("fpa2bv_rnd_max_inf_sig_neg", max_inf_sig_neg); + dbg_decouple("fpa2bv_rnd_max_inf_sig_pos", max_inf_sig_pos); + dbg_decouple("fpa2bv_rnd_rm_zero_or_neg", rm_zero_or_neg); + dbg_decouple("fpa2bv_rnd_rm_zero_or_pos", rm_zero_or_pos); dbg_decouple("fpa2bv_rnd_sgn_final", sgn); dbg_decouple("fpa2bv_rnd_sig_final", sig); diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 511bdb03c..acf6eae39 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -1221,7 +1221,7 @@ std::string mpf_manager::to_string(mpf const & x) { m_mpq_manager.display_decimal(ss, r, x.sbits); if (m_mpq_manager.is_int(r)) ss << ".0"; - ss << "p" << exponent; + ss << " " << exponent; res += ss.str(); } } From 079204d1aace9c3a2c239b5ef82370d954871d82 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 14:22:47 +0000 Subject: [PATCH 477/507] FPA Python API cosmetics Signed-off-by: Christoph M. Wintersteiger --- src/api/python/z3.py | 16 ++++++++-------- src/api/python/z3printer.py | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index 82002c4f7..fd3d1bdc8 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -7749,7 +7749,7 @@ class FPRMRef(ExprRef): return Z3_ast_to_string(self.ctx_ref(), self.as_ast()) -def RoundNearestTiesToEven (ctx=None): +def RoundNearestTiesToEven(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx) @@ -7757,7 +7757,7 @@ def RNE (ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_even(ctx.ref()), ctx) -def RoundNearestTiesToAway (ctx=None): +def RoundNearestTiesToAway(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx) @@ -7765,27 +7765,27 @@ def RNA (ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_nearest_ties_to_away(ctx.ref()), ctx) -def RoundTowardPositive (ctx=None): +def RoundTowardPositive(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx) -def RTP (ctx=None): +def RTP(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_toward_positive(ctx.ref()), ctx) -def RoundTowardNegative (ctx=None): +def RoundTowardNegative(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx) -def RTN (ctx=None): +def RTN(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_toward_negative(ctx.ref()), ctx) -def RoundTowardZero (ctx=None): +def RoundTowardZero(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx) -def RTZ (ctx=None): +def RTZ(ctx=None): ctx = _get_ctx(ctx) return FPRMRef(Z3_mk_fpa_round_toward_zero(ctx.ref()), ctx) diff --git a/src/api/python/z3printer.py b/src/api/python/z3printer.py index da49f1719..ac1607dda 100644 --- a/src/api/python/z3printer.py +++ b/src/api/python/z3printer.py @@ -64,9 +64,9 @@ _z3_precedence = { # FPA operators _z3_op_to_fpa_normal_str = { - Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN : 'RNE()', Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY : 'RNA()', - Z3_OP_FPA_RM_TOWARD_POSITIVE : 'RTP()', Z3_OP_FPA_RM_TOWARD_NEGATIVE : 'RTN()', - Z3_OP_FPA_RM_TOWARD_ZERO : 'RTZ()', + Z3_OP_FPA_RM_NEAREST_TIES_TO_EVEN : 'RoundNearestTiesToEven()', Z3_OP_FPA_RM_NEAREST_TIES_TO_AWAY : 'RoundNearestTiesToAway()', + Z3_OP_FPA_RM_TOWARD_POSITIVE : 'RoundTowardPositive()', Z3_OP_FPA_RM_TOWARD_NEGATIVE : 'RoundTowardNegative()', + Z3_OP_FPA_RM_TOWARD_ZERO : 'RoundTowardZero()', Z3_OP_FPA_PLUS_INF : '+oo', Z3_OP_FPA_MINUS_INF : '-oo', Z3_OP_FPA_NAN : 'NaN', Z3_OP_FPA_PLUS_ZERO : 'PZero', Z3_OP_FPA_MINUS_ZERO : 'NZero', Z3_OP_FPA_ADD : 'fpAdd', Z3_OP_FPA_SUB : 'fpSub', Z3_OP_FPA_NEG : 'fpNeg', Z3_OP_FPA_MUL : 'fpMul', @@ -580,7 +580,7 @@ class Formatter: if self.fpa_pretty and a.decl().kind() in _z3_op_to_fpa_pretty_str: return to_format(_z3_op_to_fpa_pretty_str.get(a.decl().kind())) else: - return to_format(a.as_string()) + return to_format(_z3_op_to_fpa_normal_str.get(a.decl().kind())) def pp_fp_value(self, a): z3._z3_assert(isinstance(a, z3.FPNumRef), 'type mismatch') From e5c5c801c725147f8a966b0671dde26c61b96e82 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 14:40:18 +0000 Subject: [PATCH 478/507] fixed botched merge Signed-off-by: Christoph M. Wintersteiger --- src/tactic/portfolio/default_tactic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tactic/portfolio/default_tactic.cpp b/src/tactic/portfolio/default_tactic.cpp index 6419098bc..5a18e0830 100644 --- a/src/tactic/portfolio/default_tactic.cpp +++ b/src/tactic/portfolio/default_tactic.cpp @@ -43,7 +43,7 @@ tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { cond(mk_is_nra_probe(), mk_nra_tactic(m), cond(mk_is_lira_probe(), mk_lira_tactic(m, p), cond(mk_is_qffp_probe(), mk_qffp_tactic(m, p), - mk_smt_tactic()))))))))), + mk_smt_tactic()))))))))))), p); return st; } From 74e60fc9558f6eefd77a8911dc3406743ec76974 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 15:01:35 +0000 Subject: [PATCH 479/507] disabled debug output Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 110311c4c..dd0fa76fc 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -3181,7 +3181,7 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result) void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) { #ifdef Z3DEBUG - // return; + return; // CMW: This works only for quantifier-free formulas. expr_ref new_e(m); new_e = m.mk_fresh_const(prefix, m.get_sort(e)); @@ -3564,4 +3564,4 @@ void fpa2bv_converter::reset(void) { m_uf23bvuf.reset(); m_extra_assertions.reset(); -} \ No newline at end of file +} From 1a6af4385ef2ae1363165e080faf0562a398c3f2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 15:01:50 +0000 Subject: [PATCH 480/507] Fixed C example Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 117 ++++++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 60 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 920fdeb8c..817ada98e 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2605,7 +2605,8 @@ void fpa_example() { Z3_sort double_sort, rm_sort; Z3_symbol s_rm, s_x, s_y, s_x_plus_y; Z3_ast rm, x, y, n, x_plus_y, c1, c2, c3, c4, c5, c6; - + Z3_ast args[2], args2[2], and_args[3], args3[3]; + printf("\nFPA-example\n"); LOG_MSG("FPA-example"); @@ -2616,76 +2617,72 @@ void fpa_example() { double_sort = Z3_mk_fpa_sort(ctx, 11, 53); rm_sort = Z3_mk_fpa_rounding_mode_sort(ctx); - { - // Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). - s_rm = Z3_mk_string_symbol(ctx, "rm"); - rm = Z3_mk_const(ctx, s_rm, rm_sort); - s_x = Z3_mk_string_symbol(ctx, "x"); - s_y = Z3_mk_string_symbol(ctx, "y"); - x = Z3_mk_const(ctx, s_x, double_sort); - y = Z3_mk_const(ctx, s_y, double_sort); - n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); + // Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). + s_rm = Z3_mk_string_symbol(ctx, "rm"); + rm = Z3_mk_const(ctx, s_rm, rm_sort); + s_x = Z3_mk_string_symbol(ctx, "x"); + s_y = Z3_mk_string_symbol(ctx, "y"); + x = Z3_mk_const(ctx, s_x, double_sort); + y = Z3_mk_const(ctx, s_y, double_sort); + n = Z3_mk_fpa_numeral_double(ctx, 42.0, double_sort); - s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y"); - x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort); - c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y)); + s_x_plus_y = Z3_mk_string_symbol(ctx, "x_plus_y"); + x_plus_y = Z3_mk_const(ctx, s_x_plus_y, double_sort); + c1 = Z3_mk_eq(ctx, x_plus_y, Z3_mk_fpa_add(ctx, rm, x, y)); - Z3_ast args[2] = { c1, Z3_mk_eq(ctx, x_plus_y, n) }; - c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); + args[0] = c1; + args[1] = Z3_mk_eq(ctx, x_plus_y, n); + c2 = Z3_mk_and(ctx, 2, (Z3_ast*)&args); - Z3_ast args2[2] = { c2, Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx))) }; - c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); + args2[0] = c2; + args2[1] = Z3_mk_not(ctx, Z3_mk_eq(ctx, rm, Z3_mk_fpa_rtz(ctx))); + c3 = Z3_mk_and(ctx, 2, (Z3_ast*)&args2); - Z3_ast and_args[3] = { - Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)), - Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)), - Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y)) }; - Z3_ast args3[2] = { c3, Z3_mk_and(ctx, 3, and_args) }; - c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); + and_args[0] = Z3_mk_not(ctx, Z3_mk_fpa_is_zero(ctx, y)); + and_args[1] = Z3_mk_not(ctx, Z3_mk_fpa_is_nan(ctx, y)); + and_args[2] = Z3_mk_not(ctx, Z3_mk_fpa_is_infinite(ctx, y)); + args3[0] = c3; + args3[1] = Z3_mk_and(ctx, 3, and_args); + c4 = Z3_mk_and(ctx, 2, (Z3_ast*)&args3); - printf("c4: %s\n", Z3_ast_to_string(ctx, c4)); - Z3_push(ctx); - Z3_assert_cnstr(ctx, c4); - check(ctx, Z3_L_TRUE); - Z3_pop(ctx, 1); - } + printf("c4: %s\n", Z3_ast_to_string(ctx, c4)); + Z3_push(ctx); + Z3_assert_cnstr(ctx, c4); + check(ctx, Z3_L_TRUE); + Z3_pop(ctx, 1); - - { - // Show that the following are equal: - // (fp #b0 #b10000000001 #xc000000000000) - // ((_ to_fp 11 53) #x401c000000000000)) - // ((_ to_fp 11 53) RTZ 1.75 2))) - // ((_ to_fp 11 53) RTZ 7.0))) - Z3_ast args3[3]; - - Z3_push(ctx); - c1 = Z3_mk_fpa_fp(ctx, - Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), - Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11)), - Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52))); - c2 = Z3_mk_fpa_to_fp_bv(ctx, - Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), - Z3_mk_fpa_sort(ctx, 11, 53)); - c3 = Z3_mk_fpa_to_fp_real_int(ctx, + // Show that the following are equal: + // (fp #b0 #b10000000001 #xc000000000000) + // ((_ to_fp 11 53) #x401c000000000000)) + // ((_ to_fp 11 53) RTZ 1.75 2))) + // ((_ to_fp 11 53) RTZ 7.0))) + + Z3_push(ctx); + c1 = Z3_mk_fpa_fp(ctx, + Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), + Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52)), + Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11))); + c2 = Z3_mk_fpa_to_fp_bv(ctx, + Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), + Z3_mk_fpa_sort(ctx, 11, 53)); + c3 = Z3_mk_fpa_to_fp_real_int(ctx, Z3_mk_fpa_rtz(ctx), Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), Z3_mk_fpa_sort(ctx, 11, 53)); - c4 = Z3_mk_fpa_to_fp_real(ctx, - Z3_mk_fpa_rtz(ctx), - Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), - Z3_mk_fpa_sort(ctx, 11, 53)); - args3[0] = Z3_mk_eq(ctx, c1, c2); - args3[1] = Z3_mk_eq(ctx, c1, c3); - args3[2] = Z3_mk_eq(ctx, c1, c4); - c5 = Z3_mk_and(ctx, 3, args3); + c4 = Z3_mk_fpa_to_fp_real(ctx, + Z3_mk_fpa_rtz(ctx), + Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), + Z3_mk_fpa_sort(ctx, 11, 53)); + args3[0] = Z3_mk_eq(ctx, c1, c2); + args3[1] = Z3_mk_eq(ctx, c1, c3); + args3[2] = Z3_mk_eq(ctx, c1, c4); + c5 = Z3_mk_and(ctx, 3, args3); - printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); - Z3_assert_cnstr(ctx, c5); - check(ctx, Z3_L_TRUE); - Z3_pop(ctx, 1); - } + printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); + Z3_assert_cnstr(ctx, c5); + check(ctx, Z3_L_TRUE); + Z3_pop(ctx, 1); Z3_del_context(ctx); } From 9a53fe43e6ee3d22366e515526cdccfc166d6cd9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 15:31:12 +0000 Subject: [PATCH 481/507] Removed unnecessary #includes Signed-off-by: Christoph M. Wintersteiger --- src/tactic/sls/sls_engine.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index c0c319ab4..162866ed6 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -16,9 +16,6 @@ Author: Notes: --*/ -#include -#include - #include"map.h" #include"ast_smt2_pp.h" #include"ast_pp.h" @@ -575,7 +572,7 @@ lbool sls_engine::operator()() { } } while (res != l_true && m_stats.m_restarts++ < m_max_restarts); - verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " time: " << std::fixed << std::setprecision(2) << m_stats.m_stopwatch.get_current_seconds() << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; + verbose_stream() << "(restarts: " << m_stats.m_restarts << " flips: " << m_stats.m_moves << " fps: " << (m_stats.m_moves / m_stats.m_stopwatch.get_current_seconds()) << ")" << std::endl; return res; } From 1209302fe6c2d5fc1205f4f7b2bb5880f801e5d5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 15:34:21 +0000 Subject: [PATCH 482/507] Fixed integration issues Signed-off-by: Christoph M. Wintersteiger --- src/muz/duality/duality_dl_interface.cpp | 2 +- src/qe/nlarith_util.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/muz/duality/duality_dl_interface.cpp b/src/muz/duality/duality_dl_interface.cpp index 0ab9762b0..aa186bd0a 100755 --- a/src/muz/duality/duality_dl_interface.cpp +++ b/src/muz/duality/duality_dl_interface.cpp @@ -82,7 +82,7 @@ namespace Duality { if(rpfp) dealloc(rpfp); if(ls) - (ls); + dealloc(ls); } }; diff --git a/src/qe/nlarith_util.cpp b/src/qe/nlarith_util.cpp index fce54aaa4..c555b71f1 100644 --- a/src/qe/nlarith_util.cpp +++ b/src/qe/nlarith_util.cpp @@ -1492,11 +1492,11 @@ namespace nlarith { } fml = mk_and(equivs.size(), equivs.c_ptr()); } - void mk_pinf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { + void mk_plus_inf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { plus_inf_subst sub(*this); mk_inf_sign(sub, literals, fml, new_atoms); } - void mk_ninf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { + void mk_minus_inf_sign(util::literal_set const& literals, app_ref& fml, app_ref_vector& new_atoms) { minus_inf_subst sub(*this); mk_inf_sign(sub, literals, fml, new_atoms); } @@ -1704,10 +1704,10 @@ namespace nlarith { app_ref fml(m()); app_ref_vector new_atoms(m()); if (is_pos) { - mk_pinf_sign(literals, fml, new_atoms); + mk_plus_inf_sign(literals, fml, new_atoms); } else { - mk_ninf_sign(literals, fml, new_atoms); + mk_minus_inf_sign(literals, fml, new_atoms); } simple_branch* br = alloc(simple_branch, m(), fml); swap_atoms(br, literals.lits(), new_atoms); From 2cb84280d811229ec60418eed5de0b08c903d09a Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 17:58:31 +0000 Subject: [PATCH 483/507] Final adjustments for the FP integration Signed-off-by: Christoph M. Wintersteiger --- RELEASE_NOTES | 4 +- doc/mk_api_doc.py | 2 + doc/z3api.dox | 33 +--- src/api/java/Context.java | 23 +-- src/api/java/Fixedpoint.java | 2 +- src/api/z3_api.h | 2 +- src/api/z3_fpa.h | 342 ++++++++++++++++++----------------- 7 files changed, 192 insertions(+), 216 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index f185983a3..f8cac4c8b 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,11 +3,13 @@ RELEASE NOTES Version 4.4 ============= +- New feature: Support for the theory of floating-point numbers. This comes in the form of logics (QF_FP and QF_FPBV), tactics (qffp and qffpbv), as well as a theory plugin that allows theory combinations. Z3 supports the official SMT theory definition of FP (see http://smtlib.cs.uiowa.edu/theories/FloatingPoint.smt2) in SMT2 files, as well as all APIs. + - New feature: Stochastic local search engine for bit-vector formulas (see the qfbv-sls tactic). See also: Froehlich, Biere, Wintersteiger, Hamadi: Stochastic Local Search for Satisfiability Modulo Theories, AAAI 2015. -- Fixed various bugs reported by Marc Brockschmidt, Venkatesh-Prasad Ranganath, Enric Carbonell, Morgan Deters, Tom Ball, and Codeplex users rsas, clockish, Heizmann. +- Fixed various bugs reported by Marc Brockschmidt, Venkatesh-Prasad Ranganath, Enric Carbonell, Morgan Deters, Tom Ball, Malte Schwerhoff, and Codeplex users rsas, clockish, Heizmann. Version 4.3.2 ============= diff --git a/doc/mk_api_doc.py b/doc/mk_api_doc.py index 633f96c6b..476f2c8c7 100644 --- a/doc/mk_api_doc.py +++ b/doc/mk_api_doc.py @@ -31,6 +31,7 @@ try: cleanup_API('../src/api/z3_polynomial.h', 'tmp/z3_polynomial.h') cleanup_API('../src/api/z3_rcf.h', 'tmp/z3_rcf.h') cleanup_API('../src/api/z3_interp.h', 'tmp/z3_interp.h') + cleanup_API('../src/api/z3_fpa.h', 'tmp/z3_fpa.h') print "Removed annotations from z3_api.h." try: @@ -46,6 +47,7 @@ try: os.remove('tmp/z3_polynomial.h') os.remove('tmp/z3_rcf.h') os.remove('tmp/z3_interp.h') + os.remove('tmp/z3_fpa.h') print "Removed temporary file z3_api.h." os.remove('tmp/website.dox') print "Removed temporary file website.dox" diff --git a/doc/z3api.dox b/doc/z3api.dox index dbaa3c8b8..cb4569dc4 100644 --- a/doc/z3api.dox +++ b/doc/z3api.dox @@ -713,39 +713,10 @@ FILE_PATTERNS = website.dox \ z3_polynomial.h \ z3_rcf.h \ z3_interp.h \ + z3_fpa.h \ z3++.h \ z3py.py \ - ApplyResult.cs \ - AST.cs \ - ASTMap.cs \ - ASTVector.cs \ - Config.cs \ - Constructor.cs \ - Context.cs \ - DecRefQUeue.cs \ - Enumerations.cs \ - Expr.cs \ - FuncDecl.cs \ - FuncInterp.cs \ - Goal.cs \ - Log.cs \ - Model.cs \ - Native.cs \ - Numeral.cs \ - Params.cs \ - Pattern.cs \ - Probe.cs \ - Quantifier.cs \ - Solver.cs \ - Sort.cs \ - Statistics.cs \ - Status.cs \ - Symbol.cs \ - Tactic.cs \ - Util.cs \ - Version.cs \ - Z3Exception.cs \ - Z3Object.cs \ + *.cs \ *.java # The RECURSIVE tag can be used to turn specify whether or not subdirectories diff --git a/src/api/java/Context.java b/src/api/java/Context.java index f7fa471fb..26a54b9c6 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -2000,25 +2000,22 @@ public class Context extends IDisposable /** * Create a universal Quantifier. + * @param sorts the sorts of the bound variables. + * @param names names of the bound variables + * @param body the body of the quantifier. + * @param weight quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. + * @param patterns array containing the patterns created using {@code MkPattern}. + * @param noPatterns array containing the anti-patterns created using {@code MkPattern}. + * @param quantifierID optional symbol to track quantifier. + * @param skolemID optional symbol to track skolem constants. + * * Remarks: Creates a forall formula, where * {@code weight"/> is the weight, Date: Wed, 21 Jan 2015 18:24:36 +0000 Subject: [PATCH 484/507] fixed build errors and warnings Signed-off-by: Christoph M. Wintersteiger --- src/ast/fpa/fpa2bv_converter.cpp | 19 ++++++++----------- src/ast/rewriter/fpa_rewriter.cpp | 4 +--- src/ast/simplifier/fpa_simplifier_plugin.cpp | 4 ---- src/ast/simplifier/fpa_simplifier_plugin.h | 1 - src/util/mpf.cpp | 1 - 5 files changed, 9 insertions(+), 20 deletions(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index dd0fa76fc..f8f283ee6 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -16,7 +16,8 @@ Author: Notes: --*/ -#include +#include + #include"ast_smt2_pp.h" #include"well_sorted.h" #include"th_rewriter.h" @@ -688,8 +689,7 @@ void fpa2bv_converter::mk_mul(func_decl * f, unsigned num, expr * const * args, m_simp.mk_xor(x_is_pos, y_is_pos, sign_xor); mk_ite(sign_xor, nzero, pzero, v6); - // else comes the actual multiplication. - unsigned ebits = m_util.get_ebits(f->get_range()); + // else comes the actual multiplication. unsigned sbits = m_util.get_sbits(f->get_range()); expr_ref a_sgn(m), a_sig(m), a_exp(m), a_lz(m), b_sgn(m), b_sig(m), b_exp(m), b_lz(m); @@ -2037,7 +2037,8 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr * dbg_decouple("fpa2bv_to_float_res_exp", res_exp); expr_ref rounded(m); - round(s, expr_ref (rm, m), res_sgn, res_sig, res_exp, rounded); + expr_ref rm_e(rm, m); + round(s, rm_e, res_sgn, res_sig, res_exp, rounded); expr_ref is_neg(m), sig_inf(m); m_simp.mk_eq(sgn, one1, is_neg); @@ -2098,7 +2099,6 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr * mk_fp(sgn, e, s, result); } else { - mpf_manager & fm = fu().fm(); bv_util & bu = m_bv_util; arith_util & au = m_arith_util; @@ -2333,7 +2333,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const expr_ref sig_rest(m); sig_4 = m_bv_util.mk_extract(bv_sz - 1, bv_sz - sig_sz + 1, shifted_sig); // one short sig_rest = m_bv_util.mk_extract(bv_sz - sig_sz, 0, shifted_sig); - sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest.get()); sig_4 = m_bv_util.mk_concat(sig_4, sticky); } else { @@ -2496,7 +2496,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con // The exponent is at most bv_sz, i.e., we need ld(bv_sz)+1 ebits. // exp < bv_sz (+sign bit which is [0]) - unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); + unsigned exp_worst_case_sz = (unsigned)((log((double)bv_sz) / log((double)2)) + 1.0); if (exp_sz < exp_worst_case_sz) { // exp_sz < exp_worst_case_sz and exp >= 0. @@ -2558,7 +2558,6 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg unsigned ebits = m_util.get_ebits(xs); unsigned sbits = m_util.get_sbits(xs); unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); - unsigned rounding_sz = bv_sz + 3; expr_ref bv0(m), bv1(m); bv0 = m_bv_util.mk_numeral(0, 1); @@ -2575,7 +2574,6 @@ void fpa2bv_converter::mk_to_ubv(func_decl * f, unsigned num, expr * const * arg expr_ref c1(m), v1(m); c1 = m.mk_or(x_is_nan, x_is_inf, m.mk_and(x_is_neg, m.mk_not(x_is_nzero))); v1 = mk_to_ubv_unspecified(bv_sz); - dbg_decouple("fpa2bv_to_ubv_c1", c1); // +-Zero -> 0 expr_ref c2(m), v2(m); @@ -2682,8 +2680,7 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg unsigned ebits = m_util.get_ebits(xs); unsigned sbits = m_util.get_sbits(xs); - unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); - unsigned rounding_sz = bv_sz + 3; + unsigned bv_sz = (unsigned)f->get_parameter(0).get_int(); expr_ref bv0(m), bv1(m), bv0_2(m), bv1_2(m), bv3_2(m); bv0 = m_bv_util.mk_numeral(0, 1); diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index ce7fe5ed6..9a8ab7da0 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -160,9 +160,7 @@ br_status fpa_rewriter::mk_to_fp(func_decl * f, unsigned num_args, expr * const br_status fpa_rewriter::mk_to_fp_unsigned(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { SASSERT(f->get_num_parameters() == 2); SASSERT(f->get_parameter(0).is_int()); - SASSERT(f->get_parameter(1).is_int()); - unsigned ebits = f->get_parameter(0).get_int(); - unsigned sbits = f->get_parameter(1).get_int(); + SASSERT(f->get_parameter(1).is_int()); return BR_FAILED; } diff --git a/src/ast/simplifier/fpa_simplifier_plugin.cpp b/src/ast/simplifier/fpa_simplifier_plugin.cpp index d2f7a3e58..4aba9c76c 100644 --- a/src/ast/simplifier/fpa_simplifier_plugin.cpp +++ b/src/ast/simplifier/fpa_simplifier_plugin.cpp @@ -19,7 +19,6 @@ Author: fpa_simplifier_plugin::fpa_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b) : simplifier_plugin(symbol("fpa"), m), m_util(m), -m_bsimp(b), m_rw(m) {} fpa_simplifier_plugin::~fpa_simplifier_plugin() {} @@ -28,9 +27,6 @@ bool fpa_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * cons set_reduce_invoked(); SASSERT(f->get_family_id() == get_family_id()); - /*switch (f->get_decl_kind()) { - case OP_FPA_FP: break; - }*/ return m_rw.mk_app_core(f, num_args, args, result) == BR_DONE; } diff --git a/src/ast/simplifier/fpa_simplifier_plugin.h b/src/ast/simplifier/fpa_simplifier_plugin.h index 36e315737..13a235091 100644 --- a/src/ast/simplifier/fpa_simplifier_plugin.h +++ b/src/ast/simplifier/fpa_simplifier_plugin.h @@ -23,7 +23,6 @@ Author: class fpa_simplifier_plugin : public simplifier_plugin { fpa_util m_util; - basic_simplifier_plugin & m_bsimp; fpa_rewriter m_rw; public: diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index acf6eae39..de4107746 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -203,7 +203,6 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode m_mpq_manager.abs(x); m_mpz_manager.set(o.significand, 0); - const mpz & p = m_powers2(sbits+3); scoped_mpq v(m_mpq_manager); m_mpq_manager.set(v, x); From b6a7d600430642fb3b9b0b9b121af4cdb5868cef Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:09:22 +0000 Subject: [PATCH 485/507] Added FPA functions to Java API Signed-off-by: Christoph M. Wintersteiger --- src/api/java/Context.java | 780 +++++++++++++++++++++++++++++++++++++- src/api/java/FPNum.java | 2 - 2 files changed, 776 insertions(+), 6 deletions(-) diff --git a/src/api/java/Context.java b/src/api/java/Context.java index f7fa471fb..46a76f50f 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -85,7 +85,7 @@ public class Context extends IDisposable /** * Create an array of symbols. **/ - Symbol[] MkSymbols(String[] names) throws Z3Exception + Symbol[] mkSymbols(String[] names) throws Z3Exception { if (names == null) return null; @@ -218,7 +218,7 @@ public class Context extends IDisposable public EnumSort mkEnumSort(String name, String... enumNames) throws Z3Exception { - return new EnumSort(this, mkSymbol(name), MkSymbols(enumNames)); + return new EnumSort(this, mkSymbol(name), mkSymbols(enumNames)); } /** @@ -295,7 +295,7 @@ public class Context extends IDisposable { return new Constructor(this, mkSymbol(name), mkSymbol(recognizer), - MkSymbols(fieldNames), sorts, sortRefs); + mkSymbols(fieldNames), sorts, sortRefs); } /** @@ -358,7 +358,7 @@ public class Context extends IDisposable public DatatypeSort[] mkDatatypeSorts(String[] names, Constructor[][] c) throws Z3Exception { - return mkDatatypeSorts(MkSymbols(names), c); + return mkDatatypeSorts(mkSymbols(names), c); } /** @@ -2789,6 +2789,778 @@ public class Context extends IDisposable return new Fixedpoint(this); } + + /** + * Create the floating-point RoundingMode sort. + * @throws Z3Exception + **/ + public FPRMSort mkFPRoundingModeSort() throws Z3Exception + { + return new FPRMSort(this); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. + * @throws Z3Exception + **/ + public FPRMExpr mkFPRoundNearestTiesToEven() throws Z3Exception + { + return new FPRMExpr(this, Native.mkFpaRoundNearestTiesToEven(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRNE() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRne(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundNearestTiesToAway() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundNearestTiesToAway(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRNA() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRna(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundTowardPositive() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundTowardPositive(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardPositive rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRTP() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRtp(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundTowardNegative() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundTowardNegative(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardNegative rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRTN() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRtn(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRoundTowardZero() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRoundTowardZero(nCtx())); + } + + /** + * Create a numeral of RoundingMode sort which represents the RoundTowardZero rounding mode. + * @throws Z3Exception + **/ + public FPRMNum mkFPRTZ() throws Z3Exception + { + return new FPRMNum(this, Native.mkFpaRtz(nCtx())); + } + + /** + * Create a FloatingPoint sort. + * @param ebits exponent bits in the FloatingPoint sort. + * @param sbits significand bits in the FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort(int ebits, int sbits) throws Z3Exception + { + return new FPSort(this, ebits, sbits); + } + + /** + * Create the half-precision (16-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortHalf() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortHalf(nCtx())); + } + + /** + * Create the half-precision (16-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort16() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort16(nCtx())); + } + + /** + * Create the single-precision (32-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortSingle() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortSingle(nCtx())); + } + + /** + * Create the single-precision (32-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort32() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort32(nCtx())); + } + + /** + * Create the double-precision (64-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortDouble() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortDouble(nCtx())); + } + + /** + * Create the double-precision (64-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort64() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort64(nCtx())); + } + + /** + * Create the quadruple-precision (128-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSortQuadruple() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSortQuadruple(nCtx())); + } + + /** + * Create the quadruple-precision (128-bit) FloatingPoint sort. + * @throws Z3Exception + **/ + public FPSort mkFPSort128() throws Z3Exception + { + return new FPSort(this, Native.mkFpaSort128(nCtx())); + } + + + /** + * Create a NaN of sort s. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNaN(FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNan(nCtx(), s.getNativeObject())); + } + + /** + * Create a floating-point infinity of sort s. + * @param s FloatingPoint sort. + * @param negative indicates whether the result should be negative. + * @throws Z3Exception + **/ + public FPNum mkFPInf(FPSort s, boolean negative) throws Z3Exception + { + return new FPNum(this, Native.mkFpaInf(nCtx(), s.getNativeObject(), negative)); + } + + /** + * Create a floating-point zero of sort s. + * @param s FloatingPoint sort. + * @param negative indicates whether the result should be negative. + * @throws Z3Exception + **/ + public FPNum mkFPZero(FPSort s, boolean negative) throws Z3Exception + { + return new FPNum(this, Native.mkFpaZero(nCtx(), s.getNativeObject(), negative)); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(float v, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralFloat(nCtx(), v, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(double v, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralDouble(nCtx(), v, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from an int. + * * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(int v, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralInt(nCtx(), v, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two integers. + * @param sgn the sign. + * @param sig the significand. + * @param exp the exponent. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(boolean sgn, int sig, int exp, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralUintInt(nCtx(), sgn, sig, exp, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. + * @param sgn the sign. + * @param sig the significand. + * @param exp the exponent. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFPNumeral(boolean sgn, long sig, long exp, FPSort s) throws Z3Exception + { + return new FPNum(this, Native.mkFpaNumeralUint64Int64(nCtx(), sgn, sig, exp, s.getNativeObject())); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(float v, FPSort s) throws Z3Exception + { + return mkFPNumeral(v, s); + } + + /** + * Create a numeral of FloatingPoint sort from a float. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(double v, FPSort s) throws Z3Exception + { + return mkFPNumeral(v, s); + } + + /** + * Create a numeral of FloatingPoint sort from an int. + * @param v numeral value. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + + public FPNum mkFP(int v, FPSort s) throws Z3Exception + { + return mkFPNumeral(v, s); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two integers. + * @param sgn the sign. + * @param exp the exponent. + * @param sig the significand. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(boolean sgn, int exp, int sig, FPSort s) throws Z3Exception + { + return mkFPNumeral(sgn, sig, exp, s); + } + + /** + * Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. + * @param sgn the sign. + * @param exp the exponent. + * @param sig the significand. + * @param s FloatingPoint sort. + * @throws Z3Exception + **/ + public FPNum mkFP(boolean sgn, long exp, long sig, FPSort s) throws Z3Exception + { + return mkFPNumeral(sgn, sig, exp, s); + } + + + /** + * Floating-point absolute value + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPAbs(FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaAbs(nCtx(), t.getNativeObject())); + } + + /** + * Floating-point negation + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPNeg(FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaNeg(nCtx(), t.getNativeObject())); + } + + /** + * Floating-point addition + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPAdd(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaAdd(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point subtraction + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPSub(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaSub(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point multiplication + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPMul(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaMul(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point division + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPDiv(FPRMExpr rm, FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaDiv(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point fused multiply-add + * @param rm rounding mode term + * @param t1 floating-point term + * @param t2 floating-point term + * @param t3">floating-point term + * Remarks: + * The result is round((t1 * t2) + t3) + * @throws Z3Exception + **/ + public FPExpr mkFPFMA(FPRMExpr rm, FPExpr t1, FPExpr t2, FPExpr t3) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaFma(nCtx(), rm.getNativeObject(), t1.getNativeObject(), t2.getNativeObject(), t3.getNativeObject())); + } + + /** + * Floating-point square root + * @param rm rounding mode term + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPSqrt(FPRMExpr rm, FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaSqrt(nCtx(), rm.getNativeObject(), t.getNativeObject())); + } + + /** + * Floating-point remainder + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPRem(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaRem(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point roundToIntegral. Rounds a floating-point number to + * the closest integer, again represented as a floating-point number. + * @param rm">term of RoundingMode sort + * @param t floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPRoundToIntegral(FPRMExpr rm, FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaRoundToIntegral(nCtx(), rm.getNativeObject(), t.getNativeObject())); + } + + /** + * Minimum of floating-point numbers. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPMin(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaMin(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Maximum of floating-point numbers. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public FPExpr mkFPMax(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaMax(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point less than or equal. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPLEq(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaLeq(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point less than. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPLt(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaLt(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point greater than or equal. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPGEq(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaGeq(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point greater than. + * @param t1 floating-point term + * @param t2 floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPGt(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaGt(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Floating-point equality. + * @param t1 floating-point term + * @param t2 floating-point term + * Remarks: + * Note that this is IEEE 754 equality (as opposed to standard =). + * @throws Z3Exception + **/ + public BoolExpr mkFPEq(FPExpr t1, FPExpr t2) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaEq(nCtx(), t1.getNativeObject(), t2.getNativeObject())); + } + + /** + * Predicate indicating whether t is a normal floating-point number.\ + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsNormal(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsNormal(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a subnormal floating-point number.\ + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsSubnormal(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsSubnormal(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a floating-point number with zero value, i.e., +0 or -0. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsZero(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsZero(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a floating-point number representing +oo or -oo. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsInfinite(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsInfinite(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a NaN. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsNaN(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsNan(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a negative floating-point number. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsNegative(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsNegative(nCtx(), t.getNativeObject())); + } + + /** + * Predicate indicating whether t is a positive floating-point number. + * @param t floating-point term + * @throws Z3Exception + **/ + public BoolExpr mkFPIsPositive(FPExpr t) throws Z3Exception + { + return new BoolExpr(this, Native.mkFpaIsPositive(nCtx(), t.getNativeObject())); + } + + /** + * Create an expression of FloatingPoint sort from three bit-vector expressions. + * @param sgn bit-vector term (of size 1) representing the sign. + * @param sig bit-vector term representing the significand. + * @param exp bit-vector term representing the exponent. + * Remarks: + * This is the operator named `fp' in the SMT FP theory definition. + * Note that sgn is required to be a bit-vector of size 1. Significand and exponent + * are required to be greater than 1 and 2 respectively. The FloatingPoint sort + * of the resulting expression is automatically determined from the bit-vector sizes + * of the arguments. + * @throws Z3Exception + **/ + public FPExpr mkFP(BitVecExpr sgn, BitVecExpr sig, BitVecExpr exp) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaFp(nCtx(), sgn.getNativeObject(), sig.getNativeObject(), exp.getNativeObject())); + } + + /** + * Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. + * @param bv">bit-vector value (of size m). + * @param s FloatingPoint sort (ebits+sbits == m) + * Remarks: + * Produces a term that represents the conversion of a bit-vector term bv to a + * floating-point term of sort s. The bit-vector size of bv (m) must be equal + * to ebits+sbits of s. The format of the bit-vector is as defined by the + * IEEE 754-2008 interchange format. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(BitVecExpr bv, FPSort s) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpBv(nCtx(), bv.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a FloatingPoint term into another term of different FloatingPoint sort. + * @param rm RoundingMode term. + * @param t FloatingPoint term. + * @param s FloatingPoint sort. + * Remarks: + * Produces a term that represents the conversion of a floating-point term t to a + * floating-point term of sort s. If necessary, the result will be rounded according + * to rounding mode rm. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPRMExpr rm, FPExpr t, FPSort s) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpFloat(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a term of real sort into a term of FloatingPoint sort. + * @param rm RoundingMode term. + * @param t term of Real sort. + * @param s FloatingPoint sort. + * Remarks: + * Produces a term that represents the conversion of term t of real sort into a + * floating-point term of sort s. If necessary, the result will be rounded according + * to rounding mode rm. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPRMExpr rm, RealExpr t, FPSort s) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpReal(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. + * @param rm RoundingMode term. + * @param t term of bit-vector sort. + * @param s FloatingPoint sort. + * @param signed flag indicating whether t is interpreted as signed or unsigned bit-vector. + * Remarks: + * Produces a term that represents the conversion of the bit-vector term t into a + * floating-point term of sort s. The bit-vector t is taken to be in signed + * 2's complement format (when signed==true, otherwise unsigned). If necessary, the + * result will be rounded according to rounding mode rm. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPRMExpr rm, BitVecExpr t, FPSort s, boolean signed) throws Z3Exception + { + if (signed) + return new FPExpr(this, Native.mkFpaToFpSigned(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + else + return new FPExpr(this, Native.mkFpaToFpUnsigned(nCtx(), rm.getNativeObject(), t.getNativeObject(), s.getNativeObject())); + } + + /** + * Conversion of a floating-point number to another FloatingPoint sort s. + * @param s FloatingPoint sort + * @param rm floating-point rounding mode term + * @param t floating-point term + * Remarks: + * Produces a term that represents the conversion of a floating-point term t to a different + * FloatingPoint sort s. If necessary, rounding according to rm is applied. + * @throws Z3Exception + **/ + public FPExpr mkFPToFP(FPSort s, FPRMExpr rm, FPExpr t) throws Z3Exception + { + return new FPExpr(this, Native.mkFpaToFpFloat(nCtx(), s.getNativeObject(), rm.getNativeObject(), t.getNativeObject())); + } + + /** + * Conversion of a floating-point term into a bit-vector. + * @param rm RoundingMode term. + * @param t FloatingPoint term + * @param sz Size of the resulting bit-vector. + * @param signed Indicates whether the result is a signed or unsigned bit-vector. + * Remarks: + * Produces a term that represents the conversion of the floating-poiunt term t into a + * bit-vector term of size sz in 2's complement format (signed when signed==true). If necessary, + * the result will be rounded according to rounding mode rm. + * @throws Z3Exception + **/ + public BitVecExpr mkFPToBV(FPRMExpr rm, FPExpr t, int sz, boolean signed) throws Z3Exception + { + if (signed) + return new BitVecExpr(this, Native.mkFpaToSbv(nCtx(), rm.getNativeObject(), t.getNativeObject(), sz)); + else + return new BitVecExpr(this, Native.mkFpaToUbv(nCtx(), rm.getNativeObject(), t.getNativeObject(), sz)); + } + + /** + * Conversion of a floating-point term into a real-numbered term. + * @param t FloatingPoint term + * Remarks: + * Produces a term that represents the conversion of the floating-poiunt term t into a + * real number. Note that this type of conversion will often result in non-linear + * constraints over real terms. + * @throws Z3Exception + **/ + public RealExpr mkFPToReal(FPExpr t) throws Z3Exception + { + return new RealExpr(this, Native.mkFpaToReal(nCtx(), t.getNativeObject())); + } + + /** + * Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. + * @param t FloatingPoint term. + * Remarks: + * The size of the resulting bit-vector is automatically determined. Note that + * IEEE 754-2008 allows multiple different representations of NaN. This conversion + * knows only one NaN and it will always produce the same bit-vector represenatation of + * that NaN. + * @throws Z3Exception + **/ + public BitVecExpr mkFPToIEEEBV(FPExpr t) throws Z3Exception + { + return new BitVecExpr(this, Native.mkFpaToIeeeBv(nCtx(), t.getNativeObject())); + } + + /** + * Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. + * @param rm RoundingMode term. + * @param sig Significand term of Real sort. + * @param exp Exponent term of Int sort. + * @param s FloatingPoint sort. + * Remarks: + * Produces a term that represents the conversion of sig * 2^exp into a + * floating-point term of sort s. If necessary, the result will be rounded + * according to rounding mode rm. + * @throws Z3Exception + **/ + + public BitVecExpr mkFPToFP(FPRMExpr rm, RealExpr sig, IntExpr exp, FPSort s) throws Z3Exception + { + return new BitVecExpr(this, Native.mkFpaToFpRealInt(nCtx(), rm.getNativeObject(), sig.getNativeObject(), exp.getNativeObject(), s.getNativeObject())); + } + + /** * Wraps an AST. * Remarks: This function is used for transitions between diff --git a/src/api/java/FPNum.java b/src/api/java/FPNum.java index f2c9b7f98..037fe63a4 100644 --- a/src/api/java/FPNum.java +++ b/src/api/java/FPNum.java @@ -31,8 +31,6 @@ public class FPNum extends FPExpr if (Native.fpaGetNumeralSign(getContext().nCtx(), getNativeObject(), res) ^ true) throw new Z3Exception("Sign is not a Boolean value"); return res.value != 0; - - } /** From 84ed1c19a077a3ef607b427062fa12b26fa80632 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:20:43 +0000 Subject: [PATCH 486/507] Bugfixes for the Java FPA API Merge branch 'unstable' of https://git01.codeplex.com/z3 into unstable Signed-off-by: Christoph M. Wintersteiger --- src/api/java/AST.java | 12 ++++-------- src/api/java/Expr.java | 8 ++++++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/api/java/AST.java b/src/api/java/AST.java index 30d303d6c..0cdfd025c 100644 --- a/src/api/java/AST.java +++ b/src/api/java/AST.java @@ -227,10 +227,8 @@ public class AST extends Z3Object void incRef(long o) throws Z3Exception { // Console.WriteLine("AST IncRef()"); - if (getContext() == null) - throw new Z3Exception("inc() called on null context"); - if (o == 0) - throw new Z3Exception("inc() called on null AST"); + if (getContext() == null || o == 0) + return; getContext().ast_DRQ().incAndClear(getContext(), o); super.incRef(o); } @@ -238,10 +236,8 @@ public class AST extends Z3Object void decRef(long o) throws Z3Exception { // Console.WriteLine("AST DecRef()"); - if (getContext() == null) - throw new Z3Exception("dec() called on null context"); - if (o == 0) - throw new Z3Exception("dec() called on null AST"); + if (getContext() == null || o == 0) + return; getContext().ast_DRQ().add(o); super.decRef(o); } diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java index f94eb12cb..762a4b672 100644 --- a/src/api/java/Expr.java +++ b/src/api/java/Expr.java @@ -2161,6 +2161,10 @@ public class Expr extends AST return new RatNum(ctx, obj); case Z3_BV_SORT: return new BitVecNum(ctx, obj); + case Z3_FLOATING_POINT_SORT: + return new FPNum(ctx, obj); + case Z3_ROUNDING_MODE_SORT: + return new FPRMNum(ctx, obj); default: ; } } @@ -2179,6 +2183,10 @@ public class Expr extends AST return new ArrayExpr(ctx, obj); case Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); + case Z3_FLOATING_POINT_SORT: + return new FPExpr(ctx, obj); + case Z3_ROUNDING_MODE_SORT: + return new FPRMExpr(ctx, obj); default: ; } From 826d2959813cfc97ebe6285159b83fd2f9c184b6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:29:31 +0000 Subject: [PATCH 487/507] build fixes and removed unused variables --- src/api/api_fpa.cpp | 4 +--- src/ast/fpa/fpa2bv_converter.cpp | 2 -- src/smt/theory_fpa.h | 4 ++-- src/tactic/sls/sls_engine.cpp | 2 ++ 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 67ffe12d9..96c3e2eb6 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -723,8 +723,7 @@ extern "C" { LOG_Z3_fpa_get_numeral_exponent_string(c, t); RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); - mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); - unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); @@ -749,7 +748,6 @@ extern "C" { RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); - unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index f8f283ee6..9f0591134 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2283,7 +2283,6 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); - unsigned f_sz = sbits + ebits; unsigned bv_sz = m_bv_util.get_bv_size(x); SASSERT(m_bv_util.get_bv_size(rm) == 3); @@ -2425,7 +2424,6 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con unsigned ebits = m_util.get_ebits(f->get_range()); unsigned sbits = m_util.get_sbits(f->get_range()); - unsigned f_sz = sbits + ebits; unsigned bv_sz = m_bv_util.get_bv_size(x); SASSERT(m_bv_util.get_bv_size(rm) == 3); diff --git a/src/smt/theory_fpa.h b/src/smt/theory_fpa.h index 33733d7d9..c3d574179 100644 --- a/src/smt/theory_fpa.h +++ b/src/smt/theory_fpa.h @@ -97,7 +97,7 @@ namespace smt { public: fpa_value_proc(theory_fpa * th, unsigned ebits, unsigned sbits) : - m_th(*th), m_fu(th->m_fpa_util), m_bu(th->m_bv_util), m(th->get_manager()), + m_th(*th), m(th->get_manager()), m_fu(th->m_fpa_util), m_bu(th->m_bv_util), m_ebits(ebits), m_sbits(sbits) {} virtual ~fpa_value_proc() {} @@ -120,7 +120,7 @@ namespace smt { public: fpa_rm_value_proc(theory_fpa * th) : - m_th(*th), m_fu(th->m_fpa_util), m_bu(th->m_bv_util), m(th->get_manager()) {} + m_th(*th), m(th->get_manager()), m_fu(th->m_fpa_util), m_bu(th->m_bv_util) {} void add_dependency(enode * e) { m_deps.push_back(model_value_dependency(e)); } diff --git a/src/tactic/sls/sls_engine.cpp b/src/tactic/sls/sls_engine.cpp index 162866ed6..98f659fe0 100644 --- a/src/tactic/sls/sls_engine.cpp +++ b/src/tactic/sls/sls_engine.cpp @@ -16,6 +16,8 @@ Author: Notes: --*/ +#include // Need DBL_MAX + #include"map.h" #include"ast_smt2_pp.h" #include"ast_pp.h" From 25011bc034164432c5c30b06632416398524242d Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:35:29 +0000 Subject: [PATCH 488/507] eliminated unused variables --- src/smt/theory_fpa.cpp | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index ac9bd5141..e76594ded 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -153,9 +153,9 @@ namespace smt { r = m_bu.is_numeral(values[2], sig_r, bv_sz); SASSERT(r && bv_sz == m_sbits - 1); - SASSERT(sgn_r.to_mpq().denominator() == mpz(1)); - SASSERT(exp_r.to_mpq().denominator() == mpz(1)); - SASSERT(sig_r.to_mpq().denominator() == mpz(1)); + SASSERT(mpzm.is_one(sgn_r.to_mpq().denominator())); + SASSERT(mpzm.is_one(exp_r.to_mpq().denominator())); + SASSERT(mpzm.is_one(sig_r.to_mpq().denominator())); mpzm.set(sgn_z, sgn_r.to_mpq().numerator()); mpzm.set(exp_z, exp_r.to_mpq().numerator()); @@ -187,8 +187,7 @@ namespace smt { TRACE("t_fpa_detail", for (unsigned i = 0; i < values.size(); i++) tout << "value[" << i << "] = " << mk_ismt2_pp(values[i], m) << std::endl;); - app * result = 0; - sort * s = m.get_sort(values[0]); + app * result = 0; unsigned bv_sz; rational val(0); @@ -215,7 +214,6 @@ namespace smt { app_ref theory_fpa::wrap(expr * e) { SASSERT(!m_fpa_util.is_wrap(e)); ast_manager & m = get_manager(); - context & ctx = get_context(); sort * e_srt = m.get_sort(e); func_decl *w; @@ -245,8 +243,7 @@ namespace smt { app_ref theory_fpa::unwrap(expr * e, sort * s) { SASSERT(!m_fpa_util.is_unwrap(e)); - ast_manager & m = get_manager(); - context & ctx = get_context(); + ast_manager & m = get_manager(); sort * bv_srt = m.get_sort(e); func_decl *u; @@ -276,8 +273,7 @@ namespace smt { expr_ref theory_fpa::convert_term(expr * e) { ast_manager & m = get_manager(); - - context & ctx = get_context(); + expr_ref e_conv(m), res(m); proof_ref pr(m); m_rw(e, e_conv); @@ -304,8 +300,7 @@ namespace smt { expr_ref theory_fpa::convert_conversion_term(expr * e) { /* This is for the conversion functions fp.to_* */ - ast_manager & m = get_manager(); - context & ctx = get_context(); + ast_manager & m = get_manager(); expr_ref res(m); proof_ref pr(m); @@ -326,7 +321,6 @@ namespace smt { } else { SASSERT(m_fpa_util.is_float(srt)); - unsigned ebits = m_fpa_util.get_ebits(srt); unsigned sbits = m_fpa_util.get_sbits(srt); expr_ref bv(m); bv = to_app(e)->get_arg(0); @@ -342,7 +336,6 @@ namespace smt { expr_ref theory_fpa::convert(expr * e) { ast_manager & m = get_manager(); - context & ctx = get_context(); expr_ref res(m); if (m_conversions.contains(e)) { @@ -524,10 +517,7 @@ namespace smt { TRACE("t_fpa_detail", tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " = " << mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); - context & ctx = get_context(); fpa_util & fu = m_fpa_util; - bv_util & bu = m_bv_util; - mpf_manager & mpfm = fu.fm(); expr_ref xe(m), ye(m); xe = get_enode(x)->get_owner(); @@ -575,9 +565,6 @@ namespace smt { TRACE("t_fpa_detail", tout << mk_ismt2_pp(get_enode(x)->get_owner(), m) << " != " << mk_ismt2_pp(get_enode(y)->get_owner(), m) << std::endl;); - context & ctx = get_context(); - mpf_manager & mpfm = m_fpa_util.fm(); - expr_ref xe(m), ye(m); xe = get_enode(x)->get_owner(); ye = get_enode(y)->get_owner(); @@ -588,13 +575,15 @@ namespace smt { return; } + fpa_util & fu = m_fpa_util; + expr_ref xc(m), yc(m); xc = convert(xe); yc = convert(ye); expr_ref c(m); - if (m_fpa_util.is_float(xe) && m_fpa_util.is_float(ye)) + if (fu.is_float(xe) && fu.is_float(ye)) { expr *x_sgn, *x_sig, *x_exp; m_converter.split_fp(xc, x_sgn, x_exp, x_sig); @@ -645,12 +634,9 @@ namespace smt { ast_manager & m = get_manager(); TRACE("t_fpa", tout << "relevant_eh for: " << mk_ismt2_pp(n, m) << "\n";); - mpf_manager & mpfm = m_fpa_util.fm(); - unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); + mpf_manager & mpfm = m_fpa_util.fm(); if (m_fpa_util.is_float(n) || m_fpa_util.is_rm(n)) { - sort * s = m.get_sort(n); - if (!m_fpa_util.is_unwrap(n)) { expr_ref wrapped(m), c(m); wrapped = wrap(n); @@ -661,7 +647,6 @@ namespace smt { assert_cnstr(c); } else if (m_fpa_util.is_numeral(n, val)) { - unsigned sz = val.get().get_ebits() + val.get().get_sbits(); expr_ref bv_val_e(m); bv_val_e = convert(n); SASSERT(is_app(bv_val_e)); From 560fa79d1ff217326e7c63fce7eda69729691539 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:36:41 +0000 Subject: [PATCH 489/507] eliminated unused variable --- src/smt/theory_fpa.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/smt/theory_fpa.cpp b/src/smt/theory_fpa.cpp index e76594ded..45cd60332 100644 --- a/src/smt/theory_fpa.cpp +++ b/src/smt/theory_fpa.cpp @@ -111,7 +111,6 @@ namespace smt { tout << "value[" << i << "] = " << mk_ismt2_pp(values[i], m) << std::endl;); mpf_manager & mpfm = m_fu.fm(); - unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); app * result; From 880cbb936e14d9535de51644f24dff343cfd1eaf Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:37:49 +0000 Subject: [PATCH 490/507] fixed portability issue --- src/ast/fpa/fpa2bv_converter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 9f0591134..bdaf2017e 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -2467,7 +2467,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con expr_ref sig_rest(m); sig_4 = m_bv_util.mk_extract(bv_sz - 1, bv_sz - sig_sz + 1, shifted_sig); // one short sig_rest = m_bv_util.mk_extract(bv_sz - sig_sz, 0, shifted_sig); - sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest); + sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, sig_rest.get()); sig_4 = m_bv_util.mk_concat(sig_4, sticky); } else { From 0ab54b9e0c3321c4dfca543b890b63df1576fdd2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Wed, 21 Jan 2015 19:43:26 +0000 Subject: [PATCH 491/507] bugfix for FPA numerals Signed-off-by: Christoph M. Wintersteiger --- src/api/api_numeral.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index d5a25dfc2..277e80c20 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -68,8 +68,8 @@ extern "C" { (' ' == *m) || ('\n' == *m) || ('.' == *m) || ('e' == *m) || ('E' == *m) || - (('p' == *m) && is_float) || - (('P' == *m)) && is_float)) { + ('p' == *m && is_float) || + ('P' == *m && is_float))) { SET_ERROR_CODE(Z3_PARSER_ERROR); return 0; } From c3ff342bea64d6868e615c0c51766d82e67ce5a6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 22 Jan 2015 18:31:30 +0000 Subject: [PATCH 492/507] Bugfixes for the Python FPA API Signed-off-by: Christoph M. Wintersteiger --- src/api/python/z3.py | 328 ++++++++++++++++++++++++------------ src/api/python/z3printer.py | 23 ++- 2 files changed, 229 insertions(+), 122 deletions(-) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index fd3d1bdc8..414aeb2af 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -7509,7 +7509,7 @@ class FPSortRef(SortRef): def sbits(self): """Retrieves the number of bits reserved for the exponent in the FloatingPoint sort `self`. - >>> b = FloatingPointSort(8, 24) + >>> b = FPSort(8, 24) >>> b.sbits() 24 """ @@ -7520,9 +7520,9 @@ class FPSortRef(SortRef): >>> b = FPSort(8, 24) >>> b.cast(1.0) - 1.0 + 1 >>> b.cast(1.0).sexpr() - '1.0' + '(fp #b0 #x7f #b00000000000000000000000)' """ if is_expr(val): if __debug__: @@ -7579,7 +7579,7 @@ class FPRMSortRef(SortRef): def is_fp_sort(s): """Return True if `s` is a Z3 floating-point sort. - >>> is_fp_sort(FloatingPointSort(8, 24)) + >>> is_fp_sort(FPSort(8, 24)) True >>> is_fp_sort(IntSort()) False @@ -7591,10 +7591,10 @@ def is_fprm_sort(s): >>> is_fprm_sort(FPSort(8, 24)) False - >>> is_fprm_sort() - False + >>> is_fprm_sort(RNE().sort()) + True """ - return isinstance(s, FPSortRef) + return isinstance(s, FPRMSortRef) ### FP Expressions @@ -7606,15 +7606,15 @@ class FPRef(ExprRef): >>> x = FP('1.0', FPSort(8, 24)) >>> x.sort() - (_ FloatingPoint 8 24) - >>> x.sort() == FloatingPointSort(8, 24) + FPSort(8, 24) + >>> x.sort() == FPSort(8, 24) True """ return FPSortRef(Z3_get_sort(self.ctx_ref(), self.as_ast()), self.ctx) def ebits(self): """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`. - >>> b = FloatingPointSort(8, 24) + >>> b = FPSort(8, 24) >>> b.ebits() 8 """ @@ -7622,7 +7622,7 @@ class FPRef(ExprRef): def sbits(self): """Retrieves the number of bits reserved for the exponent in the FloatingPoint expression `self`. - >>> b = FloatingPointSort(8, 24) + >>> b = FPSort(8, 24) >>> b.sbits() 24 """ @@ -7651,12 +7651,12 @@ class FPRef(ExprRef): def __add__(self, other): """Create the Z3 expression `self + other`. - >>> x = FP('x', 8, 24) - >>> y = FP('y', 8, 24) + >>> x = FP('x', FPSort(8, 24)) + >>> y = FP('y', FPSort(8, 24)) >>> x + y x + y >>> (x + y).sort() - FloatingPoint(8 24) + FPSort(8, 24) """ a, b = z3._coerce_exprs(self, other) return fpAdd(_dflt_rm(), self, other) @@ -7666,7 +7666,7 @@ class FPRef(ExprRef): >>> x = FP('x', FPSort(8, 24)) >>> 10 + x - 10 + x + 1.25*(2**3) + x """ a, b = _coerce_exprs(self, other) return fpAdd(_dflt_rm(), other, self) @@ -7674,12 +7674,12 @@ class FPRef(ExprRef): def __sub__(self, other): """Create the Z3 expression `self - other`. - >>> x = FP('x', 8, 24) - >>> y = FP('y', 8, 24) + >>> x = FP('x', FPSort(8, 24)) + >>> y = FP('y', FPSort(8, 24)) >>> x - y x - y >>> (x - y).sort() - FloatingPoint(8 24) + FPSort(8, 24) """ a, b = z3._coerce_exprs(self, other) return fpSub(_dflt_rm(), self, other) @@ -7689,7 +7689,7 @@ class FPRef(ExprRef): >>> x = FP('x', FPSort(8, 24)) >>> 10 - x - 10 - x + 1.25*(2**3) - x """ a, b = _coerce_exprs(self, other) return fpSub(_dflt_rm(), other, self) @@ -7697,22 +7697,27 @@ class FPRef(ExprRef): def __mul__(self, other): """Create the Z3 expression `self * other`. - >>> x = FP('x', 8, 24) - >>> y = FP('y', 8, 24) + >>> x = FP('x', FPSort(8, 24)) + >>> y = FP('y', FPSort(8, 24)) >>> x * y x * y >>> (x * y).sort() - FloatingPoint(8 24) + FPSort(8, 24) + >>> 10 * y + 1.25*(2**3) * y """ a, b = z3._coerce_exprs(self, other) return fpMul(_dflt_rm(), self, other) - def __rmul_(self, other): + def __rmul__(self, other): """Create the Z3 expression `other * self`. >>> x = FP('x', FPSort(8, 24)) - >>> 10 * x - 10 * x + >>> y = FP('y', FPSort(8, 24)) + >>> x * y + x * y + >>> x * 10 + x * 1.25*(2**3) """ a, b = _coerce_exprs(self, other) return fpMul(_dflt_rm(), other, self) @@ -7792,7 +7797,12 @@ def RTZ(ctx=None): def is_fprm(a): """Return `True` if `a` is a Z3 floating-point rounding mode expression. - >>> rm = ? + >>> rm = RNE() + >>> is_fprm(rm) + True + >>> rm = 1.0 + >>> is_fprm(rm) + False """ return isinstance(a, FPRMRef) @@ -7814,7 +7824,65 @@ class FPNumRef(FPRef): def isNegative(self): k = self.decl().kind() - return (self.num_args() == 0 and (k == Z3_OP_FPA_MINUS_INF or k == Z3_OP_FPA_MINUS_ZERO)) or (self.num_args() == 3 and self.arg(0) == BitVecVal(1)) + return (self.num_args() == 0 and (k == Z3_OP_FPA_MINUS_INF or k == Z3_OP_FPA_MINUS_ZERO)) or (self.sign() == True) + + """ + The sign of the numeral + + >>> x = FPNumRef(+1.0, FPSort(8, 24)) + >>> x.sign() + False + >>> x = FPNumRef(-1.0, FPSort(8, 24)) + >>> x.sign() + True + """ + def sign(self): + l = (ctypes.c_int)() + if Z3_fpa_get_numeral_sign(self.ctx.ref(), self.as_ast(), byref(l)) == False: + raise Z3Exception("error retrieving the sign of a numeral.") + return l.value != 0 + + """ + The significand of the numeral + + >>> x = FPNumRef(2.5, FPSort(8, 24)) + 1.25 + """ + def significand(self): + return Z3_fpa_get_numeral_significand_string(self.ctx.ref(), self.as_ast()) + + """ + The exponent of the numeral + + >>> x = FPNumRef(2.5, FPSort(8, 24)) + >>> + 1 + """ + def exponent(self): + return Z3_fpa_get_numeral_exponent_string(self.ctx.ref(), self.as_ast()) + + """ + The exponent of the numeral as a long + + >>> x = FPNumRef(2.5, FPSort(8, 24)) + 1 + """ + def exponent_as_long(self): + ptr = (ctypes.c_longlong * 1)() + if not Z3_fpa_get_numeral_exponent_int64(self.ctx.ref(), self.as_ast(), ptr): + raise Z3Exception("error retrieving the exponent of a numeral.") + return ptr[0] + + """ + The string representation of the numeral + + >>> x = FPNumRef(20, FPSort(8, 24)) + 1.25*(2**4) + """ + def as_string(self): + s = Z3_fpa_get_numeral_string(self.ctx.ref(), self.as_ast()) + return ("FPVal(%s, %s)" % (s, FPSortRef(self.sort()).as_string())) + def _to_fpnum(num, ctx=None): if isinstance(num, FPNum): @@ -7843,7 +7911,7 @@ def is_fp_value(a): False >>> b = FPVal(1.0, FPSort(8, 24)) >>> b - 1.0p0 + 1 >>> is_fp_value(b) True """ @@ -7855,9 +7923,9 @@ def FPSort(ebits, sbits, ctx=None): >>> Single = FPSort(8, 24) >>> Double = FPSort(11, 53) >>> Single - (_ FloatingPoint 8 24) + FPSort(8, 24) >>> x = Const('x', Single) - >>> eq(x, FP('x', 8, 24)) + >>> eq(x, FP('x', FPSort(8, 24))) True """ ctx = z3._get_ctx(ctx) @@ -7911,11 +7979,17 @@ def fpZero(s, negative): def FPVal(sig, exp=None, fps=None, ctx=None): """Return a floating-point value of value `val` and sort `fps`. If `ctx=None`, then the global context is used. - >>> v = FPVal(1.0, FPSort(8, 24))) + >>> v = FPVal(20.0, FPSort(8, 24)) >>> v - 1.0 - >>> print("0x%.8x" % v.as_long()) - 0x0000000a + 1.25*(2**4) + >>> print("0x%.8x" % v.exponent_as_long()) + 0x00000004 + >>> v = FPVal(2.25, FPSort(8, 24)) + >>> v + 1.125*(2**1) + >>> v = FPVal(-2.25, FPSort(8, 24)) + >>> v + -1.125*(2**1) """ ctx = _get_ctx(ctx) if is_fp_sort(exp): @@ -7923,7 +7997,7 @@ def FPVal(sig, exp=None, fps=None, ctx=None): exp = None elif fps == None: fps = _dflt_fps(ctx) - _z3_assert(is_fp_sort(fps), "sort mismatch") + _z3_assert(is_fp_sort(fps), "sort mismatch") if exp == None: exp = 0 val = _to_float_str(sig) @@ -7942,7 +8016,7 @@ def FP(name, fpsort, ctx=None): >>> x.ebits() 8 >>> x.sort() - (_ FloatingPoint 8 24) + FPSort(8, 24) >>> word = FPSort(8, 24) >>> x2 = FP('x', word) >>> eq(x, x2) @@ -7975,17 +8049,28 @@ def fpAbs(a): """Create a Z3 floating-point absolute value expression. >>> s = FPSort(8, 24) - >>> rm = FPRM.RNE + >>> rm = RNE() >>> x = FPVal(1.0, s) >>> fpAbs(x) - 1.0 - >>> x = FPVal(-1.0, s) - >>> fpAbs(x) - 1.0 + fpAbs(1) + >>> y = FPVal(-20.0, s) + >>> y + -1.25*(2**4) + >>> fpAbs(y) + fpAbs(-1.25*(2**4)) + >>> fpAbs(-1.25*(2**4)) + fpAbs(-1.25*(2**4)) >>> fpAbs(x).sort() - FloatingPoint(8, 24) + FPSort(8, 24) """ - if __debug__: + ctx = None + if not is_expr(a): + ctx =_get_ctx(ctx) + s = get_default_fp_sort(ctx) + a = FPVal(a, s) + else: + ctx = a.ctx + if __debug__: _z3_assert(is_fp(a), "First argument must be Z3 floating-point expression") return FPRef(Z3_mk_fpa_abs(a.ctx_ref(), a.as_ast()), a.ctx) @@ -7993,13 +8078,20 @@ def fpNeg(a): """Create a Z3 floating-point addition expression. >>> s = FPSort(8, 24) - >>> rm = FPRM.RNE + >>> rm = RNE() >>> x = FP('x', s) - >>> y = FP('y', s) - fp.add(rm, x, y) - >>> fp.add(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpNeg(x) + -x + >>> fpNeg(x).sort() + FPSort(8, 24) """ + ctx = None + if not is_expr(a): + ctx =_get_ctx(ctx) + s = get_default_fp_sort(ctx) + a = FPVal(a, s) + else: + ctx = a.ctx if __debug__: _z3_assert(is_fp(a), "First argument must be Z3 floating-point expression") return FPRef(Z3_mk_fpa_neg(a.ctx_ref(), a.as_ast()), a.ctx) @@ -8008,79 +8100,88 @@ def fpAdd(rm, a, b): """Create a Z3 floating-point addition expression. >>> s = FPSort(8, 24) - >>> rm = FPRM.RNE + >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) - fp.add(rm, x, y) - >>> fp.add(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpAdd(rm, x, y) + fpAdd(RNE(), x, y) + >>> fpAdd(rm, x, y).sort() + FPSort(8, 24) """ if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_add(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) def fpSub(rm, a, b): """Create a Z3 floating-point subtraction expression. >>> s = FPSort(8, 24) - >>> rm = FPRM.RNE + >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) - fp.add(rm, x, y) - >>> fp.add(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpSub(rm, x, y) + fpSub(RNE(), x, y) + >>> fpSub(rm, x, y).sort() + FPSort(8, 24) """ if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_sub(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) def fpMul(rm, a, b): """Create a Z3 floating-point multiplication expression. >>> s = FPSort(8, 24) - >>> rm = FPRM.RNE + >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) - fp.add(rm, x, y) - >>> fp.add(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpMul(rm, x, y) + fpMul(RNE(), x, y) + >>> fpMul(rm, x, y).sort() + FPSort(8, 24) """ if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_mul(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) def fpDiv(rm, a, b): """Create a Z3 floating-point divison expression. >>> s = FPSort(8, 24) - >>> rm = FPRM.RNE + >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) - fpAdd(rm, x, y) - >>> fp.add(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpDiv(rm, x, y) + fpDiv(RNE(), x, y) + >>> fpDiv(rm, x, y).sort() + FPSort(8, 24) """ if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a) and is_fp(b), "Second and third argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_div(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast()), rm.ctx) def fpRem(a, b): """Create a Z3 floating-point remainder expression. >>> s = FPSort(8, 24) - >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) + >>> fpRem(x, y) fpRem(x, y) - >>> fpRem(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpRem(x, y).sort() + FPSort(8, 24) """ if __debug__: - _z3_assert(is_fp(a) and is_fp(b), "Both arguments must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_rem(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) def fpMin(a, b): @@ -8090,12 +8191,14 @@ def fpMin(a, b): >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) + >>> fpMin(x, y) fpMin(x, y) - >>> fpMin(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpMin(x, y).sort() + FPSort(8, 24) """ if __debug__: - _z3_assert(is_fp(a) and is_fp(b), "Both arguments must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_min(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) def fpMax(a, b): @@ -8105,12 +8208,14 @@ def fpMax(a, b): >>> rm = RNE() >>> x = FP('x', s) >>> y = FP('y', s) - fpMin(x, y) - >>> fpMin(rm, x, y).sort() - FloatingPoint(8, 24) + >>> fpMax(x, y) + fpMax(x, y) + >>> fpMax(x, y).sort() + FPSort(8, 24) """ if __debug__: - _z3_assert(is_fp(a) and is_fp(b), "Both arguments must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b), "Second or third argument must be a Z3 floating-point expression") + a, b = _coerce_exprs(a, b) return FPRef(Z3_mk_fpa_max(a.ctx_ref(), a.as_ast(), b.as_ast()), a.ctx) def fpFMA(rm, a, b, c): @@ -8118,23 +8223,38 @@ def fpFMA(rm, a, b, c): """ if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a) and is_fp(b) and is_fp(c), "Second, third, and fourth argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a) or is_fp(b) or is_fp(c), "Second, third, or fourth argument must be a Z3 floating-point expression") + a, b, c = _coerce_expr_list([a, b, c]) return FPRef(Z3_mk_fpa_fma(rm.ctx_ref(), rm.as_ast(), a.as_ast(), b.as_ast(), c.as_ast()), rm.ctx) def fpSqrt(rm, a): """Create a Z3 floating-point square root expression. """ + ctx = None + if not is_expr(a): + ctx =_get_ctx(ctx) + s = get_default_fp_sort(ctx) + a = FPVal(a, s) + else: + ctx = a.ctx if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a), "Second argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expressions") return FPRef(Z3_mk_fpa_sqrt(rm.ctx_ref(), rm.as_ast(), a.as_ast()), rm.ctx) def fpRoundToIntegral(rm, a): """Create a Z3 floating-point roundToIntegral expression. """ + ctx = None + if not is_expr(a): + ctx =_get_ctx(ctx) + s = get_default_fp_sort(ctx) + a = FPVal(a, s) + else: + ctx = a.ctx if __debug__: _z3_assert(is_fprm(rm), "First argument must be a Z3 floating-point rounding mode expression") - _z3_assert(is_fp(a), "Second argument must be Z3 floating-point expressions") + _z3_assert(is_fp(a), "Second argument must be a Z3 floating-point expressions") return FPRef(Z3_mk_fpa_round_to_integral(rm.ctx_ref(), rm.as_ast(), a.as_ast()), rm.ctx) def fpIsNaN(a): @@ -8195,11 +8315,9 @@ def fpLT(a, b): >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpLT(x, y) - x <= y + x < y >>> (x <= y).sexpr() - '?' - >>> fpLT(x, y).sexpr() - '?' + '(fp.leq x y)' """ _check_fp_args(a, b) a, b = _coerce_exprs(a, b) @@ -8212,9 +8330,7 @@ def fpLEQ(a, b): >>> fpLEQ(x, y) x <= y >>> (x <= y).sexpr() - '?' - >>> fpLEQ(x, y).sexpr() - '?' + '(fp.leq x y)' """ _check_fp_args(a, b) a, b = _coerce_exprs(a, b) @@ -8225,11 +8341,9 @@ def fpGT(a, b): >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpGT(x, y) - x <= y - >>> (x <= y).sexpr() - '?' - >>> fpGT(x, y).sexpr() - '?' + x > y + >>> (x > y).sexpr() + '(fp.gt x y)' """ _check_fp_args(a, b) a, b = _coerce_exprs(a, b) @@ -8240,12 +8354,12 @@ def fpGEQ(a, b): """Create the Z3 floating-point expression `other <= self`. >>> x, y = FPs('x y', FPSort(8, 24)) - >>> fp_geq(x, y) - x <= y - >>> (x <= y).sexpr() - '?' - >>> fp_geq(x, y).sexpr() - '?' + >>> x + y + x + y + >>> fpGEQ(x, y) + x >= y + >>> (x >= y).sexpr() + '(fp.geq x y)' """ _check_fp_args(a, b) a, b = _coerce_exprs(a, b) @@ -8256,11 +8370,9 @@ def fpEQ(a, b): >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpEQ(x, y) - x <= y - >>> (x <= y).sexpr() - '?' + fpEQ(x, y) >>> fpEQ(x, y).sexpr() - '?' + '(fp.eq x y)' """ _check_fp_args(a, b) a, b = _coerce_exprs(a, b) @@ -8271,11 +8383,9 @@ def fpNEQ(a, b): >>> x, y = FPs('x y', FPSort(8, 24)) >>> fpNEQ(x, y) - x <= y - >>> (x <= y).sexpr() - '?' - >>> fpNEQ(x, y).sexpr() - '?' + Not(fpEQ(x, y)) + >>> (x != y).sexpr() + '(not (fp.eq x y))' """ _check_fp_args(a, b) a, b = _coerce_exprs(a, b) diff --git a/src/api/python/z3printer.py b/src/api/python/z3printer.py index ac1607dda..242d72c0b 100644 --- a/src/api/python/z3printer.py +++ b/src/api/python/z3printer.py @@ -182,9 +182,6 @@ _infix_map = {} _unary_map = {} _infix_compact_map = {} -for (_k,_v) in _z3_op_to_fpa_normal_str.items(): - _z3_op_to_str[_k] = _v - for _k in _z3_infix: _infix_map[_k] = True for _k in _z3_unary: @@ -515,7 +512,7 @@ class Formatter: self.precision = 10 self.ellipses = to_format(_ellipses) self.max_visited = 10000 - self.fpa_pretty = False + self.fpa_pretty = True def pp_ellipses(self): return self.ellipses @@ -576,8 +573,8 @@ class Formatter: return to_format(a.as_string()) def pp_fprm_value(self, a): - z3._z3_assert(z3.is_fprm_value(a), 'expected FPRMNumRef') - if self.fpa_pretty and a.decl().kind() in _z3_op_to_fpa_pretty_str: + z3._z3_assert(z3.is_fprm_value(a), 'expected FPRMNumRef') + if self.fpa_pretty and (a.decl().kind() in _z3_op_to_fpa_pretty_str): return to_format(_z3_op_to_fpa_pretty_str.get(a.decl().kind())) else: return to_format(_z3_op_to_fpa_normal_str.get(a.decl().kind())) @@ -600,12 +597,12 @@ class Formatter: else: z3._z3_assert(z3.is_fp_value(a), 'expecting FP num ast') r = [] - sgn = c_long(0) + sgn = c_int(0) sgnb = Z3_fpa_get_numeral_sign(a.ctx_ref(), a.ast, byref(sgn)) sig = Z3_fpa_get_numeral_significand_string(a.ctx_ref(), a.ast) exp = Z3_fpa_get_numeral_exponent_string(a.ctx_ref(), a.ast) r.append(to_format('FPVal(')) - if not sgnb and sgn: + if sgnb and sgn.value != 0: r.append(to_format('-')) r.append(to_format(sig)) r.append(to_format('*(2**')) @@ -634,17 +631,17 @@ class Formatter: sgnb = Z3_fpa_get_numeral_sign(a.ctx_ref(), a.ast, byref(sgn)) sig = Z3_fpa_get_numeral_significand_string(a.ctx_ref(), a.ast) exp = Z3_fpa_get_numeral_exponent_string(a.ctx_ref(), a.ast) - if not sgnb and sgn != 0: + if sgnb and sgn.value != 0: r.append(to_format('-')) r.append(to_format(sig)) if (exp != '0'): r.append(to_format('*(2**')) r.append(to_format(exp)) - r.append(to_format(')')) + r.append(to_format(')')) return compose(r) - def pp_fp(self, a, d, xs): + def pp_fp(self, a, d, xs): z3._z3_assert(isinstance(a, z3.FPRef), "type mismatch") k = a.decl().kind() op = '?' @@ -653,7 +650,7 @@ class Formatter: elif k in _z3_op_to_fpa_normal_str: op = _z3_op_to_fpa_normal_str[k] elif k in _z3_op_to_str: - op = _z3_op_to_str[k] + op = _z3_op_to_str[k] n = a.num_args() @@ -1164,7 +1161,7 @@ def set_fpa_pretty(flag=True): for _k in _z3_fpa_infix: _infix_map[_k] = False - +set_fpa_pretty(True) def in_html_mode(): return isinstance(_Formatter, HTMLFormatter) From 034e4f469ee5aeb9e538d5dc9a2a38a12cde3811 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 22 Jan 2015 18:43:23 +0000 Subject: [PATCH 493/507] Fixed memory leak --- src/api/api_fpa.cpp | 5 ++++- src/util/mpf.h | 6 ++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 96c3e2eb6..d9f534499 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -696,6 +696,7 @@ extern "C" { RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); @@ -709,7 +710,9 @@ extern "C" { } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); - mpqm.set(q, mpfm.sig_normalized(val)); + scoped_mpz sn(mpzm); + mpfm.sig_normalized(val, sn); + mpqm.set(q, sn); mpqm.div(q, mpfm.m_powers2(sbits - 1), q); std::stringstream ss; mpqm.display_decimal(ss, q, sbits); diff --git a/src/util/mpf.h b/src/util/mpf.h index 599e8e743..39eb7330e 100644 --- a/src/util/mpf.h +++ b/src/util/mpf.h @@ -146,14 +146,12 @@ public: bool sgn(mpf const & x) const { return x.sign; } const mpz & sig(mpf const & x) const { return x.significand; } - mpz sig_normalized(mpf const & x) { + void sig_normalized(mpf const & x, mpz & res) { mpf t; set(t, x); unpack(t, true); - mpz r; - mpz_manager().set(r, t.significand); + mpz_manager().set(res, t.significand); del(t); - return r; } const mpf_exp_t & exp(mpf const & x) const { return x.exponent; } mpf_exp_t exp_normalized(mpf const & x) { From 0c2e2d78dd3f167a93080af5a6c39c46c9e8fa42 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 22 Jan 2015 18:52:28 +0000 Subject: [PATCH 494/507] renamed function to avoid compilation issues Signed-off-by: Christoph M. Wintersteiger --- src/api/api_context.h | 2 +- src/api/api_fpa.cpp | 162 ++++++++++++++++++++-------------------- src/api/api_numeral.cpp | 14 ++-- 3 files changed, 89 insertions(+), 89 deletions(-) diff --git a/src/api/api_context.h b/src/api/api_context.h index 6312b3f69..58394c028 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -118,7 +118,7 @@ namespace api { arith_util & autil() { return m_arith_util; } bv_util & bvutil() { return m_bv_util; } datalog::dl_decl_util & datalog_util() { return m_datalog_util; } - fpa_util & fpa_util() { return m_fpa_util; } + fpa_util & fpautil() { return m_fpa_util; } family_id get_basic_fid() const { return m_basic_fid; } family_id get_array_fid() const { return m_array_fid; } family_id get_arith_fid() const { return m_arith_fid; } diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index d9f534499..9d47e152a 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -29,7 +29,7 @@ extern "C" { LOG_Z3_mk_fpa_rounding_mode_sort(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_sort r = of_sort(ctx->fpa_util().mk_rm_sort()); + Z3_sort r = of_sort(ctx->fpautil().mk_rm_sort()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -40,7 +40,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_even()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_even()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -50,7 +50,7 @@ extern "C" { LOG_Z3_mk_fpa_rne(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_even()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_even()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -61,7 +61,7 @@ extern "C" { LOG_Z3_mk_fpa_round_nearest_ties_to_away(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_away()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_away()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -71,7 +71,7 @@ extern "C" { LOG_Z3_mk_fpa_rna(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_nearest_ties_to_away()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_away()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -82,7 +82,7 @@ extern "C" { LOG_Z3_mk_fpa_round_toward_positive(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_positive()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_positive()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -92,7 +92,7 @@ extern "C" { LOG_Z3_mk_fpa_rtp(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_positive()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_positive()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -103,7 +103,7 @@ extern "C" { LOG_Z3_mk_fpa_round_toward_negative(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_negative()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_negative()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -113,7 +113,7 @@ extern "C" { LOG_Z3_mk_fpa_rtn(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_negative()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_negative()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -124,7 +124,7 @@ extern "C" { LOG_Z3_mk_fpa_round_toward_zero(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_zero()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_zero()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -134,7 +134,7 @@ extern "C" { LOG_Z3_mk_fpa_rtz(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_toward_zero()); + Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_zero()); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -148,7 +148,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); } api::context * ctx = mk_c(c); - Z3_sort r = of_sort(ctx->fpa_util().mk_float_sort(ebits, sbits)); + Z3_sort r = of_sort(ctx->fpautil().mk_float_sort(ebits, sbits)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -190,7 +190,7 @@ extern "C" { LOG_Z3_mk_fpa_nan(c, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_nan(to_sort(s))); + Z3_ast r = of_ast(ctx->fpautil().mk_nan(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -200,8 +200,8 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_ninf(to_sort(s)) : - ctx->fpa_util().mk_pinf(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->fpautil().mk_ninf(to_sort(s)) : + ctx->fpautil().mk_pinf(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -211,8 +211,8 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->fpa_util().mk_nzero(to_sort(s)) : - ctx->fpa_util().mk_pzero(to_sort(s))); + Z3_ast r = of_ast(negative != 0 ? ctx->fpautil().mk_nzero(to_sort(s)) : + ctx->fpautil().mk_pzero(to_sort(s))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -222,7 +222,7 @@ extern "C" { LOG_Z3_mk_fpa_fp(c, sgn, sig, exp); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp))); + Z3_ast r = of_ast(ctx->fpautil().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -232,12 +232,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_float(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->fpa_util().fm()); - ctx->fpa_util().fm().set(tmp, - ctx->fpa_util().get_ebits(to_sort(ty)), - ctx->fpa_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpautil().fm()); + ctx->fpautil().fm().set(tmp, + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -247,9 +247,9 @@ extern "C" { LOG_Z3_mk_fpa_numeral_double(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->fpa_util().fm()); - ctx->fpa_util().fm().set(tmp, ctx->fpa_util().get_ebits(to_sort(ty)), ctx->fpa_util().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); + scoped_mpf tmp(ctx->fpautil().fm()); + ctx->fpautil().fm().set(tmp, ctx->fpautil().get_ebits(to_sort(ty)), ctx->fpautil().get_sbits(to_sort(ty)), v); + Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -259,12 +259,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_int(c, v, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->fpa_util().fm()); - ctx->fpa_util().fm().set(tmp, - ctx->fpa_util().get_ebits(to_sort(ty)), - ctx->fpa_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpautil().fm()); + ctx->fpautil().fm().set(tmp, + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -274,12 +274,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->fpa_util().fm()); - ctx->fpa_util().fm().set(tmp, - ctx->fpa_util().get_ebits(to_sort(ty)), - ctx->fpa_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpautil().fm()); + ctx->fpautil().fm().set(tmp, + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), sgn != 0, sig, exp); - Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -289,12 +289,12 @@ extern "C" { LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - scoped_mpf tmp(ctx->fpa_util().fm()); - ctx->fpa_util().fm().set(tmp, - ctx->fpa_util().get_ebits(to_sort(ty)), - ctx->fpa_util().get_sbits(to_sort(ty)), + scoped_mpf tmp(ctx->fpautil().fm()); + ctx->fpautil().fm().set(tmp, + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), sgn != 0, sig, exp); - Z3_ast r = of_ast(ctx->fpa_util().mk_value(tmp)); + Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -304,7 +304,7 @@ extern "C" { LOG_Z3_mk_fpa_abs(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_abs(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_abs(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -314,7 +314,7 @@ extern "C" { LOG_Z3_mk_fpa_neg(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_neg(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_neg(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -324,7 +324,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -334,7 +334,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -344,7 +344,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -354,7 +354,7 @@ extern "C" { LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -364,7 +364,7 @@ extern "C" { LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); + Z3_ast r = of_ast(ctx->fpautil().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -374,7 +374,7 @@ extern "C" { LOG_Z3_mk_fpa_sqrt(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_sqrt(to_expr(rm), to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_sqrt(to_expr(rm), to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -384,7 +384,7 @@ extern "C" { LOG_Z3_mk_fpa_rem(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_rem(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_rem(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -394,7 +394,7 @@ extern "C" { LOG_Z3_mk_fpa_round_to_integral(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_round_to_integral(to_expr(rm), to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_round_to_integral(to_expr(rm), to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -404,7 +404,7 @@ extern "C" { LOG_Z3_mk_fpa_min(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_min(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_min(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -414,7 +414,7 @@ extern "C" { LOG_Z3_mk_fpa_max(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_max(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_max(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -424,7 +424,7 @@ extern "C" { LOG_Z3_mk_fpa_leq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_le(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_le(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -434,7 +434,7 @@ extern "C" { LOG_Z3_mk_fpa_lt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_lt(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_lt(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -444,7 +444,7 @@ extern "C" { LOG_Z3_mk_fpa_geq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_ge(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_ge(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -454,7 +454,7 @@ extern "C" { LOG_Z3_mk_fpa_gt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_gt(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_gt(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -464,7 +464,7 @@ extern "C" { LOG_Z3_mk_fpa_eq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_float_eq(to_expr(t1), to_expr(t2))); + Z3_ast r = of_ast(ctx->fpautil().mk_float_eq(to_expr(t1), to_expr(t2))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -474,7 +474,7 @@ extern "C" { LOG_Z3_mk_fpa_is_normal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_normal(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_normal(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -484,7 +484,7 @@ extern "C" { LOG_Z3_mk_fpa_is_subnormal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_subnormal(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_subnormal(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -494,7 +494,7 @@ extern "C" { LOG_Z3_mk_fpa_is_zero(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_zero(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_zero(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -504,7 +504,7 @@ extern "C" { LOG_Z3_mk_fpa_is_infinite(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_inf(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_inf(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -514,7 +514,7 @@ extern "C" { LOG_Z3_mk_fpa_is_nan(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_nan(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_nan(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -524,7 +524,7 @@ extern "C" { LOG_Z3_mk_fpa_is_negative(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_negative(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_negative(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -534,7 +534,7 @@ extern "C" { LOG_Z3_mk_fpa_is_positive(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_is_positive(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_is_positive(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -545,7 +545,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_bv(c, bv, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - fpa_util & fu = ctx->fpa_util(); + 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); @@ -561,7 +561,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_float(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - fpa_util & fu = ctx->fpa_util(); + fpa_util & fu = ctx->fpautil(); if (!fu.is_rm(to_expr(rm)) || !fu.is_float(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -578,7 +578,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_real(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - fpa_util & fu = ctx->fpa_util(); + fpa_util & fu = ctx->fpautil(); if (!fu.is_rm(to_expr(rm)) || !ctx->autil().is_real(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -595,7 +595,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_signed(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - fpa_util & fu = ctx->fpa_util(); + fpa_util & fu = ctx->fpautil(); if (!fu.is_rm(to_expr(rm)) || !ctx->bvutil().is_bv(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -612,7 +612,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_unsigned(c, rm, t, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - fpa_util & fu = ctx->fpa_util(); + fpa_util & fu = ctx->fpautil(); if (!fu.is_rm(to_expr(rm)) || !ctx->bvutil().is_bv(to_expr(t)) || !fu.is_float(to_sort(s))) { @@ -629,7 +629,7 @@ extern "C" { LOG_Z3_mk_fpa_to_ubv(c, rm, t, sz); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_to_ubv(to_expr(rm), to_expr(t), sz)); + Z3_ast r = of_ast(ctx->fpautil().mk_to_ubv(to_expr(rm), to_expr(t), sz)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -639,7 +639,7 @@ extern "C" { LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_to_sbv(to_expr(rm), to_expr(t), sz)); + Z3_ast r = of_ast(ctx->fpautil().mk_to_sbv(to_expr(rm), to_expr(t), sz)); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -649,7 +649,7 @@ extern "C" { LOG_Z3_mk_fpa_to_real(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_to_real(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_to_real(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -659,7 +659,7 @@ extern "C" { LOG_Z3_fpa_get_ebits(c, s); RESET_ERROR_CODE(); CHECK_NON_NULL(s, 0); - return mk_c(c)->fpa_util().get_ebits(to_sort(s)); + return mk_c(c)->fpautil().get_ebits(to_sort(s)); Z3_CATCH_RETURN(0); } @@ -668,7 +668,7 @@ extern "C" { LOG_Z3_fpa_get_ebits(c, s); RESET_ERROR_CODE(); CHECK_NON_NULL(s, 0); - return mk_c(c)->fpa_util().get_sbits(to_sort(s)); + return mk_c(c)->fpautil().get_sbits(to_sort(s)); Z3_CATCH_RETURN(0); } @@ -677,7 +677,7 @@ extern "C" { LOG_Z3_fpa_get_numeral_sign(c, t, sgn); RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); - mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + mpf_manager & mpfm = mk_c(c)->fpautil().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); @@ -695,7 +695,7 @@ extern "C" { LOG_Z3_fpa_get_numeral_significand_string(c, t); RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); - mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + mpf_manager & mpfm = mk_c(c)->fpautil().fm(); unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); @@ -726,7 +726,7 @@ extern "C" { LOG_Z3_fpa_get_numeral_exponent_string(c, t); RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); - mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + mpf_manager & mpfm = mk_c(c)->fpautil().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); @@ -750,7 +750,7 @@ extern "C" { LOG_Z3_fpa_get_numeral_exponent_string(c, t); RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); - mpf_manager & mpfm = mk_c(c)->fpa_util().fm(); + mpf_manager & mpfm = mk_c(c)->fpautil().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); @@ -768,7 +768,7 @@ extern "C" { LOG_Z3_mk_fpa_to_ieee_bv(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpa_util().mk_float_to_ieee_bv(to_expr(t))); + Z3_ast r = of_ast(ctx->fpautil().mk_float_to_ieee_bv(to_expr(t))); RETURN_Z3(r); Z3_CATCH_RETURN(0); } @@ -778,7 +778,7 @@ extern "C" { LOG_Z3_mk_fpa_to_fp_real_int(c, rm, sig, exp, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - fpa_util & fu = ctx->fpa_util(); + fpa_util & fu = ctx->fpautil(); if (!fu.is_rm(to_expr(rm)) || !ctx->autil().is_real(to_expr(sig)) || !ctx->autil().is_int(to_expr(exp)) || diff --git a/src/api/api_numeral.cpp b/src/api/api_numeral.cpp index 277e80c20..446a66bc5 100644 --- a/src/api/api_numeral.cpp +++ b/src/api/api_numeral.cpp @@ -59,7 +59,7 @@ extern "C" { RETURN_Z3(0); } sort * _ty = to_sort(ty); - bool is_float = mk_c(c)->fpa_util().is_float(_ty); + bool is_float = mk_c(c)->fpautil().is_float(_ty); std::string fixed_num; char const* m = n; while (*m) { @@ -78,7 +78,7 @@ extern "C" { ast * a = 0; if (_ty->get_family_id() == mk_c(c)->get_fpa_fid()) { // avoid expanding floats into huge rationals. - fpa_util & fu = mk_c(c)->fpa_util(); + fpa_util & fu = mk_c(c)->fpautil(); scoped_mpf t(fu.fm()); fu.fm().set(t, fu.get_ebits(_ty), fu.get_sbits(_ty), MPF_ROUND_TOWARD_ZERO, n); a = fu.mk_value(t); @@ -148,8 +148,8 @@ extern "C" { return mk_c(c)->autil().is_numeral(e) || mk_c(c)->bvutil().is_numeral(e) || - mk_c(c)->fpa_util().is_numeral(e) || - mk_c(c)->fpa_util().is_rm_numeral(e); + mk_c(c)->fpautil().is_numeral(e) || + mk_c(c)->fpautil().is_rm_numeral(e); Z3_CATCH_RETURN(Z3_FALSE); } @@ -191,10 +191,10 @@ extern "C" { } else { // floats are separated from all others to avoid huge rationals. - fpa_util & fu = mk_c(c)->fpa_util(); + fpa_util & fu = mk_c(c)->fpautil(); scoped_mpf tmp(fu.fm()); mpf_rounding_mode rm; - if (mk_c(c)->fpa_util().is_rm_numeral(to_expr(a), rm)) { + if (mk_c(c)->fpautil().is_rm_numeral(to_expr(a), rm)) { switch (rm) { case OP_FPA_RM_NEAREST_TIES_TO_EVEN: return mk_c(c)->mk_external_string("roundNearestTiesToEven"); @@ -214,7 +214,7 @@ extern "C" { break; } } - else if (mk_c(c)->fpa_util().is_numeral(to_expr(a), tmp)) { + else if (mk_c(c)->fpautil().is_numeral(to_expr(a), tmp)) { return mk_c(c)->mk_external_string(fu.fm().to_string(tmp)); } else { From 8cd69acacafbfe60d0b1c9d11e4310219b39b547 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Jan 2015 11:34:08 +0000 Subject: [PATCH 495/507] build fix --- src/api/python/z3printer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/python/z3printer.py b/src/api/python/z3printer.py index 242d72c0b..2cc29bd5d 100644 --- a/src/api/python/z3printer.py +++ b/src/api/python/z3printer.py @@ -627,7 +627,7 @@ class Formatter: else: z3._z3_assert(z3.is_fp_value(a), 'expecting FP num ast') r = [] - sgn = c_long(0) + sgn = (ctypes.c_int)(0) sgnb = Z3_fpa_get_numeral_sign(a.ctx_ref(), a.ast, byref(sgn)) sig = Z3_fpa_get_numeral_significand_string(a.ctx_ref(), a.ast) exp = Z3_fpa_get_numeral_exponent_string(a.ctx_ref(), a.ast) From 3d915105658c8e4690100017fa817031d5f2c788 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Jan 2015 17:03:56 +0000 Subject: [PATCH 496/507] FPA API: naming consistency fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 8 ++++---- src/api/z3_fpa.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 9d47e152a..2d4529309 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -269,9 +269,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(Z3_context c, Z3_bool sgn, unsigned sig, signed exp, Z3_sort ty) { + Z3_ast Z3_API Z3_mk_fpa_numeral_int_uint(Z3_context c, Z3_bool sgn, signed exp, unsigned sig, Z3_sort ty) { Z3_TRY; - LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); + LOG_Z3_mk_fpa_numeral_int64_uint64(c, sgn, exp, sig, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); @@ -284,9 +284,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(Z3_context c, Z3_bool sgn, __uint64 sig, __int64 exp, Z3_sort ty) { + Z3_ast Z3_API Z3_mk_fpa_numeral_int64_uint64(Z3_context c, Z3_bool sgn, __int64 exp, __uint64 sig, Z3_sort ty) { Z3_TRY; - LOG_Z3_mk_fpa_numeral_uint64_int64(c, sgn, sig, exp, ty); + LOG_Z3_mk_fpa_numeral_int64_uint64(c, sgn, exp, sig, ty); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 10a7dc4cf..275c30fe0 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -337,9 +337,9 @@ extern "C" { \sa Z3_mk_numeral - def_API('Z3_mk_fpa_numeral_uint_int', AST, (_in(CONTEXT), _in(BOOL), _in(UINT), _in(INT), _in(SORT))) + def_API('Z3_mk_fpa_numeral_int_uint', AST, (_in(CONTEXT), _in(BOOL), _in(INT), _in(UINT), _in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_numeral_uint_int(__in Z3_context c, __in Z3_bool sgn, __in unsigned sig, __in signed exp, Z3_sort ty); + Z3_ast Z3_API Z3_mk_fpa_numeral_int_uint(__in Z3_context c, __in Z3_bool sgn, __in signed exp, __in unsigned sig, Z3_sort ty); /** \brief Create a numeral of FloatingPoint sort from a sign bit and two 64-bit integers. @@ -354,9 +354,9 @@ extern "C" { \sa Z3_mk_numeral - def_API('Z3_mk_fpa_numeral_uint64_int64', AST, (_in(CONTEXT), _in(BOOL), _in(UINT64), _in(INT64), _in(SORT))) + def_API('Z3_mk_fpa_numeral_int64_uint64', AST, (_in(CONTEXT), _in(BOOL), _in(INT64), _in(UINT64), _in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_numeral_uint64_int64(__in Z3_context c, __in Z3_bool sgn, __in __uint64 sig, __in __int64 exp, Z3_sort ty); + Z3_ast Z3_API Z3_mk_fpa_numeral_int64_uint64(__in Z3_context c, __in Z3_bool sgn, __in __int64 exp, __in __uint64 sig, Z3_sort ty); /** \brief Floating-point absolute value From 06051989be4369e4a98707cb04610ee9ecadf5b5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Jan 2015 17:11:12 +0000 Subject: [PATCH 497/507] FPA API: Naming consistency Signed-off-by: Christoph M. Wintersteiger --- src/api/dotnet/Context.cs | 10 +++++----- src/api/java/Context.java | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 1a36a35dc..96999d2d9 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -3706,7 +3706,7 @@ namespace Microsoft.Z3 public FPNum MkFPNumeral(bool sgn, uint sig, int exp, FPSort s) { Contract.Ensures(Contract.Result() != null); - return new FPNum(this, Native.Z3_mk_fpa_numeral_uint_int(nCtx, sgn ? 1 : 0, sig, exp, s.NativeObject)); + return new FPNum(this, Native.Z3_mk_fpa_numeral_int_uint(nCtx, sgn ? 1 : 0, exp, sig, s.NativeObject)); } /// @@ -3716,10 +3716,10 @@ namespace Microsoft.Z3 /// the significand. /// the exponent. /// FloatingPoint sort. - public FPNum MkFPNumeral(bool sgn, UInt64 sig, Int64 exp, FPSort s) + public FPNum MkFPNumeral(bool sgn, Int64 exp, UInt64 sig, FPSort s) { Contract.Ensures(Contract.Result() != null); - return new FPNum(this, Native.Z3_mk_fpa_numeral_uint64_int64(nCtx, sgn ? 1 : 0, sig, exp, s.NativeObject)); + return new FPNum(this, Native.Z3_mk_fpa_numeral_int64_uint64(nCtx, sgn ? 1 : 0, exp, sig, s.NativeObject)); } /// @@ -3765,7 +3765,7 @@ namespace Microsoft.Z3 public FPNum MkFP(bool sgn, int exp, uint sig, FPSort s) { Contract.Ensures(Contract.Result() != null); - return MkFPNumeral(sgn, sig, exp, s); + return MkFPNumeral(sgn, exp, sig, s); } /// @@ -3778,7 +3778,7 @@ namespace Microsoft.Z3 public FPNum MkFP(bool sgn, Int64 exp, UInt64 sig, FPSort s) { Contract.Ensures(Contract.Result() != null); - return MkFPNumeral(sgn, sig, exp, s); + return MkFPNumeral(sgn, exp, sig, s); } #endregion diff --git a/src/api/java/Context.java b/src/api/java/Context.java index 18e1b7b2c..baa84f60a 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3043,9 +3043,9 @@ public class Context extends IDisposable * @param s FloatingPoint sort. * @throws Z3Exception **/ - public FPNum mkFPNumeral(boolean sgn, int sig, int exp, FPSort s) throws Z3Exception + public FPNum mkFPNumeral(boolean sgn, int exp, int sig, FPSort s) throws Z3Exception { - return new FPNum(this, Native.mkFpaNumeralUintInt(nCtx(), sgn, sig, exp, s.getNativeObject())); + return new FPNum(this, Native.mkFpaNumeralIntUint(nCtx(), sgn, exp, sig, s.getNativeObject())); } /** @@ -3056,9 +3056,9 @@ public class Context extends IDisposable * @param s FloatingPoint sort. * @throws Z3Exception **/ - public FPNum mkFPNumeral(boolean sgn, long sig, long exp, FPSort s) throws Z3Exception + public FPNum mkFPNumeral(boolean sgn, long exp, long sig, FPSort s) throws Z3Exception { - return new FPNum(this, Native.mkFpaNumeralUint64Int64(nCtx(), sgn, sig, exp, s.getNativeObject())); + return new FPNum(this, Native.mkFpaNumeralInt64Uint64(nCtx(), sgn, exp, sig, s.getNativeObject())); } /** From 145e0259590cb39bee591a02dd46b6a656a663c3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Jan 2015 18:14:49 +0000 Subject: [PATCH 498/507] FPA API naming consistency Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 4 ++-- src/api/dotnet/Context.cs | 6 +++--- src/api/java/Context.java | 6 +++--- src/api/z3_fpa.h | 14 +++++++------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 2d4529309..86166a5cf 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -773,9 +773,9 @@ extern "C" { Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_to_fp_real_int(Z3_context c, Z3_ast rm, Z3_ast sig, Z3_ast exp, Z3_sort s) { + Z3_ast Z3_API Z3_mk_fpa_to_fp_int_real(Z3_context c, Z3_ast rm, Z3_ast exp, Z3_ast sig, Z3_sort s) { Z3_TRY; - LOG_Z3_mk_fpa_to_fp_real_int(c, rm, sig, exp, s); + LOG_Z3_mk_fpa_to_fp_int_real(c, rm, exp, sig, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); fpa_util & fu = ctx->fpautil(); diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 96999d2d9..65ec87bc6 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -4227,13 +4227,13 @@ namespace Microsoft.Z3 /// according to rounding mode rm. /// /// RoundingMode term. - /// Significand term of Real sort. /// Exponent term of Int sort. + /// Significand term of Real sort. /// FloatingPoint sort. - public BitVecExpr MkFPToFP(FPRMExpr rm, RealExpr sig, IntExpr exp, FPSort s) + public BitVecExpr MkFPToFP(FPRMExpr rm, IntExpr exp, RealExpr sig, FPSort s) { Contract.Ensures(Contract.Result() != null); - return new BitVecExpr(this, Native.Z3_mk_fpa_to_fp_real_int(this.nCtx, rm.NativeObject, sig.NativeObject, exp.NativeObject, s.NativeObject)); + return new BitVecExpr(this, Native.Z3_mk_fpa_to_fp_int_real(this.nCtx, rm.NativeObject, exp.NativeObject, sig.NativeObject, s.NativeObject)); } #endregion #endregion // Floating-point Arithmetic diff --git a/src/api/java/Context.java b/src/api/java/Context.java index baa84f60a..294826f55 100644 --- a/src/api/java/Context.java +++ b/src/api/java/Context.java @@ -3542,8 +3542,8 @@ public class Context extends IDisposable /** * Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. * @param rm RoundingMode term. - * @param sig Significand term of Real sort. * @param exp Exponent term of Int sort. + * @param sig Significand term of Real sort. * @param s FloatingPoint sort. * Remarks: * Produces a term that represents the conversion of sig * 2^exp into a @@ -3552,9 +3552,9 @@ public class Context extends IDisposable * @throws Z3Exception **/ - public BitVecExpr mkFPToFP(FPRMExpr rm, RealExpr sig, IntExpr exp, FPSort s) throws Z3Exception + public BitVecExpr mkFPToFP(FPRMExpr rm, IntExpr exp, RealExpr sig, FPSort s) throws Z3Exception { - return new BitVecExpr(this, Native.mkFpaToFpRealInt(nCtx(), rm.getNativeObject(), sig.getNativeObject(), exp.getNativeObject(), s.getNativeObject())); + return new BitVecExpr(this, Native.mkFpaToFpIntReal(nCtx(), rm.getNativeObject(), exp.getNativeObject(), sig.getNativeObject(), s.getNativeObject())); } diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index 275c30fe0..ca5ffebf7 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -501,10 +501,10 @@ extern "C" { t1, t2 must have the same FloatingPoint sort. def_API('Z3_mk_fpa_min', AST, (_in(CONTEXT),_in(AST),_in(AST))) - */ - Z3_ast Z3_API Z3_mk_fpa_min(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); + */ + Z3_ast Z3_API Z3_mk_fpa_min(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2); - /** + /** \brief Maximum of floating-point numbers. \param c logical context @@ -905,15 +905,15 @@ extern "C" { \param c logical context \param rm term of RoundingMode sort - \param sig significand term of Real sort \param exp exponent term of Int sort + \param sig significand term of Real sort \param s FloatingPoint sort - s must be a FloatingPoint sort, rm must be of RoundingMode sort, t must be of real sort. + s must be a FloatingPoint sort, rm must be of RoundingMode sort, exp must be of int sort, sig must be of real sort. - def_API('Z3_mk_fpa_to_fp_real_int', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST),_in(SORT))) + def_API('Z3_mk_fpa_to_fp_int_real', AST, (_in(CONTEXT),_in(AST),_in(AST),_in(AST),_in(SORT))) */ - Z3_ast Z3_API Z3_mk_fpa_to_fp_real_int(__in Z3_context c, __in Z3_ast rm, __in Z3_ast sig, __in Z3_ast exp, __in Z3_sort s); + Z3_ast Z3_API Z3_mk_fpa_to_fp_int_real(__in Z3_context c, __in Z3_ast rm, __in Z3_ast exp, __in Z3_ast sig, __in Z3_sort s); /*@}*/ From 48c72d2c38bc0d1da9d2627e9b933bb65f4de5a6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Jan 2015 18:18:26 +0000 Subject: [PATCH 499/507] FPA API: naming consistency Signed-off-by: Christoph M. Wintersteiger --- examples/c/test_capi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 817ada98e..c0ea70453 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -2665,10 +2665,10 @@ void fpa_example() { c2 = Z3_mk_fpa_to_fp_bv(ctx, Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), Z3_mk_fpa_sort(ctx, 11, 53)); - c3 = Z3_mk_fpa_to_fp_real_int(ctx, + c3 = Z3_mk_fpa_to_fp_int_real(ctx, Z3_mk_fpa_rtz(ctx), - Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), - Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), + Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), + Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), Z3_mk_fpa_sort(ctx, 11, 53)); c4 = Z3_mk_fpa_to_fp_real(ctx, Z3_mk_fpa_rtz(ctx), From 65ccc9a8eadfb5fbebe95bd76c6323818d091398 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Fri, 23 Jan 2015 19:36:47 +0000 Subject: [PATCH 500/507] added FPA ML API Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 89 +++++++++- scripts/update_api.py | 2 +- src/api/ml/z3.ml | 210 ++++++++++++++++++++++- src/api/ml/z3.mli | 352 +++++++++++++++++++++++++++++++++++++- 4 files changed, 630 insertions(+), 23 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 33334930e..8a2d71d82 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -19,6 +19,7 @@ open Z3.Arithmetic.Integer open Z3.Arithmetic.Real open Z3.BitVector + exception TestFailedException of string (** @@ -73,7 +74,6 @@ let model_converter_test ( ctx : context ) = *) let basic_tests ( ctx : context ) = Printf.printf "BasicTests\n" ; -(* let qi = (mk_int ctx 1) in *) let fname = (mk_string ctx "f") in let x = (mk_string ctx "x") in let y = (mk_string ctx "y") in @@ -167,8 +167,8 @@ let basic_tests ( ctx : context ) = let rn = Real.mk_numeral_nd ctx 42 43 in let inum = (get_numerator rn) in let iden = get_denominator rn in - Printf.printf "Numerator: %s Denominator: %s\n" (Real.to_string inum) (Real.to_string iden) ; - if ((Real.to_string inum) <> "42" || (Real.to_string iden) <> "43") then + Printf.printf "Numerator: %s Denominator: %s\n" (Real.numeral_to_string inum) (Real.numeral_to_string iden) ; + if ((Real.numeral_to_string inum) <> "42" || (Real.numeral_to_string iden) <> "43") then raise (TestFailedException "") else Printf.printf "Test passed.\n" @@ -190,7 +190,7 @@ let basic_tests ( ctx : context ) = (* Error handling test. *) try ( let i = Integer.mk_numeral_s ctx "1/2" in - raise (TestFailedException (to_string i)) (* unreachable *) + raise (TestFailedException (numeral_to_string i)) (* unreachable *) ) with Z3native.Exception(_) -> ( Printf.printf "Exception caught, OK.\n" @@ -199,7 +199,7 @@ let basic_tests ( ctx : context ) = (** A basic example of how to use quantifiers. **) -let quantifierExample1 ( ctx : context ) = +let quantifier_example1 ( ctx : context ) = Printf.printf "QuantifierExample\n" ; let is = (Integer.mk_sort ctx) in let types = [ is; is; is ] in @@ -239,6 +239,82 @@ let quantifierExample1 ( ctx : context ) = else if (is_const (Quantifier.expr_of_quantifier x)) then raise (TestFailedException "") (* unreachable *) + +open Z3.FloatingPoint + +(** + A basic example of floating point arithmetic +**) +let fpa_example ( ctx : context ) = + Printf.printf "FPAExample\n" ; + let double_sort = (FloatingPoint.mk_sort_double ctx) in + let rm_sort = (FloatingPoint.RoundingMode.mk_sort ctx) in + + (** Show that there are x, y s.t. (x + y) = 42.0 (with rounding mode). *) + let s_rm = (mk_string ctx "rm") in + let rm = (mk_const ctx s_rm rm_sort) in + let s_x = (mk_string ctx "x") in + let s_y = (mk_string ctx "y") in + let x = (mk_const ctx s_x double_sort) in + let y = (mk_const ctx s_y double_sort)in + Printf.printf "A\n" ; + let n = (mk_numeral_f ctx 42.0 double_sort) in + Printf.printf "B\n" ; + let s_x_plus_y = (mk_string ctx "x_plus_y") in + let x_plus_y = (mk_const ctx s_x_plus_y double_sort) in + let c1 = (mk_eq ctx x_plus_y (mk_add ctx rm x y)) in + let args = [ c1 ; (mk_eq ctx x_plus_y n) ] in + let c2 = (Boolean.mk_and ctx args) in + let args2 = [ c2 ; (Boolean.mk_not ctx (mk_eq ctx rm (RoundingMode.mk_rtz ctx))) ] in + let c3 = (Boolean.mk_and ctx args2) in + let and_args = [ (Boolean.mk_not ctx (mk_is_zero ctx y)) ; + (Boolean.mk_not ctx (mk_is_nan ctx y)) ; + (Boolean.mk_not ctx (mk_is_infinite ctx y)) ] in + let args3 = [ c3 ; (Boolean.mk_and ctx and_args) ] in + let c4 = (Boolean.mk_and ctx args3) in + + (Printf.printf "c4: %s\n" (Expr.to_string c4)) + (* push(ctx); *) + (* Z3_assert_cnstr(ctx, c4); *) + (* check(ctx, Z3_L_TRUE); *) + (* Z3_pop(ctx, 1); *) + + (* // Show that the following are equal: *) + (* // (fp #b0 #b10000000001 #xc000000000000) *) + (* // ((_ to_fp 11 53) #x401c000000000000)) *) + (* // ((_ to_fp 11 53) RTZ 1.75 2))) *) + (* // ((_ to_fp 11 53) RTZ 7.0))) *) + + (* Z3_push(ctx); *) + (* c1 = Z3_mk_fpa_fp(ctx, *) + (* Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), *) + (* Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52)), *) + (* Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11))); *) + (* c2 = Z3_mk_fpa_to_fp_bv(ctx, *) + (* Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), *) + (* Z3_mk_fpa_sort(ctx, 11, 53)); *) + (* c3 = Z3_mk_fpa_to_fp_real_int(ctx, *) + (* Z3_mk_fpa_rtz(ctx), *) + (* Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), *) + (* Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), *) + (* Z3_mk_fpa_sort(ctx, 11, 53)); *) + (* c4 = Z3_mk_fpa_to_fp_real(ctx, *) + (* Z3_mk_fpa_rtz(ctx), *) + (* Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), *) + (* Z3_mk_fpa_sort(ctx, 11, 53)); *) + (* args3[0] = Z3_mk_eq(ctx, c1, c2); *) + (* args3[1] = Z3_mk_eq(ctx, c1, c3); *) + (* args3[2] = Z3_mk_eq(ctx, c1, c4); *) + (* c5 = Z3_mk_and(ctx, 3, args3); *) + + (* printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); *) + (* Z3_assert_cnstr(ctx, c5); *) + (* check(ctx, Z3_L_TRUE); *) + (* Z3_pop(ctx, 1); *) + + (* Z3_del_context(ctx); *) + + let _ = try ( if not (Log.open_ "z3.log") then @@ -259,7 +335,8 @@ let _ = Printf.printf "int sort: %s\n" (Sort.to_string ints); Printf.printf "real sort: %s\n" (Sort.to_string rs); basic_tests ctx ; - quantifierExample1 ctx ; + quantifier_example1 ctx ; + fpa_example ctx ; Printf.printf "Disposing...\n"; Gc.full_major () ); diff --git a/scripts/update_api.py b/scripts/update_api.py index 79b34c315..889044d1f 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -159,7 +159,7 @@ Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', I # Mapping to ML types Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float', - STRING : 'string', STRING_PTR : 'char**', + FLOAT : 'float', STRING : 'string', STRING_PTR : 'char**', BOOL : 'bool', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int' } next_type_id = FIRST_OBJ_ID diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 350457525..601da1cbc 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -362,7 +362,9 @@ struct | REAL_SORT | UNINTERPRETED_SORT | FINITE_DOMAIN_SORT - | RELATION_SORT -> Sort(q) + | RELATION_SORT + | FLOATING_POINT_SORT + | ROUNDING_MODE_SORT -> Sort(q) | UNKNOWN_SORT -> raise (Z3native.Exception "Unknown sort kind encountered") let ast_of_sort s = match s with Sort(x) -> x @@ -745,7 +747,8 @@ end = struct Expr(z3_native_object_of_ast_ptr ctx no) else if (Z3native.is_numeral_ast (context_gno ctx) no) then - if (sk == INT_SORT || sk == REAL_SORT || sk == BV_SORT) then + if (sk == INT_SORT || sk == REAL_SORT || sk == BV_SORT || + sk == FLOATING_POINT_SORT || sk == ROUNDING_MODE_SORT) then Expr(z3_native_object_of_ast_ptr ctx no) else raise (Z3native.Exception "Unsupported numeral object") @@ -1507,7 +1510,7 @@ struct (Big_int.big_int_of_string s) else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_const ( ctx : context ) ( name : Symbol.symbol ) = Expr.mk_const ctx name (mk_sort ctx) @@ -1554,7 +1557,7 @@ struct let to_decimal_string ( x : expr ) ( precision : int ) = Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_const ( ctx : context ) ( name : Symbol.symbol ) = Expr.mk_const ctx name (mk_sort ctx) @@ -1562,7 +1565,7 @@ struct let mk_const_s ( ctx : context ) ( name : string ) = mk_const ctx (Symbol.mk_string ctx name) - let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int) = + let mk_numeral_nd ( ctx : context ) ( num : int ) ( den : int ) = if (den == 0) then raise (Z3native.Exception "Denominator is zero") else @@ -1591,7 +1594,7 @@ struct let to_decimal_string ( x : expr ) ( precision : int ) = Z3native.get_numeral_decimal_string (Expr.gnc x) (Expr.gno x) precision - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) end end @@ -1692,7 +1695,7 @@ struct let (r, v) = Z3native.get_numeral_int (Expr.gnc x) (Expr.gno x) in if r then v else raise (Z3native.Exception "Conversion failed.") - let to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( size : int ) = Expr.mk_const ctx name (mk_sort ctx size) let mk_const_s ( ctx : context ) ( name : string ) ( size : int ) = @@ -1791,11 +1794,202 @@ struct (expr_of_ptr ctx (Z3native.mk_bvmul_no_overflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2) signed)) let mk_mul_no_underflow ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = (expr_of_ptr ctx (Z3native.mk_bvmul_no_underflow (context_gno ctx) (Expr.gno t1) (Expr.gno t2))) - let mk_numeral ( ctx : context ) ( v : string ) ( size : int) = + let mk_numeral ( ctx : context ) ( v : string ) ( size : int ) = expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno (mk_sort ctx size))) end +module FloatingPoint = +struct + module RoundingMode = + struct + let mk_sort ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_rounding_mode_sort (context_gno ctx))) + let is_fprm ( x : expr ) = + (Sort.get_sort_kind (Expr.get_sort(x))) == ROUNDING_MODE_SORT + let mk_round_nearest_ties_to_even ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_round_nearest_ties_to_even (context_gno ctx))) + let mk_rne ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_rne (context_gno ctx))) + let mk_round_nearest_ties_to_away ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_round_nearest_ties_to_away (context_gno ctx))) + let mk_rna ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_rna (context_gno ctx))) + let mk_round_toward_positive ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_round_toward_positive (context_gno ctx))) + let mk_rtp ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_rtp (context_gno ctx))) + let mk_round_toward_negative ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_round_toward_negative (context_gno ctx))) + let mk_rtn ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_rtn (context_gno ctx))) + let mk_round_toward_zero ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_round_toward_zero (context_gno ctx))) + let mk_rtz ( ctx : context ) = + (expr_of_ptr ctx (Z3native.mk_fpa_rtz (context_gno ctx))) + end + + let mk_sort ( ctx : context ) ( ebits : int ) ( sbits : int ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort (context_gno ctx) ebits sbits)) + let mk_sort_half ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_half (context_gno ctx))) + let mk_sort_16 ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_16 (context_gno ctx))) + let mk_sort_single ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_single (context_gno ctx))) + let mk_sort_32 ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_32 (context_gno ctx))) + let mk_sort_double ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_double (context_gno ctx))) + let mk_sort_64 ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_64 (context_gno ctx))) + let mk_sort_quadruple ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_quadruple (context_gno ctx))) + let mk_sort_128 ( ctx : context ) = + (sort_of_ptr ctx (Z3native.mk_fpa_sort_128 (context_gno ctx))) + let mk_nan ( ctx : context ) ( s : sort ) = + (expr_of_ptr ctx (Z3native.mk_fpa_nan (context_gno ctx) (Sort.gno s))) + let mk_inf ( ctx : context ) ( s : sort ) ( negative : bool ) = + (expr_of_ptr ctx (Z3native.mk_fpa_inf (context_gno ctx) (Sort.gno s) negative)) + let mk_zero ( ctx : context ) ( s : sort ) ( negative : bool ) = + (expr_of_ptr ctx (Z3native.mk_fpa_zero (context_gno ctx) (Sort.gno s) negative)) + + let mk_fp ( ctx : context ) ( sign : expr ) ( exponent : expr ) ( significand : expr ) = + (expr_of_ptr ctx (Z3native.mk_fpa_fp (context_gno ctx) (Expr.gno sign) (Expr.gno exponent) (Expr.gno significand))) + let mk_numeral_f ( ctx : context ) ( value : float ) ( s : sort ) = + (expr_of_ptr ctx (Z3native.mk_fpa_numeral_double (context_gno ctx) value (Sort.gno s))) + let mk_numeral_i ( ctx : context ) ( value : int ) ( s : sort ) = + (expr_of_ptr ctx (Z3native.mk_fpa_numeral_int (context_gno ctx) value (Sort.gno s))) + let mk_numeral_i_u ( ctx : context ) ( sign : bool ) ( exponent : int ) ( significand : int ) ( s : sort ) = + (expr_of_ptr ctx (Z3native.mk_fpa_numeral_int64_uint64 (context_gno ctx) sign exponent significand (Sort.gno s))) + let mk_numeral_s ( ctx : context ) ( v : string ) ( s : sort ) = + (expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno s))) + + let is_fp ( x : expr ) = (Sort.get_sort_kind (Expr.get_sort x)) == FLOATING_POINT_SORT + let is_abs ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_ABS) + let is_neg ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_NEG) + let is_add ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_ADD) + let is_sub ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_SUB) + let is_mul ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_MUL) + let is_div ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_DIV) + let is_fma ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_FMA) + let is_sqrt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_SQRT) + let is_rem ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_REM) + let is_round_to_integral ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_ROUND_TO_INTEGRAL) + let is_min ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_MIN) + let is_max ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_MAX) + let is_leq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_LE) + let is_lt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_LT) + let is_geq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_GE) + let is_gt ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_GT) + let is_eq ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_EQ) + let is_is_normal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_NORMAL) + let is_is_subnormal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_SUBNORMAL) + let is_is_zero ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_ZERO) + let is_is_infinite ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_INF) + let is_is_nan ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_NAN) + let is_is_negative ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_NEGATIVE) + let is_is_positive ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_IS_POSITIVE) + let is_to_fp ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_TO_FP) + let is_to_fp_unsigned ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_TO_FP_UNSIGNED) + let is_to_ubv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_TO_UBV) + let is_to_sbv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_TO_SBV) + let is_to_real ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_TO_REAL) + let is_to_ieee_bv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_FPA_TO_IEEE_BV) + + let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) + let mk_const ( ctx : context ) ( name : Symbol.symbol ) ( s : sort ) = + Expr.mk_const ctx name s + let mk_const_s ( ctx : context ) ( name : string ) ( s : sort ) = + mk_const ctx (Symbol.mk_string ctx name) s + + let mk_abs ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_abs (context_gno ctx) (Expr.gno t)) + let mk_neg ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_neg (context_gno ctx) (Expr.gno t)) + let mk_add ( ctx : context ) ( rm : expr ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_add (context_gno ctx) (Expr.gno rm) (Expr.gno t1) (Expr.gno t2)) + let mk_sub ( ctx : context ) ( rm : expr ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_sub (context_gno ctx) (Expr.gno rm) (Expr.gno t1) (Expr.gno t2)) + let mk_mul ( ctx : context ) ( rm : expr ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_mul (context_gno ctx) (Expr.gno rm) (Expr.gno t1) (Expr.gno t2)) + let mk_div ( ctx : context ) ( rm : expr ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_div (context_gno ctx) (Expr.gno rm) (Expr.gno t1) (Expr.gno t2)) + let mk_fma ( ctx : context ) ( rm : expr ) ( t1 : expr ) ( t2 : expr ) ( t3 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_fma (context_gno ctx) (Expr.gno rm) (Expr.gno t1) (Expr.gno t2) (Expr.gno t3)) + let mk_sqrt ( ctx : context ) ( rm : expr ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_sqrt (context_gno ctx) (Expr.gno rm) (Expr.gno t)) + let mk_rem ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_rem (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_round_to_integral ( ctx : context ) ( rm : expr ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_round_to_integral (context_gno ctx) (Expr.gno rm) (Expr.gno t)) + let mk_min ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_min (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_max ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_max (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_leq ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_leq (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_lt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_lt (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_geq ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_geq (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_gt ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_gt (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_eq ( ctx : context ) ( t1 : expr ) ( t2 : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_eq (context_gno ctx) (Expr.gno t1) (Expr.gno t2)) + let mk_is_normal ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_normal (context_gno ctx) (Expr.gno t)) + let mk_is_subnormal ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_subnormal (context_gno ctx) (Expr.gno t)) + let mk_is_zero ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_zero (context_gno ctx) (Expr.gno t)) + let mk_is_infinite ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_infinite (context_gno ctx) (Expr.gno t)) + let mk_is_nan ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_nan (context_gno ctx) (Expr.gno t)) + let mk_is_negative ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_negative (context_gno ctx) (Expr.gno t)) + let mk_is_positive ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_is_positive (context_gno ctx) (Expr.gno t)) + let mk_to_fp_bv ( ctx : context ) ( t : expr ) ( s : sort ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_fp_bv (context_gno ctx) (Expr.gno t) (Sort.gno s)) + let mk_to_fp_float ( ctx : context ) ( rm : expr) ( t : expr ) ( s : sort ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_fp_float (context_gno ctx) (Expr.gno rm) (Expr.gno t) (Sort.gno s)) + let mk_to_fp_real ( ctx : context ) ( rm : expr ) ( t : expr ) ( s : sort ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_fp_real (context_gno ctx) (Expr.gno rm) (Expr.gno t) (Sort.gno s)) + let mk_to_fp_signed ( ctx : context ) ( rm : expr) ( t : expr ) ( s : sort ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_fp_signed (context_gno ctx) (Expr.gno rm) (Expr.gno t) (Sort.gno s)) + let mk_to_fp_unsigned ( ctx : context ) ( rm : expr) ( t : expr ) ( s : sort ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_fp_unsigned (context_gno ctx) (Expr.gno rm) (Expr.gno t) (Sort.gno s)) + let mk_to_fp_ubv ( ctx : context ) ( rm : expr) ( t : expr ) ( size : int ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_ubv (context_gno ctx) (Expr.gno rm) (Expr.gno t) size) + let mk_to_fp_sbv ( ctx : context ) ( rm : expr) ( t : expr ) ( size : int ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_sbv (context_gno ctx) (Expr.gno rm) (Expr.gno t) size) + let mk_to_fp_real ( ctx : context ) ( t : expr ) = + expr_of_ptr ctx (Z3native.mk_fpa_to_real (context_gno ctx) (Expr.gno t)) + + let get_ebits ( ctx : context ) ( s : sort ) = + (Z3native.fpa_get_ebits (context_gno ctx) (Sort.gno s)) + let get_sbits ( ctx : context ) ( s : sort ) = + (Z3native.fpa_get_sbits (context_gno ctx) (Sort.gno s)) + let get_numeral_sign ( ctx : context ) ( t : expr ) = + (Z3native.fpa_get_numeral_sign (context_gno ctx) (Expr.gno t)) + let get_numeral_significand_string ( ctx : context ) ( t : expr ) = + (Z3native.fpa_get_numeral_significand_string (context_gno ctx) (Expr.gno t)) + let get_numeral_exponent_string ( ctx : context ) ( t : expr ) = + (Z3native.fpa_get_numeral_exponent_string (context_gno ctx) (Expr.gno t)) + let get_numeral_exponent_int ( ctx : context ) ( t : expr ) = + (Z3native.fpa_get_numeral_exponent_int64 (context_gno ctx) (Expr.gno t)) + + let mk_to_ieee_bv ( ctx : context ) ( t : expr ) = + (expr_of_ptr ctx (Z3native.mk_fpa_to_ieee_bv (context_gno ctx) (Expr.gno t))) + let mk_to_fp_real_int ( ctx : context ) ( rm : expr ) ( exponent : expr ) ( significand : expr ) ( s : sort) = + (expr_of_ptr ctx (Z3native.mk_fpa_to_fp_real_int (context_gno ctx) (Expr.gno rm) (Expr.gno exponent) (Expr.gno significand) (Sort.gno s))) + + let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) +end + + module Proof = struct let is_true ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_PR_TRUE) diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index b2f0939d0..ab2a14725 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -1157,8 +1157,8 @@ sig (** Get a big_int from an integer numeral *) val get_big_int : Expr.expr -> Big_int.big_int - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string + (** Returns a string representation of a numeral. *) + val numeral_to_string : Expr.expr -> string (** Creates an integer constant. *) val mk_const : context -> Symbol.symbol -> Expr.expr @@ -1221,8 +1221,8 @@ sig The result has at most as many decimal places as indicated by the int argument.*) val to_decimal_string : Expr.expr-> int -> string - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr-> string + (** Returns a string representation of a numeral. *) + val numeral_to_string : Expr.expr-> string (** Creates a real constant. *) val mk_const : context -> Symbol.symbol -> Expr.expr @@ -1271,8 +1271,8 @@ sig The result has at most as many decimal places as the int argument provided.*) val to_decimal_string : Expr.expr -> int -> string - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string + (** Returns a string representation of a numeral. *) + val numeral_to_string : Expr.expr -> string end end @@ -1551,8 +1551,8 @@ sig (** Retrieve the int value. *) val get_int : Expr.expr -> int - (** Returns a string representation of the numeral. *) - val to_string : Expr.expr -> string + (** Returns a string representation of a numeral. *) + val numeral_to_string : Expr.expr -> string (** Creates a bit-vector constant. *) val mk_const : context -> Symbol.symbol -> int -> Expr.expr @@ -1830,6 +1830,342 @@ sig val mk_numeral : context -> string -> int -> Expr.expr end +(** Floating-Point Arithmetic *) +module FloatingPoint : + sig + + (** Rounding Modes *) + module RoundingMode : + sig + (** Create the RoundingMode sort. *) + val mk_sort : context -> Sort.sort + + (** Indicates whether the terms is of floating-point rounding mode sort. *) + val is_fprm : Expr.expr -> bool + + (** Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. *) + val mk_round_nearest_ties_to_even : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. *) + val mk_rne : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. *) + val mk_round_nearest_ties_to_away : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. *) + val mk_rna : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. *) + val mk_round_toward_positive : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. *) + val mk_rtp : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. *) + val mk_round_toward_negative : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. *) + val mk_rtn : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. *) + val mk_round_toward_zero : context -> Expr.expr + + (** Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. *) + val mk_rtz : context -> Expr.expr + end + + (** Create a FloatingPoint sort. *) + val mk_sort : context -> int -> int -> Sort.sort + + (** Create the half-precision (16-bit) FloatingPoint sort.*) + val mk_sort_half : context -> Sort.sort + + (** Create the half-precision (16-bit) FloatingPoint sort. *) + val mk_sort_16 : context -> Sort.sort + + (** Create the single-precision (32-bit) FloatingPoint sort.*) + val mk_sort_single : context -> Sort.sort + + (** Create the single-precision (32-bit) FloatingPoint sort. *) + val mk_sort_32 : context -> Sort.sort + + (** Create the double-precision (64-bit) FloatingPoint sort. *) + val mk_sort_double : context -> Sort.sort + + (** Create the double-precision (64-bit) FloatingPoint sort. *) + val mk_sort_64 : context -> Sort.sort + + (** Create the quadruple-precision (128-bit) FloatingPoint sort. *) + val mk_sort_quadruple : context -> Sort.sort + + (** Create the quadruple-precision (128-bit) FloatingPoint sort. *) + val mk_sort_128 : context -> Sort.sort + + (** Create a floating-point NaN of a given FloatingPoint sort. *) + val mk_nan : context -> Sort.sort -> Expr.expr + + (** Create a floating-point infinity of a given FloatingPoint sort. *) + val mk_inf : context -> Sort.sort -> bool -> Expr.expr + + (** Create a floating-point zero of a given FloatingPoint sort. *) + val mk_zero : context -> Sort.sort -> bool -> Expr.expr + + (** Create an expression of FloatingPoint sort from three bit-vector expressions. + + This is the operator named `fp' in the SMT FP theory definition. + Note that \c sign is required to be a bit-vector of size 1. Significand and exponent + are required to be greater than 1 and 2 respectively. The FloatingPoint sort + of the resulting expression is automatically determined from the bit-vector sizes + of the arguments. *) + val mk_fp : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a float. + + This function is used to create numerals that fit in a float value. + It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. *) + val mk_numeral_f : context -> float -> Sort.sort -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a signed integer. *) + val mk_numeral_i : context -> int -> Sort.sort -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a sign bit and two integers. *) + val mk_numeral_i_u : context -> bool -> int -> int -> Sort.sort -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a string *) + val mk_numeral_s : context -> string -> Sort.sort -> Expr.expr + + (** Indicates whether the terms is of floating-point sort. *) + val is_fp : Expr.expr -> bool + + + (** Indicates whether an expression is a floating-point abs expression *) + val is_abs : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point neg expression *) + val is_neg : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point add expression *) + val is_add : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point sub expression *) + val is_sub : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point mul expression *) + val is_mul : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point div expression *) + val is_div : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point fma expression *) + val is_fma : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point sqrt expression *) + val is_sqrt : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point rem expression *) + val is_rem : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point round_to_integral expression *) + val is_round_to_integral : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point min expression *) + val is_min : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point max expression *) + val is_max : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point leq expression *) + val is_leq : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point lt expression *) + val is_lt : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point geqexpression *) + val is_geq : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point gt expression *) + val is_gt : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point eq expression *) + val is_eq : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_normal expression *) + val is_is_normal : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_subnormal expression *) + val is_is_subnormal : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_zero expression *) + val is_is_zero : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_infinite expression *) + val is_is_infinite : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_nan expression *) + val is_is_nan : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_negative expression *) + val is_is_negative : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_positive expression *) + val is_is_positive : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_fp expression *) + val is_to_fp : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_fp_unsigned expression *) + val is_to_fp_unsigned : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_ubv expression *) + val is_to_ubv : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_sbv expression *) + val is_to_sbv : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_real expression *) + val is_to_real : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_ieee_bv expression *) + val is_to_ieee_bv : Expr.expr -> bool + + + (** Returns a string representation of a numeral. *) + val numeral_to_string : Expr.expr -> string + + (** Creates a floating-point constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> Expr.expr + + (** Creates a floating-point constant. *) + val mk_const_s : context -> string -> Sort.sort -> Expr.expr + + (** Floating-point absolute value *) + val mk_abs : context -> Expr.expr -> Expr.expr + + (** Floating-point negation *) + val mk_neg : context -> Expr.expr -> Expr.expr + + (** Floating-point addition *) + val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point subtraction *) + val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point multiplication *) + val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point division *) + val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point fused multiply-add. *) + val mk_fma : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point square root *) + val mk_sqrt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point remainder *) + val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point roundToIntegral. + + Rounds a floating-point number to the closest integer, + again represented as a floating-point number. *) + val mk_round_to_integral : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Minimum of floating-point numbers. *) + val mk_min : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Maximum of floating-point numbers. *) + val mk_max : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point less than or equal. *) + val mk_leq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point less than. *) + val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point greater than or equal. *) + val mk_geq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point greater than. *) + val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point equality. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a normal floating-point number. *) + val mk_is_normal : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a subnormal floating-point number. *) + val mk_is_subnormal : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a floating-point number with zero value, i.e., +zero or -zero. *) + val mk_is_zero : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a floating-point number representing +oo or -oo. *) + val mk_is_infinite : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a NaN. *) + val mk_is_nan : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a negative floating-point number. *) + val mk_is_negative : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a positive floating-point number. *) + val mk_is_positive : context -> Expr.expr -> Expr.expr + + (** Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. *) + val mk_to_fp_bv : context -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a FloatingPoint term into another term of different FloatingPoint sort. *) + val mk_to_fp_float : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a term of real sort into a term of FloatingPoint sort. *) + val mk_to_fp_real : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. *) + val mk_to_fp_signed : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a 2's complement unsigned bit-vector term into a term of FloatingPoint sort. *) + val mk_to_fp_unsigned : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** C1onversion of a floating-point term into an unsigned bit-vector. *) + val mk_to_fp_ubv : context -> Expr.expr -> Expr.expr -> int -> Expr.expr + + (** Conversion of a floating-point term into a signed bit-vector. *) + val mk_to_fp_sbv : context -> Expr.expr -> Expr.expr -> int -> Expr.expr + + (** Conversion of a floating-point term into a real-numbered term. *) + val mk_to_fp_real : context -> Expr.expr -> Expr.expr + + (** Retrieves the number of bits reserved for the exponent in a FloatingPoint sort. *) + val get_ebits : context -> Sort.sort -> int + + (** Retrieves the number of bits reserved for the significand in a FloatingPoint sort. *) + val get_sbits : context -> Sort.sort -> int + + (** Retrieves the sign of a floating-point literal. *) + val get_numeral_sign : context -> Expr.expr -> bool * int + + (** Return the significand value of a floating-point numeral as a string. *) + val get_numeral_significand_string : context -> Expr.expr -> string + + (** Return the exponent value of a floating-point numeral as a string *) + val get_numeral_exponent_string : context -> Expr.expr -> string + + (** Return the exponent value of a floating-point numeral as a signed integer *) + val get_numeral_exponent_int : context -> Expr.expr -> bool * int + + (** Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. *) + val mk_to_ieee_bv : context -> Expr.expr -> Expr.expr + + (** Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. *) + val mk_to_fp_real_int : context -> Expr.expr -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** The string representation of a numeral *) + val numeral_to_string : Expr.expr -> string + end + + (** Functions to manipulate proof expressions *) module Proof : sig From 5f527fa5626dd800db956267e089c782fd18f031 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 15:54:32 +0000 Subject: [PATCH 501/507] documentation fixes Signed-off-by: Christoph M. Wintersteiger --- src/api/z3_fpa.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/api/z3_fpa.h b/src/api/z3_fpa.h index ca5ffebf7..e1bd67d66 100644 --- a/src/api/z3_fpa.h +++ b/src/api/z3_fpa.h @@ -274,7 +274,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_fp(__in Z3_context c, __in Z3_ast sgn, __in Z3_ast exp, __in Z3_ast sig); /** - \brief Create a numeral of FloatingPoint sort from a float. + \brief Create a numeral of FloatingPoint sort from a float. This function is used to create numerals that fit in a float value. It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. @@ -292,20 +292,20 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_numeral_float(__in Z3_context c, __in float v, __in Z3_sort ty); /** - \brief Create a numeral of FloatingPoint sort from a double. + \brief Create a numeral of FloatingPoint sort from a double. - This function is used to create numerals that fit in a double value. - It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. + This function is used to create numerals that fit in a double value. + It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. - \param c logical context - \param v value - \param ty sort + \param c logical context + \param v value + \param ty sort - ty must be a FloatingPoint sort + ty must be a FloatingPoint sort - \sa Z3_mk_numeral + \sa Z3_mk_numeral - def_API('Z3_mk_fpa_numeral_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) + def_API('Z3_mk_fpa_numeral_double', AST, (_in(CONTEXT), _in(DOUBLE), _in(SORT))) */ Z3_ast Z3_API Z3_mk_fpa_numeral_double(__in Z3_context c, __in double v, __in Z3_sort ty); From 9cb50c9f2833a708b1da3c828f0781f6c600554c Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 17:33:26 +0000 Subject: [PATCH 502/507] FPA API bugfixes Signed-off-by: Christoph M. Wintersteiger --- src/api/api_fpa.cpp | 384 +++++++++++++++++++++++++------------------- 1 file changed, 216 insertions(+), 168 deletions(-) diff --git a/src/api/api_fpa.cpp b/src/api/api_fpa.cpp index 86166a5cf..e7ae685fc 100644 --- a/src/api/api_fpa.cpp +++ b/src/api/api_fpa.cpp @@ -14,7 +14,7 @@ Author: Christoph M. Wintersteiger (cwinter) 2013-06-05 Notes: - + --*/ #include #include"z3.h" @@ -27,21 +27,22 @@ extern "C" { Z3_sort Z3_API Z3_mk_fpa_rounding_mode_sort(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_rounding_mode_sort(c); - RESET_ERROR_CODE(); - api::context * ctx = mk_c(c); - Z3_sort r = of_sort(ctx->fpautil().mk_rm_sort()); - RETURN_Z3(r); + RESET_ERROR_CODE(); + api::context * ctx = mk_c(c); + sort * s = ctx->fpautil().mk_rm_sort(); + mk_c(c)->save_ast_trail(s); + RETURN_Z3(of_sort(s)); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(Z3_context c) - { + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_even(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_even(c); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_even()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_nearest_ties_to_even(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -50,19 +51,20 @@ extern "C" { LOG_Z3_mk_fpa_rne(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_even()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_nearest_ties_to_even(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(Z3_context c) - { + Z3_ast Z3_API Z3_mk_fpa_round_nearest_ties_to_away(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_nearest_ties_to_away(c); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_away()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_nearest_ties_to_away(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -71,19 +73,20 @@ extern "C" { LOG_Z3_mk_fpa_rna(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_nearest_ties_to_away()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_nearest_ties_to_away(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(Z3_context c) - { + Z3_ast Z3_API Z3_mk_fpa_round_toward_positive(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_toward_positive(c); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_positive()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_toward_positive(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -92,19 +95,20 @@ extern "C" { LOG_Z3_mk_fpa_rtp(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_positive()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_toward_positive(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(Z3_context c) - { + Z3_ast Z3_API Z3_mk_fpa_round_toward_negative(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_toward_negative(c); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_negative()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_toward_negative(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -113,19 +117,20 @@ extern "C" { LOG_Z3_mk_fpa_rtn(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_negative()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_toward_negative(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(Z3_context c) - { + Z3_ast Z3_API Z3_mk_fpa_round_toward_zero(Z3_context c) { Z3_TRY; LOG_Z3_mk_fpa_round_toward_zero(c); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_zero()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_toward_zero(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -134,8 +139,9 @@ extern "C" { LOG_Z3_mk_fpa_rtz(c); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_toward_zero()); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_toward_zero(); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -143,13 +149,14 @@ extern "C" { Z3_sort Z3_API Z3_mk_fpa_sort(Z3_context c, unsigned ebits, unsigned sbits) { Z3_TRY; LOG_Z3_mk_fpa_sort(c, ebits, sbits); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); if (ebits < 2 || sbits < 3) { SET_ERROR_CODE(Z3_INVALID_ARG); - } - api::context * ctx = mk_c(c); - Z3_sort r = of_sort(ctx->fpautil().mk_float_sort(ebits, sbits)); - RETURN_Z3(r); + } + api::context * ctx = mk_c(c); + sort * s = ctx->fpautil().mk_float_sort(ebits, sbits); + ctx->save_ast_trail(s); + RETURN_Z3(of_sort(s)); Z3_CATCH_RETURN(0); } @@ -188,21 +195,23 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_nan(Z3_context c, Z3_sort s) { Z3_TRY; LOG_Z3_mk_fpa_nan(c, s); - RESET_ERROR_CODE(); + RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_nan(to_sort(s))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_nan(to_sort(s)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_inf(Z3_context c, Z3_sort s, Z3_bool negative) { Z3_TRY; LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->fpautil().mk_ninf(to_sort(s)) : - ctx->fpautil().mk_pinf(to_sort(s))); - RETURN_Z3(r); + expr * a = negative != 0 ? ctx->fpautil().mk_ninf(to_sort(s)) : + ctx->fpautil().mk_pinf(to_sort(s)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -211,9 +220,10 @@ extern "C" { LOG_Z3_mk_fpa_inf(c, s, negative); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(negative != 0 ? ctx->fpautil().mk_nzero(to_sort(s)) : - ctx->fpautil().mk_pzero(to_sort(s))); - RETURN_Z3(r); + expr * a = negative != 0 ? ctx->fpautil().mk_nzero(to_sort(s)) : + ctx->fpautil().mk_pzero(to_sort(s)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -222,8 +232,9 @@ extern "C" { LOG_Z3_mk_fpa_fp(c, sgn, sig, exp); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_fp(to_expr(sgn), to_expr(sig), to_expr(exp)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -233,12 +244,13 @@ extern "C" { RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); - ctx->fpautil().fm().set(tmp, - ctx->fpautil().get_ebits(to_sort(ty)), - ctx->fpautil().get_sbits(to_sort(ty)), - v); - Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); - RETURN_Z3(r); + ctx->fpautil().fm().set(tmp, + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), + v); + expr * a = ctx->fpautil().mk_value(tmp); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -249,8 +261,9 @@ extern "C" { api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); ctx->fpautil().fm().set(tmp, ctx->fpautil().get_ebits(to_sort(ty)), ctx->fpautil().get_sbits(to_sort(ty)), v); - Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_value(tmp); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -261,11 +274,12 @@ extern "C" { api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); ctx->fpautil().fm().set(tmp, - ctx->fpautil().get_ebits(to_sort(ty)), - ctx->fpautil().get_sbits(to_sort(ty)), - v); - Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); - RETURN_Z3(r); + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), + v); + expr * a = ctx->fpautil().mk_value(tmp); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -275,12 +289,13 @@ extern "C" { RESET_ERROR_CODE(); api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); - ctx->fpautil().fm().set(tmp, - ctx->fpautil().get_ebits(to_sort(ty)), - ctx->fpautil().get_sbits(to_sort(ty)), - sgn != 0, sig, exp); - Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); - RETURN_Z3(r); + ctx->fpautil().fm().set(tmp, + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), + sgn != 0, sig, exp); + expr * a = ctx->fpautil().mk_value(tmp); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -291,111 +306,122 @@ extern "C" { api::context * ctx = mk_c(c); scoped_mpf tmp(ctx->fpautil().fm()); ctx->fpautil().fm().set(tmp, - ctx->fpautil().get_ebits(to_sort(ty)), - ctx->fpautil().get_sbits(to_sort(ty)), - sgn != 0, sig, exp); - Z3_ast r = of_ast(ctx->fpautil().mk_value(tmp)); - RETURN_Z3(r); + ctx->fpautil().get_ebits(to_sort(ty)), + ctx->fpautil().get_sbits(to_sort(ty)), + sgn != 0, sig, exp); + expr * a = ctx->fpautil().mk_value(tmp); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_abs(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_abs(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_abs(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_abs(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_neg(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_neg(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_neg(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_neg(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_add(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_add(to_expr(rm), to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_add(to_expr(rm), to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_sub(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_sub(to_expr(rm), to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_mul(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_mul(to_expr(rm), to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_div(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_add(c, rm, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_div(to_expr(rm), to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_div(to_expr(rm), to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_fma(Z3_context c, Z3_ast rm, Z3_ast t1, Z3_ast t2, Z3_ast t3) { Z3_TRY; LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_fma(to_expr(rm), to_expr(t1), to_expr(t2), to_expr(t3)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_sqrt(Z3_context c, Z3_ast rm, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_sqrt(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_sqrt(to_expr(rm), to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_sqrt(to_expr(rm), to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_rem(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_rem(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_rem(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_rem(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_round_to_integral(Z3_context c, Z3_ast rm, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_round_to_integral(c, rm, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_round_to_integral(to_expr(rm), to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_round_to_integral(to_expr(rm), to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -404,8 +430,9 @@ extern "C" { LOG_Z3_mk_fpa_min(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_min(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_min(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -418,14 +445,15 @@ extern "C" { RETURN_Z3(r); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_leq(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_leq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_le(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_le(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -434,18 +462,20 @@ extern "C" { LOG_Z3_mk_fpa_lt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_lt(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_lt(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_geq(Z3_context c, Z3_ast t1, Z3_ast t2) { Z3_TRY; LOG_Z3_mk_fpa_geq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_ge(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_ge(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -454,8 +484,9 @@ extern "C" { LOG_Z3_mk_fpa_gt(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_gt(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_gt(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -464,18 +495,20 @@ extern "C" { LOG_Z3_mk_fpa_eq(c, t1, t2); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_float_eq(to_expr(t1), to_expr(t2))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_float_eq(to_expr(t1), to_expr(t2)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } - + Z3_ast Z3_API Z3_mk_fpa_is_normal(Z3_context c, Z3_ast t) { Z3_TRY; LOG_Z3_mk_fpa_is_normal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_normal(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_normal(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -484,8 +517,9 @@ extern "C" { LOG_Z3_mk_fpa_is_subnormal(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_subnormal(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_subnormal(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -494,8 +528,9 @@ extern "C" { LOG_Z3_mk_fpa_is_zero(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_zero(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_zero(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -504,8 +539,9 @@ extern "C" { LOG_Z3_mk_fpa_is_infinite(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_inf(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_inf(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -514,8 +550,9 @@ extern "C" { LOG_Z3_mk_fpa_is_nan(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_nan(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_nan(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -524,8 +561,9 @@ extern "C" { LOG_Z3_mk_fpa_is_negative(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_negative(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_negative(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -534,8 +572,9 @@ extern "C" { LOG_Z3_mk_fpa_is_positive(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_is_positive(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_is_positive(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -551,8 +590,9 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(bv))); - RETURN_Z3(r); + expr * a = fu.mk_to_fp(to_sort(s), to_expr(bv)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -562,14 +602,15 @@ extern "C" { RESET_ERROR_CODE(); api::context * ctx = mk_c(c); fpa_util & fu = ctx->fpautil(); - if (!fu.is_rm(to_expr(rm)) || + 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); return 0; } - Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t))); - RETURN_Z3(r); + expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -585,8 +626,9 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t))); - RETURN_Z3(r); + expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -602,8 +644,9 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t))); - RETURN_Z3(r); + expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -613,14 +656,15 @@ extern "C" { RESET_ERROR_CODE(); api::context * ctx = mk_c(c); fpa_util & fu = ctx->fpautil(); - if (!fu.is_rm(to_expr(rm)) || + 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); return 0; } - Z3_ast r = of_ast(fu.mk_to_fp_unsigned(to_sort(s), to_expr(rm), to_expr(t))); - RETURN_Z3(r); + expr * a = fu.mk_to_fp_unsigned(to_sort(s), to_expr(rm), to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -629,8 +673,9 @@ extern "C" { LOG_Z3_mk_fpa_to_ubv(c, rm, t, sz); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_to_ubv(to_expr(rm), to_expr(t), sz)); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_to_ubv(to_expr(rm), to_expr(t), sz); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -639,8 +684,9 @@ extern "C" { LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_to_sbv(to_expr(rm), to_expr(t), sz)); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_to_sbv(to_expr(rm), to_expr(t), sz); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -649,8 +695,9 @@ extern "C" { LOG_Z3_mk_fpa_to_real(c, t); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); - Z3_ast r = of_ast(ctx->fpautil().mk_to_real(to_expr(t))); - RETURN_Z3(r); + expr * a = ctx->fpautil().mk_to_real(to_expr(t)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } @@ -689,7 +736,7 @@ extern "C" { return r; Z3_CATCH_RETURN(0); } - + Z3_string Z3_API Z3_fpa_get_numeral_significand_string(__in Z3_context c, __in Z3_ast t) { Z3_TRY; LOG_Z3_fpa_get_numeral_significand_string(c, t); @@ -699,14 +746,14 @@ extern "C" { unsynch_mpz_manager & mpzm = mpfm.mpz_manager(); unsynch_mpq_manager & mpqm = mpfm.mpq_manager(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); - scoped_mpf val(mpfm); - if (!plugin->is_numeral(to_expr(t), val)) { + scoped_mpf val(mpfm); + if (!plugin->is_numeral(to_expr(t), val)) { SET_ERROR_CODE(Z3_INVALID_ARG); return ""; } else if (!mpfm.is_regular(val)) { SET_ERROR_CODE(Z3_INVALID_ARG) - return ""; + return ""; } unsigned sbits = val.get().get_sbits(); scoped_mpq q(mpqm); @@ -726,7 +773,7 @@ extern "C" { LOG_Z3_fpa_get_numeral_exponent_string(c, t); RESET_ERROR_CODE(); ast_manager & m = mk_c(c)->m(); - mpf_manager & mpfm = mk_c(c)->fpautil().fm(); + mpf_manager & mpfm = mk_c(c)->fpautil().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); bool r = plugin->is_numeral(to_expr(t), val); @@ -738,7 +785,7 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG) return ""; } - mpf_exp_t exp = mpfm.exp_normalized(val); + mpf_exp_t exp = mpfm.exp_normalized(val); std::stringstream ss; ss << exp; return mk_c(c)->mk_external_string(ss.str()); @@ -753,7 +800,7 @@ extern "C" { mpf_manager & mpfm = mk_c(c)->fpautil().fm(); fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(mk_c(c)->get_fpa_fid()); scoped_mpf val(mpfm); - bool r = plugin->is_numeral(to_expr(t), val); + bool r = plugin->is_numeral(to_expr(t), val); if (!r) { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; @@ -775,7 +822,7 @@ extern "C" { Z3_ast Z3_API Z3_mk_fpa_to_fp_int_real(Z3_context c, Z3_ast rm, Z3_ast exp, Z3_ast sig, Z3_sort s) { Z3_TRY; - LOG_Z3_mk_fpa_to_fp_int_real(c, rm, exp, sig, s); + LOG_Z3_mk_fpa_to_fp_int_real(c, rm, sig, exp, s); RESET_ERROR_CODE(); api::context * ctx = mk_c(c); fpa_util & fu = ctx->fpautil(); @@ -786,8 +833,9 @@ extern "C" { SET_ERROR_CODE(Z3_INVALID_ARG); return 0; } - Z3_ast r = of_ast(fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(sig), to_expr(exp))); - RETURN_Z3(r); + expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(sig), to_expr(exp)); + ctx->save_ast_trail(a); + RETURN_Z3(of_expr(a)); Z3_CATCH_RETURN(0); } From 5c7d0380d3c2d5fba59d0da2f62f870feaf279cc Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 18:29:52 +0000 Subject: [PATCH 503/507] Fixes in the OCaml FPA API and example --- examples/ml/ml_example.ml | 93 ++--- scripts/mk_util.py | 2 +- src/api/ml/z3.ml | 25 +- src/api/ml/z3.mli | 754 +++++++++++++++++++------------------- 4 files changed, 436 insertions(+), 438 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 8a2d71d82..127a973aa 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -247,6 +247,8 @@ open Z3.FloatingPoint **) let fpa_example ( ctx : context ) = Printf.printf "FPAExample\n" ; + (* let str = ref "" in *) + (* (read_line ()) ; *) let double_sort = (FloatingPoint.mk_sort_double ctx) in let rm_sort = (FloatingPoint.RoundingMode.mk_sort ctx) in @@ -257,63 +259,64 @@ let fpa_example ( ctx : context ) = let s_y = (mk_string ctx "y") in let x = (mk_const ctx s_x double_sort) in let y = (mk_const ctx s_y double_sort)in - Printf.printf "A\n" ; - let n = (mk_numeral_f ctx 42.0 double_sort) in - Printf.printf "B\n" ; + let n = (FloatingPoint.mk_numeral_f ctx 42.0 double_sort) in let s_x_plus_y = (mk_string ctx "x_plus_y") in let x_plus_y = (mk_const ctx s_x_plus_y double_sort) in let c1 = (mk_eq ctx x_plus_y (mk_add ctx rm x y)) in let args = [ c1 ; (mk_eq ctx x_plus_y n) ] in let c2 = (Boolean.mk_and ctx args) in - let args2 = [ c2 ; (Boolean.mk_not ctx (mk_eq ctx rm (RoundingMode.mk_rtz ctx))) ] in + let args2 = [ c2 ; (Boolean.mk_not ctx (Boolean.mk_eq ctx rm (RoundingMode.mk_rtz ctx))) ] in let c3 = (Boolean.mk_and ctx args2) in let and_args = [ (Boolean.mk_not ctx (mk_is_zero ctx y)) ; (Boolean.mk_not ctx (mk_is_nan ctx y)) ; (Boolean.mk_not ctx (mk_is_infinite ctx y)) ] in let args3 = [ c3 ; (Boolean.mk_and ctx and_args) ] in - let c4 = (Boolean.mk_and ctx args3) in - - (Printf.printf "c4: %s\n" (Expr.to_string c4)) - (* push(ctx); *) - (* Z3_assert_cnstr(ctx, c4); *) - (* check(ctx, Z3_L_TRUE); *) - (* Z3_pop(ctx, 1); *) + let c4 = (Boolean.mk_and ctx args3) in + (Printf.printf "c4: %s\n" (Expr.to_string c4)) ; + ( + let solver = (mk_solver ctx None) in + (Solver.add solver [ c4 ]) ; + if (check solver []) != SATISFIABLE then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ); - (* // Show that the following are equal: *) - (* // (fp #b0 #b10000000001 #xc000000000000) *) - (* // ((_ to_fp 11 53) #x401c000000000000)) *) - (* // ((_ to_fp 11 53) RTZ 1.75 2))) *) - (* // ((_ to_fp 11 53) RTZ 7.0))) *) +(* Show that the following are equal: *) +(* (fp #b0 #b10000000001 #xc000000000000) *) +(* ((_ to_fp 11 53) #x401c000000000000)) *) +(* ((_ to_fp 11 53) RTZ 1.75 2))) *) +(* ((_ to_fp 11 53) RTZ 7.0))) *) - (* Z3_push(ctx); *) - (* c1 = Z3_mk_fpa_fp(ctx, *) - (* Z3_mk_numeral(ctx, "0", Z3_mk_bv_sort(ctx, 1)), *) - (* Z3_mk_numeral(ctx, "3377699720527872", Z3_mk_bv_sort(ctx, 52)), *) - (* Z3_mk_numeral(ctx, "1025", Z3_mk_bv_sort(ctx, 11))); *) - (* c2 = Z3_mk_fpa_to_fp_bv(ctx, *) - (* Z3_mk_numeral(ctx, "4619567317775286272", Z3_mk_bv_sort(ctx, 64)), *) - (* Z3_mk_fpa_sort(ctx, 11, 53)); *) - (* c3 = Z3_mk_fpa_to_fp_real_int(ctx, *) - (* Z3_mk_fpa_rtz(ctx), *) - (* Z3_mk_numeral(ctx, "1.75", Z3_mk_real_sort(ctx)), *) - (* Z3_mk_numeral(ctx, "2", Z3_mk_int_sort(ctx)), *) - (* Z3_mk_fpa_sort(ctx, 11, 53)); *) - (* c4 = Z3_mk_fpa_to_fp_real(ctx, *) - (* Z3_mk_fpa_rtz(ctx), *) - (* Z3_mk_numeral(ctx, "7.0", Z3_mk_real_sort(ctx)), *) - (* Z3_mk_fpa_sort(ctx, 11, 53)); *) - (* args3[0] = Z3_mk_eq(ctx, c1, c2); *) - (* args3[1] = Z3_mk_eq(ctx, c1, c3); *) - (* args3[2] = Z3_mk_eq(ctx, c1, c4); *) - (* c5 = Z3_mk_and(ctx, 3, args3); *) - - (* printf("c5: %s\n", Z3_ast_to_string(ctx, c5)); *) - (* Z3_assert_cnstr(ctx, c5); *) - (* check(ctx, Z3_L_TRUE); *) - (* Z3_pop(ctx, 1); *) - - (* Z3_del_context(ctx); *) - + let solver = (mk_solver ctx None) in + let c1 = (mk_fp ctx + (mk_numeral_string ctx "0" (BitVector.mk_sort ctx 1)) + (mk_numeral_string ctx "3377699720527872" (BitVector.mk_sort ctx 52)) + (mk_numeral_string ctx "1025" (BitVector.mk_sort ctx 11))) in + let c2 = (mk_to_fp_bv ctx + (mk_numeral_string ctx "4619567317775286272" (BitVector.mk_sort ctx 64)) + (mk_sort ctx 11 53)) in + let c3 = (mk_to_fp_int_real ctx + (RoundingMode.mk_rtz ctx) + (mk_numeral_string ctx "2" (Integer.mk_sort ctx)) + (mk_numeral_string ctx "1.75" (Real.mk_sort ctx)) + (FloatingPoint.mk_sort ctx 11 53)) in + let c4 = (mk_to_fp_real ctx (RoundingMode.mk_rtz ctx) + (mk_numeral_string ctx "7.0" (Real.mk_sort ctx)) + (FloatingPoint.mk_sort ctx 11 53)) in + let args3 = [ (mk_eq ctx c1 c2) ; + (mk_eq ctx c1 c3) ; + (mk_eq ctx c1 c4) ] in + let c5 = (Boolean.mk_and ctx args3) in + (Printf.printf "c5: %s\n" (Expr.to_string c5)) ; + ( + let solver = (mk_solver ctx None) in + (Solver.add solver [ c5 ]) ; + if (check solver []) != SATISFIABLE then + raise (TestFailedException "") + else + Printf.printf "Test passed.\n" + ) let _ = try ( diff --git a/scripts/mk_util.py b/scripts/mk_util.py index af0c59355..2ed420c20 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -546,7 +546,7 @@ def parse_options(): 'b:df:sxhmcvtnp:gj', ['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof', - 'githash=', 'x86']) + 'githash=', 'x86', 'ml']) except: print("ERROR: Invalid command line option") display_help(1) diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index 601da1cbc..fe78b65a6 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -1479,9 +1479,9 @@ struct let is_modulus ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_MOD) - let is_inttoreal ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) + let is_int2real ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_REAL) - let is_real_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) + let is_real2int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_TO_INT) let is_real_is_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_IS_INT) @@ -1686,8 +1686,8 @@ struct let is_bv_rotateright ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_ROTATE_RIGHT) let is_bv_rotateleftextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_LEFT) let is_bv_rotaterightextended ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_EXT_ROTATE_RIGHT) - let is_int_to_bv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) - let is_bv_to_int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) + let is_int2bv ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_INT2BV) + let is_bv2int ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_BV2INT) let is_bv_carry ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_CARRY) let is_bv_xor3 ( x : expr ) = (AST.is_app (Expr.ast_of_expr x)) && (FuncDecl.get_decl_kind (Expr.get_func_decl x) == OP_XOR3) let get_size (x : sort ) = Z3native.get_bv_sort_size (Sort.gnc x) (Sort.gno x) @@ -1847,6 +1847,7 @@ struct (sort_of_ptr ctx (Z3native.mk_fpa_sort_quadruple (context_gno ctx))) let mk_sort_128 ( ctx : context ) = (sort_of_ptr ctx (Z3native.mk_fpa_sort_128 (context_gno ctx))) + let mk_nan ( ctx : context ) ( s : sort ) = (expr_of_ptr ctx (Z3native.mk_fpa_nan (context_gno ctx) (Sort.gno s))) let mk_inf ( ctx : context ) ( s : sort ) ( negative : bool ) = @@ -1857,11 +1858,11 @@ struct let mk_fp ( ctx : context ) ( sign : expr ) ( exponent : expr ) ( significand : expr ) = (expr_of_ptr ctx (Z3native.mk_fpa_fp (context_gno ctx) (Expr.gno sign) (Expr.gno exponent) (Expr.gno significand))) let mk_numeral_f ( ctx : context ) ( value : float ) ( s : sort ) = - (expr_of_ptr ctx (Z3native.mk_fpa_numeral_double (context_gno ctx) value (Sort.gno s))) + (expr_of_ptr ctx (Z3native.mk_fpa_numeral_double (context_gno ctx) value (Sort.gno s))) let mk_numeral_i ( ctx : context ) ( value : int ) ( s : sort ) = - (expr_of_ptr ctx (Z3native.mk_fpa_numeral_int (context_gno ctx) value (Sort.gno s))) + (expr_of_ptr ctx (Z3native.mk_fpa_numeral_int (context_gno ctx) value (Sort.gno s))) let mk_numeral_i_u ( ctx : context ) ( sign : bool ) ( exponent : int ) ( significand : int ) ( s : sort ) = - (expr_of_ptr ctx (Z3native.mk_fpa_numeral_int64_uint64 (context_gno ctx) sign exponent significand (Sort.gno s))) + (expr_of_ptr ctx (Z3native.mk_fpa_numeral_int64_uint64 (context_gno ctx) sign exponent significand (Sort.gno s))) let mk_numeral_s ( ctx : context ) ( v : string ) ( s : sort ) = (expr_of_ptr ctx (Z3native.mk_numeral (context_gno ctx) v (Sort.gno s))) @@ -1961,11 +1962,11 @@ struct expr_of_ptr ctx (Z3native.mk_fpa_to_fp_signed (context_gno ctx) (Expr.gno rm) (Expr.gno t) (Sort.gno s)) let mk_to_fp_unsigned ( ctx : context ) ( rm : expr) ( t : expr ) ( s : sort ) = expr_of_ptr ctx (Z3native.mk_fpa_to_fp_unsigned (context_gno ctx) (Expr.gno rm) (Expr.gno t) (Sort.gno s)) - let mk_to_fp_ubv ( ctx : context ) ( rm : expr) ( t : expr ) ( size : int ) = + let mk_to_ubv ( ctx : context ) ( rm : expr) ( t : expr ) ( size : int ) = expr_of_ptr ctx (Z3native.mk_fpa_to_ubv (context_gno ctx) (Expr.gno rm) (Expr.gno t) size) - let mk_to_fp_sbv ( ctx : context ) ( rm : expr) ( t : expr ) ( size : int ) = + let mk_to_sbv ( ctx : context ) ( rm : expr) ( t : expr ) ( size : int ) = expr_of_ptr ctx (Z3native.mk_fpa_to_sbv (context_gno ctx) (Expr.gno rm) (Expr.gno t) size) - let mk_to_fp_real ( ctx : context ) ( t : expr ) = + let mk_to_real ( ctx : context ) ( t : expr ) = expr_of_ptr ctx (Z3native.mk_fpa_to_real (context_gno ctx) (Expr.gno t)) let get_ebits ( ctx : context ) ( s : sort ) = @@ -1983,8 +1984,8 @@ struct let mk_to_ieee_bv ( ctx : context ) ( t : expr ) = (expr_of_ptr ctx (Z3native.mk_fpa_to_ieee_bv (context_gno ctx) (Expr.gno t))) - let mk_to_fp_real_int ( ctx : context ) ( rm : expr ) ( exponent : expr ) ( significand : expr ) ( s : sort) = - (expr_of_ptr ctx (Z3native.mk_fpa_to_fp_real_int (context_gno ctx) (Expr.gno rm) (Expr.gno exponent) (Expr.gno significand) (Sort.gno s))) + let mk_to_fp_int_real ( ctx : context ) ( rm : expr ) ( exponent : expr ) ( significand : expr ) ( s : sort ) = + (expr_of_ptr ctx (Z3native.mk_fpa_to_fp_int_real (context_gno ctx) (Expr.gno rm) (Expr.gno exponent) (Expr.gno significand) (Sort.gno s))) let numeral_to_string ( x : expr ) = Z3native.get_numeral_string (Expr.gnc x) (Expr.gno x) end diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index ab2a14725..aa526417e 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -139,7 +139,7 @@ sig val get_size : ast_vector -> int (** Retrieves the i-th object in the vector. - @return An AST *) + @return An AST *) val get : ast_vector -> int -> ast (** Sets the i-th object in the vector. *) @@ -149,11 +149,11 @@ sig val resize : ast_vector -> int -> unit (** Add an ast to the back of the vector. The size - is increased by 1. *) + is increased by 1. *) val push : ast_vector -> ast -> unit (** Translates all ASTs in the vector to another context. - @return A new ASTVector *) + @return A new ASTVector *) val translate : ast_vector -> context -> ast_vector (** Retrieves a string representation of the vector. *) @@ -169,11 +169,11 @@ sig val mk_ast_map : context -> ast_map (** Checks whether the map contains a key. - @return True if the key in the map, false otherwise. *) + @return True if the key in the map, false otherwise. *) val contains : ast_map -> ast -> bool (** Finds the value associated with the key. - This function signs an error when the key is not a key in the map. *) + This function signs an error when the key is not a key in the map. *) val find : ast_map -> ast -> ast (** Stores or replaces a new key/value pair in the map. *) @@ -302,14 +302,14 @@ sig sig (** Parameters of func_decls *) type parameter = - P_Int of int + P_Int of int | P_Dbl of float | P_Sym of Symbol.symbol | P_Srt of Sort.sort | P_Ast of AST.ast | P_Fdl of func_decl | P_Rat of string - + (** The kind of the parameter. *) val get_kind : parameter -> Z3enums.parameter_kind @@ -723,7 +723,7 @@ sig (** The no-patterns. *) val get_no_patterns : quantifier -> Pattern.pattern list - (** The number of bound variables. *) + (** The number of bound variables. *) val get_num_bound : quantifier -> int (** The symbols for the bound variables. *) @@ -759,7 +759,7 @@ sig (** Create a Quantifier. *) val mk_quantifier : context -> bool -> Expr.expr list -> Expr.expr -> int option -> Pattern.pattern list -> Expr.expr list -> Symbol.symbol option -> Symbol.symbol option -> quantifier - (** A string representation of the quantifier. *) + (** A string representation of the quantifier. *) val to_string : quantifier -> string end @@ -1167,38 +1167,36 @@ sig val mk_const_s : context -> string -> Expr.expr (** Create an expression representing [t1 mod t2]. - The arguments must have int type. *) + The arguments must have int type. *) val mk_mod : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an expression representing [t1 rem t2]. - The arguments must have int type. *) + The arguments must have int type. *) val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr (** Create an integer numeral. *) val mk_numeral_s : context -> string -> Expr.expr (** Create an integer numeral. - @return A Term with the given value and sort Integer *) + @return A Term with the given value and sort Integer *) val mk_numeral_i : context -> int -> Expr.expr - (** Coerce an integer to a real. - - - There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - - You can take the floor of a real by creating an auxiliary integer Term [k] and - and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. - The argument must be of integer sort. *) + (** Coerce an integer to a real. + + There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. + + You can take the floor of a real by creating an auxiliary integer Term [k] and + and asserting [MakeInt2Real(k) <= t1 < MkInt2Real(k)+1]. + The argument must be of integer sort. *) val mk_int2real : context -> Expr.expr -> Expr.expr - (** Create an n-bit bit-vector from an integer argument. - - - NB. This function is essentially treated as uninterpreted. - So you cannot expect Z3 to precisely reflect the semantics of this function - when solving constraints with this function. - - The argument must be of integer sort. *) + (** Create an n-bit bit-vector from an integer argument. + + NB. This function is essentially treated as uninterpreted. + So you cannot expect Z3 to precisely reflect the semantics of this function + when solving constraints with this function. + + The argument must be of integer sort. *) val mk_int2bv : context -> int -> Expr.expr -> Expr.expr end @@ -1218,7 +1216,7 @@ sig val get_ratio : Expr.expr -> Ratio.ratio (** Returns a string representation in decimal notation. - The result has at most as many decimal places as indicated by the int argument.*) + The result has at most as many decimal places as indicated by the int argument.*) val to_decimal_string : Expr.expr-> int -> string (** Returns a string representation of a numeral. *) @@ -1231,16 +1229,16 @@ sig val mk_const_s : context -> string -> Expr.expr (** Create a real numeral from a fraction. - @return A Term with rational value and sort Real - {!mk_numeral_s} *) + @return A Term with rational value and sort Real + {!mk_numeral_s} *) val mk_numeral_nd : context -> int -> int -> Expr.expr (** Create a real numeral. - @return A Term with the given value and sort Real *) + @return A Term with the given value and sort Real *) val mk_numeral_s : context -> string -> Expr.expr (** Create a real numeral. - @return A Term with the given value and sort Real *) + @return A Term with the given value and sort Real *) val mk_numeral_i : context -> int -> Expr.expr (** Creates an expression that checks whether a real number is an integer. *) @@ -1248,29 +1246,29 @@ sig (** Coerce a real to an integer. - The semantics of this function follows the SMT-LIB standard for the function to_int. - The argument must be of real sort. *) + The semantics of this function follows the SMT-LIB standard for the function to_int. + The argument must be of real sort. *) val mk_real2int : context -> Expr.expr -> Expr.expr (** Algebraic Numbers *) module AlgebraicNumber : sig (** Return a upper bound for a given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) val to_upper : Expr.expr -> int -> Expr.expr - + (** Return a lower bound for the given real algebraic number. - The interval isolating the number is smaller than 1/10^precision. - {!is_algebraic_number} - @return A numeral Expr of sort Real *) + The interval isolating the number is smaller than 1/10^precision. + {!is_algebraic_number} + @return A numeral Expr of sort Real *) val to_lower : Expr.expr -> int -> Expr.expr - + (** Returns a string representation in decimal notation. - The result has at most as many decimal places as the int argument provided.*) + The result has at most as many decimal places as the int argument provided.*) val to_decimal_string : Expr.expr -> int -> string - + (** Returns a string representation of a numeral. *) val numeral_to_string : Expr.expr -> string end @@ -1319,10 +1317,10 @@ sig val is_modulus : Expr.expr -> bool (** Indicates whether the term is a coercion of integer to real (unary) *) - val is_inttoreal : Expr.expr -> bool + val is_int2real : Expr.expr -> bool (** Indicates whether the term is a coercion of real to integer (unary) *) - val is_real_to_int : Expr.expr -> bool + val is_real2int : Expr.expr -> bool (** Indicates whether the term is a check that tests whether a real is integral (unary) *) val is_real_is_int : Expr.expr -> bool @@ -1522,19 +1520,15 @@ sig Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. *) val is_bv_rotaterightextended : Expr.expr -> bool - (** Indicates whether the term is a coercion from integer to bit-vector - This function is not supported by the decision procedures. Only the most - rudimentary simplification rules are applied to this function. *) - (** Indicates whether the term is a coercion from bit-vector to integer This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - val is_int_to_bv : Expr.expr -> bool + val is_int2bv : Expr.expr -> bool (** Indicates whether the term is a coercion from integer to bit-vector This function is not supported by the decision procedures. Only the most rudimentary simplification rules are applied to this function. *) - val is_bv_to_int : Expr.expr -> bool + val is_bv2int : Expr.expr -> bool (** Indicates whether the term is a bit-vector carry Compute the carry bit in a full-adder. The meaning is given by the @@ -1832,339 +1826,339 @@ end (** Floating-Point Arithmetic *) module FloatingPoint : +sig + + (** Rounding Modes *) + module RoundingMode : sig + (** Create the RoundingMode sort. *) + val mk_sort : context -> Sort.sort - (** Rounding Modes *) - module RoundingMode : - sig - (** Create the RoundingMode sort. *) - val mk_sort : context -> Sort.sort + (** Indicates whether the terms is of floating-point rounding mode sort. *) + val is_fprm : Expr.expr -> bool - (** Indicates whether the terms is of floating-point rounding mode sort. *) - val is_fprm : Expr.expr -> bool - - (** Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. *) - val mk_round_nearest_ties_to_even : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. *) - val mk_rne : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. *) - val mk_round_nearest_ties_to_away : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. *) - val mk_rna : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. *) - val mk_round_toward_positive : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. *) - val mk_rtp : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. *) - val mk_round_toward_negative : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. *) - val mk_rtn : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. *) - val mk_round_toward_zero : context -> Expr.expr - - (** Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. *) - val mk_rtz : context -> Expr.expr - end - - (** Create a FloatingPoint sort. *) - val mk_sort : context -> int -> int -> Sort.sort - - (** Create the half-precision (16-bit) FloatingPoint sort.*) - val mk_sort_half : context -> Sort.sort - - (** Create the half-precision (16-bit) FloatingPoint sort. *) - val mk_sort_16 : context -> Sort.sort - - (** Create the single-precision (32-bit) FloatingPoint sort.*) - val mk_sort_single : context -> Sort.sort - - (** Create the single-precision (32-bit) FloatingPoint sort. *) - val mk_sort_32 : context -> Sort.sort - - (** Create the double-precision (64-bit) FloatingPoint sort. *) - val mk_sort_double : context -> Sort.sort - - (** Create the double-precision (64-bit) FloatingPoint sort. *) - val mk_sort_64 : context -> Sort.sort + (** Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. *) + val mk_round_nearest_ties_to_even : context -> Expr.expr - (** Create the quadruple-precision (128-bit) FloatingPoint sort. *) - val mk_sort_quadruple : context -> Sort.sort + (** Create a numeral of RoundingMode sort which represents the NearestTiesToEven rounding mode. *) + val mk_rne : context -> Expr.expr - (** Create the quadruple-precision (128-bit) FloatingPoint sort. *) - val mk_sort_128 : context -> Sort.sort - - (** Create a floating-point NaN of a given FloatingPoint sort. *) - val mk_nan : context -> Sort.sort -> Expr.expr - - (** Create a floating-point infinity of a given FloatingPoint sort. *) - val mk_inf : context -> Sort.sort -> bool -> Expr.expr - - (** Create a floating-point zero of a given FloatingPoint sort. *) - val mk_zero : context -> Sort.sort -> bool -> Expr.expr - - (** Create an expression of FloatingPoint sort from three bit-vector expressions. - - This is the operator named `fp' in the SMT FP theory definition. - Note that \c sign is required to be a bit-vector of size 1. Significand and exponent - are required to be greater than 1 and 2 respectively. The FloatingPoint sort - of the resulting expression is automatically determined from the bit-vector sizes - of the arguments. *) - val mk_fp : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Create a numeral of FloatingPoint sort from a float. - - This function is used to create numerals that fit in a float value. - It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. *) - val mk_numeral_f : context -> float -> Sort.sort -> Expr.expr - - (** Create a numeral of FloatingPoint sort from a signed integer. *) - val mk_numeral_i : context -> int -> Sort.sort -> Expr.expr + (** Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. *) + val mk_round_nearest_ties_to_away : context -> Expr.expr - (** Create a numeral of FloatingPoint sort from a sign bit and two integers. *) - val mk_numeral_i_u : context -> bool -> int -> int -> Sort.sort -> Expr.expr - - (** Create a numeral of FloatingPoint sort from a string *) - val mk_numeral_s : context -> string -> Sort.sort -> Expr.expr - - (** Indicates whether the terms is of floating-point sort. *) - val is_fp : Expr.expr -> bool - - - (** Indicates whether an expression is a floating-point abs expression *) - val is_abs : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point neg expression *) - val is_neg : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point add expression *) - val is_add : Expr.expr -> bool + (** Create a numeral of RoundingMode sort which represents the NearestTiesToAway rounding mode. *) + val mk_rna : context -> Expr.expr - (** Indicates whether an expression is a floating-point sub expression *) - val is_sub : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point mul expression *) - val is_mul : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point div expression *) - val is_div : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point fma expression *) - val is_fma : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point sqrt expression *) - val is_sqrt : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point rem expression *) - val is_rem : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point round_to_integral expression *) - val is_round_to_integral : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point min expression *) - val is_min : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point max expression *) - val is_max : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point leq expression *) - val is_leq : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point lt expression *) - val is_lt : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point geqexpression *) - val is_geq : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point gt expression *) - val is_gt : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point eq expression *) - val is_eq : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point is_normal expression *) - val is_is_normal : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point is_subnormal expression *) - val is_is_subnormal : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point is_zero expression *) - val is_is_zero : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point is_infinite expression *) - val is_is_infinite : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point is_nan expression *) - val is_is_nan : Expr.expr -> bool + (** Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. *) + val mk_round_toward_positive : context -> Expr.expr - (** Indicates whether an expression is a floating-point is_negative expression *) - val is_is_negative : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point is_positive expression *) - val is_is_positive : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point to_fp expression *) - val is_to_fp : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point to_fp_unsigned expression *) - val is_to_fp_unsigned : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point to_ubv expression *) - val is_to_ubv : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point to_sbv expression *) - val is_to_sbv : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point to_real expression *) - val is_to_real : Expr.expr -> bool - - (** Indicates whether an expression is a floating-point to_ieee_bv expression *) - val is_to_ieee_bv : Expr.expr -> bool - - - (** Returns a string representation of a numeral. *) - val numeral_to_string : Expr.expr -> string - - (** Creates a floating-point constant. *) - val mk_const : context -> Symbol.symbol -> Sort.sort -> Expr.expr - - (** Creates a floating-point constant. *) - val mk_const_s : context -> string -> Sort.sort -> Expr.expr - - (** Floating-point absolute value *) - val mk_abs : context -> Expr.expr -> Expr.expr - - (** Floating-point negation *) - val mk_neg : context -> Expr.expr -> Expr.expr - - (** Floating-point addition *) - val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point subtraction *) - val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point multiplication *) - val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point division *) - val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point fused multiply-add. *) - val mk_fma : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + (** Create a numeral of RoundingMode sort which represents the TowardPositive rounding mode. *) + val mk_rtp : context -> Expr.expr - (** Floating-point square root *) - val mk_sqrt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point remainder *) - val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr + (** Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. *) + val mk_round_toward_negative : context -> Expr.expr - (** Floating-point roundToIntegral. - - Rounds a floating-point number to the closest integer, - again represented as a floating-point number. *) - val mk_round_to_integral : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Minimum of floating-point numbers. *) - val mk_min : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Maximum of floating-point numbers. *) - val mk_max : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point less than or equal. *) - val mk_leq : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point less than. *) - val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point greater than or equal. *) - val mk_geq : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point greater than. *) - val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Floating-point equality. *) - val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a normal floating-point number. *) - val mk_is_normal : context -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a subnormal floating-point number. *) - val mk_is_subnormal : context -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a floating-point number with zero value, i.e., +zero or -zero. *) - val mk_is_zero : context -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a floating-point number representing +oo or -oo. *) - val mk_is_infinite : context -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a NaN. *) - val mk_is_nan : context -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a negative floating-point number. *) - val mk_is_negative : context -> Expr.expr -> Expr.expr - - (** Predicate indicating whether t is a positive floating-point number. *) - val mk_is_positive : context -> Expr.expr -> Expr.expr - - (** Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. *) - val mk_to_fp_bv : context -> Expr.expr -> Sort.sort -> Expr.expr - - (** Conversion of a FloatingPoint term into another term of different FloatingPoint sort. *) - val mk_to_fp_float : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr - - (** Conversion of a term of real sort into a term of FloatingPoint sort. *) - val mk_to_fp_real : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr - - (** Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. *) - val mk_to_fp_signed : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr - - (** Conversion of a 2's complement unsigned bit-vector term into a term of FloatingPoint sort. *) - val mk_to_fp_unsigned : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr - - (** C1onversion of a floating-point term into an unsigned bit-vector. *) - val mk_to_fp_ubv : context -> Expr.expr -> Expr.expr -> int -> Expr.expr - - (** Conversion of a floating-point term into a signed bit-vector. *) - val mk_to_fp_sbv : context -> Expr.expr -> Expr.expr -> int -> Expr.expr - - (** Conversion of a floating-point term into a real-numbered term. *) - val mk_to_fp_real : context -> Expr.expr -> Expr.expr + (** Create a numeral of RoundingMode sort which represents the TowardNegative rounding mode. *) + val mk_rtn : context -> Expr.expr - (** Retrieves the number of bits reserved for the exponent in a FloatingPoint sort. *) - val get_ebits : context -> Sort.sort -> int - - (** Retrieves the number of bits reserved for the significand in a FloatingPoint sort. *) - val get_sbits : context -> Sort.sort -> int + (** Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. *) + val mk_round_toward_zero : context -> Expr.expr - (** Retrieves the sign of a floating-point literal. *) - val get_numeral_sign : context -> Expr.expr -> bool * int - - (** Return the significand value of a floating-point numeral as a string. *) - val get_numeral_significand_string : context -> Expr.expr -> string - - (** Return the exponent value of a floating-point numeral as a string *) - val get_numeral_exponent_string : context -> Expr.expr -> string - - (** Return the exponent value of a floating-point numeral as a signed integer *) - val get_numeral_exponent_int : context -> Expr.expr -> bool * int - - (** Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. *) - val mk_to_ieee_bv : context -> Expr.expr -> Expr.expr - - (** Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. *) - val mk_to_fp_real_int : context -> Expr.expr -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr - - (** The string representation of a numeral *) - val numeral_to_string : Expr.expr -> string + (** Create a numeral of RoundingMode sort which represents the TowardZero rounding mode. *) + val mk_rtz : context -> Expr.expr end + (** Create a FloatingPoint sort. *) + val mk_sort : context -> int -> int -> Sort.sort + + (** Create the half-precision (16-bit) FloatingPoint sort.*) + val mk_sort_half : context -> Sort.sort + + (** Create the half-precision (16-bit) FloatingPoint sort. *) + val mk_sort_16 : context -> Sort.sort + + (** Create the single-precision (32-bit) FloatingPoint sort.*) + val mk_sort_single : context -> Sort.sort + + (** Create the single-precision (32-bit) FloatingPoint sort. *) + val mk_sort_32 : context -> Sort.sort + + (** Create the double-precision (64-bit) FloatingPoint sort. *) + val mk_sort_double : context -> Sort.sort + + (** Create the double-precision (64-bit) FloatingPoint sort. *) + val mk_sort_64 : context -> Sort.sort + + (** Create the quadruple-precision (128-bit) FloatingPoint sort. *) + val mk_sort_quadruple : context -> Sort.sort + + (** Create the quadruple-precision (128-bit) FloatingPoint sort. *) + val mk_sort_128 : context -> Sort.sort + + (** Create a floating-point NaN of a given FloatingPoint sort. *) + val mk_nan : context -> Sort.sort -> Expr.expr + + (** Create a floating-point infinity of a given FloatingPoint sort. *) + val mk_inf : context -> Sort.sort -> bool -> Expr.expr + + (** Create a floating-point zero of a given FloatingPoint sort. *) + val mk_zero : context -> Sort.sort -> bool -> Expr.expr + + (** Create an expression of FloatingPoint sort from three bit-vector expressions. + + This is the operator named `fp' in the SMT FP theory definition. + Note that \c sign is required to be a bit-vector of size 1. Significand and exponent + are required to be greater than 1 and 2 respectively. The FloatingPoint sort + of the resulting expression is automatically determined from the bit-vector sizes + of the arguments. *) + val mk_fp : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a float. + + This function is used to create numerals that fit in a float value. + It is slightly faster than #Z3_mk_numeral since it is not necessary to parse a string. *) + val mk_numeral_f : context -> float -> Sort.sort -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a signed integer. *) + val mk_numeral_i : context -> int -> Sort.sort -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a sign bit and two integers. *) + val mk_numeral_i_u : context -> bool -> int -> int -> Sort.sort -> Expr.expr + + (** Create a numeral of FloatingPoint sort from a string *) + val mk_numeral_s : context -> string -> Sort.sort -> Expr.expr + + (** Indicates whether the terms is of floating-point sort. *) + val is_fp : Expr.expr -> bool + + + (** Indicates whether an expression is a floating-point abs expression *) + val is_abs : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point neg expression *) + val is_neg : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point add expression *) + val is_add : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point sub expression *) + val is_sub : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point mul expression *) + val is_mul : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point div expression *) + val is_div : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point fma expression *) + val is_fma : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point sqrt expression *) + val is_sqrt : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point rem expression *) + val is_rem : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point round_to_integral expression *) + val is_round_to_integral : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point min expression *) + val is_min : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point max expression *) + val is_max : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point leq expression *) + val is_leq : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point lt expression *) + val is_lt : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point geqexpression *) + val is_geq : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point gt expression *) + val is_gt : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point eq expression *) + val is_eq : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_normal expression *) + val is_is_normal : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_subnormal expression *) + val is_is_subnormal : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_zero expression *) + val is_is_zero : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_infinite expression *) + val is_is_infinite : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_nan expression *) + val is_is_nan : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_negative expression *) + val is_is_negative : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point is_positive expression *) + val is_is_positive : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_fp expression *) + val is_to_fp : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_fp_unsigned expression *) + val is_to_fp_unsigned : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_ubv expression *) + val is_to_ubv : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_sbv expression *) + val is_to_sbv : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_real expression *) + val is_to_real : Expr.expr -> bool + + (** Indicates whether an expression is a floating-point to_ieee_bv expression *) + val is_to_ieee_bv : Expr.expr -> bool + + + (** Returns a string representation of a numeral. *) + val numeral_to_string : Expr.expr -> string + + (** Creates a floating-point constant. *) + val mk_const : context -> Symbol.symbol -> Sort.sort -> Expr.expr + + (** Creates a floating-point constant. *) + val mk_const_s : context -> string -> Sort.sort -> Expr.expr + + (** Floating-point absolute value *) + val mk_abs : context -> Expr.expr -> Expr.expr + + (** Floating-point negation *) + val mk_neg : context -> Expr.expr -> Expr.expr + + (** Floating-point addition *) + val mk_add : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point subtraction *) + val mk_sub : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point multiplication *) + val mk_mul : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point division *) + val mk_div : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point fused multiply-add. *) + val mk_fma : context -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point square root *) + val mk_sqrt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point remainder *) + val mk_rem : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point roundToIntegral. + + Rounds a floating-point number to the closest integer, + again represented as a floating-point number. *) + val mk_round_to_integral : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Minimum of floating-point numbers. *) + val mk_min : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Maximum of floating-point numbers. *) + val mk_max : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point less than or equal. *) + val mk_leq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point less than. *) + val mk_lt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point greater than or equal. *) + val mk_geq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point greater than. *) + val mk_gt : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Floating-point equality. *) + val mk_eq : context -> Expr.expr -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a normal floating-point number. *) + val mk_is_normal : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a subnormal floating-point number. *) + val mk_is_subnormal : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a floating-point number with zero value, i.e., +zero or -zero. *) + val mk_is_zero : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a floating-point number representing +oo or -oo. *) + val mk_is_infinite : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a NaN. *) + val mk_is_nan : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a negative floating-point number. *) + val mk_is_negative : context -> Expr.expr -> Expr.expr + + (** Predicate indicating whether t is a positive floating-point number. *) + val mk_is_positive : context -> Expr.expr -> Expr.expr + + (** Conversion of a single IEEE 754-2008 bit-vector into a floating-point number. *) + val mk_to_fp_bv : context -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a FloatingPoint term into another term of different FloatingPoint sort. *) + val mk_to_fp_float : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a term of real sort into a term of FloatingPoint sort. *) + val mk_to_fp_real : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a 2's complement signed bit-vector term into a term of FloatingPoint sort. *) + val mk_to_fp_signed : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** Conversion of a 2's complement unsigned bit-vector term into a term of FloatingPoint sort. *) + val mk_to_fp_unsigned : context -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** C1onversion of a floating-point term into an unsigned bit-vector. *) + val mk_to_ubv : context -> Expr.expr -> Expr.expr -> int -> Expr.expr + + (** Conversion of a floating-point term into a signed bit-vector. *) + val mk_to_sbv : context -> Expr.expr -> Expr.expr -> int -> Expr.expr + + (** Conversion of a floating-point term into a real-numbered term. *) + val mk_to_real : context -> Expr.expr -> Expr.expr + + (** Retrieves the number of bits reserved for the exponent in a FloatingPoint sort. *) + val get_ebits : context -> Sort.sort -> int + + (** Retrieves the number of bits reserved for the significand in a FloatingPoint sort. *) + val get_sbits : context -> Sort.sort -> int + + (** Retrieves the sign of a floating-point literal. *) + val get_numeral_sign : context -> Expr.expr -> bool * int + + (** Return the significand value of a floating-point numeral as a string. *) + val get_numeral_significand_string : context -> Expr.expr -> string + + (** Return the exponent value of a floating-point numeral as a string *) + val get_numeral_exponent_string : context -> Expr.expr -> string + + (** Return the exponent value of a floating-point numeral as a signed integer *) + val get_numeral_exponent_int : context -> Expr.expr -> bool * int + + (** Conversion of a floating-point term into a bit-vector term in IEEE 754-2008 format. *) + val mk_to_ieee_bv : context -> Expr.expr -> Expr.expr + + (** Conversion of a real-sorted significand and an integer-sorted exponent into a term of FloatingPoint sort. *) + val mk_to_fp_int_real : context -> Expr.expr -> Expr.expr -> Expr.expr -> Sort.sort -> Expr.expr + + (** The string representation of a numeral *) + val numeral_to_string : Expr.expr -> string +end + (** Functions to manipulate proof expressions *) module Proof : @@ -2654,7 +2648,7 @@ sig (** Function interpretations entries - An Entry object represents an element in the finite map used to a function interpretation. *) + An Entry object represents an element in the finite map used to a function interpretation. *) module FuncEntry : sig type func_entry @@ -2844,8 +2838,8 @@ sig val get_subgoal : apply_result -> int -> Goal.goal (** Convert a model for a subgoal into a model for the original - goal [g], that the ApplyResult was obtained from. - #return A model for [g] *) + goal [g], that the ApplyResult was obtained from. + #return A model for [g] *) val convert_model : apply_result -> int -> Model.model -> Model.model (** A string representation of the ApplyResult. *) @@ -2946,7 +2940,7 @@ sig type statistics (** Statistical data is organized into pairs of \[Key, Entry\], where every - Entry is either a floating point or integer value. + Entry is either a floating point or integer value. *) module Entry : sig @@ -2960,16 +2954,16 @@ sig (** The float-value of the entry. *) val get_float : statistics_entry -> float - + (** True if the entry is uint-valued. *) val is_int : statistics_entry -> bool - + (** True if the entry is float-valued. *) val is_float : statistics_entry -> bool - + (** The string representation of the the entry's value. *) val to_string_value : statistics_entry -> string - + (** The string representation of the entry (key and value) *) val to_string : statistics_entry -> string end From e29abefb12330ee4c6a053a95c28f7ab129ae5c0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 18:44:59 +0000 Subject: [PATCH 504/507] Merge branch 'unstable' of https://git01.codeplex.com/z3 into ml-ng Conflicts: scripts/mk_util.py + Cosmetics Signed-off-by: Christoph M. Wintersteiger --- examples/ml/ml_example.ml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index 127a973aa..df062bde4 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -282,13 +282,11 @@ let fpa_example ( ctx : context ) = Printf.printf "Test passed.\n" ); -(* Show that the following are equal: *) -(* (fp #b0 #b10000000001 #xc000000000000) *) -(* ((_ to_fp 11 53) #x401c000000000000)) *) -(* ((_ to_fp 11 53) RTZ 1.75 2))) *) -(* ((_ to_fp 11 53) RTZ 7.0))) *) - - let solver = (mk_solver ctx None) in + (* Show that the following are equal: *) + (* (fp #b0 #b10000000001 #xc000000000000) *) + (* ((_ to_fp 11 53) #x401c000000000000)) *) + (* ((_ to_fp 11 53) RTZ 1.75 2))) *) + (* ((_ to_fp 11 53) RTZ 7.0))) *) let c1 = (mk_fp ctx (mk_numeral_string ctx "0" (BitVector.mk_sort ctx 1)) (mk_numeral_string ctx "3377699720527872" (BitVector.mk_sort ctx 52)) From 2f3ea1f39d2f700120f34d40fdcc4d4626e8f808 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 18:48:51 +0000 Subject: [PATCH 505/507] removed legacy ML API Signed-off-by: Christoph M. Wintersteiger --- src/api/ml/old/Makefile | 14 - src/api/ml/old/Makefile.build | 69 - src/api/ml/old/README-linux | 22 - src/api/ml/old/README-osx | 22 - src/api/ml/old/README-test-linux | 17 - src/api/ml/old/README-test-osx | 17 - src/api/ml/old/add_error_checking.V3.sed | 2 - src/api/ml/old/add_error_checking.sed | 113 - src/api/ml/old/build-lib.cmd | 3 - src/api/ml/old/build-lib.sh | 31 - src/api/ml/old/build-test.cmd | 19 - src/api/ml/old/build-test.sh | 6 - src/api/ml/old/build.cmd | 53 - src/api/ml/old/clean.cmd | 13 - src/api/ml/old/cleantmp.cmd | 15 - src/api/ml/old/compile_mlapi.cmd | 98 - src/api/ml/old/error_handling.idl | 165 - src/api/ml/old/exec.cmd | 5 - src/api/ml/old/exec.sh | 4 - src/api/ml/old/generate_mlapi.cmd | 72 - src/api/ml/old/generate_mlapi.sh | 53 - src/api/ml/old/import.cmd | 55 - src/api/ml/old/mlx_get_app_args.idl | 11 - src/api/ml/old/mlx_get_array_sort.idl | 11 - src/api/ml/old/mlx_get_datatype_sort.idl | 13 - src/api/ml/old/mlx_get_domains.idl | 11 - src/api/ml/old/mlx_get_error_msg.idl | 6 - src/api/ml/old/mlx_get_pattern_terms.idl | 11 - src/api/ml/old/mlx_get_tuple_sort.idl | 12 - src/api/ml/old/mlx_mk_context_x.idl | 36 - src/api/ml/old/mlx_mk_datatypes.idl | 28 - src/api/ml/old/mlx_mk_numeral.idl | 21 - src/api/ml/old/mlx_mk_sort.idl | 69 - src/api/ml/old/mlx_mk_symbol.idl | 22 - src/api/ml/old/mlx_model.idl | 19 - src/api/ml/old/mlx_numeral_refine.idl | 10 - src/api/ml/old/mlx_parse_smtlib.idl | 40 - src/api/ml/old/mlx_sort_refine.idl | 8 - src/api/ml/old/mlx_statistics.idl | 10 - src/api/ml/old/mlx_symbol_refine.idl | 8 - src/api/ml/old/mlx_term_refine.idl | 37 - src/api/ml/old/postprocess.sed | 8 - src/api/ml/old/preprocess.sed | 82 - src/api/ml/old/queen.ml | 112 - src/api/ml/old/queen.regress.err | 0 src/api/ml/old/queen.regress.out | 1852 -- src/api/ml/old/reverse.sed | 3 - src/api/ml/old/test_mlapi.cmd | 61 - src/api/ml/old/test_mlapi.ml | 209 - src/api/ml/old/test_mlapiV3.ml | 1418 -- src/api/ml/old/test_theory.ml | 42 - src/api/ml/old/update-ml-doc.cmd | 38 - src/api/ml/old/x3.ml | 366 - src/api/ml/old/x3V3.ml | 378 - src/api/ml/old/x3V3.mli | 361 - src/api/ml/old/z3.0.idl | 597 - src/api/ml/old/z3_stubs.c | 19044 --------------------- src/api/ml/old/z3_theory_stubs.c | 339 - 58 files changed, 26161 deletions(-) delete mode 100644 src/api/ml/old/Makefile delete mode 100644 src/api/ml/old/Makefile.build delete mode 100644 src/api/ml/old/README-linux delete mode 100644 src/api/ml/old/README-osx delete mode 100644 src/api/ml/old/README-test-linux delete mode 100644 src/api/ml/old/README-test-osx delete mode 100644 src/api/ml/old/add_error_checking.V3.sed delete mode 100644 src/api/ml/old/add_error_checking.sed delete mode 100755 src/api/ml/old/build-lib.cmd delete mode 100644 src/api/ml/old/build-lib.sh delete mode 100755 src/api/ml/old/build-test.cmd delete mode 100644 src/api/ml/old/build-test.sh delete mode 100755 src/api/ml/old/build.cmd delete mode 100755 src/api/ml/old/clean.cmd delete mode 100755 src/api/ml/old/cleantmp.cmd delete mode 100755 src/api/ml/old/compile_mlapi.cmd delete mode 100644 src/api/ml/old/error_handling.idl delete mode 100755 src/api/ml/old/exec.cmd delete mode 100644 src/api/ml/old/exec.sh delete mode 100755 src/api/ml/old/generate_mlapi.cmd delete mode 100755 src/api/ml/old/generate_mlapi.sh delete mode 100755 src/api/ml/old/import.cmd delete mode 100644 src/api/ml/old/mlx_get_app_args.idl delete mode 100644 src/api/ml/old/mlx_get_array_sort.idl delete mode 100644 src/api/ml/old/mlx_get_datatype_sort.idl delete mode 100644 src/api/ml/old/mlx_get_domains.idl delete mode 100644 src/api/ml/old/mlx_get_error_msg.idl delete mode 100644 src/api/ml/old/mlx_get_pattern_terms.idl delete mode 100644 src/api/ml/old/mlx_get_tuple_sort.idl delete mode 100644 src/api/ml/old/mlx_mk_context_x.idl delete mode 100644 src/api/ml/old/mlx_mk_datatypes.idl delete mode 100644 src/api/ml/old/mlx_mk_numeral.idl delete mode 100644 src/api/ml/old/mlx_mk_sort.idl delete mode 100644 src/api/ml/old/mlx_mk_symbol.idl delete mode 100644 src/api/ml/old/mlx_model.idl delete mode 100644 src/api/ml/old/mlx_numeral_refine.idl delete mode 100644 src/api/ml/old/mlx_parse_smtlib.idl delete mode 100644 src/api/ml/old/mlx_sort_refine.idl delete mode 100644 src/api/ml/old/mlx_statistics.idl delete mode 100644 src/api/ml/old/mlx_symbol_refine.idl delete mode 100644 src/api/ml/old/mlx_term_refine.idl delete mode 100644 src/api/ml/old/postprocess.sed delete mode 100644 src/api/ml/old/preprocess.sed delete mode 100644 src/api/ml/old/queen.ml delete mode 100644 src/api/ml/old/queen.regress.err delete mode 100644 src/api/ml/old/queen.regress.out delete mode 100644 src/api/ml/old/reverse.sed delete mode 100755 src/api/ml/old/test_mlapi.cmd delete mode 100644 src/api/ml/old/test_mlapi.ml delete mode 100644 src/api/ml/old/test_mlapiV3.ml delete mode 100644 src/api/ml/old/test_theory.ml delete mode 100755 src/api/ml/old/update-ml-doc.cmd delete mode 100644 src/api/ml/old/x3.ml delete mode 100644 src/api/ml/old/x3V3.ml delete mode 100644 src/api/ml/old/x3V3.mli delete mode 100644 src/api/ml/old/z3.0.idl delete mode 100644 src/api/ml/old/z3_stubs.c delete mode 100644 src/api/ml/old/z3_theory_stubs.c diff --git a/src/api/ml/old/Makefile b/src/api/ml/old/Makefile deleted file mode 100644 index 55f89fe1c..000000000 --- a/src/api/ml/old/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# to set ARGS, invoke as e.g.: $ make ARGS='-DUNSAFE_ERRORS -DLEAK_CONTEXTS' -ARGS= - - -default: z3.ml z3.mli z3_stubs.c - - -%.ml %.mli %_stubs.c: ../%_api.h %.0.idl x3.ml x3V3.ml x3V3.mli \ - error_handling.idl mlx_get_app_args.idl mlx_get_array_sort.idl mlx_get_datatype_sort.idl mlx_get_domains.idl mlx_get_error_msg.idl mlx_get_pattern_terms.idl mlx_get_tuple_sort.idl mlx_mk_context_x.idl mlx_mk_datatypes.idl mlx_mk_numeral.idl mlx_mk_sort.idl mlx_mk_symbol.idl mlx_model.idl mlx_numeral_refine.idl mlx_parse_smtlib.idl mlx_sort_refine.idl mlx_statistics.idl mlx_symbol_refine.idl mlx_term_refine.idl \ - generate_mlapi.sh add_error_checking.V3.sed add_error_checking.sed preprocess.sed postprocess.sed reverse.sed - ./generate_mlapi.sh $(ARGS) - -clean: - rm -f z3.ml z3.mli z3_stubs.c diff --git a/src/api/ml/old/Makefile.build b/src/api/ml/old/Makefile.build deleted file mode 100644 index 0a737e356..000000000 --- a/src/api/ml/old/Makefile.build +++ /dev/null @@ -1,69 +0,0 @@ -# Makefile to compile OCaml interface to Z3 -# -# Parameters: ARGS and DEPS environment variables -# ARGS is passed through to the Makefile that generates the OCaml interface -# DEPS is a sequence of files that are deleted when the OCaml interface changes - -SRC_ML=../../../src/api/ml -ifeq (${OS}, Windows_NT) -# the BLD_ML path ends up stored in z3.cm{,x}a, so it must be in windows format -BLD_ML=$(shell cygpath -m $(CURDIR)) -CFLAGS=-ccopt -wd4090 -ccopt -I$(SRC_ML)/.. -XCDBG=-g $(CFLAGS) -XCOPT=-ccopt -Ox -ccopt -Oy- $(CFLAGS) -# ole32 is needed by camlidl (COM support) -XLIB=-cclib ole32.lib -AR=lib /nologo /LIBPATH:../../build ../../libz3.lib /out: -O=obj -A=lib -else -BLD_ML=$(CURDIR) -CFLAGS=-ccopt -Wno-discard-qual -ccopt -Wno-unused-variable -ccopt -I$(SRC_ML)/.. -XCDBG=-g -ccopt -g $(CFLAGS) -XCOPT=-ccopt -O3 -ccopt -fomit-frame-pointer $(CFLAGS) -XLIB= -AR=ar rcs # note trailing space is significant -O=o -A=a -endif - - -all: z3.cma z3.cmxa ocamlz3 - - -# keep these files to avoid repeatedly rebuilding them -.PRECIOUS: $(SRC_ML)/z3.ml $(SRC_ML)/z3.mli $(SRC_ML)/z3_stubs.c z3.ml z3.mli z3_stubs.c z3_theory_stubs.c - -# regenerate OCaml API if needed -$(SRC_ML)/%.mli $(SRC_ML)/%.ml $(SRC_ML)/%_stubs.c: $(SRC_ML)/Makefile - make -C $(SRC_ML) z3.mli z3.ml z3_stubs.c - -# copy OCaml API from src to build directories -%.mli %.ml %_stubs.c %_theory_stubs.c: $(SRC_ML)/%.mli $(SRC_ML)/%.ml $(SRC_ML)/%_stubs.c Makefile - cp $(SRC_ML)/z3.mli $(SRC_ML)/z3.ml $(SRC_ML)/z3_stubs.c $(SRC_ML)/z3_theory_stubs.c . - -# OCaml library module for native code clients -%.cmxa %.cmi lib%stubs.a %.a: %.mli %.ml %_stubs.c %_theory_stubs.c Makefile - rm -f $(DEPS) - ocamlopt.opt -c $(XCOPT) z3.mli z3.ml z3_stubs.c z3_theory_stubs.c - $(AR)libz3stubs.$(A) z3.$(O) z3_stubs.$(O) z3_theory_stubs.$(O) - ocamlopt.opt -a -cclib -L$(BLD_ML)/../.. $(XLIB) -cclib -lcamlidl -cclib -lz3 -cclib -lz3stubs z3.cmx -o z3.cmxa - rm -f z3_theory_stubs.$(O) z3_stubs.$(O) z3.$(O) z3.cmx - -# OCaml library module for byte code clients -%.cma %.cmi lib%stubs_dbg.a: %.mli %.ml %_stubs.c %_theory_stubs.c Makefile - rm -f $(DEPS) - ocamlc.opt -c $(XCDBG) z3.mli z3.ml z3_stubs.c z3_theory_stubs.c - $(AR)libz3stubs_dbg.$(A) z3_stubs.$(O) z3_theory_stubs.$(O) - ocamlc.opt -custom -a $(CXDBG) -cclib -L$(BLD_ML)/../.. $(XLIB) -cclib -lcamlidl -cclib -lz3 -cclib -lz3stubs_dbg z3.cmo -o z3.cma - rm -f z3_theory_stubs.$(O) z3_stubs.$(O) z3.cmo - - -# OCaml custom toplevel system pre-linked with Z3 -ocamlz3: z3.cma Makefile - ocamlmktop -o ocamlz3 z3.cma -cclib -L. - - -clean: Makefile - make -C $(SRC_ML) clean - rm -rf Makefile libz3stubs.$(A) libz3stubs_dbg.$(A) ocamlz3 ocamlz3.dSYM z3.$(O) z3.$(A) z3.cma z3.cmi z3.cmo z3.cmx z3.cmxa z3.ml z3.mli z3_stubs.$(O) z3_stubs.c z3_theory_stubs.$(O) z3_theory_stubs.c diff --git a/src/api/ml/old/README-linux b/src/api/ml/old/README-linux deleted file mode 100644 index 5ee20bb27..000000000 --- a/src/api/ml/old/README-linux +++ /dev/null @@ -1,22 +0,0 @@ -The OCaml API for Z3 was tested using OCaml 3.12.1. -You also need CamlIDL to be able to generate the OCaml API. - -- To download OCaml: - http://caml.inria.fr/ocaml/ - -- To download CamlIDL: - http://forge.ocamlcore.org/projects/camlidl/ - -- To build the OCaml API for Z3: - ./build-lib.sh - -Remark: The OCaml and C compiler tool chains must be configured in your environment. - -Remark: Building the OCaml API copies some pathnames into files, -so the OCaml API must be recompiled if the Z3 library files are moved. - -See ../examples/ocaml/build-test.sh for an example of how to compile and link with Z3. - -Acknowledgements: -The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg. -Many thanks to them! diff --git a/src/api/ml/old/README-osx b/src/api/ml/old/README-osx deleted file mode 100644 index 5ee20bb27..000000000 --- a/src/api/ml/old/README-osx +++ /dev/null @@ -1,22 +0,0 @@ -The OCaml API for Z3 was tested using OCaml 3.12.1. -You also need CamlIDL to be able to generate the OCaml API. - -- To download OCaml: - http://caml.inria.fr/ocaml/ - -- To download CamlIDL: - http://forge.ocamlcore.org/projects/camlidl/ - -- To build the OCaml API for Z3: - ./build-lib.sh - -Remark: The OCaml and C compiler tool chains must be configured in your environment. - -Remark: Building the OCaml API copies some pathnames into files, -so the OCaml API must be recompiled if the Z3 library files are moved. - -See ../examples/ocaml/build-test.sh for an example of how to compile and link with Z3. - -Acknowledgements: -The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg. -Many thanks to them! diff --git a/src/api/ml/old/README-test-linux b/src/api/ml/old/README-test-linux deleted file mode 100644 index fc15fb2a2..000000000 --- a/src/api/ml/old/README-test-linux +++ /dev/null @@ -1,17 +0,0 @@ -This directory contains scripts to build the test application using -OCaml. You also need CamlIDL to be able to generate the OCaml API. - -- To download OCaml: - http://caml.inria.fr/ocaml/ - -- To download CamlIDL: - http://forge.ocamlcore.org/projects/camlidl/ - -- One must build the OCaml library before compiling the example. - Go to directory ../ocaml - -- Use 'build-test.sh' to build the test application using the OCaml compiler. - -Remark: The OCaml and C compiler tool chains must be configured in your environment. - -- Use 'exec.sh' to execute test_mlapi. The script sets LD_LIBRARY_PATH, and invokes test_mlapi. diff --git a/src/api/ml/old/README-test-osx b/src/api/ml/old/README-test-osx deleted file mode 100644 index 3a20d1f1d..000000000 --- a/src/api/ml/old/README-test-osx +++ /dev/null @@ -1,17 +0,0 @@ -This directory contains scripts to build the test application using -OCaml. You also need CamlIDL to be able to generate the OCaml API. - -- To download OCaml: - http://caml.inria.fr/ocaml/ - -- To download CamlIDL: - http://forge.ocamlcore.org/projects/camlidl/ - -- One must build the OCaml library before compiling the example. - Go to directory ../ocaml - -- Use 'build-test.sh' to build the test application using the OCaml compiler. - -Remark: The OCaml and C compiler tool chains must be configured in your environment. - -- Use 'exec.sh' to execute test_mlapi. The script sets DYLD_LIBRARY_PATH, and invokes test_mlapi. diff --git a/src/api/ml/old/add_error_checking.V3.sed b/src/api/ml/old/add_error_checking.V3.sed deleted file mode 100644 index 7df291520..000000000 --- a/src/api/ml/old/add_error_checking.V3.sed +++ /dev/null @@ -1,2 +0,0 @@ -# Customize error handling for contexts created in ML: -s/Z3_API Z3_mk_context(\(.*\))/Z3_API Z3_mk_context(\1) quote(dealloc,\"Z3_set_error_handler(_res, (void*)caml_z3_error_handler);\")/g diff --git a/src/api/ml/old/add_error_checking.sed b/src/api/ml/old/add_error_checking.sed deleted file mode 100644 index 71c06b9e4..000000000 --- a/src/api/ml/old/add_error_checking.sed +++ /dev/null @@ -1,113 +0,0 @@ -# Do not add epilogue to Z3_del_context -/Z3_API .*Z3_del_context.*/b endt - -# Add error checking epilogue for all Z3_API functions that accept two Z3_contexts -:begincc -# add epilogue for two Z3_context parameters and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\");/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3);\");/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\")/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3);\")/g -t endt - -# if complete prototype, done with two Z3_contexts -/Z3_API .*(.*);[ ]*$/b endcc -/Z3_API .*(.*)[ ]*$/b endcc - -# if incomplete prototype -/Z3_API .*(.*/{ - - # read another line - N - - # add epilogue for two Z3_context parameters and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\");/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\");/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")/g - t endt - - # else keep looking for two Z3_contexts - b begincc -} -:endcc - -# Add error checking epilogue for all Z3_API functions that accept one Z3_context -:beginc -# add epilogue for one Z3_context parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\");/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\");/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\")/g -t endt - -# if complete prototype, done with all Z3_contexts -/Z3_API .*(.*);[ ]*$/b endc -/Z3_API .*(.*)[ ]*$/b endc - -# if incomplete prototype -/Z3_API .*(.*/{ - - # read another line - N - - # add epilogue for one Z3_context parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\");/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\");/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\")/g - t endt - - # else keep looking for one Z3_context - b beginc -} -:endc - - -# Add error checking epilogue for all Z3_API functions that accept a Z3_theory -:begint -# add epilogue for one Z3_theory parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt -s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g -t endt -s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g -t endt - -# if complete prototype, done with all Z3_theorys -/Z3_API .*(.*);[ ]*$/b endt -/Z3_API .*(.*)[ ]*$/b endt - -/Z3_API .*(.*/{ - - # read another line - N - - # add epilogue for one Z3_theory parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt - s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g - t endt - s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g - t endt - - # else keep looking for one Z3_theory - b begint -} -:endt diff --git a/src/api/ml/old/build-lib.cmd b/src/api/ml/old/build-lib.cmd deleted file mode 100755 index 7cf1bbcbd..000000000 --- a/src/api/ml/old/build-lib.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@echo off - -call .\compile_mlapi.cmd ..\include ..\bin ..\bin diff --git a/src/api/ml/old/build-lib.sh b/src/api/ml/old/build-lib.sh deleted file mode 100644 index 93c7262b1..000000000 --- a/src/api/ml/old/build-lib.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# Script to compile the Z3 OCaml API -# Expects to find ../lib/libz3{,_dbg}.{a,so,dylib} - -CFLAGS="-ccopt -Wno-discard-qual -ccopt -I../include" -XCDBG="-g -ccopt -g $CFLAGS" -XCOPT="-ccopt -O3 -ccopt -fomit-frame-pointer $CFLAGS" - - -ocamlc -c $XCDBG z3_stubs.c z3_theory_stubs.c z3.mli z3.ml - -ocamlopt -c $XCDBG z3_stubs.c z3_theory_stubs.c z3.mli z3.ml - -ar rcs libz3stubs_dbg.a z3.o z3_stubs.o z3_theory_stubs.o - -ocamlopt -c $XCOPT z3_stubs.c z3_theory_stubs.c z3.mli z3.ml - -ar rcs libz3stubs.a z3.o z3_stubs.o z3_theory_stubs.o - -ocamlc -custom -a $XCDBG -cclib -L$PWD/../lib -cclib -lz3_dbg -cclib -lcamlidl -cclib -lz3stubs_dbg z3.cmo -o z3_dbg.cma - -ocamlc -custom -a $XCDBG -cclib -L$PWD/../lib -cclib -lz3 -cclib -lcamlidl -cclib -lz3stubs z3.cmo -o z3.cma - -ocamlopt -a $XCDBG -cclib -L$PWD/../lib -cclib -lz3_dbg -cclib -lcamlidl -cclib -lz3stubs_dbg z3.cmx -o z3_dbg.cmxa - -ocamlopt -a $XCOPT -cclib -L$PWD/../lib -cclib -lz3 -cclib -lcamlidl -cclib -lz3stubs z3.cmx -o z3.cmxa - -ocamlmktop -o ocamlz3 z3.cma -cclib -L. - -rm z3.cm{o,x} *.o diff --git a/src/api/ml/old/build-test.cmd b/src/api/ml/old/build-test.cmd deleted file mode 100755 index 13a752dbb..000000000 --- a/src/api/ml/old/build-test.cmd +++ /dev/null @@ -1,19 +0,0 @@ -@echo off - -if not exist ..\..\ocaml\z3.cmxa ( - echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml" - goto :EOF -) - -REM ocaml (>= 3.11) calls the linker through flexlink -ocamlc -version >> ocaml_version -set /p OCAML_VERSION= NUL z3_stubs.c z3.mli z3.ml z3V3_stubs.*.c z3V3.*.mli z3V3.*.ml - -REM files produced by update-ml-doc.cmd -rd 2>NUL /s /q doc - -exit /B 0 diff --git a/src/api/ml/old/cleantmp.cmd b/src/api/ml/old/cleantmp.cmd deleted file mode 100755 index 257e26a96..000000000 --- a/src/api/ml/old/cleantmp.cmd +++ /dev/null @@ -1,15 +0,0 @@ -@echo off - -REM Script to delete intermediate temporary files from generating Z3 OCaml API - -REM files produced by generate_mlapi.cmd -del /q 2>NUL z3_api.idl - -REM files produced by compile_mlapi.cmd -del /q 2>NUL *.cmi *.cmo *.cmx *.cma *.cmxa *.obj *.lib *.pdb ocamlz3.exe - -REM files produced by test_mlapi.cmd -del /q 2>NUL test*.exe queen*.exe test_*api.out test_*apiV3.out test_*api.err test_*apiV3.err queen.out queen.err z3.log ml.log test_mlapi.log .z3-trace - -REM backup files -del /q 2>NUL *~ diff --git a/src/api/ml/old/compile_mlapi.cmd b/src/api/ml/old/compile_mlapi.cmd deleted file mode 100755 index 17776b6b8..000000000 --- a/src/api/ml/old/compile_mlapi.cmd +++ /dev/null @@ -1,98 +0,0 @@ -@echo off -SETLOCAL - -REM Script to compile the Z3 OCaml API -REM -REM Compiles byte and debug native code versions with debug info, optimized native code versions without -REM -REM Assumes that environment variables are set to provide access to the C and OCaml compilers - -REM directory containing z3_api.h -set Z3SRC=%1 - -REM directory containing z3.dll -set Z3BIN=%2 - -REM directory containing debug z3.dll -set Z3BINDBG=%3 - -REM link Z3 statically or dynamically -set STATIC=false -REM set STATIC=true - -if %STATIC% == true ( - set Z3LIB=z3lib.lib - set Z3DBGLIB=z3lib.lib -) else ( - set Z3LIB=z3.lib - set Z3DBGLIB=z3.lib -) - -REM ocaml 3.11 and later calls the linker through flexlink -ocamlc -version >> ocaml_version -set /p OCAML_VERSION= DBG z3_stubs.obj z3.{cmi,cmo,obj} -ocamlc -c %XCDBG% z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -if errorlevel 1 goto :EOF - -REM z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -> DBG z3_stubs.obj z3.{cmi,cmx,obj} -ocamlopt -c %XCDBG% z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -if errorlevel 1 goto :EOF - -REM %Z3DBGLIB% z3.obj z3_stubs.obj z3_theory_stubs.obj -> libz3_dbg.lib: -lib /nologo %XLIBPATH% /out:libz3_dbg.lib %Z3BINDBG%\%Z3DBGLIB% z3.obj z3_stubs.obj z3_theory_stubs.obj -if errorlevel 1 goto :EOF - -REM z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -> OPT z3_stubs.obj z3.{cmi,cmx,obj} -ocamlopt -c %XCOPT% z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -if errorlevel 1 goto :EOF - -REM %Z3LIB% z3.obj z3_stubs.obj z3_theory_stubs.obj -> libz3.lib: -lib /nologo %XLIBPATH% /out:libz3.lib %Z3BIN%\%Z3LIB% z3.obj z3_stubs.obj z3_theory_stubs.obj -if errorlevel 1 goto :EOF - - -REM ole32.lib is needed by camlidl -REM camlidl.lib is the runtime library for camlidl -REM psapi.lib is needed when statically linking Z3 for process statistics functions - -REM libz3_dbg.lib ole32.lib camlidl.lib z3.cmo -> z3_dbg.cma -ocamlc -custom -a %XCDBG% -cclib -L"%CD%\..\bin" -cclib -lz3_dbg -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmo -o z3_dbg.cma -if errorlevel 1 goto :EOF - -REM libz3.lib ole32.lib camlidl.lib z3.cmo -> z3.cma -ocamlc -custom -a -cclib -L"%CD%\..\bin" -cclib -lz3 -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmo -o z3.cma -if errorlevel 1 goto :EOF - - -REM libz3_dbg.lib ole32.lib camlidl.lib z3.cmx -> z3_dbg.cmxa -ocamlopt -a -cclib -L"%CD%\..\bin" -cclib -lz3_dbg -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmx -o z3_dbg.cmxa -if errorlevel 1 goto :EOF - -REM libz3.lib ole32.lib camlidl.lib z3.cmx -> z3.cmxa -ocamlopt -a -cclib -L"%CD%\..\bin" -cclib -lz3 -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmx -o z3.cmxa -if errorlevel 1 goto :EOF - - -REM build OCaml toplevel 'ocamlz3' pre-linked with Z3 -ocamlmktop -o ocamlz3 z3.cma -if errorlevel 1 goto :EOF - - -del /q 2>NUL z3.cmo z3.cmx *.obj - -ENDLOCAL diff --git a/src/api/ml/old/error_handling.idl b/src/api/ml/old/error_handling.idl deleted file mode 100644 index 5a2ec9915..000000000 --- a/src/api/ml/old/error_handling.idl +++ /dev/null @@ -1,165 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation - -Module Name: - - error_handling - -Abstract: - - Error handling in the OCaml API for Z3. - - The wrapper of each Z3 API routine that takes a Z3_context or a Z3_theory - argument calls check_error_code before returning. (These calls are added - in generate_mlapi.cmd using the build.sed script.) - - There are two error handling schemes implemented, depending on whether - (UN)SAFE_ERRORS is set. - - - SAFE_ERRORS checks Z3_error_code after each call and raises an OCaml - exception in error conditions. Z3_set_error_handler is not exposed by - the SAFE_ERRORS version. - - - UNSAFE_ERRORS sets a Z3 error handler routine that either calls a - globally registered OCaml function or, by default, raises an OCaml - exception. This avoids overhead of repeatedly checking - Z3_get_error_code, but leaves Z3 in a broken state. - -Notes: - - The current SAFE_ERRORS implementation interacts badly with theory plugin - callbacks. Z3 errors are converted into OCaml exceptions, which the - wrappers of theory plugin callbacks are not expecting. Therefore, if a - theory plugin calls a Z3 API routine that triggers an error, an OCaml - exception will be raised and bypass any C++ destructors pushed onto the - stack by Z3 before the call to the plugin and after the preceding OCaml - exception handler. One solution to this would be to modify the theory - plugin callback registration functions to wrap callbacks in an OCaml - exception handler. Since OCaml exceptions are cheap to raise at the - expense of some cost to install a handler, this may not be desirable. - Another solution would be to modify check_error_code to detect if it is - executing in a plugin callback and simply maintain the Z3_error_code, or - raise a C++ exception, instead of raising an OCaml exception. - -Author: - - Josh Berdine (jjb) 2012-03-21 - ---*/ - - -#if !defined(UNSAFE_ERRORS) && !defined(SAFE_ERRORS) -#define SAFE_ERRORS -#endif - - -// The V3 API uses a single handler irregardless of UNSAFE_ERRORS -quote(c," -/* All contexts share the same handler */ -static value caml_z3_error_handler = 0; -"); - -#ifdef SAFE_ERRORS - -quote(mlmli," -(** Exceptions raised by Z3. It is safe to continue interacting with Z3 after - catching [Error] exceptions. - - - {b See also}: {!get_error_msg} -*) -exception Error of context * error_code -"); -quote(ml," -(* Register dynamically-generated exception tag for use from C *) -let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK)) -"); - -quote(c," -value camlidl_c2ml_z3_Z3_error_code(Z3_error_code * _c2, camlidl_ctx _ctx); - -/* Error checking routine that raises OCaml Error exceptions */ -void check_error_code (Z3_context c) -{ - static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - value* exn_tag = NULL; - value ctx_err[2]; - Z3_error_code e; - e = Z3_get_error_code(c); - if (e != Z3_OK) { - ctx_err[0] = c2ml_Z3_context(&c); - ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs); - exn_tag = caml_named_value(\"Z3.Error\"); - if (*exn_tag == 0) { - fprintf(stderr, \"Z3.Error not found\"); - exit(1); - } - caml_raise_with_args(*exn_tag, 2, ctx_err); - } -} - -/* Disable default error handler, all error checking is done by check_error_code */ -void* error_handler_static = NULL; -"); - -#else - -quote(mlmli," -(** Exceptions raised by Z3. {b Warning}: It is unsafe to continue - interacting with Z3 after catching [Error] exceptions. To recover from - error conditions, use {!set_error_handler} to set an error handler that - does nothing, and then test {!get_error_code} after every call to Z3. - - - {b See also}: {!get_error_msg} -*) -exception Error of context * error_code -"); -quote(ml," -(* Register dynamically-generated exception tag for use from C *) -let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK)) -"); - -quote(c," -/* Error checking routine that does nothing */ -void check_error_code(Z3_context c) {} - -static void error_handler_static (Z3_context c, Z3_error_code e) -{ - static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - value* exn_tag = NULL; - value ctx_err[2]; - ctx_err[0] = c2ml_Z3_context(&c); - ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs); - if (caml_z3_error_handler) { - caml_callback2(caml_z3_error_handler, ctx_err[0], ctx_err[1]); - } else { - /* if no handler set, raise OCaml Error exception */ - exn_tag = caml_named_value(\"Z3.Error\"); - if (*exn_tag == 0) { - fprintf(stderr, \"Z3.Error not found\"); - exit(1); - } - caml_raise_with_args(*exn_tag, 2, ctx_err); - } -} - -void ml2c_Z3_error_handler (value ml_handler, void* c_handler) -{ - caml_z3_error_handler = ml_handler; - c_handler = (void*)error_handler_static; -} - -/* Never called */ -value c2ml_Z3_error_handler (void* _) -{ - return 0; -} -"); - -typedef [mltype("context -> error_code -> unit"), - ml2c(ml2c_Z3_error_handler), - c2ml(c2ml_Z3_error_handler) - ] void Z3_error_handler; - -quote(c,"#define Z3_error_handler void*"); - -#endif diff --git a/src/api/ml/old/exec.cmd b/src/api/ml/old/exec.cmd deleted file mode 100755 index 2bb632ef6..000000000 --- a/src/api/ml/old/exec.cmd +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -SETLOCAL -set PATH=..\..\bin;%PATH% -test_mlapi.exe -ENDLOCAL diff --git a/src/api/ml/old/exec.sh b/src/api/ml/old/exec.sh deleted file mode 100644 index 573ec6ddf..000000000 --- a/src/api/ml/old/exec.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH # for linux -export DYLD_LIBRARY_PATH=../../lib:$DYLD_LIBRARY_PATH # for osx -./test_mlapi diff --git a/src/api/ml/old/generate_mlapi.cmd b/src/api/ml/old/generate_mlapi.cmd deleted file mode 100755 index 6a796a401..000000000 --- a/src/api/ml/old/generate_mlapi.cmd +++ /dev/null @@ -1,72 +0,0 @@ -@echo off - -REM Script to generate the Z3 OCaml API -REM -REM Assumes that environment variables are set to provide access to the following commands: camlidl, dos2unix, grep, sed, unix2dos -REM -REM Invoke with "-D UNSAFE_ERRORS" to build version that does not support recoverable errors, but avoids some error-checking overhead. -REM Invoke with "-D LEAK_CONTEXTS" to build version that leaks Z3_context objects, but avoids some garbage-collection overhead. - -REM ../lib/z3_api.h -> z3V3_api.idl using add_error_checking.V3.sed and build.sed -sed -f add_error_checking.V3.sed ../lib/z3_api.h | sed -f build.sed >z3V3_api.idl -if errorlevel 1 goto :EOF - -REM z3.idl -> z3V3_stubs.c, z3V3.mli, z3V3.ml -camlidl -D MLAPIV3 %* z3.idl -move >NUL z3_stubs.c z3V3_stubs.c -move >NUL z3.ml z3V3.ml -move >NUL z3.mli z3V3.mli -if errorlevel 1 goto :EOF - -REM ../lib/z3_api.h -> z3_api.idl -REM add calls to error checking routine -REM convert from doxygen to ocamldoc markup and other syntactic munging -sed <../lib/z3_api.h -f add_error_checking.sed | ^ -sed -f build.sed >z3_api.idl -if errorlevel 1 goto :EOF - -REM z3.idl -> z3_stubs.c, z3.mli, z3.ml -camlidl %* z3.idl -if errorlevel 1 goto :EOF - -REM sometimes z3_stubs.c can be generated with mixed line endings, which can confuse sed and grep -dos2unix 2>NUL z3V3_stubs.c ; unix2dos 2>NUL z3V3_stubs.c -dos2unix 2>NUL z3_stubs.c ; unix2dos 2>NUL z3_stubs.c - -REM modify generated z3.ml{,i} to remove "Z3_" prefix from names -move >NUL z3V3.mli z3V3.1.mli && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3V3.1.mli >z3V3.mli && del z3V3.1.mli -move >NUL z3V3.ml z3V3.1.ml && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3V3.1.ml >z3V3.ml && del z3V3.1.ml -move >NUL z3.mli z3.1.mli && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3.1.mli >z3.mli && del z3.1.mli -move >NUL z3.ml z3.1.ml && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3.1.ml >z3.ml && del z3.1.ml - -REM modify generated z3V3 files to rename z3_ to z3V3_ -move >NUL z3V3.mli z3V3.2.mli && sed "s/camlidl\(.*\)_z3_/camlidl\1_z3V3_/g" z3V3.2.mli >z3V3.mli && del z3V3.2.mli -move >NUL z3V3.ml z3V3.2.ml && sed "s/camlidl\(.*\)_z3_/camlidl\1_z3V3_/g" z3V3.2.ml >z3V3.ml && del z3V3.2.ml -move >NUL z3V3_stubs.c z3V3_stubs.2.c && sed "s/camlidl\(.*\)_z3_/camlidl\1_z3V3_/g" z3V3_stubs.2.c >z3V3_stubs.c && del z3V3_stubs.2.c - - -REM substitute out type equations for enums and options -REM reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10 -grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]*[0-9]*\)$" z3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\2/\1/g|g" | sed "1!G;h;$!d" >rename.sed -grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]* option*\)$" z3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\1/\2/g|g" >>rename.sed -move >NUL z3.mli z3.3.mli && sed -f rename.sed z3.3.mli >z3.mli && del z3.3.mli -move >NUL z3.ml z3.3.ml && sed -f rename.sed z3.3.ml >z3.ml && del z3.3.ml -del rename.sed - -grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]*[0-9]*\)$" z3V3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\2/\1/g|g" | sed "1!G;h;$!d" >rename.sed -grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]* option*\)$" z3V3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\1/\2/g|g" >>rename.sed -move >NUL z3V3.mli z3V3.3.mli && sed -f rename.sed z3V3.3.mli >z3V3.mli && del z3V3.3.mli -move >NUL z3V3.ml z3V3.3.ml && sed -f rename.sed z3V3.3.ml >z3V3.ml && del z3V3.3.ml -del rename.sed - -REM remove cyclic definitions introduced by substituting type equations -move >NUL z3V3.mli z3V3.4.mli && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3V3.4.mli >z3V3.mli && del z3V3.4.mli -move >NUL z3V3.ml z3V3.4.ml && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3V3.4.ml >z3V3.ml && del z3V3.4.ml -move >NUL z3.mli z3.4.mli && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3.4.mli >z3.mli && del z3.4.mli -move >NUL z3.ml z3.4.ml && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3.4.ml >z3.ml && del z3.4.ml - -REM append Z3.V3 module onto Z3 module -type z3V3.ml >> z3.ml -type z3V3.mli >> z3.mli -sed "1,22d" z3V3_stubs.c >> z3_stubs.c -del /q 2>NUL z3V3_api.idl z3V3.ml z3V3.mli z3V3_stubs.c diff --git a/src/api/ml/old/generate_mlapi.sh b/src/api/ml/old/generate_mlapi.sh deleted file mode 100755 index dd8692833..000000000 --- a/src/api/ml/old/generate_mlapi.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -# Script to generate the Z3 OCaml API -# -# Assumes that environment variables are set to provide access to the following commands: camlidl, gcc, grep, sed -# -# This script uses 'gcc -E' as the C preprocessor, other C preprocessors may work but have not been tested. -# -# Invoke with "-DUNSAFE_ERRORS" to build version that does not support recoverable errors, but avoids some error-checking overhead. -# Invoke with "-DLEAK_CONTEXTS" to build version that leaks Z3_context objects, but avoids some garbage-collection overhead. - - -# add calls to error checking routine -# convert from doxygen to ocamldoc markup and other syntactic munging -# ../z3_api.h -> z3V3_api.idl -sed -f add_error_checking.V3.sed -f preprocess.sed ../z3_api.h > z3V3_api.idl - -# z3.idl (z3V3_api.idl x3V3.mli x3V3.ml) -> z3V3_stubs.c, z3V3.mli, z3V3.ml -gcc -E -w -P -CC -xc -DCAMLIDL -DMLAPIV3 $@ z3.0.idl > z3V3.idl -camlidl -nocpp z3V3.idl - -# reverse.sed to reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10 -grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_]*$" z3V3.mli | sed -e "s|and z3_\([a-zA-Z0-9_]*\) = \([a-zA-Z0-9_]*\)|s/\2/\1/g|g" -f reverse.sed > /tmp/renameV3.sed -grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_ ]* option$" z3V3.mli | sed -e "s|and \(z3_[a-zA-Z0-9_]*\) = \([a-zA-Z0-9_ ]*\)|s/\1/\2/g|g" >> /tmp/renameV3.sed - -# rename.sed to substitute out type equations for enums and options, then postprocess -cp -f z3V3.mli z3V3.ml /tmp -sed -f /tmp/renameV3.sed -f postprocess.sed /tmp/z3V3.mli > z3V3.mli -sed -f /tmp/renameV3.sed -f postprocess.sed /tmp/z3V3.ml > z3V3.ml - -# ../z3_api.h -> z3_api.idl -sed -f add_error_checking.sed -f preprocess.sed ../z3_api.h > z3_api.idl - -# z3.idl (z3_api.idl x3.ml) -> z3_stubs.c, z3.mli, z3.ml -gcc -E -w -P -CC -xc -I. -DCAMLIDL $@ z3.0.idl > z3.idl -camlidl -nocpp z3.idl - -# reverse.sed to reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10 -grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_]*$" z3.mli | sed -e "s|and z3_\([a-zA-Z0-9_]*\) = \([a-zA-Z0-9_]*\)|s/\2/\1/g|g" -f reverse.sed > /tmp/rename.sed -grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_ ]* option$" z3.mli | sed -e "s|and \(z3_[a-zA-Z0-9_]*\) = \([a-zA-Z0-9_ ]*\)|s/\1/\2/g|g" >> /tmp/rename.sed - -# rename.sed to substitute out type equations for enums and options, then postprocess -cp z3.mli z3.ml /tmp -sed -f /tmp/rename.sed -f postprocess.sed /tmp/z3.mli > z3.mli -sed -f /tmp/rename.sed -f postprocess.sed /tmp/z3.ml > z3.ml - - -# append Z3.V3 module onto Z3 module -cat z3V3.mli >> z3.mli -cat z3V3.ml >> z3.ml -sed "1,22d" z3V3_stubs.c >> z3_stubs.c - -rm -f z3V3_api.idl z3V3.idl z3V3.ml z3V3.mli z3V3_stubs.c z3_api.idl z3.idl diff --git a/src/api/ml/old/import.cmd b/src/api/ml/old/import.cmd deleted file mode 100755 index b5239e011..000000000 --- a/src/api/ml/old/import.cmd +++ /dev/null @@ -1,55 +0,0 @@ -@echo off -SETLOCAL - -:CHECKARG1 -if not "%1"=="" ( - set SDTROOT=%1 - goto :CHECKARG2 -) - -goto :FAIL - - -:CHECKARG2 -if "%2"=="" ( - goto :IMPORT -) - -goto :FAIL - - -:IMPORT -cd import -sd edit ... -del z3.h z3_api.h z3_macros.h z3lib.lib msbig_rational.lib z3.exe test_capi.c test_mlapi_header.html z3_mlapi_header.html mldoc_footer.html tabs.css z3.png z3_ml.css -copy %SDTROOT%\lib\z3.h -copy %SDTROOT%\lib\z3_api.h -copy %SDTROOT%\lib\z3_macros.h -copy %SDTROOT%\release_mt\z3lib.lib -copy %SDTROOT%\release_mt\msbig_rational.lib -copy %SDTROOT%\release_mt\z3.exe -copy %SDTROOT%\test_capi\test_capi.c -copy %SDTROOT%\doc\test_mlapi_header.html -copy %SDTROOT%\doc\z3_mlapi_header.html -copy %SDTROOT%\doc\mldoc_footer.html -copy %SDTROOT%\doc\html\tabs.css -copy %SDTROOT%\doc\z3.png -copy %SDTROOT%\doc\z3_ml.css -sd add ... -sd revert -a ... -cd .. -goto :END - -:FAIL -echo "Usage:" -echo " %0 SDTROOT" -echo "" -echo "Examples:" -echo " %0 \\risebuild\drops\z32\2.0.51220.7" -echo " %0 \\risebuild\drops\z32\latest" -echo " %0 J:\SD\other\sdt1\src\z3_2" -echo "" -goto :END - -:END -ENDLOCAL diff --git a/src/api/ml/old/mlx_get_app_args.idl b/src/api/ml/old/mlx_get_app_args.idl deleted file mode 100644 index fe3407af8..000000000 --- a/src/api/ml/old/mlx_get_app_args.idl +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ get_app_args c a ] \] is the array of arguments of an application. If [t] is a constant, then the array is empty. - - - {b See also}: {!get_app_num_args} - - {b See also}: {!get_app_arg} -*) -val get_app_args: context -> app -> ast array -"); diff --git a/src/api/ml/old/mlx_get_array_sort.idl b/src/api/ml/old/mlx_get_array_sort.idl deleted file mode 100644 index 81bf6e00f..000000000 --- a/src/api/ml/old/mlx_get_array_sort.idl +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ get_array_sort c t ] \] is the domain and the range of [t]. - - - {b See also}: {!get_array_sort_domain} - - {b See also}: {!get_array_sort_range} -*) -val get_array_sort: context -> sort -> sort * sort -"); diff --git a/src/api/ml/old/mlx_get_datatype_sort.idl b/src/api/ml/old/mlx_get_datatype_sort.idl deleted file mode 100644 index 3466a9050..000000000 --- a/src/api/ml/old/mlx_get_datatype_sort.idl +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ get_datatype_sort c ty ] \] is the array of triples [(constructor, recognizer, fields)] where [constructor] is the constructor declaration of [ty], [recognizer] is the recognizer for the [constructor], and [fields] is the array of fields in [ty]. - - - {b See also}: {!get_datatype_sort_num_constructors} - - {b See also}: {!get_datatype_sort_constructor} - - {b See also}: {!get_datatype_sort_recognizer} - - {b See also}: {!get_datatype_sort_constructor_accessor} -*) -val get_datatype_sort: context -> sort -> datatype_constructor array -"); diff --git a/src/api/ml/old/mlx_get_domains.idl b/src/api/ml/old/mlx_get_domains.idl deleted file mode 100644 index ebc6d8556..000000000 --- a/src/api/ml/old/mlx_get_domains.idl +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ get_domains c d ] \] is the array of parameters of [d]. - - - {b See also}: {!get_domain_size} - - {b See also}: {!get_domain} -*) -val get_domains: context -> func_decl -> sort array -"); diff --git a/src/api/ml/old/mlx_get_error_msg.idl b/src/api/ml/old/mlx_get_error_msg.idl deleted file mode 100644 index b8ea97e03..000000000 --- a/src/api/ml/old/mlx_get_error_msg.idl +++ /dev/null @@ -1,6 +0,0 @@ -quote(mli," -(** - Summary: Return a string describing the given error code. -*) -val get_error_msg: context -> error_code -> string -"); diff --git a/src/api/ml/old/mlx_get_pattern_terms.idl b/src/api/ml/old/mlx_get_pattern_terms.idl deleted file mode 100644 index 749a90f3a..000000000 --- a/src/api/ml/old/mlx_get_pattern_terms.idl +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ get_pattern_terms c p ] \] is the ast's in pattern. - - - {b See also}: {!get_pattern_num_terms} - - {b See also}: {!get_pattern} -*) -val get_pattern_terms: context -> pattern -> ast array;; -"); diff --git a/src/api/ml/old/mlx_get_tuple_sort.idl b/src/api/ml/old/mlx_get_tuple_sort.idl deleted file mode 100644 index 1555f6c8a..000000000 --- a/src/api/ml/old/mlx_get_tuple_sort.idl +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ get_tuple_sort c ty ] \] is the pair [(mk_decl, fields)] where [mk_decl] is the constructor declaration of [ty], and [fields] is the array of fields in [ty]. - - - {b See also}: {!get_tuple_sort_mk_decl} - - {b See also}: {!get_tuple_sort_num_fields} - - {b See also}: {!get_tuple_sort_field_decl} -*) -val get_tuple_sort: context -> sort -> (func_decl * func_decl array) -"); diff --git a/src/api/ml/old/mlx_mk_context_x.idl b/src/api/ml/old/mlx_mk_context_x.idl deleted file mode 100644 index 7e4fd25c9..000000000 --- a/src/api/ml/old/mlx_mk_context_x.idl +++ /dev/null @@ -1,36 +0,0 @@ -quote(mlmli,"external mk_context: (string * string) list -> context = \"caml_z3_mk_context\" -"); -// Note: lack of whitespace and comments in the previous 2 lines is important for the documentation generation -quote(c," -value caml_z3_mk_context(value key_val_list) -{ - CAMLparam1( key_val_list ); - CAMLlocal4( item, vkey, vval, _vres ); - char * ckey; - char * cval; - Z3_config cfg; - Z3_context _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - - cfg = Z3_mk_config(); - - while (key_val_list != Val_emptylist) - { - item = Field(key_val_list, 0); - vkey = Field(item, 0); - vval = Field(item, 1); - ckey = camlidl_malloc_string(vkey, _ctx); - cval = camlidl_malloc_string(vval, _ctx); - Z3_set_param_value(cfg, ckey, cval); - key_val_list = Field(key_val_list, 1); - } - - _res = Z3_mk_context_rc(cfg); - Z3_del_config(cfg); - _vres = camlidl_c2ml_z3_Z3_context(&_res, _ctx); - camlidl_free(_ctx); - Z3_set_error_handler(_res, error_handler_static); - CAMLreturn(_vres); -} -"); diff --git a/src/api/ml/old/mlx_mk_datatypes.idl b/src/api/ml/old/mlx_mk_datatypes.idl deleted file mode 100644 index 21bdcdbc7..000000000 --- a/src/api/ml/old/mlx_mk_datatypes.idl +++ /dev/null @@ -1,28 +0,0 @@ -quote(mlmli," -(** A constructor of a datatype is described by: *) -type datatype_constructor_desc = { - constructor_desc : symbol; (** name of the constructor function *) - recognizer_desc : symbol; (** name of the recognizer function *) - accessor_descs : (symbol * sort) array; (** names and sorts of the fields *) -} - -(** A datatype is described by a name and constructor descriptors. *) -type datatype_desc = symbol * datatype_constructor_desc array - -(** A constructor of a datatype is represented by: *) -type datatype_constructor = { - constructor : func_decl; (** constructor function *) - recognizer : func_decl; (** recognizer function *) - accessors : func_decl array; (** field accessor functions *) -} - -(** A datatype is represented by a sort and constructors. *) -type datatype = sort * datatype_constructor array -"); - -quote(mli," -(** [mk_datatypes ctx sorts_to_descriptors] creates mutually recursive datatypes described by - [sorts_to_descriptors], which is a function from the sorts of the datatypes to be created to - descriptors of the datatypes' constructors. {b See also}: {!Test_mlapi.forest_example} *) -val mk_datatypes: context -> (sort array -> (datatype_desc array) option) -> datatype array -"); diff --git a/src/api/ml/old/mlx_mk_numeral.idl b/src/api/ml/old/mlx_mk_numeral.idl deleted file mode 100644 index 0fa9caf39..000000000 --- a/src/api/ml/old/mlx_mk_numeral.idl +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mlmli," -(** - Summary: \[ [ numeral_refined ] \] is the refined view of a numeral . -*) -type numeral_refined = - | Numeral_int of int * sort - | Numeral_int64 of int64 * sort - | Numeral_large of string * sort - | Numeral_rational of numeral_refined * numeral_refined -"); - -quote(mli," -(** - Summary: \[ [ embed_numeral c nr ] \] constructs the numeral described by [nr]. - - - {b See also}: {!numeral_refine} -*) -val embed_numeral: context -> numeral_refined -> ast -"); diff --git a/src/api/ml/old/mlx_mk_sort.idl b/src/api/ml/old/mlx_mk_sort.idl deleted file mode 100644 index dd4222f81..000000000 --- a/src/api/ml/old/mlx_mk_sort.idl +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mlmli," -(** - A datatype constructor descriptor. -*) -type datatype_constructor_desc = { - constructor_desc : symbol; (** name of the constructor function *) - recognizer_desc : symbol; (** name of the recognizer function *) - accessor_descs : (symbol * sort) array; (** names and sorts of the fields *) -} - -(** - A datatype is described by a name and constructor descriptors. -*) -type datatype_desc = symbol * datatype_constructor_desc array - -(** - A datatype constructor representation. -*) -type datatype_constructor = { - constructor : func_decl; (** constructor function *) - recognizer : func_decl; (** recognizer function *) - accessors : func_decl array; (** field accessor functions *) -} - -(** - A datatype is represented by a sort and constructors. -*) -type datatype = sort * datatype_constructor array - -(** - Refined view of a {!sort}. - - - {b See also}: {!mk_sort} - - {b See also}: {!sort_refine} -*) -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_bv of int - | Sort_finite_domain of symbol * int64 - | Sort_real - | Sort_array of sort * sort - | Sort_datatype of datatype_constructor array - | Sort_relation of sort array - | Sort_unknown -"); - -quote(mli," -(** - Summary: \[ [ mk_sort c sr ] \] constructs the sort described by [sr]. - - - {b Precondition}: [sr] is not of form [Sort_relation] or [Sort_unknown], which cannot be directly constructed - - {b See also}: {!mk_datatypes} - - {b See also}: {!sort_refine} -*) -val mk_sort: context -> sort_refined -> sort - -(** - \[ [mk_datatypes ctx sorts_to_descriptors] \] creates mutually recursive datatypes described by - [sorts_to_descriptors], which is a function from the sorts of the datatypes to be created to - descriptors of the datatypes' constructors. - - - {b See also}: {!Test_mlapi.forest_example} -*) -val mk_datatypes: context -> (sort array -> (datatype_desc array) option) -> datatype array -"); diff --git a/src/api/ml/old/mlx_mk_symbol.idl b/src/api/ml/old/mlx_mk_symbol.idl deleted file mode 100644 index 6969c7380..000000000 --- a/src/api/ml/old/mlx_mk_symbol.idl +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mlmli," -(** - Refined view of a {!symbol}. - - - {b See also}: {!mk_symbol} - - {b See also}: {!symbol_refine} -*) -type symbol_refined = - | Symbol_int of int - | Symbol_string of string -"); - -quote(mli," -(** - Summary: \[ [ mk_symbol c sr ] \] constructs the symbol described by [sr]. - - - {b See also}: {!symbol_refine} -*) -val mk_symbol: context -> symbol_refined -> symbol -"); diff --git a/src/api/ml/old/mlx_model.idl b/src/api/ml/old/mlx_model.idl deleted file mode 100644 index 192a982b3..000000000 --- a/src/api/ml/old/mlx_model.idl +++ /dev/null @@ -1,19 +0,0 @@ -quote(mlmli," -(** - A model assigns uninterpreted sorts to finite universes of distinct values, constants to values, - and arrays and functions to finite maps from argument values to result values plus a default - value for all other arguments. -*) -type model_refined = { - sorts : (sort, ast_vector) Hashtbl.t; - consts : (func_decl, ast) Hashtbl.t; - arrays : (func_decl, (ast, ast) Hashtbl.t * ast) Hashtbl.t; - funcs : (func_decl, (ast array, ast) Hashtbl.t * ast) Hashtbl.t; -} -"); -quote(mli," -(** - Summary: [model_refine c m] is the refined model of [m]. -*) -val model_refine : context -> model -> model_refined -"); diff --git a/src/api/ml/old/mlx_numeral_refine.idl b/src/api/ml/old/mlx_numeral_refine.idl deleted file mode 100644 index 8b2f0a07f..000000000 --- a/src/api/ml/old/mlx_numeral_refine.idl +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ numeral_refine c a ] \] is the refined view of [a]. - - - {b Precondition}: [get_ast_kind c a = NUMERAL_AST] -*) -val numeral_refine : context -> ast -> numeral_refined -"); diff --git a/src/api/ml/old/mlx_parse_smtlib.idl b/src/api/ml/old/mlx_parse_smtlib.idl deleted file mode 100644 index dbc2e42da..000000000 --- a/src/api/ml/old/mlx_parse_smtlib.idl +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ parse_smtlib_string_x c str sort_names sorts decl_names decls ] \] - - Parse the given string using the SMT-LIB parser. - - The symbol table of the parser can be initialized using the given sorts and declarations. - The symbols in the arrays [sort_names] and [decl_names] don't need to match the names - of the sorts and declarations in the arrays [sorts] and [decls]. This is an useful feature - since we can use arbitrary names to reference sorts and declarations defined using the API. - - - {b See also}: {!parse_smtlib_file_x} -*) -val parse_smtlib_string_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) - -(** - Summary: Similar to {!parse_smtlib_string_x}, but reads the benchmark from a file. - - - {b See also}: {!parse_smtlib_string_x} -*) -val parse_smtlib_file_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) - -(** - Summary: \[ [ parse_smtlib_string_formula c ... ] \] calls [(parse_smtlib_string c ...)] and returns the single formula produced. - - - {b See also}: {!parse_smtlib_file_formula} - - {b See also}: {!parse_smtlib_string_x} -*) -val parse_smtlib_string_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - -(** - Summary: \[ [ parse_smtlib_file_formula c ... ] \] calls [(parse_smtlib_file c ...)] and returns the single formula produced. - - - {b See also}: {!parse_smtlib_string_formula} - - {b See also}: {!parse_smtlib_file_x} -*) -val parse_smtlib_file_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast -"); diff --git a/src/api/ml/old/mlx_sort_refine.idl b/src/api/ml/old/mlx_sort_refine.idl deleted file mode 100644 index 1f2ba8eab..000000000 --- a/src/api/ml/old/mlx_sort_refine.idl +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ sort_refine c s ] \] is the refined view of [s]. -*) -val sort_refine: context -> sort -> sort_refined -"); diff --git a/src/api/ml/old/mlx_statistics.idl b/src/api/ml/old/mlx_statistics.idl deleted file mode 100644 index 47028f012..000000000 --- a/src/api/ml/old/mlx_statistics.idl +++ /dev/null @@ -1,10 +0,0 @@ -quote(mlmli," -type stat_datum = Stat_int of int | Stat_float of float -type stats_refined = (string, stat_datum) Hashtbl.t -"); -quote(mli," -(** - Summary: [stats_refine c s] is the refined stats of [s]. -*) -val stats_refine : context -> stats -> stats_refined -"); diff --git a/src/api/ml/old/mlx_symbol_refine.idl b/src/api/ml/old/mlx_symbol_refine.idl deleted file mode 100644 index 0d74e9cd9..000000000 --- a/src/api/ml/old/mlx_symbol_refine.idl +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mli," -(** - Summary: \[ [ symbol_refine c s ] \] is the refined view of [s]. -*) -val symbol_refine: context -> symbol -> symbol_refined -"); diff --git a/src/api/ml/old/mlx_term_refine.idl b/src/api/ml/old/mlx_term_refine.idl deleted file mode 100644 index 2fa8fd36f..000000000 --- a/src/api/ml/old/mlx_term_refine.idl +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote(mlmli," -(** - Summary: \[ [ binder_type ] \] is a universal or existential quantifier. - - - {b See also}: {!term_refined} -*) -type binder_type = Forall | Exists - -(** - Summary: \[ [ term_refined ] \] is the refinement of a {!ast} . - - - {b See also}: {!term_refine} -*) -type term_refined = - | Term_numeral of numeral_refined - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast - | Term_var of int * sort -"); - -quote(mli," -(** - Summary: \[ [ mk_term c tr ] \] constructs the term described by [tr]. - - - {b Precondition}: [tr] is not of form - - {b See also}: {!term_refine} -*) -(* val mk_term: context -> term_refined -> ast *) - - -(** - Summary: \[ [ term_refine c a ] \] is the refined view of [a]. -*) -val term_refine : context -> ast -> term_refined -"); diff --git a/src/api/ml/old/postprocess.sed b/src/api/ml/old/postprocess.sed deleted file mode 100644 index f25f70cb7..000000000 --- a/src/api/ml/old/postprocess.sed +++ /dev/null @@ -1,8 +0,0 @@ -# remove 'z3_' and 'Z3_' prefixes on names - -s/{\!Z3\./{\!/g -s/\([^_]\)[zZ]3_/\1/g - -# remove cyclic definitions introduced by substituting type equations - -s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g diff --git a/src/api/ml/old/preprocess.sed b/src/api/ml/old/preprocess.sed deleted file mode 100644 index c7d1fc804..000000000 --- a/src/api/ml/old/preprocess.sed +++ /dev/null @@ -1,82 +0,0 @@ -# attempt to clean up the mess with 'unsigned' -s/ unsigned/ unsigned int/g -s/unsigned int long/unsigned long/g -s/unsigned int __/unsigned __/g - - -# '@name ' -> 'Section: ' -# '\sa ' -> 'See also: ' -# '\brief ' -> 'Summary: ' -# '\remark ' -> 'Remark: ' -# '\pre ' -> 'Precondition: ' -# '\param ' -> '@param' -# '\warning ' -> 'Warning: ' -# '\code' -> 'C Example:' -# '\endcode' -> '' -/\\pre/s/(/ /g;/\\pre/s/,//g;/\\pre/s/)//g;s/\\pre /- {b Precondition}: /g -/\\ccode/s/(/ /g;/\\ccode/s/\\,//g;/\\ccode/s/)//g;s/\\ccode{\(.*\)}/\[\1\]/g -s/\\defgroup .*//g -s/@name \(.*\)/{2 {L \1}}/g -s/\\sa \(.*\)/- {b See also}: {!Z3.\1}/g -s/\\see \(.*\)/- {b See}: {!Z3.\1}/g -s//{e /g -s|| }|g -s/\\nicebox{/{e/g -s/\\brief /Summary: /g -s/\\remark /- {b Remarks}: /g -s/\\pre /- {b Precondition}: /g -s/\\param /@param /g -s/\\conly .*//g -s/\\warning /- {b Warning}: /g -s/\\code/{v /g -s/\\endcode/ v}/g -s/\\verbatim/{v /g -s/\\endverbatim/ v}/g -s/\\mlonly//g -s/\\endmlonly//g -s/\\mlh/\\\[ \[/g -s/\\endmlh/\] \\\]/g -s/\\deprecated/@deprecated/g -s/\\ / /g - -# '\c code ' -> '[code]' -s/\\c \([^ .,:]*\)/[\1]/g - -# '#Z3_' -> 'Z3.' -s/#Z3_\([^ \.,) ]*\)/{!Z3.\1}/g - -# '/*@}*/' -> '' -s/\/\*@{\*\///g - -# '/*@{*/' -> '' -s/\/\*@}\*\///g - -# '/*...*/' -> '' -s/\/\*.*\*\///g - -s|(\*\*/\*\*)|(\*\*%\*\*)|g - -# '/**' -> 'quote(mli,"(**' -s|/\*\*|quote(mli,\"(**|g - -# '...*/' -> '*)");' -s|[ ]*\*/|*)\");|g - -s|(\*\*%\*\*)|(\*\*/\*\*)|g - -# 'extern "C"' -> 'extern ~~C~~' -# 'quote(foo,"bar")' -> quote(foo,~~bar~~) -# mltype("foo") -> mltype(~~foo~~) -s/extern \"C\"/extern ~~C~~/g -s/quote(\(.*\),\"\(.*\)\")/quote(\1,~~\2~~)/g -s/quote(\(.*\),\"/quote(\1,~~/g -s/\")\;/~~);/g -s/\;\"/;~~/g -s/mltype(\"\(.*\)\")/mltype(~~\1~~)/g - -# '"' -> '\"' -s/\\\"/\"/g -s/\"/\\\"/g - -# '~~' -> '"' -s/~~/\"/g diff --git a/src/api/ml/old/queen.ml b/src/api/ml/old/queen.ml deleted file mode 100644 index e22db9cfb..000000000 --- a/src/api/ml/old/queen.ml +++ /dev/null @@ -1,112 +0,0 @@ -(* - queen.exe - JakobL@2007-09-22 - - Demonstration of how Z3 can be used to find solutions to the - N-Queens problem. - - See: http://en.wikipedia.org/wiki/Eight_queens_puzzle - - Problem specification: Is the following constraint system satisfiable, - for increasing n>=1, what are the models? - - constant - n: 8; - - variable - row: array n of [0..n-1]; - - rule - forall i in [0..n-2]: - (forall j in [i+1..n-1]: - ((row[i] <> row[j]) and - (i+row[i]) <> (j+row[j]) and - (i+row[j]) <> (j+row[i]))); - - The answer is yes for n different from 2 and 3. The number of solutions are: - * n=1: 1 - * n=2: 0 - * n=3: 0 - * n=4: 2 - * n=5: 10 - * n=6: 4 - * n=7: 40 - * n=8: 92 - * n=9: 352 - * n=10: 724 - ... -*) - -module Z3 = Z3.V3 - -(* Auxillary functions *) -let ( |> ) x f = f x;; -let printf = Printf.printf;; -let mk_var ctx name ty = Z3.mk_const ctx (Z3.mk_int_symbol ctx name) ty;; -let mk_int_var ctx name = Z3.mk_int_sort ctx |> mk_var ctx name;; -let mk_int ctx v = Z3.mk_int ctx v (Z3.mk_int_sort ctx);; -let checkreturn v = match v with | (true,r) -> r | _ -> failwith "checkreturn";; -let get_numeral_value_int a1 a2 = Z3.get_numeral_int a1 a2 |> checkreturn;; -let iterate_x lower upper f = for i = lower to upper do f i done;; -let forall_x ctx lower upper f = Z3.mk_and ctx (Array.init (1+upper-lower) (fun i->f (i+lower))) -let exist_x ctx lower upper f = Z3.mk_or ctx (Array.init (1+upper-lower) (fun i->f (i+lower))) -let get_value ctx model f = let (ok, v) = Z3.eval_func_decl ctx model f in (assert ok; v) - -let queen_n n = - let ctx = Z3.mk_context_x - [|("MODEL","true"); - ("RELEVANCY","0")|] in - let ( &&& ) x y = Z3.mk_and ctx [|x;y|] in - let ( <~> ) x y = Z3.mk_not ctx (Z3.mk_eq ctx x y) in - let ( <<= ) x y = Z3.mk_le ctx x y in - let ( +++ ) x y = Z3.mk_add ctx [|x;y|] in - let row = Array.init n (fun i->mk_int_var ctx i) in - let c x = mk_int ctx x in (* make constant *) - let v x = row.(x) in (* make variable *) - let constraint_domain=forall_x ctx (0) (n-1) (fun x-> ((c 0) <<= (v x)) &&& ((v x) <<= (c (n-1)))) in - let constraint_queen= - forall_x ctx (0) (n-2) (fun i-> - forall_x ctx (i+1) (n-1) (fun j-> - ((v i) <~> (v j)) &&& - (((c i)+++(v i)) <~> ((c j)+++(v j))) &&& - (((c i)+++(v j)) <~> ((c j)+++(v i))) - ) - ) in - let res = constraint_domain &&& constraint_queen in - Z3.assert_cnstr ctx res; - let rec f i = - (match Z3.check_and_get_model ctx with - | (Z3.L_FALSE,_) -> - printf "queen %d, total models: %d\n" n i; - flush stdout; - | (Z3.L_UNDEF,_) -> failwith "Z3.L_UNDEF" - | (Z3.L_TRUE,model) -> - begin - let model_constants=Z3.get_model_constants ctx model in - let vars=Array.map (fun mc->Z3.mk_app ctx mc [||]) model_constants in - let vals=Array.map (fun mc->get_value ctx model mc |> get_numeral_value_int ctx) model_constants in - Z3.del_model ctx model; - - let line = String.make n '-' in - let q_line i = let r = String.make n ' ' in String.set r i 'Q'; r in - printf "queen %d, model #%d:\n" n (i+1); - printf "\n"; - printf " /%s\\\n" line; - iterate_x 0 (n-1) (fun x->printf " |%s|\n" (q_line (vals.(x)))); - printf " \\%s/\n" line; - printf "\n"; - flush stdout; - let negated_model = exist_x ctx 0 (n-1) (fun x->(vars.(x)) <~> (c (vals.(x)))) in - Z3.assert_cnstr ctx negated_model; - f (i+1); - end - ) in - f 0; - Z3.del_context ctx; - ();; - -let queen() = - for n = 1 to 8 do - queen_n n - done;; - -let _ = queen();; diff --git a/src/api/ml/old/queen.regress.err b/src/api/ml/old/queen.regress.err deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/api/ml/old/queen.regress.out b/src/api/ml/old/queen.regress.out deleted file mode 100644 index 30e713386..000000000 --- a/src/api/ml/old/queen.regress.out +++ /dev/null @@ -1,1852 +0,0 @@ -queen 1, model #1: - - /-\ - |Q| - \-/ - -queen 1, total models: 1 -queen 2, total models: 0 -queen 3, total models: 0 -queen 4, model #1: - - /----\ - | Q | - | Q| - |Q | - | Q | - \----/ - -queen 4, model #2: - - /----\ - | Q | - |Q | - | Q| - | Q | - \----/ - -queen 4, total models: 2 -queen 5, model #1: - - /-----\ - | Q | - | Q | - |Q | - | Q | - | Q| - \-----/ - -queen 5, model #2: - - /-----\ - | Q | - | Q| - | Q | - |Q | - | Q | - \-----/ - -queen 5, model #3: - - /-----\ - | Q| - | Q | - |Q | - | Q | - | Q | - \-----/ - -queen 5, model #4: - - /-----\ - |Q | - | Q | - | Q | - | Q| - | Q | - \-----/ - -queen 5, model #5: - - /-----\ - | Q | - | Q| - | Q | - | Q | - |Q | - \-----/ - -queen 5, model #6: - - /-----\ - | Q | - |Q | - | Q | - | Q| - | Q | - \-----/ - -queen 5, model #7: - - /-----\ - | Q| - | Q | - | Q | - |Q | - | Q | - \-----/ - -queen 5, model #8: - - /-----\ - | Q | - | Q | - | Q| - | Q | - |Q | - \-----/ - -queen 5, model #9: - - /-----\ - |Q | - | Q | - | Q| - | Q | - | Q | - \-----/ - -queen 5, model #10: - - /-----\ - | Q | - |Q | - | Q | - | Q | - | Q| - \-----/ - -queen 5, total models: 10 -queen 6, model #1: - - /------\ - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - \------/ - -queen 6, model #2: - - /------\ - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - \------/ - -queen 6, model #3: - - /------\ - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - \------/ - -queen 6, model #4: - - /------\ - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - \------/ - -queen 6, total models: 4 -queen 7, model #1: - - /-------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - \-------/ - -queen 7, model #2: - - /-------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #3: - - /-------\ - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - |Q | - \-------/ - -queen 7, model #4: - - /-------\ - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #5: - - /-------\ - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - \-------/ - -queen 7, model #6: - - /-------\ - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #7: - - /-------\ - | Q | - | Q| - | Q | - | Q | - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #8: - - /-------\ - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #9: - - /-------\ - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - \-------/ - -queen 7, model #10: - - /-------\ - |Q | - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #11: - - /-------\ - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #12: - - /-------\ - |Q | - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \-------/ - -queen 7, model #13: - - /-------\ - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #14: - - /-------\ - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #15: - - /-------\ - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - | Q| - \-------/ - -queen 7, model #16: - - /-------\ - | Q | - |Q | - | Q | - | Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #17: - - /-------\ - | Q | - |Q | - | Q | - | Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #18: - - /-------\ - | Q | - |Q | - | Q | - | Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #19: - - /-------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #20: - - /-------\ - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #21: - - /-------\ - | Q | - |Q | - | Q | - | Q | - | Q | - | Q| - | Q | - \-------/ - -queen 7, model #22: - - /-------\ - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - \-------/ - -queen 7, model #23: - - /-------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - | Q| - \-------/ - -queen 7, model #24: - - /-------\ - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #25: - - /-------\ - | Q| - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - \-------/ - -queen 7, model #26: - - /-------\ - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #27: - - /-------\ - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \-------/ - -queen 7, model #28: - - /-------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - \-------/ - -queen 7, model #29: - - /-------\ - | Q| - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #30: - - /-------\ - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - \-------/ - -queen 7, model #31: - - /-------\ - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - \-------/ - -queen 7, model #32: - - /-------\ - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - \-------/ - -queen 7, model #33: - - /-------\ - | Q | - | Q| - | Q | - | Q | - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #34: - - /-------\ - | Q | - | Q| - | Q | - | Q | - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #35: - - /-------\ - | Q | - | Q| - | Q | - | Q | - | Q | - |Q | - | Q | - \-------/ - -queen 7, model #36: - - /-------\ - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - \-------/ - -queen 7, model #37: - - /-------\ - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - |Q | - \-------/ - -queen 7, model #38: - - /-------\ - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - \-------/ - -queen 7, model #39: - - /-------\ - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - \-------/ - -queen 7, model #40: - - /-------\ - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - \-------/ - -queen 7, total models: 40 -queen 8, model #1: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #2: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - \--------/ - -queen 8, model #3: - - /--------\ - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #4: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - \--------/ - -queen 8, model #5: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - \--------/ - -queen 8, model #6: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - | Q| - \--------/ - -queen 8, model #7: - - /--------\ - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #8: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - \--------/ - -queen 8, model #9: - - /--------\ - |Q | - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #10: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #11: - - /--------\ - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #12: - - /--------\ - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #13: - - /--------\ - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #14: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - \--------/ - -queen 8, model #15: - - /--------\ - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #16: - - /--------\ - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #17: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #18: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - \--------/ - -queen 8, model #19: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - |Q | - \--------/ - -queen 8, model #20: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #21: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - \--------/ - -queen 8, model #22: - - /--------\ - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #23: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - \--------/ - -queen 8, model #24: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #25: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #26: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #27: - - /--------\ - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #28: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #29: - - /--------\ - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #30: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - \--------/ - -queen 8, model #31: - - /--------\ - | Q| - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #32: - - /--------\ - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #33: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - \--------/ - -queen 8, model #34: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - \--------/ - -queen 8, model #35: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - \--------/ - -queen 8, model #36: - - /--------\ - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #37: - - /--------\ - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #38: - - /--------\ - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #39: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #40: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #41: - - /--------\ - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #42: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #43: - - /--------\ - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #44: - - /--------\ - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #45: - - /--------\ - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #46: - - /--------\ - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #47: - - /--------\ - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #48: - - /--------\ - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #49: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - \--------/ - -queen 8, model #50: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #51: - - /--------\ - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #52: - - /--------\ - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #53: - - /--------\ - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #54: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #55: - - /--------\ - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #56: - - /--------\ - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #57: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #58: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #59: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #60: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #61: - - /--------\ - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #62: - - /--------\ - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #63: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #64: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - \--------/ - -queen 8, model #65: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #66: - - /--------\ - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #67: - - /--------\ - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #68: - - /--------\ - | Q | - |Q | - | Q| - | Q | - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #69: - - /--------\ - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #70: - - /--------\ - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #71: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #72: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #73: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #74: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - \--------/ - -queen 8, model #75: - - /--------\ - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - \--------/ - -queen 8, model #76: - - /--------\ - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #77: - - /--------\ - |Q | - | Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #78: - - /--------\ - | Q | - |Q | - | Q | - | Q| - | Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #79: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - \--------/ - -queen 8, model #80: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - \--------/ - -queen 8, model #81: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #82: - - /--------\ - | Q | - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - \--------/ - -queen 8, model #83: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - \--------/ - -queen 8, model #84: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - |Q | - | Q| - | Q | - \--------/ - -queen 8, model #85: - - /--------\ - | Q | - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - \--------/ - -queen 8, model #86: - - /--------\ - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #87: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q| - | Q | - \--------/ - -queen 8, model #88: - - /--------\ - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #89: - - /--------\ - | Q | - | Q| - | Q | - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #90: - - /--------\ - | Q | - | Q | - | Q| - | Q | - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, model #91: - - /--------\ - | Q | - | Q | - | Q | - | Q | - |Q | - | Q | - | Q | - | Q| - \--------/ - -queen 8, model #92: - - /--------\ - | Q | - | Q | - | Q | - | Q| - |Q | - | Q | - | Q | - | Q | - \--------/ - -queen 8, total models: 92 diff --git a/src/api/ml/old/reverse.sed b/src/api/ml/old/reverse.sed deleted file mode 100644 index 31ac563d2..000000000 --- a/src/api/ml/old/reverse.sed +++ /dev/null @@ -1,3 +0,0 @@ -# output lines of input in reverse order - -1!G;h;$!d diff --git a/src/api/ml/old/test_mlapi.cmd b/src/api/ml/old/test_mlapi.cmd deleted file mode 100755 index 64315e3f7..000000000 --- a/src/api/ml/old/test_mlapi.cmd +++ /dev/null @@ -1,61 +0,0 @@ -@echo off -SETLOCAL - -REM Script to test the Z3 OCaml API -REM -REM Assumes that environment variables are set to provide access to the C and OCaml compilers, as well as the following commands: diff, dos2unix, sed - -REM directory containing z3_api.h -set Z3SRC=%1 - -REM directory containing z3.dll and z3.lib -set Z3BIN=%2 - -REM directory containing debug z3.dll -set Z3BINDBG=%3 - -set PATH=.;%2;%3;%PATH% - -echo Build test_capi -cl /nologo /I %Z3SRC% %Z3BIN%\z3.lib ..\test_capi\test_capi.c - -echo Build test_mlapi -ocamlc -w -a -o test_mlapi.byte.exe z3.cma test_mlapi.ml -ocamlopt -w -a -o test_mlapi.exe z3.cmxa test_mlapi.ml -ocamlc -g -w -a -o test_mlapi.byte.dbg.exe z3_dbg.cma test_mlapi.ml -ocamlopt -g -w -a -o test_mlapi.dbg.exe z3_dbg.cmxa test_mlapi.ml - -echo Build test_mlapiV3 -ocamlopt -g -w -a -o test_mlapiV3.dbg.exe z3_dbg.cmxa test_mlapiV3.ml - -echo Build test_theory -ocamlopt -g -w -a -o test_theory.dbg.exe z3_dbg.cmxa test_theory.ml - -echo Build queen -ocamlopt -g -w -a -o queen.exe z3_dbg.cmxa queen.ml - -echo Execute test_capi, test_mlapi, test_mlapiV3 and queen -test_capi.exe >test_capi.out 2>test_capi.orig.err -test_mlapi.dbg.exe >test_mlapi.out 2>test_mlapi.orig.err -test_mlapiV3.dbg.exe >test_mlapiV3.out 2>test_mlapiV3.orig.err -queen.exe >queen.out 2>queen.orig.err - -REM Strip pointers as they will always differ -sed test_capi.err "s/ \[.*\]/ [...]/g" -sed test_mlapi.err "s/ \[.*\]/ [...]/g" -sed test_mlapiV3.err "s/ \[.*\]/ [...]/g" -sed queen.err "s/ \[.*\]/ [...]/g" -del test_capi.orig.err test_mlapi.orig.err test_mlapiV3.orig.err queen.orig.err - -REM Compare with regressions -dos2unix *.out *.err 2>NUL -diff test_capi.regress.out test_capi.out >NUL || echo Regression failed, see: diff test_capi.regress.out test_capi.out -diff test_mlapi.regress.out test_mlapi.out >NUL || echo Regression failed, see: diff test_mlapi.regress.out test_mlapi.out -diff test_mlapiV3.regress.out test_mlapiV3.out >NUL || echo Regression failed, see: diff test_mlapiV3.regress.out test_mlapiV3.out -diff test_capi.regress.err test_capi.err >NUL || echo Regression failed, see: diff test_capi.regress.err test_capi.err -diff test_mlapi.regress.err test_mlapi.err >NUL || echo Regression failed, see: diff test_mlapi.regress.err test_mlapi.err -diff test_mlapiV3.regress.err test_mlapiV3.err >NUL || echo Regression failed, see: diff test_mlapiV3.regress.err test_mlapiV3.err -diff queen.regress.out queen.out >NUL || echo Regression failed, see: diff queen.regress.out queen.out -diff queen.regress.err queen.err >NUL || echo Regression failed, see: diff queen.regress.err queen.err - -ENDLOCAL diff --git a/src/api/ml/old/test_mlapi.ml b/src/api/ml/old/test_mlapi.ml deleted file mode 100644 index 149ae27f8..000000000 --- a/src/api/ml/old/test_mlapi.ml +++ /dev/null @@ -1,209 +0,0 @@ -(** Examples of using the OCaml API for Z3. *) - -(**/**) -(* pause documentation *) - -(* - @name Auxiliary Functions -*) - -(** - printf -*) -let printf = Printf.printf -;; - -(** - fprintf -*) -let fprintf = Printf.fprintf -;; - -(** - Exit gracefully in case of error. -*) -let exitf message = fprintf stderr "BUG: %s.\n" message ; exit 1 -;; - -(** - Create and print datatypes -*) -let mk_datatypes ctx generator = - let datatypes = Z3.mk_datatypes ctx generator in - printf "datatype created:\n%!" ; - Array.iter (fun (sort, ctors) -> - printf "sort: %s\n%!" (Z3.sort_to_string ctx sort) ; - Array.iter (fun {Z3.constructor; recognizer; accessors} -> - printf "constructor: %s%! recognizer: %s%! accessors:" - (Z3.func_decl_to_string ctx constructor) - (Z3.func_decl_to_string ctx recognizer) ; - Array.iter (fun accessor -> - printf " %s%!" (Z3.func_decl_to_string ctx accessor) - ) accessors ; - printf "\n" - ) ctors - ) datatypes ; - printf "\n" ; - datatypes -;; - - -(** - Create a variable using the given name and type. -*) -let mk_var ctx name ty = Z3.mk_const ctx (Z3.mk_string_symbol ctx name) ty -;; - -(* resume documentation *) -(**/**) - - -(** - Prove that the constraints already asserted into the logical - context implies the given formula. The result of the proof is - displayed. - Z3 is a satisfiability checker. So, one can prove {e f } by showing - that {e (not f) } is unsatisfiable. - The context {e ctx } is not modified by this function. -*) -let prove ctx slv f is_valid = - (* save the current state of the context *) - Z3.solver_push ctx slv ; - - let not_f = Z3.mk_not ctx f in - Z3.solver_assert ctx slv not_f ; - - (match Z3.solver_check ctx slv with - | Z3.L_FALSE -> - (* proved *) - printf "valid\n" ; - if not is_valid then exitf "unexpected result" - | Z3.L_UNDEF -> - (* Z3 failed to prove/disprove f. *) - printf "unknown\n" ; - let m = Z3.solver_get_model ctx slv in - (* m should be viewed as a potential counterexample. *) - printf "potential counterexample:\n%s\n" (Z3.model_to_string ctx m) ; - if is_valid then exitf "unexpected result" - | Z3.L_TRUE -> - (* disproved *) - printf "invalid\n" ; - let m = Z3.solver_get_model ctx slv in - (* the model returned by Z3 is a counterexample *) - printf "counterexample:\n%s\n" (Z3.model_to_string ctx m) ; - if is_valid then exitf "unexpected result" - ); - (* restore context *) - Z3.solver_pop ctx slv 1 -;; - - -(* n-ary trees and forests in OCaml *) -type tree = Leaf of int | Node of forest -and forest = tree list - -(** - Demonstrates the usage of {!Z3.mk_datatypes} with an example of forests of trees. -*) -let forest_example () = - let ctx = Z3.mk_context [] in - let slv = Z3.mk_solver ctx - in - let int_sort = Z3.mk_int_sort ctx in - let sym name = Z3.mk_string_symbol ctx name - in - (* n-ary trees and forests in Z3 *) - match - mk_datatypes ctx - (function [|tree; forest|] -> Some - [|(sym"tree", - [|{Z3.constructor_desc= sym"leaf"; recognizer_desc= sym"is_leaf"; accessor_descs= [|(sym"data", int_sort)|]}; - {Z3.constructor_desc= sym"node"; recognizer_desc= sym"is_node"; accessor_descs= [|(sym"children", forest)|]}|]); - (sym"forest", - [|{Z3.constructor_desc= sym"nil" ; recognizer_desc= sym"is_nil" ; accessor_descs= [||]}; - {Z3.constructor_desc= sym"cons"; recognizer_desc= sym"is_cons"; accessor_descs= [|(sym"hd", tree); (sym"tl", forest)|]}|])|] - | _ -> None - ) - with - [|(tree, - [|{Z3.constructor= leaf; recognizer= is_leaf; accessors= [|data|]}; - {Z3.constructor= node; recognizer= is_node; accessors= [|children|]}|]); - (forest, - [|{Z3.constructor= nil ; recognizer= is_nil ; accessors= [||]}; - {Z3.constructor= cons; recognizer= is_cons; accessors= [|hd; tl|]}|])|] - -> - (* translate from OCaml to Z3 *) - let rec ml2z3_tree = function - | Leaf(i) -> Z3.mk_app ctx leaf [|Z3.mk_int ctx i (Z3.mk_int_sort ctx)|] - | Node(f) -> Z3.mk_app ctx node [|ml2z3_forest f|] - - and ml2z3_forest = function - | [] -> Z3.mk_app ctx nil [||] - | t :: f -> Z3.mk_app ctx cons [|ml2z3_tree t; ml2z3_forest f|] - in - - (* construct some OCaml trees *) - let t0 = Leaf 0 in - let t12 = Node [Leaf 1; Leaf 2] in - let t123 = Node [t12; Leaf 3] in - let t1212 = Node [t12; t12] in - let t412 = Node [Leaf 4; t12] in - - (* construct some Z3 trees using the translation from OCaml *) - let t1 = ml2z3_tree t12 in printf "t1: %s\n%!" (Z3.ast_to_string ctx t1) ; - let t2 = ml2z3_tree t123 in printf "t2: %s\n%!" (Z3.ast_to_string ctx t2) ; - let t3 = ml2z3_tree t1212 in printf "t3: %s\n%!" (Z3.ast_to_string ctx t3) ; - let t4 = ml2z3_tree t412 in printf "t4: %s\n%!" (Z3.ast_to_string ctx t4) ; - let f1 = ml2z3_forest [t0] in printf "f1: %s\n%!" (Z3.ast_to_string ctx f1) ; - let f2 = ml2z3_forest [t12] in printf "f2: %s\n%!" (Z3.ast_to_string ctx f2) ; - let f3 = ml2z3_forest [t12; t0] in printf "f3: %s\n%!" (Z3.ast_to_string ctx f3) ; - - (* or using the Z3 API *) - let nil = Z3.mk_app ctx nil [||] in - let cons t f = Z3.mk_app ctx cons [|t; f|] in - let leaf i = Z3.mk_app ctx leaf [|Z3.mk_int ctx i (Z3.mk_int_sort ctx)|] in - let node f = Z3.mk_app ctx node [|f|] in - - let t0 = leaf 0 in - let t12 = node (cons (leaf 1) (cons (leaf 2) nil)) in - let t123 = node (cons t12 (cons (leaf 3) nil)) in - let t1212 = node (cons t12 (cons t12 nil)) in - let t412 = node (cons (leaf 4) (cons t12 nil)) in - - let t1 = t12 in printf "t1: %s\n%!" (Z3.ast_to_string ctx t1) ; - let t2 = t123 in printf "t2: %s\n%!" (Z3.ast_to_string ctx t2) ; - let t3 = t1212 in printf "t3: %s\n%!" (Z3.ast_to_string ctx t3) ; - let t4 = t412 in printf "t4: %s\n%!" (Z3.ast_to_string ctx t4) ; - let f1 = cons t0 nil in printf "f1: %s\n%!" (Z3.ast_to_string ctx f1) ; - let f2 = cons t12 nil in printf "f2: %s\n%!" (Z3.ast_to_string ctx f2) ; - let f3 = cons t12 f1 in printf "f3: %s\n%!" (Z3.ast_to_string ctx f3) ; - - (* nil != cons(nil,nil) *) - prove ctx slv (Z3.mk_not ctx (Z3.mk_eq ctx nil f1)) true ; - prove ctx slv (Z3.mk_not ctx (Z3.mk_eq ctx (leaf 5) t1)) true ; - - (* cons(x,u) = cons(x, v) => u = v *) - let u = mk_var ctx "u" forest in - let v = mk_var ctx "v" forest in - let x = mk_var ctx "x" tree in - let y = mk_var ctx "y" tree in - let l1 = cons x u in printf "l1: %s\n%!" (Z3.ast_to_string ctx l1) ; - let l2 = cons y v in printf "l2: %s\n%!" (Z3.ast_to_string ctx l2) ; - - prove ctx slv (Z3.mk_implies ctx (Z3.mk_eq ctx l1 l2) (Z3.mk_eq ctx u v)) true ; - prove ctx slv (Z3.mk_implies ctx (Z3.mk_eq ctx l1 l2) (Z3.mk_eq ctx x y)) true ; - - (* is_nil(u) or is_cons(u) *) - prove ctx slv (Z3.mk_or ctx [|Z3.mk_app ctx is_nil [|u|]; Z3.mk_app ctx is_cons [|u|]|]) true ; - - (* occurs check u != cons(x,u) *) - prove ctx slv (Z3.mk_not ctx (Z3.mk_eq ctx u l1)) true ; - - | _ -> - exitf "unexpected datatype signature" -;; - -let _ = - ignore( Z3.open_log "test_mlapi.log" ); - forest_example () ; -;; diff --git a/src/api/ml/old/test_mlapiV3.ml b/src/api/ml/old/test_mlapiV3.ml deleted file mode 100644 index a88d13000..000000000 --- a/src/api/ml/old/test_mlapiV3.ml +++ /dev/null @@ -1,1418 +0,0 @@ -(** Module test_mlapi - ML test and demo program for Z3. Matches test_capi.ml - JakobL@2007-09-08 *) - -module Z3 = Z3.V3 - -(* - @name Auxiliary Functions -*) - -(** - printf -*) -let printf = Printf.printf;; - -(** - fprintf -*) -let fprintf = Printf.fprintf;; - -(** - Exit gracefully in case of error. -*) -let exitf message = fprintf stderr "BUG: %s.\n" message; exit 1;; - -(** - Create a logical context. Enable model construction. - Also enable tracing to stderr. -*) -let mk_context ctx = - let ctx = Z3.mk_context_x (Array.append [|("MODEL", "true")|] ctx) in - (* You may comment out the following line to disable tracing: *) - (* Z3.trace_to_stderr ctx; *) - ctx;; - -(** - Create a variable using the given name and type. -*) -let mk_var ctx name ty = Z3.mk_const ctx (Z3.mk_string_symbol ctx name) ty;; - -(** - Create a boolean variable using the given name. -*) -let mk_bool_var ctx name = mk_var ctx name (Z3.mk_bool_sort ctx);; - -(** - Create an integer variable using the given name. -*) -let mk_int_var ctx name = mk_var ctx name (Z3.mk_int_sort ctx);; - -(** - Create a Z3 integer node using a C int. -*) -let mk_int ctx v = Z3.mk_int ctx v (Z3.mk_int_sort ctx);; - -(** - Create a real variable using the given name. -*) -let mk_real_var ctx name = mk_var ctx name (Z3.mk_real_sort ctx);; - -(** - Create the unary function application: {e (f x) }. -*) -let mk_unary_app ctx f x = Z3.mk_app ctx f [|x|];; - -(** - Create the binary function application: {e (f x y) }. -*) -let mk_binary_app ctx f x y = Z3.mk_app ctx f [|x;y|];; - -(** - Auxiliary function to check whether two Z3 types are equal or not. -*) -let equal_sorts ctx t1 t2 = Z3.is_eq_sort ctx t1 t2;; - -(** - Check whether the logical context is satisfiable, and compare the result with the expected result. - If the context is satisfiable, then display the model. -*) -let check ctx expected_result = - begin - let (result, m) = Z3.check_and_get_model ctx in - (match result with - | Z3.L_FALSE -> printf "unsat\n"; - | Z3.L_UNDEF -> - printf "unknown\n"; - printf "potential model:\n%s\n" (Z3.model_to_string ctx m); - (Z3.del_model ctx m); - | Z3.L_TRUE -> printf "sat\n%s\n" (Z3.model_to_string ctx m); - (Z3.del_model ctx m); - ); - if result != expected_result then exitf "unexpected result"; - end;; - -(** - Prove that the constraints already asserted into the logical - context implies the given formula. The result of the proof is - displayed. - Z3 is a satisfiability checker. So, one can prove {e f } by showing - that {e (not f) } is unsatisfiable. - The context {e ctx } is not modified by this function. -*) -let prove ctx f is_valid = - begin - (* save the current state of the context *) - Z3.push ctx; - - let not_f = Z3.mk_not ctx f in - Z3.assert_cnstr ctx not_f; - - (match Z3.check_and_get_model ctx with - | (Z3.L_FALSE,_) -> - (* proved *) - printf "valid\n"; - if not is_valid then exitf "unexpected result"; - | (Z3.L_UNDEF,m) -> - (* Z3 failed to prove/disprove f. *) - printf "unknown\n"; - (* m should be viewed as a potential counterexample. *) - printf "potential counterexample:\n%s\n" (Z3.model_to_string ctx m); - if is_valid then exitf "unexpected result"; - (Z3.del_model ctx m); - | (Z3.L_TRUE,m) -> - (* disproved *) - printf "invalid\n"; - (* the model returned by Z3 is a counterexample *) - printf "counterexample:\n%s\n" (Z3.model_to_string ctx m); - if is_valid then exitf "unexpected result"; - (Z3.del_model ctx m); - ); - (* restore context *) - Z3.pop ctx 1; - end;; - -(** - Assert the axiom: function f is injective in the i-th argument. - - The following axiom is asserted into the logical context: - - forall (x_1, ..., x_n) finv(f(x_1, ..., x_i, ..., x_n)) = x_i - - Where, {e finv } is a fresh function declaration. -*) -let assert_inj_axiom ctx f i = - begin - let sz = Z3.get_domain_size ctx f in - if i >= sz then exitf "failed to create inj axiom"; - - (* declare the i-th inverse of f: finv *) - let finv_domain = Z3.get_range ctx f in - let finv_range = Z3.get_domain ctx f i in - let finv = Z3.mk_fresh_func_decl ctx "inv" [|finv_domain|] finv_range in - - (* allocate temporary arrays *) - (* fill types, names and xs *) - let types = Z3.get_domains ctx f in - let names = Array.init sz (Z3.mk_int_symbol ctx) in - let xs = Array.init sz (fun j->Z3.mk_bound ctx j (types.(j))) in - - (* create f(x_0, ..., x_i, ..., x_{n-1}) *) - let fxs = Z3.mk_app ctx f xs in - - (* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) *) - let finv_fxs = mk_unary_app ctx finv fxs in - - (* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i *) - let eq = Z3.mk_eq ctx finv_fxs (xs.(i)) in - - (* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier *) - let p = Z3.mk_pattern ctx [|fxs|] in - printf "pattern: %s\n" (Z3.pattern_to_string ctx p); - printf "\n"; - - (* create & assert quantifier *) - let q = Z3.mk_forall ctx - 0 (* using default weight *) - [|p|] (* the "array" of patterns *) - types - names - eq - in - printf "assert axiom:\n%s\n" (Z3.ast_to_string ctx q); - Z3.assert_cnstr ctx q; - end;; - -(** - Assert the axiom: function f is commutative. - - This example uses the SMT-LIB parser to simplify the axiom construction. -*) -let assert_comm_axiom ctx f = - begin - let t = Z3.get_range ctx f in - if Z3.get_domain_size ctx f != 2 || not (equal_sorts ctx (Z3.get_domain ctx f 0) t) || not (equal_sorts ctx (Z3.get_domain ctx f 1) t) then - exitf "function must be binary, and argument types must be equal to return type"; - (* Inside the parser, function f will be referenced using the symbol 'f'. *) - let f_name = Z3.mk_string_symbol ctx "f" in - (* Inside the parser, type t will be referenced using the symbol 'T'. *) - let t_name = Z3.mk_string_symbol ctx "T" in - let str = "(benchmark comm :formula (forall (x T) (y T) (= (f x y) (f y x))))" in - let q = Z3.parse_smtlib_string_formula ctx str [|t_name|] [|t|] [|f_name|] [|f|] in - printf "assert axiom:\n%s\n" (Z3.ast_to_string ctx q); - Z3.assert_cnstr ctx q; - end;; - -(** - Z3 does not support explicitly tuple updates. They can be easily implemented - as macros. The argument {e t } must have tuple type. - A tuple update is a new tuple where field {e i } has value {e new_val }, and all - other fields have the value of the respective field of {e t }. - - {e update(t, i, new_val) } is equivalent to - {e mk_tuple(proj_0(t), ..., new_val, ..., proj_n(t)) } -*) -let mk_tuple_update c t i new_val = - begin - let ty = Z3.get_sort c t in - let (mk_tuple_decl,fields)=Z3.get_tuple_sort c ty in - if i>=Array.length fields then exitf "invalid tuple update, index is too big"; - let f j = - if i = j then (* use new_val at position i: *) new_val - else (* use field j of t: *) (mk_unary_app c (fields.(j)) t) - in let new_fields = Array.init (Array.length fields) f in - Z3.mk_app c (Z3.get_tuple_sort_mk_decl c ty) new_fields; - end;; - -(** - Display a symbol in the given output stream. -*) -let display_symbol c out s = - match Z3.symbol_refine c s with - | Z3.Symbol_int i -> fprintf out "#%d" i; - | Z3.Symbol_string r ->fprintf out "%s" r; - | Z3.Symbol_unknown -> ();; - -(** - Display the given type. -*) -let rec display_sort c out ty = - begin - match Z3.sort_refine c ty with - | Z3.Sort_uninterpreted s -> display_symbol c out s; - | Z3.Sort_bool -> fprintf out "bool"; - | Z3.Sort_int -> fprintf out "int"; - | Z3.Sort_real -> fprintf out "real"; - | Z3.Sort_relation -> fprintf out "relation"; - | Z3.Sort_finite_domain -> fprintf out "finite-domain"; - | Z3.Sort_bv sz -> fprintf out "bv%d" sz; - | Z3.Sort_array (domain, range) -> - fprintf out "["; - display_sort c out domain; - fprintf out "->"; - display_sort c out range; - fprintf out "]"; - | Z3.Sort_datatype cons -> - Array.iter (fun (dt_con : Z3.datatype_constructor_refined) -> - let fields = dt_con.Z3.accessors in - fprintf out "("; - let f i v = - if i>0 then fprintf out ", "; - display_sort c out (Z3.get_range c v); - in Array.iteri f fields; - fprintf out ")") cons - | Z3.Sort_unknown s -> - fprintf out "unknown["; - display_symbol c out s; - fprintf out "unknown]"; - end;; - -(** - Custom ast pretty printer. - - This function demonstrates how to use the API to navigate terms. -*) - -let rec display_numeral c out nm = - match nm with - | Z3.Numeral_small(n,1L) -> - Printf.fprintf out "%Ld" n - | Z3.Numeral_small(n,d) -> - Printf.fprintf out "%Ld/%Ld" n d - | Z3.Numeral_large s -> - Printf.fprintf out "%s" s - -let rec display_ast c out v = - begin - match Z3.term_refine c v with - | Z3.Term_app(k, f, args) -> - let num_fields = Array.length args in - let a = Z3.to_app c v in - let d = Z3.get_app_decl c a in - Printf.fprintf out "%s" (Z3.func_decl_to_string c d); - if num_fields > 0 then - begin - Printf.fprintf out "["; - for i = 0 to num_fields - 1 do - if i > 0 then Printf.fprintf out ", "; - display_ast c out (Z3.get_app_arg c a i) - done; - Printf.fprintf out "]" - end - | Z3.Term_numeral(nm, s) -> - display_numeral c out nm; - Printf.fprintf out ":"; - display_sort c out s - | Z3.Term_var(idx, s) -> - printf "#unknown" - | Z3.Term_quantifier(b, w, pats, bound, body) -> - printf "quantifier" - end;; - -(** - Custom function for traversing a term and replacing the constant - 'x' by the bound variable having index 'idx'. - This function illustrates how to walk Z3 terms and - reconstruct them. -**) - -let rec abstract c x idx term = - if Z3.is_eq_ast c term x then Z3.mk_bound c idx (Z3.get_sort c x) else - match Z3.term_refine c term with - | Z3.Term_app(k, f, args) -> Z3.mk_app c f (Array.map (abstract c x idx) args) - | Z3.Term_numeral(nm, s) -> term - | Z3.Term_var(idx, s) -> term - | Z3.Term_quantifier(b, w, pats, bound, body) -> - let idx = (idx + Array.length bound) in - let body = abstract c x idx body in - let is_forall = b = Z3.Forall in - let mk_pattern terms = Z3.mk_pattern c (Array.map (abstract c x idx) terms) in - let patterns = Array.map mk_pattern pats in - Z3.mk_quantifier c is_forall w patterns - (Array.map snd bound) (Array.map fst bound) body - -(** - Example abstraction function. -**) - - -let abstract_example() = - begin - printf "\nabstract_example\n"; - let ctx = mk_context [||] in - let x = mk_int_var ctx "x" in - let x_decl = Z3.get_app_decl ctx (Z3.to_app ctx x) in - let y = mk_int_var ctx "y" in - let y_decl = Z3.get_app_decl ctx (Z3.to_app ctx y) in - let decls = [| x_decl; y_decl |] in - let a = Z3.mk_string_symbol ctx "a" in - let b = Z3.mk_string_symbol ctx "b" in - let names = [| a; b |] in - let str = "(benchmark tst :formula (> a b))" in - let f = Z3.parse_smtlib_string_formula ctx str [||] [||] names decls in - printf "formula: %s\n" (Z3.ast_to_string ctx f); - - let f2 = abstract ctx x 0 f in - - printf "abstracted formula: %s\n" (Z3.ast_to_string ctx f2); - (* delete logical context *) - Z3.del_context ctx; - - end;; - -(** - Custom function interpretations pretty printer. -*) -let display_function_interpretations c out m = - begin - fprintf out "function interpretations:\n"; - let display_function (name, entries, func_else) = - begin - display_symbol c out name; - fprintf out " = {"; - let display_entry j (args,valu) = - if j > 0 then fprintf out ", "; - fprintf out "("; - let f k arg = - if k > 0 then fprintf out ", "; - display_ast c out arg - in Array.iteri f args; - fprintf out "|->"; - display_ast c out valu; - fprintf out ")"; - in Array.iteri display_entry entries; - if Array.length entries > 0 then fprintf out ", "; - fprintf out "(else|->"; - display_ast c out func_else; - fprintf out ")}\n"; - end; - in - Array.iter display_function (Z3.get_model_funcs c m); - end;; - -(** - Custom model pretty printer. -*) -let display_model c out m = - begin - let constants=Z3.get_model_constants c m in - let f i e = - let name = Z3.get_decl_name c e in - let (ok, v) = Z3.eval_func_decl c m e in - display_symbol c out name; - fprintf out " = "; - display_ast c out v; - fprintf out "\n" - in Array.iteri f constants; - display_function_interpretations c out m; - end;; - -(** - Similar to #check, but uses #display_model instead of #Z3_model_to_string. -*) -let check2 ctx expected_result = - begin - let (result,m) = Z3.check_and_get_model ctx in - (match result with - | Z3.L_FALSE -> - printf "unsat\n"; - | Z3.L_UNDEF -> - printf "unknown\n"; - printf "potential model:\n"; - display_model ctx stdout m; - (Z3.del_model ctx m); - | Z3.L_TRUE -> - printf "sat\n"; - display_model ctx stdout m; - (Z3.del_model ctx m); - ); - if result != expected_result then exitf "unexpected result"; - end;; - -(** - Display Z3 version in the standard output. -*) -let display_version() = - begin - let (major, minor, build, revision)=Z3.get_version() in - printf "Z3 %d.%d.%d.%d\n" major minor build revision; - end;; - -(* - @name Examples -*) - -(** - "Hello world" example: create a Z3 logical context, and delete it. -*) -let simple_example() = - begin - printf "\nsimple_example\n"; - let ctx = mk_context [||] in - (* do something with the context *) - printf "CONTEXT:\n%sEND OF CONTEXT\n" (Z3.context_to_string ctx); - (* delete logical context *) - Z3.del_context ctx; - end;; - -(** - Demonstration of how Z3 can be used to prove validity of - De Morgan's Duality Law: {e not(x and y) <-> (not x) or ( not y) } -*) -let demorgan() = - begin - printf "\nDeMorgan\n"; - let ctx = mk_context [||] in - let bool_sort = Z3.mk_bool_sort ctx in - let symbol_x = Z3.mk_int_symbol ctx 0 in - let symbol_y = Z3.mk_int_symbol ctx 1 in - let x = Z3.mk_const ctx symbol_x bool_sort in - let y = Z3.mk_const ctx symbol_y bool_sort in - - (* De Morgan - with a negation around: *) - (* !(!(x && y) <-> (!x || !y)) *) - let not_x = Z3.mk_not ctx x in - let not_y = Z3.mk_not ctx y in - let x_and_y = Z3.mk_and ctx [|x;y|] in - let ls = Z3.mk_not ctx x_and_y in - let rs = Z3.mk_or ctx [|not_x;not_y|] in - let conjecture = Z3.mk_iff ctx ls rs in - let negated_conjecture = Z3.mk_not ctx conjecture in - - Z3.assert_cnstr ctx negated_conjecture; - (match Z3.check ctx with - | Z3.L_FALSE -> - (* The negated conjecture was unsatisfiable, hence the conjecture is valid *) - printf "DeMorgan is valid\n" - | Z3.L_UNDEF -> - (* Check returned undef *) - printf "Undef\n" - | Z3.L_TRUE -> - (* The negated conjecture was satisfiable, hence the conjecture is not valid *) - Printf.printf "DeMorgan is not valid\n"); - Z3.del_context ctx; - end;; - -(** - Find a model for {e x xor y }. -*) -let find_model_example1() = - begin - printf "\nfind_model_example1\n"; - let ctx = mk_context [||] in - let x = mk_bool_var ctx "x" in - let y = mk_bool_var ctx "y" in - let x_xor_y = Z3.mk_xor ctx x y in - Z3.assert_cnstr ctx x_xor_y; - printf "model for: x xor y\n"; - check ctx Z3.L_TRUE; - Z3.del_context ctx; - end;; - -(** - Find a model for {e x < y + 1, x > 2 }. - Then, assert {e not(x = y) }, and find another model. -*) -let find_model_example2() = - begin - printf "\nfind_model_example2\n"; - let ctx = mk_context [||] in - let x = mk_int_var ctx "x" in - let y = mk_int_var ctx "y" in - let one = mk_int ctx 1 in - let two = mk_int ctx 2 in - let y_plus_one = Z3.mk_add ctx [|y;one|] in - let c1 = Z3.mk_lt ctx x y_plus_one in - let c2 = Z3.mk_gt ctx x two in - Z3.assert_cnstr ctx c1; - Z3.assert_cnstr ctx c2; - printf "model for: x < y + 1, x > 2\n"; - check ctx Z3.L_TRUE; - - (* assert not(x = y) *) - let x_eq_y = Z3.mk_eq ctx x y in - let c3 = Z3.mk_not ctx x_eq_y in - Z3.assert_cnstr ctx c3; - printf "model for: x < y + 1, x > 2, not(x = y)\n"; - check ctx Z3.L_TRUE; - Z3.del_context ctx; - end;; - -(** - Prove {e x = y implies g(x) = g(y) }, and - disprove {e x = y implies g(g(x)) = g(y) }. - - This function demonstrates how to create uninterpreted types and - functions. -*) -let prove_example1() = - begin - printf "\nprove_example1\n"; - - let ctx = mk_context [||] in - - (* create uninterpreted type. *) - let u_name = Z3.mk_string_symbol ctx "U" in - let u = Z3.mk_uninterpreted_sort ctx u_name in - - (* declare function g *) - let g_name = Z3.mk_string_symbol ctx "g" in - let g = Z3.mk_func_decl ctx g_name [|u|] u in - - (* create x and y *) - let x_name = Z3.mk_string_symbol ctx "x" in - let y_name = Z3.mk_string_symbol ctx "y" in - let x = Z3.mk_const ctx x_name u in - let y = Z3.mk_const ctx y_name u in - (* create g(x), g(y) *) - let gx = mk_unary_app ctx g x in - let gy = mk_unary_app ctx g y in - - (* assert x = y *) - let eq = Z3.mk_eq ctx x y in - Z3.assert_cnstr ctx eq; - - (* prove g(x) = g(y) *) - let f = Z3.mk_eq ctx gx gy in - printf "prove: x = y implies g(x) = g(y)\n"; - prove ctx f true; - - (* create g(g(x)) *) - let ggx = mk_unary_app ctx g gx in - - (* disprove g(g(x)) = g(y) *) - let f = Z3.mk_eq ctx ggx gy in - printf "disprove: x = y implies g(g(x)) = g(y)\n"; - prove ctx f false; - - Z3.del_context ctx; - end;; - -(** - Prove {e not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 }. - Then, show that {e z < -1 } is not implied. - - This example demonstrates how to combine uninterpreted functions and arithmetic. -*) -let prove_example2() = - begin - printf "\nprove_example2\n"; - - let ctx = mk_context [||] in - - (* declare function g *) - let int_sort = Z3.mk_int_sort ctx in - let g_name = Z3.mk_string_symbol ctx "g" in - let g = Z3.mk_func_decl ctx g_name [|int_sort|] int_sort in - - (* create x, y, and z *) - let x = mk_int_var ctx "x" in - let y = mk_int_var ctx "y" in - let z = mk_int_var ctx "z" in - - (* create gx, gy, gz *) - let gx = mk_unary_app ctx g x in - let gy = mk_unary_app ctx g y in - let gz = mk_unary_app ctx g z in - - (* create zero *) - let zero = mk_int ctx 0 in - - (* assert not(g(g(x) - g(y)) = g(z)) *) - let gx_gy = Z3.mk_sub ctx [|gx;gy|] in - let ggx_gy = mk_unary_app ctx g gx_gy in - let eq = Z3.mk_eq ctx ggx_gy gz in - let c1 = Z3.mk_not ctx eq in - Z3.assert_cnstr ctx c1; - - (* assert x + z <= y *) - let x_plus_z = Z3.mk_add ctx [|x;z|] in - let c2 = Z3.mk_le ctx x_plus_z y in - Z3.assert_cnstr ctx c2; - - (* assert y <= x *) - let c3 = Z3.mk_le ctx y x in - Z3.assert_cnstr ctx c3; - - (* prove z < 0 *) - let f = Z3.mk_lt ctx z zero in - printf "prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0\n"; - prove ctx f true; - - (* disprove z < -1 *) - let minus_one = mk_int ctx (-1) in - let f = Z3.mk_lt ctx z minus_one in - printf "disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1\n"; - prove ctx f false; - - Z3.del_context ctx; - end;; - -(** - Show how push & pop can be used to create "backtracking" - points. - - This example also demonstrates how big numbers can be created in Z3. -*) -let push_pop_example1() = - begin - printf "\npush_pop_example1\n"; - let ctx = mk_context [||] in - - (* create a big number *) - let int_sort = Z3.mk_int_sort ctx in - let big_number = Z3.mk_numeral ctx "1000000000000000000000000000000000000000000000000000000" int_sort in - - (* create number 3 *) - let three = Z3.mk_numeral ctx "3" int_sort in - - (* create x *) - let x_sym = Z3.mk_string_symbol ctx "x" in - let x = Z3.mk_const ctx x_sym int_sort in - - (* assert x >= "big number" *) - let c1 = Z3.mk_ge ctx x big_number in - printf "assert: x >= 'big number'\n"; - Z3.assert_cnstr ctx c1; - - (* create a backtracking point *) - printf "push\n"; - Z3.push ctx; - - printf "number of scopes: %d\n" (Z3.get_num_scopes ctx); - - (* assert x <= 3 *) - let c2 = Z3.mk_le ctx x three in - printf "assert: x <= 3\n"; - Z3.assert_cnstr ctx c2; - - (* context is inconsistent at this point *) - check2 ctx Z3.L_FALSE; - - (* backtrack: the constraint x <= 3 will be removed, since it was - asserted after the last push. *) - printf "pop\n"; - Z3.pop ctx 1; - - printf "number of scopes: %d\n" (Z3.get_num_scopes ctx); - - (* the context is consistent again. *) - check2 ctx Z3.L_TRUE; - - (* new constraints can be asserted... *) - - (* create y *) - let y_sym = Z3.mk_string_symbol ctx "y" in - let y = Z3.mk_const ctx y_sym int_sort in - - (* assert y > x *) - let c3 = Z3.mk_gt ctx y x in - printf "assert: y > x\n"; - Z3.assert_cnstr ctx c3; - - (* the context is still consistent. *) - check2 ctx Z3.L_TRUE; - - Z3.del_context ctx; - end;; - -(** - Prove that {e f(x, y) = f(w, v) implies y = v } when - {e f } is injective in the second argument. -*) -let quantifier_example1() = - begin - printf "\nquantifier_example1\n"; - - (* If quantified formulas are asserted in a logical context, then - Z3 may return L_UNDEF. In this case, the model produced by Z3 should be viewed as a potential/candidate model. - Limiting the number of iterations of the model finder for quantified formulas. - *) - let ctx = mk_context [|("MBQI_MAX_ITERATIONS", "10")|] in - - (* declare function f *) - let int_sort = Z3.mk_int_sort ctx in - let f_name = Z3.mk_string_symbol ctx "f" in - let f = Z3.mk_func_decl ctx f_name [|int_sort; int_sort|] int_sort in - - (* assert that f is injective in the second argument. *) - assert_inj_axiom ctx f 1; - - (* create x, y, v, w, fxy, fwv *) - let x = mk_int_var ctx "x" in - let y = mk_int_var ctx "y" in - let v = mk_int_var ctx "v" in - let w = mk_int_var ctx "w" in - let fxy = mk_binary_app ctx f x y in - let fwv = mk_binary_app ctx f w v in - - (* assert f(x, y) = f(w, v) *) - let p1 = Z3.mk_eq ctx fxy fwv in - Z3.assert_cnstr ctx p1; - - (* prove f(x, y) = f(w, v) implies y = v *) - let p2 = Z3.mk_eq ctx y v in - printf "prove: f(x, y) = f(w, v) implies y = v\n"; - prove ctx p2 true; - - (* disprove f(x, y) = f(w, v) implies x = w *) - (* using check2 instead of prove *) - let p3 = Z3.mk_eq ctx x w in - let not_p3 = Z3.mk_not ctx p3 in - Z3.assert_cnstr ctx not_p3; - printf "disprove: f(x, y) = f(w, v) implies x = w\n"; - printf "that is: not(f(x, y) = f(w, v) implies x = w) is satisfiable\n"; - check2 ctx Z3.L_UNDEF; - Printf.printf - "reason for last failure: %d (7 = quantifiers)\n" - (if Z3.get_search_failure(ctx) = Z3.QUANTIFIERS then 7 else -1); - - - Z3.del_context ctx; - end;; - -(** - Prove {e store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) }. - - This example demonstrates how to use the array theory. -*) -let array_example1() = - begin - printf "\narray_example1\n"; - - let ctx = mk_context [||] in - - let int_sort = Z3.mk_int_sort ctx in - let array_sort = Z3.mk_array_sort ctx int_sort int_sort in - - let a1 = mk_var ctx "a1" array_sort in - let a2 = mk_var ctx "a2" array_sort in - let i1 = mk_var ctx "i1" int_sort in - let i2 = mk_var ctx "i2" int_sort in - let i3 = mk_var ctx "i3" int_sort in - let v1 = mk_var ctx "v1" int_sort in - let v2 = mk_var ctx "v2" int_sort in - - let st1 = Z3.mk_store ctx a1 i1 v1 in - let st2 = Z3.mk_store ctx a2 i2 v2 in - - let sel1 = Z3.mk_select ctx a1 i3 in - let sel2 = Z3.mk_select ctx a2 i3 in - - (* create antecedent *) - let antecedent = Z3.mk_eq ctx st1 st2 in - - (* create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3) *) - let ds = [| - Z3.mk_eq ctx i1 i3; - Z3.mk_eq ctx i2 i3; - Z3.mk_eq ctx sel1 sel2; - |] in - - let consequent = Z3.mk_or ctx ds in - - (* prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3)) *) - let thm = Z3.mk_implies ctx antecedent consequent in - printf "prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))\n"; - printf "%s\n" (Z3.ast_to_string ctx thm); - prove ctx thm true; - - Z3.del_context ctx; - end;; - -(** - Show that {e distinct(a_0, ... , a_n) } is - unsatisfiable when {e a_i's } are arrays from boolean to - boolean and n > 4. - - This example also shows how to use the {e distinct } construct. -*) -let array_example2() = - begin - printf "\narray_example2\n"; - - for n = 2 to 5 do - printf "n = %d\n" n; - let ctx = mk_context [||] in - - let bool_sort = Z3.mk_bool_sort ctx in - let array_sort = Z3.mk_array_sort ctx bool_sort bool_sort in - - (* create arrays *) - let a = Array.init n - (fun i->Z3.mk_const ctx (Z3.mk_int_symbol ctx i) array_sort) in - - (* assert distinct(a[0], ..., a[n]) *) - let d = Z3.mk_distinct ctx a in - printf "%s\n" (Z3.ast_to_string ctx d); - Z3.assert_cnstr ctx d; - - (* context is satisfiable if n < 5 *) - check2 ctx (if n < 5 then Z3.L_TRUE else Z3.L_FALSE); - - Z3.del_context ctx; - done - end;; - -(** - Simple array type construction/deconstruction example. -*) -let array_example3() = - begin - printf "\narray_example3\n"; - - let ctx = mk_context [||] in - - let bool_sort = Z3.mk_bool_sort ctx in - let int_sort = Z3.mk_int_sort ctx in - let array_sort = Z3.mk_array_sort ctx int_sort bool_sort in - - let (domain,range) = Z3.get_array_sort ctx array_sort in - printf "domain: "; - display_sort ctx stdout domain; - printf "\n"; - printf "range: "; - display_sort ctx stdout range; - printf "\n"; - - if (not (Z3.is_eq_sort ctx int_sort domain)) || - (not (Z3.is_eq_sort ctx bool_sort range)) then - exitf "invalid array type"; - Z3.del_context ctx; - end;; - -(** - Simple tuple type example. It creates a tuple that is a pair of real numbers. -*) -let tuple_example1() = - begin - printf "\ntuple_example1\n"; - let ctx = mk_context [||] in - - let real_sort = Z3.mk_real_sort ctx in - - (* Create pair (tuple) type *) - let mk_tuple_name = Z3.mk_string_symbol ctx "mk_pair" in - let proj_names_0 = Z3.mk_string_symbol ctx "get_x" in - let proj_names_1 = Z3.mk_string_symbol ctx "get_y" in - let proj_names = [|proj_names_0; proj_names_1|] in - let proj_sorts = [|real_sort;real_sort|] in - (* Z3_mk_tuple_sort will set mk_tuple_decl and proj_decls *) - let (pair_sort,mk_tuple_decl,proj_decls) = Z3.mk_tuple_sort ctx mk_tuple_name proj_names proj_sorts in - let get_x_decl = proj_decls.(0) in (* function that extracts the first element of a tuple. *) - let get_y_decl = proj_decls.(1) in (* function that extracts the second element of a tuple. *) - - printf "tuple_sort: "; - display_sort ctx stdout pair_sort; - printf "\n"; - - begin - (* prove that get_x(mk_pair(x,y)) == 1 implies x = 1*) - let x = mk_real_var ctx "x" in - let y = mk_real_var ctx "y" in - let app1 = mk_binary_app ctx mk_tuple_decl x y in - let app2 = mk_unary_app ctx get_x_decl app1 in - let one = Z3.mk_numeral ctx "1" real_sort in - let eq1 = Z3.mk_eq ctx app2 one in - let eq2 = Z3.mk_eq ctx x one in - let thm = Z3.mk_implies ctx eq1 eq2 in - printf "prove: get_x(mk_pair(x, y)) = 1 implies x = 1\n"; - prove ctx thm true; - - (* disprove that get_x(mk_pair(x,y)) == 1 implies y = 1*) - let eq3 = Z3.mk_eq ctx y one in - let thm = Z3.mk_implies ctx eq1 eq3 in - printf "disprove: get_x(mk_pair(x, y)) = 1 implies y = 1\n"; - prove ctx thm false; - end; - - begin - (* prove that get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2 *) - let p1 = mk_var ctx "p1" pair_sort in - let p2 = mk_var ctx "p2" pair_sort in - let x1 = mk_unary_app ctx get_x_decl p1 in - let y1 = mk_unary_app ctx get_y_decl p1 in - let x2 = mk_unary_app ctx get_x_decl p2 in - let y2 = mk_unary_app ctx get_y_decl p2 in - let antecedents_0 = Z3.mk_eq ctx x1 x2 in - let antecedents_1 = Z3.mk_eq ctx y1 y2 in - let antecedents = [|antecedents_0; antecedents_1|] in - let antecedent = Z3.mk_and ctx antecedents in - let consequent = Z3.mk_eq ctx p1 p2 in - let thm = Z3.mk_implies ctx antecedent consequent in - printf "prove: get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2\n"; - prove ctx thm true; - - (* disprove that get_x(p1) = get_x(p2) implies p1 = p2 *) - let thm = Z3.mk_implies ctx (antecedents.(0)) consequent in - printf "disprove: get_x(p1) = get_x(p2) implies p1 = p2\n"; - prove ctx thm false; - end; - - begin - (* demonstrate how to use the mk_tuple_update function *) - (* prove that p2 = update(p1, 0, 10) implies get_x(p2) = 10 *) - let p1 = mk_var ctx "p1" pair_sort in - let p2 = mk_var ctx "p2" pair_sort in - let one = Z3.mk_numeral ctx "1" real_sort in - let ten = Z3.mk_numeral ctx "10" real_sort in - let updt = mk_tuple_update ctx p1 0 ten in - let antecedent = Z3.mk_eq ctx p2 updt in - let x = mk_unary_app ctx get_x_decl p2 in - let consequent = Z3.mk_eq ctx x ten in - let thm = Z3.mk_implies ctx antecedent consequent in - printf "prove: p2 = update(p1, 0, 10) implies get_x(p2) = 10\n"; - prove ctx thm true; - - (* disprove that p2 = update(p1, 0, 10) implies get_y(p2) = 10 *) - let y = mk_unary_app ctx get_y_decl p2 in - let consequent = Z3.mk_eq ctx y ten in - let thm = Z3.mk_implies ctx antecedent consequent in - printf "disprove: p2 = update(p1, 0, 10) implies get_y(p2) = 10\n"; - prove ctx thm false; - end; - - Z3.del_context ctx; - end;; - -(** - Simple bit-vector example. This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers - *) -let bitvector_example1() = - begin - printf "\nbitvector_example1\n"; - - let ctx = mk_context [||] in - - let bv_sort = Z3.mk_bv_sort ctx 32 in - - let x = mk_var ctx "x" bv_sort in - let zero = Z3.mk_numeral ctx "0" bv_sort in - let ten = Z3.mk_numeral ctx "10" bv_sort in - let x_minus_ten = Z3.mk_bvsub ctx x ten in - (* bvsle is signed less than or equal to *) - let c1 = Z3.mk_bvsle ctx x ten in - let c2 = Z3.mk_bvsle ctx x_minus_ten zero in - let thm = Z3.mk_iff ctx c1 c2 in - printf "disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers\n"; - prove ctx thm false; - - Z3.del_context ctx; - end;; - -(** - Find x and y such that: x ^ y - 103 == x * y - *) -let bitvector_example2() = - begin - printf "\nbitvector_example2\n"; - let ctx = mk_context [||] in - (* construct x ^ y - 103 == x * y *) - let bv_sort = Z3.mk_bv_sort ctx 32 in - let x = mk_var ctx "x" bv_sort in - let y = mk_var ctx "y" bv_sort in - let x_xor_y = Z3.mk_bvxor ctx x y in - let c103 = Z3.mk_numeral ctx "103" bv_sort in - let lhs = Z3.mk_bvsub ctx x_xor_y c103 in - let rhs = Z3.mk_bvmul ctx x y in - let ctr = Z3.mk_eq ctx lhs rhs in - printf "find values of x and y, such that x ^ y - 103 == x * y\n"; - Z3.assert_cnstr ctx ctr; - check ctx Z3.L_TRUE; - Z3.del_context ctx; - end;; - -(** - Demonstrate how to use #Z3_eval. -*) -let eval_example1() = - begin - printf "\neval_example1\n"; - - let ctx = mk_context [||] in - let x = mk_int_var ctx "x" in - let y = mk_int_var ctx "y" in - let two = mk_int ctx 2 in - - (* assert x < y *) - let c1 = Z3.mk_lt ctx x y in - Z3.assert_cnstr ctx c1; - - (* assert x > 2 *) - let c2 = Z3.mk_gt ctx x two in - Z3.assert_cnstr ctx c2; - - (* find model for the constraints above *) - (match Z3.check_and_get_model ctx with - | (Z3.L_TRUE, m) -> - begin - let args = [|x; y|] in - printf "MODEL:\n%s" (Z3.model_to_string ctx m); - let x_plus_y = Z3.mk_add ctx args in - printf "\nevaluating x+y\n"; - (match Z3.eval ctx m x_plus_y with - | (true,v) -> - printf "result = "; - display_ast ctx stdout v; - printf "\n"; - | _ -> - exitf "failed to evaluate: x+y"; - ); - (Z3.del_model ctx m); - end; - | (_,_) -> - exitf "the constraints are satisfiable"; - ); - Z3.del_context ctx; - end;; - -(** - Several logical context can be used simultaneously. -*) -let two_contexts_example1() = - begin - printf "\ntwo_contexts_example1\n"; - (* using the same (default) configuration to initialized both logical contexts. *) - let ctx1 = mk_context [||] in - let ctx2 = mk_context [||] in - let x1 = Z3.mk_const ctx1 (Z3.mk_int_symbol ctx1 0) (Z3.mk_bool_sort ctx1) in - let x2 = Z3.mk_const ctx2 (Z3.mk_int_symbol ctx2 0) (Z3.mk_bool_sort ctx2) in - Z3.del_context ctx1; - (* ctx2 can still be used. *) - printf "%s\n" (Z3.ast_to_string ctx2 x2); - Z3.del_context ctx2; - end;; - -(** - Demonstrates how error codes can be read insted of registering an error handler. - *) -let error_code_example1() = - begin - printf "\nerror_code_example1\n"; - - let ctx = mk_context [||] in - let x = mk_bool_var ctx "x" in - let x_decl = Z3.get_app_decl ctx (Z3.to_app ctx x) in - Z3.assert_cnstr ctx x; - - match Z3.check_and_get_model ctx with - | (Z3.L_TRUE,m) -> - begin - let (ok, v) = Z3.eval_func_decl ctx m x_decl in - printf "last call succeeded.\n"; - - (* The following call will fail since the value of x is a boolean *) - (try ignore(Z3.get_numeral_string ctx v) - with | _ -> printf "last call failed.\n"); - (Z3.del_model ctx m); - Z3.del_context ctx; - end - | (_,_) -> exitf "unexpected result"; - end;; - -(** - Demonstrates how Z3 exceptions can be used. -*) -let error_code_example2() = - begin - printf "\nerror_code_example2\n%!"; - - let ctx = mk_context [||] in - try - let x = mk_int_var ctx "x" in - let y = mk_bool_var ctx "y" in - printf "before Z3_mk_iff\n"; - let app = Z3.mk_iff ctx x y in - printf "unreachable"; - with | _ -> printf "Z3 error: type error.\n"; - Z3.del_context ctx; - end;; - -(** - Demonstrates how to use the SMTLIB parser. - *) -let parser_example1() = - begin - printf "\nparser_example1\n"; - - let ctx = mk_context [||] in - let str = "(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))" in - let (formulas,_,_) = Z3.parse_smtlib_string_x ctx str [||] [||] [||] [||] in - let f i c = - printf "formula %d: %s\n" i (Z3.ast_to_string ctx c); - Z3.assert_cnstr ctx c; - in Array.iteri f formulas; - check ctx Z3.L_TRUE; - Z3.del_context ctx; - end;; - -(** - Demonstrates how to initialize the parser symbol table. - *) -let parser_example2() = - begin - printf "\nparser_example2\n%!"; - - let ctx = mk_context [||] in - let x = mk_int_var ctx "x" in - let x_decl = Z3.get_app_decl ctx (Z3.to_app ctx x) in - let y = mk_int_var ctx "y" in - let y_decl = Z3.get_app_decl ctx (Z3.to_app ctx y) in - let decls = [| x_decl; y_decl |] in - let a = Z3.mk_string_symbol ctx "a" in - let b = Z3.mk_string_symbol ctx "b" in - let names = [| a; b |] in - let str = "(benchmark tst :formula (> a b))" in - let f = Z3.parse_smtlib_string_formula ctx str [||] [||] names decls in - printf "formula: %s\n" (Z3.ast_to_string ctx f); - Z3.assert_cnstr ctx f; - check ctx Z3.L_TRUE; - Z3.del_context ctx; - end;; - -(** - Demonstrates how to initialize the parser symbol table. - *) -let parser_example3() = - begin - printf "\nparser_example3\n%!"; - - let ctx = mk_context [| |] in - let int_sort = Z3.mk_int_sort ctx in - let g_name = Z3.mk_string_symbol ctx "g" in - let g = Z3.mk_func_decl ctx g_name [| int_sort; int_sort |] int_sort in - let str = "(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (g x 0) (g 0 y)))))" in - assert_comm_axiom ctx g; - let thm = Z3.parse_smtlib_string_formula ctx str [||] [||] [|g_name|] [|g|] in - printf "formula: %s\n" (Z3.ast_to_string ctx thm); - prove ctx thm true; - Z3.del_context ctx; - end;; - -(** - Display the declarations, assumptions and formulas in a SMT-LIB string. - *) -let parser_example4() = - begin - printf "\nparser_example4\n%!"; - - let ctx = mk_context [||] in - let str = "(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))" in - (* arithmetic theory is automatically initialized, when an - int/real variable or arith operation is created using the API. - Since no such function is invoked in this example, we should do - that manually. - *) - let (formulas, assumptions, decls) = Z3.parse_smtlib_string_x ctx str [||] [||] [||] [||] in - let f prefix i n = printf "%s %d: %s\n" prefix i (Z3.ast_to_string ctx n) in - Array.iteri (fun i n -> printf "declaration %d: %s\n" i (Z3.func_decl_to_string ctx n)) decls; - Array.iteri (f "assumption") assumptions; - Array.iteri (f "formula") formulas; - Z3.del_context ctx; - end;; - -(** - Demonstrates how to handle parser errors using Z3 exceptions. - *) -let parser_example5() = - begin - printf "\nparser_example5\n"; - let ctx = mk_context [||] in - try - (* the following string has a parsing error: missing parenthesis *) - let str = "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))" in - ignore(Z3.parse_smtlib_string_x ctx str [||] [||] [||] [||]); - with | _ -> (printf "Z3 error: parser error.\n"; - printf "Error message: '%s'.\n" (Z3.get_smtlib_error ctx) - ); - Z3.del_context ctx; - end;; - -(** - Example for creating an if-then-else expression. - *) -let ite_example() = - begin - printf "\nite_example\n%!"; - let ctx = mk_context [||] in - let f = Z3.mk_false ctx in - let one = mk_int ctx 1 in - let zero = mk_int ctx 0 in - let ite = Z3.mk_ite ctx f one zero in - printf "term: %s\n" (Z3.ast_to_string ctx ite); - Z3.del_context ctx; - end;; - - -(** - Create an enumeration data type. - - Several more examples of creating and using data-types (lists, trees, records) - are provided for the C-based API. - The translation from the examples in C to use the OCaml API follow the same pattern - that is used here. -*) -let enum_example() = - begin - printf "\nenum_example\n"; - let ctx = mk_context [||] in - let name = Z3.mk_string_symbol ctx "fruit" in - let enum_names = [| Z3.mk_string_symbol ctx "apple"; - Z3.mk_string_symbol ctx "banana"; - Z3.mk_string_symbol ctx "orange" |] in - let (fruit, enum_consts, enum_testers) = Z3.mk_enumeration_sort ctx name enum_names in - - printf "%s\n" (Z3.func_decl_to_string ctx enum_consts.(0)); - printf "%s\n" (Z3.func_decl_to_string ctx enum_consts.(1)); - printf "%s\n" (Z3.func_decl_to_string ctx enum_consts.(2)); - printf "%s\n" (Z3.func_decl_to_string ctx enum_testers.(0)); - printf "%s\n" (Z3.func_decl_to_string ctx enum_testers.(1)); - printf "%s\n" (Z3.func_decl_to_string ctx enum_testers.(2)); - - let apple = Z3.mk_app ctx (enum_consts.(0)) [||] in - let banana = Z3.mk_app ctx (enum_consts.(1)) [||] in - let orange = Z3.mk_app ctx (enum_consts.(2)) [||] in - - (* Apples are different from oranges *) - prove ctx (Z3.mk_not ctx (Z3.mk_eq ctx apple orange)) true; - - (* Apples pass the apple test *) - prove ctx (Z3.mk_app ctx enum_testers.(0) [| apple |]) true; - - (* Oranges fail the apple test *) - prove ctx (Z3.mk_app ctx enum_testers.(0) [| orange |]) false; - prove ctx (Z3.mk_not ctx (Z3.mk_app ctx enum_testers.(0) [| orange |])) true; - - let fruity = mk_var ctx "fruity" fruit in - - (* If something is fruity, then it is an apple, banana, or orange *) - let ors = [| Z3.mk_eq ctx fruity apple; - Z3.mk_eq ctx fruity banana; - Z3.mk_eq ctx fruity orange |] in - - prove ctx (Z3.mk_or ctx ors) true; - Z3.del_context ctx; - end;; - -(** - Example for extracting unsatisfiable core and proof. - The example uses the function check_assumptions which allows passing in additional - hypotheses. The unsatisfiable core is a subset of these additional hypotheses. - *) -let unsat_core_and_proof_example() = - begin - printf "\nunsat_core_and_proof_example\n%!"; - let ctx = mk_context [| ("PROOF_MODE","2") |] in - let pa = mk_bool_var ctx "PredA" in - let pb = mk_bool_var ctx "PredB" in - let pc = mk_bool_var ctx "PredC" in - let pd = mk_bool_var ctx "PredD" in - let p1 = mk_bool_var ctx "P1" in - let p2 = mk_bool_var ctx "P2" in - let p3 = mk_bool_var ctx "P3" in - let p4 = mk_bool_var ctx "P4" in - let assumptions = [| Z3.mk_not ctx p1; Z3.mk_not ctx p2; Z3.mk_not ctx p3; Z3.mk_not ctx p4 |] in - let f1 = Z3.mk_and ctx [| pa; pb; pc |] in - let f2 = Z3.mk_and ctx [| pa; Z3.mk_not ctx pc; pb |] in - let f3 = Z3.mk_or ctx [| Z3.mk_not ctx pa; Z3.mk_not ctx pc |] in - let f4 = pd in - let core_dummy = [| pa; pa; pa; pa |] in - Z3.assert_cnstr ctx (Z3.mk_or ctx [| f1; p1 |]); - Z3.assert_cnstr ctx (Z3.mk_or ctx [| f2; p2 |]); - Z3.assert_cnstr ctx (Z3.mk_or ctx [| f3; p3 |]); - Z3.assert_cnstr ctx (Z3.mk_or ctx [| f4; p4 |]); - let result = Z3.check_assumptions ctx assumptions 4 core_dummy in - (match result with - | (Z3.L_FALSE, _, proof, core_size, core) -> - printf "unsat\n"; - printf "proof: %s\n" (Z3.ast_to_string ctx proof); - printf("\ncore:\n"); - for i = 0 to core_size - 1 do - printf "%s\n" (Z3.ast_to_string ctx (core.(i))); - done; - printf("\n") - | (_,_,_,_,_)-> assert false; - ); - (* delete logical context *) - Z3.del_context(ctx); - end - -(** - -*) - -let get_implied_equalities_example() = - begin - printf "\nget_implied_equalities example\n%!"; - let ctx = mk_context [| |] in - let int_ty = Z3.mk_int_sort ctx in - let a = mk_int_var ctx "a" in - let b = mk_int_var ctx "b" in - let c = mk_int_var ctx "c" in - let d = mk_int_var ctx "d" in - let f = Z3.mk_func_decl ctx (Z3.mk_string_symbol ctx "f") [| int_ty |] int_ty in - let fa = Z3.mk_app ctx f [| a |] in - let fb = Z3.mk_app ctx f [| b |] in - let fc = Z3.mk_app ctx f [| c |] in - let terms = [| a; b; c; d; fa; fb; fc |] in - Z3.assert_cnstr ctx (Z3.mk_eq ctx a b); - Z3.assert_cnstr ctx (Z3.mk_eq ctx b c); - Z3.assert_cnstr ctx (Z3.mk_le ctx fc b); - Z3.assert_cnstr ctx (Z3.mk_le ctx b fa); - let is_sat, class_ids = Z3.get_implied_equalities ctx terms in - for i = 0 to 6 do - printf "Class %s |-> %d\n" (Z3.ast_to_string ctx (terms.(i))) (class_ids.(i)); - done; - printf "asserting f(a) <= b\n"; - Z3.assert_cnstr ctx (Z3.mk_le ctx fa b); - let is_sat, class_ids = Z3.get_implied_equalities ctx terms in - for i = 0 to 6 do - printf "Class %s |-> %d\n" (Z3.ast_to_string ctx (terms.(i))) (class_ids.(i)); - done; - (* delete logical context *) - Z3.del_context(ctx) - end;; - -let main() = - begin - ignore (Z3.open_log("ml.log")); - display_version(); - simple_example(); - demorgan(); - find_model_example1(); - find_model_example2(); - prove_example1(); - prove_example2(); - push_pop_example1(); - quantifier_example1(); - array_example1(); - array_example2(); - array_example3(); - tuple_example1(); - bitvector_example1(); - bitvector_example2(); - eval_example1(); - two_contexts_example1(); - error_code_example1(); - error_code_example2(); - parser_example1(); - parser_example2(); - parser_example3(); - parser_example4(); - parser_example5(); -(* numeral_example(); *) - ite_example(); -(* list_example(); *) -(* tree_example(); *) -(* forest_example(); *) -(* binary_tree_example(); *) - enum_example(); - unsat_core_and_proof_example(); - abstract_example(); - get_implied_equalities_example(); -(* incremental_example1(); *) -(* reference_counter_example(); *) -(* smt2parser_example(); *) -(* substitute_example(); *) -(* substitute_vars_example(); *) - end;; - -let _ = main();; diff --git a/src/api/ml/old/test_theory.ml b/src/api/ml/old/test_theory.ml deleted file mode 100644 index 8732bf220..000000000 --- a/src/api/ml/old/test_theory.ml +++ /dev/null @@ -1,42 +0,0 @@ -module Z3 = Z3.V3 - -let print_lbool lb = - match lb with - | Z3.L_FALSE -> Printf.printf "false\n" - | Z3.L_TRUE -> Printf.printf "true\n" - | Z3.L_UNDEF -> Printf.printf "undef\n" - -(* simple sanity test of theory plugin *) -let test_theory() = - let ctx = Z3.mk_context_x [| |] in - let th = Z3.mk_theory ctx "test-theory" in - let _ = Z3.set_push_callback th (fun () -> Printf.printf "push\n") in - let _ = Z3.set_pop_callback th (fun () -> Printf.printf "pop\n") in - let _ = Z3.set_delete_callback th (fun () -> Printf.printf "delete\n") in - let _ = Z3.set_final_check_callback th (fun () -> (Printf.printf "final\n"; true)) in - let _ = Z3.set_delete_callback th (fun () -> Printf.printf "deleted\n") in - let f_sym = Z3.mk_string_symbol ctx "f" in - let a_sym = Z3.mk_string_symbol ctx "a" in - let b_sym = Z3.mk_string_symbol ctx "b" in - let int_sort = Z3.mk_int_sort ctx in - let f = Z3.theory_mk_func_decl ctx th f_sym [|int_sort |] int_sort in - let a = Z3.theory_mk_constant ctx th a_sym int_sort in - let b = Z3.theory_mk_constant ctx th b_sym int_sort in - let reduce_f g args = - Printf.printf "reduce %s\n" (Z3.func_decl_to_string ctx g); - match g, args with - | _, [| a' |] when Z3.is_eq_func_decl ctx g f && Z3.is_eq_ast ctx a' a -> Some b - | _, _ -> None - in - let _ = Z3.set_reduce_app_callback th reduce_f in - (* b != f(b) is consistent *) - let _ = Z3.assert_cnstr ctx (Z3.mk_not ctx (Z3.mk_eq ctx b (Z3.mk_app ctx f [| b |]))) in - let res = Z3.check ctx in - print_lbool res; - (* b != f(a) is not consistent *) - let _ = Z3.assert_cnstr ctx (Z3.mk_not ctx (Z3.mk_eq ctx b (Z3.mk_app ctx f [| a |]))) in - let res = Z3.check ctx in - print_lbool res; - Z3.del_context ctx - -let _ = test_theory() diff --git a/src/api/ml/old/update-ml-doc.cmd b/src/api/ml/old/update-ml-doc.cmd deleted file mode 100755 index 32c39109e..000000000 --- a/src/api/ml/old/update-ml-doc.cmd +++ /dev/null @@ -1,38 +0,0 @@ -@echo off -SETLOCAL - -REM Script to generate Z3 OCaml API documentation -REM -REM Assumes that environment variables are set to provide access to the OCaml compilers, as well as the following commands: sed - -rd 2>NUL /s /q doc -md doc -cd doc -set MLDIR=.. -set DOCDIR=..\%1 - -ocamldoc.opt -hide Z3,Z3.V3,Test_mlapi -html -css-style z3_ml.css -I %MLDIR% %MLDIR%\test_mlapi.ml %MLDIR%\z3.mli - -sed "s|
val\(.*\)
|
val\1
|g;s|
type\(.*\)
|
type\1
|g;s|type\(.*\) = |
type\1 =
|g" Z3.html > Z3.new.html -move >NUL Z3.new.html Z3.html - -sed "s|
val\(.*\)
|
val\1
|g" Test_mlapi.html > Test_mlapi.new.html -move >NUL Test_mlapi.new.html Test_mlapi.html - -sed "s|

Index of values

|

OCaml: Index

|" Index_values.html > Index_values.new.html -move >NUL Index_values.new.html Index_values.html - -copy >NUL %DOCDIR%\tabs.css -copy >NUL %DOCDIR%\z3.png -copy >NUL %DOCDIR%\z3_ml.css - -sed "1,23d" Test_mlapi.html | sed "$d" > Test_mlapi.new.html - -type 2>NUL %DOCDIR%\test_mlapi_header.html Test_mlapi.new.html %DOCDIR%\mldoc_footer.html >Test_mlapi.html - -sed "1,37d" Z3.html > Z3.new.html - -type 2>NUL %DOCDIR%\z3_mlapi_header.html Z3.new.html >Z3.html - -exit /B 0 -ENDLOCAL diff --git a/src/api/ml/old/x3.ml b/src/api/ml/old/x3.ml deleted file mode 100644 index 6ca5d49eb..000000000 --- a/src/api/ml/old/x3.ml +++ /dev/null @@ -1,366 +0,0 @@ -/* Copyright (c) Microsoft Corporation */ - -quote (ml," - -(* Internal auxiliary functions: *) -(* -(* Transform a pair of arrays into an array of pairs *) -let array_combine a b = - if Array.length a <> Array.length b then raise (Invalid_argument \"array_combine\"); - Array.init (Array.length a) (fun i -> (a.(i), b.(i))) - -(* [a |> b] is the pipeline operator for [b(a)] *) -let ( |> ) x f = f x -*) - -(* Find the index of an element in an array, raises Not_found is missing *) -let find equal x a = - let len = Array.length a in - let rec find_ i = - if i >= len then - raise Not_found - else - if equal x a.(i) then - i - else - find_ (i+1) - in - find_ 0 - - -(* Symbols *) - -let symbol_refine c s = - match get_symbol_kind c s with - | INT_SYMBOL -> Symbol_int (get_symbol_int c s) - | STRING_SYMBOL -> Symbol_string (get_symbol_string c s) - -let mk_symbol c = function - | Symbol_int(i) -> mk_int_symbol c i - | Symbol_string(s) -> mk_string_symbol c s - - -(* Sorts *) - -let get_datatype_sort c s = - Array.init (get_datatype_sort_num_constructors c s) (fun i -> - let constructor = get_datatype_sort_constructor c s i in - let recognizer = get_datatype_sort_recognizer c s i in - let accessors = - Array.init (get_domain_size c constructor) (fun j -> - get_datatype_sort_constructor_accessor c s i j - ) in - {constructor; recognizer; accessors} - ) - -let sort_refine c s = - match get_sort_kind c s with - | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c s) - | BOOL_SORT -> Sort_bool - | INT_SORT -> Sort_int - | BV_SORT -> Sort_bv (get_bv_sort_size c s) - | FINITE_DOMAIN_SORT -> - (match get_finite_domain_sort_size c s with - | Some(sz) -> Sort_finite_domain (get_sort_name c s, sz) - | None -> failwith \"Z3.sort_refine: failed to get size of finite-domain sort\" - ) - | REAL_SORT -> Sort_real - | ARRAY_SORT -> Sort_array (get_array_sort_domain c s, get_array_sort_range c s) - | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c s) - | RELATION_SORT -> Sort_relation (Array.init (get_relation_arity c s) (fun i -> get_relation_column c s i)) - | UNKNOWN_SORT -> Sort_unknown - -let mk_sort c = function - | Sort_uninterpreted(s) -> mk_uninterpreted_sort c s - | Sort_bool -> mk_bool_sort c - | Sort_int -> mk_int_sort c - | Sort_bv(size) -> mk_bv_sort c size - | Sort_finite_domain(name,size) -> mk_finite_domain_sort c name size - | Sort_real -> mk_real_sort c - | Sort_array(domain,range) -> mk_array_sort c domain range - | Sort_datatype(constructors) -> get_range c constructors.(0).constructor - | Sort_relation(_) -> invalid_arg \"Z3.mk_sort: cannot construct relation sorts\" - | Sort_unknown(_) -> invalid_arg \"Z3.mk_sort: cannot construct unknown sorts\" - - -(* Replacement datatypes creation API *) - -let mk_datatypes ctx generator = - let usort0 = mk_uninterpreted_sort ctx (mk_int_symbol ctx 0) - in - let rec find_num_sorts i = - if i = max_int then invalid_arg \"mk_datatypes: too many sorts\" - else - match generator (Array.make i usort0) with - | None -> find_num_sorts (i+1) - | Some(a) when Array.length a = i -> i - | Some _ -> invalid_arg \"mk_datatypes: number of sorts and datatype descriptors must be equal\" - in - let num_sorts = find_num_sorts 0 - in - let sorts0 = Array.init num_sorts (fun i -> mk_uninterpreted_sort ctx (mk_int_symbol ctx i)) - in - let ctorss_descriptors = - match generator sorts0 with - | Some(ctorss_descriptors) -> ctorss_descriptors - | None -> invalid_arg \"mk_datatypes: generator failed\" - in - let names = Array.map fst ctorss_descriptors - in - let ctorss = - Array.map (fun (_, ctors_descriptor) -> - Array.map (fun {constructor_desc; recognizer_desc; accessor_descs} -> - let field_names = Array.map fst accessor_descs - in - let sort_refs = Array.make (Array.length accessor_descs) 0 - in - let field_sorts = - Array.mapi (fun i (_, sort) -> - try - let j = find (fun s t -> is_eq_sort ctx s t) sort sorts0 in - sort_refs.(i) <- j ; - None - with Not_found -> - Some(sort) - ) accessor_descs - in - mk_constructor ctx constructor_desc recognizer_desc field_names field_sorts sort_refs - ) ctors_descriptor - ) ctorss_descriptors - in - let constructor_lists = Array.map (mk_constructor_list ctx) ctorss - in - let sorts,_ = mk_datatypes ctx names constructor_lists - in - let datatypes = - Array.mapi (fun i sort -> - (sort, - Array.mapi (fun j ctor -> - let num_fields = Array.length (snd ctorss_descriptors.(i)).(j).accessor_descs in - let constructor, recognizer, accessors = query_constructor ctx ctor num_fields in - {constructor; recognizer; accessors} - ) ctorss.(i)) - ) sorts - in - Array.iter (fun ctor_list -> - del_constructor_list ctx ctor_list - ) constructor_lists - ; - Array.iter (fun ctors -> - Array.iter (fun ctor -> - del_constructor ctx ctor - ) ctors - ) ctorss - ; - datatypes - - -(* Numerals *) - -let rec numeral_refine c t = - assert( get_ast_kind c t = NUMERAL_AST ); - let sort = get_sort c t in - let is_int, i = get_numeral_int c t in - if is_int then - Numeral_int (i, sort) - else - let is_int64, i = get_numeral_int64 c t in - if is_int64 then - Numeral_int64 (i, sort) - else - if get_sort_kind c sort <> REAL_SORT then - Numeral_large (get_numeral_string c t, sort) - else - let n = numeral_refine c (get_numerator c t) in - let d = numeral_refine c (get_denominator c t) in - Numeral_rational (n, d) - - -let to_real c x = - if get_sort_kind c (get_sort c x) = REAL_SORT then - x - else - mk_int2real c x - -let rec embed_numeral c = function - | Numeral_int (i, s) -> mk_int c i s - | Numeral_int64 (i, s) -> mk_int64 c i s - | Numeral_large (l, s) -> mk_numeral c l s - | Numeral_rational (Numeral_int(n,_), Numeral_int(d,_)) -> mk_real c n d - | Numeral_rational (n, d) -> - mk_div c (to_real c (embed_numeral c n)) (to_real c (embed_numeral c d)) - (* Or should the following be used instead? - let n_str = get_numeral_string c (embed_numeral c n) in - let d_str = get_numeral_string c (embed_numeral c d) in - mk_numeral c (n_str ^ \" / \" ^ d_str) (mk_real_sort c) - *) - -(* Terms *) - -let get_app_args c a = - Array.init (get_app_num_args c a) (get_app_arg c a);; - -let get_domains c d = - Array.init (get_domain_size c d) (get_domain c d);; - - -let get_pattern_terms c p = - Array.init (get_pattern_num_terms c p) (get_pattern c p) - - -let term_refine c t = - match get_ast_kind c t with - | NUMERAL_AST -> - Term_numeral (numeral_refine c t) - | APP_AST -> - let t' = to_app c t in - let f = get_app_decl c t' in - let num_args = get_app_num_args c t' in - let args = Array.init num_args (get_app_arg c t') in - let k = get_decl_kind c f in - Term_app (k, f, args) - | QUANTIFIER_AST -> - let bt = if is_quantifier_forall c t then Forall else Exists in - let w = get_quantifier_weight c t in - let np = get_quantifier_num_patterns c t in - let pats = Array.init np (get_quantifier_pattern_ast c t) in - let pats = Array.map (get_pattern_terms c) pats in - let nb = get_quantifier_num_bound c t in - let bound = - Array.init nb (fun i -> - (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i) - ) in - let body = get_quantifier_body c t in - Term_quantifier (bt, w, pats, bound, body) - | VAR_AST -> - Term_var (get_index_value c t, get_sort c t) - | _ -> - assert false - - -(* let mk_term c = function *) -(* | Term_numeral (numeral, sort) -> mk_numeral c numeral sort *) -(* | Term_app (kind, decl, args) -> *) -(* | Term_quantifier (strength, weight, pats, bound, body) -> *) -(* | Term_var (index, sort) -> *) - - - -(* Refined model API *) - -let model_refine c m = - let num_sorts = model_get_num_sorts c m in - let sorts = Hashtbl.create num_sorts in - for i = 0 to num_sorts - 1 do - let sort = model_get_sort c m i in - let universe = model_get_sort_universe c m sort in - Hashtbl.add sorts sort universe - done; - let num_consts = model_get_num_consts c m in - let consts = Hashtbl.create num_consts in - let arrays = Hashtbl.create 0 in - for i = 0 to num_consts - 1 do - let const_decl = model_get_const_decl c m i in - match model_get_const_interp c m const_decl with - | Some(const_interp) -> - if is_as_array c const_interp then - let array_decl = get_as_array_func_decl c const_interp in - match model_get_func_interp c m array_decl with - | Some(array_interp) -> - let num_entries = func_interp_get_num_entries c array_interp in - let tbl = Hashtbl.create num_entries in - for i = 0 to num_entries - 1 do - let entry = func_interp_get_entry c array_interp i in - assert( func_entry_get_num_args c entry = 1 ); - let arg = func_entry_get_arg c entry 0 in - let value = func_entry_get_value c entry in - Hashtbl.add tbl arg value - done; - let default = func_interp_get_else c array_interp in - Hashtbl.add arrays const_decl (tbl, default) - | None -> - () - else - Hashtbl.add consts const_decl const_interp - | None -> - () - done; - let num_funcs = model_get_num_funcs c m in - let funcs = Hashtbl.create num_funcs in - for i = 0 to num_funcs - 1 do - let func_decl = model_get_func_decl c m i in - if not (Hashtbl.mem arrays func_decl) then - match model_get_func_interp c m func_decl with - | Some(func_interp) -> - let num_entries = func_interp_get_num_entries c func_interp in - let tbl = Hashtbl.create num_entries in - for i = 0 to num_entries - 1 do - let entry = func_interp_get_entry c func_interp i in - let num_args = func_entry_get_num_args c entry in - let args = Array.init num_args (fun i -> func_entry_get_arg c entry i) in - let value = func_entry_get_value c entry in - Hashtbl.add tbl args value - done; - let default = func_interp_get_else c func_interp in - Hashtbl.add funcs func_decl (tbl, default) - | None -> - () - done; - {sorts; consts; arrays; funcs} - - -(* Extended parser API *) - -let get_smtlib_formulas c = - Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c) - -let get_smtlib_assumptions c = - Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c) - -let get_smtlib_decls c = - Array.init (get_smtlib_num_decls c) (get_smtlib_decl c) - -let get_smtlib_parse_results c = - (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c) - -let parse_smtlib_string_x c a1 a2 a3 a4 a5 = - parse_smtlib_string c a1 a2 a3 a4 a5 ; - get_smtlib_parse_results c - -let parse_smtlib_file_x c a1 a2 a3 a4 a5 = - parse_smtlib_file c a1 a2 a3 a4 a5 ; - get_smtlib_parse_results c - -let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = - parse_smtlib_string c a1 a2 a3 a4 a5 ; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_string_formula\" - -let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = - parse_smtlib_file c a1 a2 a3 a4 a5 ; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_file_formula\" - - -(* Error handling *) - -let get_error_msg c e = - match e with - | PARSER_ERROR -> (get_error_msg_ex c e) ^ \": \" ^ (get_smtlib_error c) - | _ -> get_error_msg_ex c e - - -(* Refined stats API *) - -let stats_refine c s = - let num_stats = stats_size c s in - let tbl = Hashtbl.create num_stats in - for i = 0 to num_stats - 1 do - let key = stats_get_key c s i in - let datum = - if stats_is_uint c s i then - Stat_int(stats_get_uint_value c s i) - else - Stat_float(stats_get_double_value c s i) in - Hashtbl.add tbl key datum - done; - tbl -"); diff --git a/src/api/ml/old/x3V3.ml b/src/api/ml/old/x3V3.ml deleted file mode 100644 index 96156f0a8..000000000 --- a/src/api/ml/old/x3V3.ml +++ /dev/null @@ -1,378 +0,0 @@ -quote (ml," - - -(* Internal auxillary functions: *) - -(* Transform a pair of arrays into an array of pairs *) -let array_combine a b = - if Array.length a <> Array.length b then raise (Invalid_argument \"array_combine\"); - Array.init (Array.length a) (fun i->(a.(i),b.(i)));; - -(* [a |> b] is the pipeline operator for [b(a)] *) -let ( |> ) x f = f x;; - - -(* Extensions, except for refinement: *) -let mk_context_x configs = - let config = mk_config() in - let f(param_id,param_value) = set_param_value config param_id param_value in - Array.iter f configs; - let context = mk_context config in - del_config config; - context;; - -let get_app_args c a = - Array.init (get_app_num_args c a) (get_app_arg c a);; - -let get_domains c d = - Array.init (get_domain_size c d) (get_domain c d);; - -let get_array_sort c t = (get_array_sort_domain c t, get_array_sort_range c t);; - -let get_tuple_sort c ty = - (get_tuple_sort_mk_decl c ty, - Array.init (get_tuple_sort_num_fields c ty) (get_tuple_sort_field_decl c ty));; - -type datatype_constructor_refined = { - constructor : func_decl; - recognizer : func_decl; - accessors : func_decl array -} - -let get_datatype_sort c ty = - Array.init (get_datatype_sort_num_constructors c ty) - (fun idx_c -> - let constr = get_datatype_sort_constructor c ty idx_c in - let recog = get_datatype_sort_recognizer c ty idx_c in - let num_acc = get_domain_size c constr in - { constructor = constr; - recognizer = recog; - accessors = Array.init num_acc (get_datatype_sort_constructor_accessor c ty idx_c); - }) - -let get_model_constants c m = - Array.init (get_model_num_constants c m) (get_model_constant c m);; - - -let get_model_func_entry c m i j = - (Array.init - (get_model_func_entry_num_args c m i j) - (get_model_func_entry_arg c m i j), - get_model_func_entry_value c m i j);; - -let get_model_func_entries c m i = - Array.init (get_model_func_num_entries c m i) (get_model_func_entry c m i);; - -let get_model_funcs c m = - Array.init (get_model_num_funcs c m) - (fun i->(get_model_func_decl c m i |> get_decl_name c, - get_model_func_entries c m i, - get_model_func_else c m i));; - -let get_smtlib_formulas c = - Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c);; - -let get_smtlib_assumptions c = - Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c);; - -let get_smtlib_decls c = - Array.init (get_smtlib_num_decls c) (get_smtlib_decl c);; - -let get_smtlib_parse_results c = - (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c);; - -let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = - (parse_smtlib_string c a1 a2 a3 a4 a5; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_string_formula\");; - -let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = - (parse_smtlib_file c a1 a2 a3 a4 a5; - match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_file_formula\");; - -let parse_smtlib_string_x c a1 a2 a3 a4 a5 = - (parse_smtlib_string c a1 a2 a3 a4 a5; get_smtlib_parse_results c);; - -let parse_smtlib_file_x c a1 a2 a3 a4 a5 = - (parse_smtlib_file c a1 a2 a3 a4 a5; get_smtlib_parse_results c);; - -(* Refinement: *) - -type symbol_refined = - | Symbol_int of int - | Symbol_string of string - | Symbol_unknown;; - -let symbol_refine c s = - match get_symbol_kind c s with - | INT_SYMBOL -> Symbol_int (get_symbol_int c s) - | STRING_SYMBOL -> Symbol_string (get_symbol_string c s);; - -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_real - | Sort_bv of int - | Sort_array of (sort * sort) - | Sort_datatype of datatype_constructor_refined array - | Sort_relation - | Sort_finite_domain - | Sort_unknown of symbol;; - -let sort_refine c ty = - match get_sort_kind c ty with - | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c ty) - | BOOL_SORT -> Sort_bool - | INT_SORT -> Sort_int - | REAL_SORT -> Sort_real - | BV_SORT -> Sort_bv (get_bv_sort_size c ty) - | ARRAY_SORT -> Sort_array (get_array_sort_domain c ty, get_array_sort_range c ty) - | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c ty) - | RELATION_SORT -> Sort_relation - | FINITE_DOMAIN_SORT -> Sort_finite_domain - | UNKNOWN_SORT -> Sort_unknown (get_sort_name c ty);; - -let get_pattern_terms c p = - Array.init (get_pattern_num_terms c p) (get_pattern c p) - -type binder_type = | Forall | Exists - -type numeral_refined = - | Numeral_small of int64 * int64 - | Numeral_large of string - -type term_refined = - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol *sort) array * ast - | Term_numeral of numeral_refined * sort - | Term_var of int * sort - -let term_refine c t = - match get_ast_kind c t with - | NUMERAL_AST -> - let (is_small, n, d) = get_numeral_small c t in - if is_small then - Term_numeral(Numeral_small(n,d), get_sort c t) - else - Term_numeral(Numeral_large(get_numeral_string c t), get_sort c t) - | APP_AST -> - let t' = to_app c t in - let f = get_app_decl c t' in - let num_args = get_app_num_args c t' in - let args = Array.init num_args (get_app_arg c t') in - let k = get_decl_kind c f in - Term_app (k, f, args) - | QUANTIFIER_AST -> - let bt = if is_quantifier_forall c t then Forall else Exists in - let w = get_quantifier_weight c t in - let np = get_quantifier_num_patterns c t in - let pats = Array.init np (get_quantifier_pattern_ast c t) in - let pats = Array.map (get_pattern_terms c) pats in - let nb = get_quantifier_num_bound c t in - let bound = Array.init nb - (fun i -> (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i)) in - let body = get_quantifier_body c t in - Term_quantifier(bt, w, pats, bound, body) - | VAR_AST -> - Term_var(get_index_value c t, get_sort c t) - | _ -> assert false - -type theory_callbacks = - { - mutable delete_theory : unit -> unit; - mutable reduce_eq : ast -> ast -> ast option; - mutable reduce_app : func_decl -> ast array -> ast option; - mutable reduce_distinct : ast array -> ast option; - mutable final_check : unit -> bool; - mutable new_app : ast -> unit; - mutable new_elem : ast -> unit; - mutable init_search: unit -> unit; - mutable push: unit -> unit; - mutable pop: unit -> unit; - mutable restart : unit -> unit; - mutable reset: unit -> unit; - mutable new_eq : ast -> ast -> unit; - mutable new_diseq : ast -> ast -> unit; - mutable new_assignment: ast -> bool -> unit; - mutable new_relevant : ast -> unit; - } - -let mk_theory_callbacks() = - { - delete_theory = (fun () -> ()); - reduce_eq = (fun _ _ -> None); - reduce_app = (fun _ _ -> None); - reduce_distinct = (fun _ -> None); - final_check = (fun _ -> true); - new_app = (fun _ -> ()); - new_elem = (fun _ -> ()); - init_search= (fun () -> ()); - push= (fun () -> ()); - pop= (fun () -> ()); - restart = (fun () -> ()); - reset= (fun () -> ()); - new_eq = (fun _ _ -> ()); - new_diseq = (fun _ _ -> ()); - new_assignment = (fun _ _ -> ()); - new_relevant = (fun _ -> ()); - } - - -external get_theory_callbacks : theory -> theory_callbacks = \"get_theory_callbacks\" -external mk_theory_register : context -> string -> theory_callbacks -> theory = \"mk_theory_register\" -external set_delete_callback_register : theory -> unit = \"set_delete_callback_register\" -external set_reduce_app_callback_register : theory -> unit = \"set_reduce_app_callback_register\" -external set_reduce_eq_callback_register : theory -> unit = \"set_reduce_eq_callback_register\" -external set_reduce_distinct_callback_register : theory -> unit = \"set_reduce_distinct_callback_register\" -external set_new_app_callback_register : theory -> unit = \"set_new_app_callback_register\" -external set_new_elem_callback_register : theory -> unit = \"set_new_elem_callback_register\" -external set_init_search_callback_register : theory -> unit = \"set_init_search_callback_register\" -external set_push_callback_register : theory -> unit = \"set_push_callback_register\" -external set_pop_callback_register : theory -> unit = \"set_pop_callback_register\" -external set_restart_callback_register : theory -> unit = \"set_restart_callback_register\" -external set_reset_callback_register : theory -> unit = \"set_reset_callback_register\" -external set_final_check_callback_register : theory -> unit = \"set_final_check_callback_register\" -external set_new_eq_callback_register : theory -> unit = \"set_new_eq_callback_register\" -external set_new_diseq_callback_register : theory -> unit = \"set_new_diseq_callback_register\" -external set_new_assignment_callback_register : theory -> unit = \"set_new_assignment_callback_register\" -external set_new_relevant_callback_register : theory -> unit = \"set_new_relevant_callback_register\" - -let is_some opt = - match opt with - | Some v -> true - | None -> false - -let get_some opt = - match opt with - | Some v -> v - | None -> failwith \"None unexpected\" - - - - -let apply_delete (th:theory_callbacks) = th.delete_theory () -let set_delete_callback th cb = - let cbs = get_theory_callbacks th in - cbs.delete_theory <- cb; - set_delete_callback_register th - -let mk_theory context name = - Callback.register \"is_some\" is_some; - Callback.register \"get_some\" get_some; - Callback.register \"apply_delete\" apply_delete; - let cbs = mk_theory_callbacks() in - mk_theory_register context name cbs - - -let apply_reduce_app (th:theory_callbacks) f args = th.reduce_app f args -let set_reduce_app_callback th cb = - Callback.register \"apply_reduce_app\" apply_reduce_app; - let cbs = get_theory_callbacks th in - cbs.reduce_app <- cb; - set_reduce_app_callback_register th - -let apply_reduce_eq (th:theory_callbacks) a b = th.reduce_eq a b -let set_reduce_eq_callback th cb = - Callback.register \"apply_reduce_eq\" apply_reduce_eq; - let cbs = get_theory_callbacks th in - cbs.reduce_eq <- cb; - set_reduce_eq_callback_register th - -let apply_reduce_distinct (th:theory_callbacks) args = th.reduce_distinct args -let set_reduce_distinct_callback th cb = - Callback.register \"apply_reduce_distinct\" apply_reduce_distinct; - let cbs = get_theory_callbacks th in - cbs.reduce_distinct <- cb; - set_reduce_distinct_callback_register th - - -let apply_new_app (th:theory_callbacks) a = th.new_app a -let set_new_app_callback th cb = - Callback.register \"apply_new_app\" apply_new_app; - let cbs = get_theory_callbacks th in - cbs.new_app <- cb; - set_new_app_callback_register th - -let apply_new_elem (th:theory_callbacks) a = th.new_elem a -let set_new_elem_callback th cb = - Callback.register \"apply_new_elem\" apply_new_elem; - let cbs = get_theory_callbacks th in - cbs.new_elem <- cb; - set_new_elem_callback_register th - - -let apply_init_search (th:theory_callbacks) = th.init_search() -let set_init_search_callback th cb = - Callback.register \"apply_init_search\" apply_init_search; - let cbs = get_theory_callbacks th in - cbs.init_search <- cb; - set_init_search_callback_register th - - -let apply_push (th:theory_callbacks) = th.push() -let set_push_callback th cb = - Callback.register \"apply_push\" apply_push; - let cbs = get_theory_callbacks th in - cbs.push <- cb; - set_push_callback_register th - -let apply_pop (th:theory_callbacks) = th.pop() -let set_pop_callback th cb = - Callback.register \"apply_pop\" apply_pop; - let cbs = get_theory_callbacks th in - cbs.pop <- cb; - set_pop_callback_register th - - -let apply_restart (th:theory_callbacks) = th.restart() -let set_restart_callback th cb = - Callback.register \"apply_restart\" apply_restart; - let cbs = get_theory_callbacks th in - cbs.restart <- cb; - set_restart_callback_register th - - -let apply_reset (th:theory_callbacks) = th.reset() -let set_reset_callback th cb = - Callback.register \"apply_reset\" apply_reset; - let cbs = get_theory_callbacks th in - cbs.reset <- cb; - set_reset_callback_register th - -let apply_final_check (th:theory_callbacks) = th.final_check() -let set_final_check_callback th cb = - Callback.register \"apply_final_check\" apply_final_check; - let cbs = get_theory_callbacks th in - cbs.final_check <- cb; - set_final_check_callback_register th - -let apply_new_eq (th:theory_callbacks) a b = th.new_eq a b -let set_new_eq_callback th cb = - Callback.register \"apply_new_eq\" apply_new_eq; - let cbs = get_theory_callbacks th in - cbs.new_eq <- cb; - set_new_eq_callback_register th - - -let apply_new_diseq (th:theory_callbacks) a b = th.new_diseq a b -let set_new_diseq_callback th cb = - Callback.register \"apply_new_diseq\" apply_new_diseq; - let cbs = get_theory_callbacks th in - cbs.new_diseq <- cb; - set_new_diseq_callback_register th - -let apply_new_assignment (th:theory_callbacks) a b = th.new_assignment a b -let set_new_assignment_callback th cb = - Callback.register \"apply_new_assignment\" apply_new_assignment; - let cbs = get_theory_callbacks th in - cbs.new_assignment <- cb; - set_new_assignment_callback_register th - -let apply_new_relevant (th:theory_callbacks) a = th.new_relevant a -let set_new_relevant_callback th cb = - Callback.register \"apply_new_relevant\" apply_new_relevant; - let cbs = get_theory_callbacks th in - cbs.new_relevant <- cb; - set_new_relevant_callback_register th - -"); diff --git a/src/api/ml/old/x3V3.mli b/src/api/ml/old/x3V3.mli deleted file mode 100644 index 2aa2ba4e7..000000000 --- a/src/api/ml/old/x3V3.mli +++ /dev/null @@ -1,361 +0,0 @@ - -quote (mli," - -(** {2 {L ML Extensions}} *) - -(** - \[ [ mk_context_x configs] \] is a shorthand for the context with configurations in [configs]. -*) -val mk_context_x: (string * string) array -> context;; - -(** - \[ [ get_app_args c a ] \] is the array of arguments of an application. If [t] is a constant, then the array is empty. - - - {b See also}: {!Z3.get_app_num_args} - - {b See also}: {!Z3.get_app_arg} -*) -val get_app_args: context -> app -> ast array - -(** - \[ [ get_app_args c d ] \] is the array of parameters of [d]. - - - {b See also}: {!Z3.get_domain_size} - - {b See also}: {!Z3.get_domain} -*) -val get_domains: context -> func_decl -> sort array - -(** - \[ [ get_array_sort c t ] \] is the domain and the range of [t]. - - - {b See also}: {!Z3.get_array_sort_domain} - - {b See also}: {!Z3.get_array_sort_range} -*) -val get_array_sort: context -> sort -> sort * sort - -(** - \[ [ get_tuple_sort c ty ] \] is the pair [(mk_decl, fields)] where [mk_decl] is the constructor declaration of [ty], and [fields] is the array of fields in [ty]. - - - {b See also}: {!Z3.get_tuple_sort_mk_decl} - - {b See also}: {!Z3.get_tuple_sort_num_fields} - - {b See also}: {!Z3.get_tuple_sort_field_decl} -*) -val get_tuple_sort: context -> sort -> (func_decl * func_decl array) - -(** - \[ [ datatype_constructor_refined ] \] is the refinement of a datatype constructor. - - It contains the constructor declaration, recognizer, and list of accessor functions. -*) -type datatype_constructor_refined = { - constructor : func_decl; - recognizer : func_decl; - accessors : func_decl array -} - -(** - \[ [ get_datatype_sort c ty ] \] is the array of triples [(constructor, recognizer, fields)] where [constructor] is the constructor declaration of [ty], [recognizer] is the recognizer for the [constructor], and [fields] is the array of fields in [ty]. - - - {b See also}: {!Z3.get_datatype_sort_num_constructors} - - {b See also}: {!Z3.get_datatype_sort_constructor} - - {b See also}: {!Z3.get_datatype_sort_recognizer} - - {b See also}: {!Z3.get_datatype_sort_constructor_accessor} -*) - - -val get_datatype_sort: context -> sort -> datatype_constructor_refined array - -(** - \[ [ get_model_constants c m ] \] is the array of constants in the model [m]. - - - {b See also}: {!Z3.get_model_num_constants} - - {b See also}: {!Z3.get_model_constant} -*) -val get_model_constants: context -> model -> func_decl array - - -(** - \[ [ get_model_func_entry c m i j ] \] is the [j]'th entry in the [i]'th function in the model [m]. - - - {b See also}: {!Z3.get_model_func_entry_num_args} - - {b See also}: {!Z3.get_model_func_entry_arg} - - {b See also}: {!Z3.get_model_func_entry_value} -*) -val get_model_func_entry: context -> model -> int -> int -> (ast array * ast);; - -(** - \[ [ get_model_func_entries c m i ] \] is the array of entries in the [i]'th function in the model [m]. - - - {b See also}: {!Z3.get_model_func_num_entries} - - {b See also}: {!Z3.get_model_func_entry} -*) -val get_model_func_entries: context -> model -> int -> (ast array * ast) array;; - -(** - \[ [ get_model_funcs c m ] \] is the array of functions in the model [m]. Each function is represented by the triple [(decl, entries, else)], where [decl] is the declaration name for the function, [entries] is the array of entries in the function, and [else] is the default (else) value for the function. - - - {b See also}: {!Z3.get_model_num_funcs} - - {b See also}: {!Z3.get_model_func_decl} - - {b See also}: {!Z3.get_model_func_entries} - - {b See also}: {!Z3.get_model_func_else} -*) -val get_model_funcs: context -> model -> - (symbol * - (ast array * ast) array * - ast) array - -(** - \[ [ get_smtlib_formulas c ] \] is the array of formulas created by a preceding call to {!Z3.parse_smtlib_string} or {!Z3.parse_smtlib_file}. - - Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - - {b See also}: {!Z3.parse_smtlib_string_x} - - {b See also}: {!Z3.parse_smtlib_file_x} - - {b See also}: {!Z3.parse_smtlib_string} - - {b See also}: {!Z3.parse_smtlib_file} - - {b See also}: {!Z3.get_smtlib_num_formulas} - - {b See also}: {!Z3.get_smtlib_formula} -*) -val get_smtlib_formulas: context -> ast array - -(** - \[ [get_smtlib_assumptions c] \] is the array of assumptions created by a preceding call to {!Z3.parse_smtlib_string} or {!Z3.parse_smtlib_file}. - - Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - - - {b See also}: {!Z3.parse_smtlib_string_x} - - {b See also}: {!Z3.parse_smtlib_file_x} - - {b See also}: {!Z3.parse_smtlib_string} - - {b See also}: {!Z3.parse_smtlib_file} - - {b See also}: {!Z3.get_smtlib_num_assumptions} - - {b See also}: {!Z3.get_smtlib_assumption} -*) -val get_smtlib_assumptions: context -> ast array - -(** - \[ [ get_smtlib_decls c ] \] is the array of declarations created by a preceding call to {!Z3.parse_smtlib_string} or {!Z3.parse_smtlib_file}. - - Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - - - {b See also}: {!Z3.parse_smtlib_string_x} - - {b See also}: {!Z3.parse_smtlib_file_x} - - {b See also}: {!Z3.parse_smtlib_string} - - {b See also}: {!Z3.parse_smtlib_file} - - {b See also}: {!Z3.get_smtlib_num_decls} - - {b See also}: {!Z3.get_smtlib_decl} -*) -val get_smtlib_decls: context -> func_decl array - -(** - \[ [ get_smtlib_parse_results c ] \] is the triple [(get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c)]. - - Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser. - - - - {b See also}: {!Z3.parse_smtlib_string_x} - - {b See also}: {!Z3.parse_smtlib_file_x} - - {b See also}: {!Z3.parse_smtlib_string} - - {b See also}: {!Z3.parse_smtlib_file} - - {b See also}: {!Z3.get_smtlib_formulas} - - {b See also}: {!Z3.get_smtlib_assumptions} - - {b See also}: {!Z3.get_smtlib_decls} -*) -val get_smtlib_parse_results: context -> (ast array * ast array * func_decl array) - -(** - \[ [ parse_smtlib_string_formula c ... ] \] calls [(parse_smtlib_string c ...)] and returns the single formula produced. - - Recommended for functional style interface to the SMT-LIB parser. - - - {b See also}: {!Z3.parse_smtlib_file_formula} - - {b See also}: {!Z3.parse_smtlib_string_x} -*) -val parse_smtlib_string_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - -(** - \[ [ parse_smtlib_file_formula c ... ] \] calls [(parse_smtlib_file c ...)] and returns the single formula produced. - - Recommended for functional style interface to the SMT-LIB parser. - - - {b See also}: {!Z3.parse_smtlib_file_formula} - - {b See also}: {!Z3.parse_smtlib_file_x} -*) -val parse_smtlib_file_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast - -(** - \[ [ parse_smtlib_string_x c ... ] \] is [(parse_smtlib_string c ...; get_smtlib_parse_results c)] - - Recommended for functional style interface to the SMT-LIB parser. - - - {b See also}: {!Z3.parse_smtlib_file_x} - - {b See also}: {!Z3.parse_smtlib_string} - - {b See also}: {!Z3.get_smtlib_parse_results} -*) -val parse_smtlib_string_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) - -(** - \[ [ parse_smtlib_file_x c ... ] \] is [(parse_smtlib_file c ...; get_smtlib_parse_results c)] - - Recommended for functional style interface to the SMT-LIB parser. - - - {b See also}: {!Z3.parse_smtlib_string_x} - - {b See also}: {!Z3.parse_smtlib_file} - - {b See also}: {!Z3.get_smtlib_parse_results} -*) -val parse_smtlib_file_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array) - -(** - \[ [ symbol_refined ] \] is the refinement of a {!Z3.symbol} . - - - {b See also}: {!Z3.symbol_refine} - - {b See also}: {!Z3.get_symbol_kind} -*) -type symbol_refined = - | Symbol_int of int - | Symbol_string of string - | Symbol_unknown;; - -(** - \[ [ symbol_refine c s ] \] is the refined symbol of [s]. - - - {b See also}: {!Z3.symbol_refined} - - {b See also}: {!Z3.get_symbol_kind} -*) -val symbol_refine: context -> symbol -> symbol_refined;; - -(** - \[ [ sort_refined ] \] is the refinement of a {!Z3.sort} . - - - {b See also}: {!Z3.sort_refine} - - {b See also}: {!Z3.get_sort_kind} -*) - - -type sort_refined = - | Sort_uninterpreted of symbol - | Sort_bool - | Sort_int - | Sort_real - | Sort_bv of int - | Sort_array of (sort * sort) - | Sort_datatype of datatype_constructor_refined array - | Sort_relation - | Sort_finite_domain - | Sort_unknown of symbol - -(** - \[ [ sort_refine c t ] \] is the refined sort of [t]. - - - {b See also}: {!Z3.sort_refined} - - {b See also}: {!Z3.get_sort_kind} -*) -val sort_refine: context -> sort -> sort_refined;; - -(** - \[ [ binder_type ] \] is a universal or existential quantifier. - - - {b See also}: {!Z3.term_refined} -*) -type binder_type = | Forall | Exists - -(** - \[ [ numeral_refined ] \] is the refinement of a numeral . - - Numerals whose fractional representation can be fit with - 64 bit integers are treated as small. - -*) -type numeral_refined = - | Numeral_small of int64 * int64 - | Numeral_large of string - -(** - \[ [ term_refined ] \] is the refinement of a {!Z3.ast} . - - - {b See also}: {!Z3.term_refine} -*) -type term_refined = - | Term_app of decl_kind * func_decl * ast array - | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast - | Term_numeral of numeral_refined * sort - | Term_var of int * sort - -(** - \[ [ term_refine c a ] \] is the refined term of [a]. - - - {b See also}: {!Z3.term_refined} -*) -val term_refine : context -> ast -> term_refined - -(** - \[ [mk_theory c name ] \] create a custom theory. - -*) -val mk_theory : context -> string -> theory - -(** - \[ [set_delete_callback th cb] \] set callback when theory gets deleted. -*) -val set_delete_callback : theory -> (unit -> unit) -> unit - -(** - \[ [set_reduce_app_callback th cb] \] set callback for simplifying theory terms. -*) -val set_reduce_app_callback : theory -> (func_decl -> ast array -> ast option) -> unit - -(** - \[ [set_reduce_eq_callback th cb] \] set callback for simplifying equalities over theory terms. -*) -val set_reduce_eq_callback : theory -> (ast -> ast -> ast option) -> unit - -(** - \[ [set_reduce_distinct_callback th cb] \] set callback for simplifying disequalities over theory terms. -*) -val set_reduce_distinct_callback : theory -> (ast array -> ast option) -> unit - -(** - \[ [set_new_app_callback th cb] \] set callback for registering new application. -*) -val set_new_app_callback : theory -> (ast -> unit) -> unit - -(** - \[ [set_new_elem_callback th cb] \] set callback for registering new element. - - - {b See also}: the help for the corresponding C API function. -*) -val set_new_elem_callback : theory -> (ast -> unit) -> unit - -(** - \[ [set_init_search_callback th cb] \] set callback when Z3 starts searching for a satisfying assignment. -*) -val set_init_search_callback : theory -> (unit -> unit) -> unit - -(** - \[ [set_push_callback th cb] \] set callback for a logical context push. -*) -val set_push_callback : theory -> (unit -> unit) -> unit - -(** - \[ [set_pop_callback th cb] \] set callback for a logical context pop. -*) -val set_pop_callback : theory -> (unit -> unit) -> unit - -(** - \[ [set_restart_callback th cb] \] set callback for search restart. -*) -val set_restart_callback : theory -> (unit -> unit) -> unit - -val set_reset_callback : theory -> (unit -> unit) -> unit - -val set_final_check_callback : theory -> (unit -> bool) -> unit - -val set_new_eq_callback : theory -> (ast -> ast -> unit) -> unit - -val set_new_diseq_callback : theory -> (ast -> ast -> unit) -> unit - -val set_new_assignment_callback : theory -> (ast -> bool -> unit) -> unit - -val set_new_relevant_callback : theory -> (ast -> unit) -> unit - -"); diff --git a/src/api/ml/old/z3.0.idl b/src/api/ml/old/z3.0.idl deleted file mode 100644 index 3773a28e3..000000000 --- a/src/api/ml/old/z3.0.idl +++ /dev/null @@ -1,597 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation - -Module Name: - - Z3 - -Abstract: - - OCaml API for Z3. - - The following design is used for the treatment of reference counting: - - - The conversion of Z3_context from ML to C remembers the Z3 context, and - registers a finalizer using Gc.finalize that calls Z3_del_context. - - - The conversion of Z3_ast and other reference counted types from C to ML: - - + stores the last translated context with the Z3_ast in the wrapper - object; - - + registers a finalizer using Gc.finalize that decrements the reference - counter of the Z3_ast; - - + increments the reference count of the Z3_ast. - - The finalizers are registered using (the C interface to) Gc.finalize, - not attaching a finalizer to a custom block. The finalizers registered - by Gc.finalize are guaranteed to be called in reverse - registration-order, which is necessary to ensure that Z3_context's are - finalized only after all the Z3_ast's within them. - - - ML Z3.ast (and subtypes) are given generic hash and comparison - operations using Z3_get_ast_hash and Z3_get_ast_id. Other types could - be handled similarly if analogous hash and id operations were exported - by the C API. - - - The wrapper for Z3_mk_context is customized (using quote(call,...) in - z3_api.patched.h) to call Z3_mk_context_rc, and the ML API does not - include mk_context_rc. - - This scheme relies on the property that all reference counted values - returned from C to ML are in the Z3_context that was last sent from ML to - C. This is normally straightforward, but note that it depends on the - argument order of e.g. the Z3_*translate functions. - - Non-reference counted Z3 types that have delete operations have finalizers - that call the delete operations. The exposed delete operations are - shadowed by nop functions. The types whose delete operation accepts a - context use Gc.finalize while those that do not use custom block - finalizers. - - Custom c2ml functions check the Z3 error code prior to allocating ML - values or registering finalizers. Other functions check the Z3 error code - after making a Z3 library call. - - Some operations return NULL pointers when operations fail, or accept NULL - pointers. To handle these cases Z3_{ast,func_interp,sort}_opt types are - introduced. These are synonyms of Z3_{ast,func_interp,sort} but are - translated into OCaml option types. If the NULL pointers were passed to - ML, even if the user does not access them, they will have finalizers - registered, so when they die the OCaml GC will crash trying to call - dec_ref on NULL. - - There is an alternate implementation, enabled by setting LEAK_CONTEXTS, - that avoids the overhead of Gc.finalize finalizers, but at the price of - leaking Z3_context objects. - -Notes: - - OCaml does not support unsigned types, so CamlIDL conflates signed and - unsigned types of the same size. Therefore, functions in the C API - operating on unsigned values that become redundant after this conflation - are excluded from the ML API using [#ifndef CAMLIDL] in z3_api.h. - - CamlIDL does not support function pointers, so functions in the C API with - function pointer arguments are handled manually. - -Author: - - Jakob Lichtenberg (JakobL) 2007-08-08 - Josh Berdine (jjb) 2012-03-21 - ---*/ - - -// cpp trick to include expanded macro arguments in string literals -#define xstr(s) str(s) -#define str(s) #s -quote(c,"#define xstr(s) str(s)"); -quote(c,"#define str(s) #s"); - - -#ifndef MLAPIV3 - -#define DEFINE_TYPE(T) typedef [abstract] void* T -#define DEFINE_VOID(T) typedef [abstract] void* T - -#define BEGIN_MLAPI_EXCLUDE quote(mli,"(*"); -#define END_MLAPI_EXCLUDE quote(mli,"*)"); - -#ifdef LEAK_CONTEXTS - - // Declare pointer type with custom conversion functions. - #define DEFINE_CUST_TYPE(T) \ - typedef [abstract, ml2c(ml2c_Z3_ ## T), c2ml(c2ml_Z3_ ## T)] void* Z3_ ## T - -#else - - // Declare pointer type with custom conversion functions. - // Register an OCaml closure that just calls a C finalization function. - #define DEFINE_CUST_TYPE(T) \ - quote(ml,xstr(\ - external finalize_Z3_ ## T : T -> unit = xstr(finalize_Z3_ ## T);; \ - let _ = Callback.register xstr(finalize_Z3_ ## T) finalize_Z3_ ## T \ - )); \ - typedef [abstract, ml2c(ml2c_Z3_ ## T), c2ml(c2ml_Z3_ ## T)] void* Z3_ ## T - -#endif - - -// Z3_context -quote(c," -void check_error_code (Z3_context c); - -Z3_context last_ctx; -"); - -#ifdef LEAK_CONTEXTS - - quote(c," - value c2ml_Z3_context(Z3_context* c) - { - value v; - v = caml_alloc_small(1, Abstract_tag); - *((Z3_context *) Bp_val(v)) = *c; - return v; - } - - void ml2c_Z3_context(value v, Z3_context* c) - { - *c = *((Z3_context *) Bp_val(v)); - last_ctx = *c; - } - "); - -#else - - quote(c," - // caml_final_register is the implementation of Gc.finalize - value caml_final_register (value f, value v); - - void register_finalizer(value** closure, char* name, Z3_context ctx, value v) - { - if (*closure == NULL) { - *closure = caml_named_value(name); - if (*closure == NULL) { - Z3_set_error(ctx, Z3_INTERNAL_FATAL); - return; - } - } - caml_final_register(**closure, v); - } - - value c2ml_Z3_context (Z3_context* c) - { - static value* finalize_Z3_context_closure = NULL; - value v; - v = caml_alloc_small(1, Abstract_tag); - Field(v, 0) = (value) *c; - register_finalizer(&finalize_Z3_context_closure, \"finalize_Z3_context\", - (Z3_context) *c, v); - return v; - } - - void ml2c_Z3_context (value v, Z3_context* c) - { - *c = (Z3_context) Field(v, 0); - last_ctx = *c; - } - - value finalize_Z3_context (value v) - { - Z3_context c; - c = (Z3_context) Field(v, 0); - Z3_del_context(c); - return Val_unit; - } - "); - -#endif - -DEFINE_CUST_TYPE(context); - - -// Z3_symbol -typedef [abstract] void* Z3_symbol; - - -// Z3_ast: reference counted type with hashing and comparison -quote(c," -typedef struct _Z3_ast_context { - Z3_ast ast; - Z3_context ctx; -} Z3_ast_context; - -void ml2c_Z3_ast (value v, Z3_ast* c) -{ - *c = ((Z3_ast_context*) Data_custom_val(v))->ast; -} - -static int compare_Z3_ast (value v1, value v2) -{ - Z3_ast_context* ac1; - Z3_ast_context* ac2; - unsigned id1, id2; - ac1 = Data_custom_val(v1); - ac2 = Data_custom_val(v2); - id1 = Z3_get_ast_id(ac1->ctx, ac1->ast); - check_error_code(ac1->ctx); - id2 = Z3_get_ast_id(ac2->ctx, ac2->ast); - check_error_code(ac2->ctx); - return id2 - id1; -} - -static intnat hash_Z3_ast (value v) -{ - Z3_ast_context* ac; - unsigned hash; - ac = Data_custom_val(v); - hash = Z3_get_ast_hash(ac->ctx, ac->ast); - check_error_code(ac->ctx); - return hash; -} -"); - -#ifdef LEAK_CONTEXTS - - quote(c," - static void finalize_Z3_ast (value v) - { - Z3_ast_context* ac; - ac = Data_custom_val(v); - Z3_dec_ref(ac->ctx, ac->ast); - check_error_code(ac->ctx); - } - - static struct custom_operations cops_Z3_ast = { - NULL, - finalize_Z3_ast, - compare_Z3_ast, - hash_Z3_ast, - custom_serialize_default, - custom_deserialize_default - }; - - value c2ml_Z3_ast (Z3_ast* c) - { - value v; - Z3_ast_context* ac; - check_error_code(last_ctx); - v = alloc_custom(&cops_Z3_ast, sizeof(Z3_ast_context), 0, 1); - ac = Data_custom_val(v); - ac->ctx = last_ctx; - ac->ast = *c; - Z3_inc_ref(ac->ctx, ac->ast); - return v; - } - "); - -#else - - quote(c," - value finalize_Z3_ast (value v) - { - Z3_ast_context* ac; - ac = Data_custom_val(v); - Z3_dec_ref(ac->ctx, ac->ast); - check_error_code(ac->ctx); - return Val_unit; - } - - static struct custom_operations cops_Z3_ast = { - NULL, - custom_finalize_default, - compare_Z3_ast, - hash_Z3_ast, - custom_serialize_default, - custom_deserialize_default - }; - - value c2ml_Z3_ast (Z3_ast* c) - { - static value* finalize_Z3_ast_closure = NULL; - value v; - Z3_ast_context* ac; - check_error_code(last_ctx); - v = caml_alloc_custom(&cops_Z3_ast, sizeof(Z3_ast_context), 0, 1); - ac = Data_custom_val(v); - ac->ast = *c; - ac->ctx = last_ctx; - register_finalizer(&finalize_Z3_ast_closure, \"finalize_Z3_ast\", - (Z3_context) *c, v); - Z3_inc_ref(last_ctx, *c); - return v; - } - "); - -#endif - -DEFINE_CUST_TYPE(ast); - - -// subtypes of Z3_ast -quote(c,"\ -#define DEFINE_SUBAST_OPS(T) \ - void ml2c_ ## T (value v, T * a) \ - { \ - ml2c_Z3_ast(v, (Z3_ast*) a); \ - } \ - \ - value c2ml_ ## T (T * a) \ - { \ - return c2ml_Z3_ast((Z3_ast*) a); \ - } \ -"); - -#define DEFINE_SUBAST(T) \ - typedef [mltype("private ast"), ml2c(ml2c_ ## T), c2ml(c2ml_ ## T)] Z3_ast T - -quote(c,"DEFINE_SUBAST_OPS(Z3_sort)"); DEFINE_SUBAST(Z3_sort); -quote(c,"DEFINE_SUBAST_OPS(Z3_func_decl)"); DEFINE_SUBAST(Z3_func_decl); -quote(c,"DEFINE_SUBAST_OPS(Z3_app)"); DEFINE_SUBAST(Z3_app); -quote(c,"DEFINE_SUBAST_OPS(Z3_pattern)"); DEFINE_SUBAST(Z3_pattern); - - -// reference counted types without hashing and comparison -#ifdef LEAK_CONTEXTS - - quote(c,"\ - #define DEFINE_RC_OPS(T) \ - typedef struct _ ## T ## _context { \ - T dat; \ - Z3_context ctx; \ - } T ## _context; \ - \ - static void finalize_ ## T (value v) \ - { \ - T ## _context* ac; \ - ac = Data_custom_val(v); \ - T ## _dec_ref(ac->ctx, ac->dat); \ - check_error_code(ac->ctx); \ - } \ - \ - static struct custom_operations cops_ ## T = { \ - NULL, \ - finalize_ ## T, \ - custom_compare_default, \ - custom_hash_default, \ - custom_serialize_default, \ - custom_deserialize_default \ - }; \ - \ - value c2ml_ ## T (T * c) \ - { \ - value v; \ - T ## _context* ac; \ - check_error_code(last_ctx); \ - v = alloc_custom(&cops_ ## T, sizeof(T ## _context), 0, 1); \ - ac = Data_custom_val(v); \ - ac->dat = *c; \ - ac->ctx = last_ctx; \ - T ## _inc_ref(ac->ctx, ac->dat); \ - return v; \ - } \ - \ - void ml2c_ ## T (value v, T * c) \ - { \ - *c = ((T ## _context*) Data_custom_val(v))->dat; \ - } \ - "); - -#else - - quote(c,"\ - #define DEFINE_RC_OPS(T) \ - value c2ml_ ## T (T * c) \ - { \ - static value* finalize_ ## T ## _closure = NULL; \ - value v; \ - check_error_code(last_ctx); \ - v = caml_alloc_small(2, Abstract_tag); \ - Field(v, 0) = (value) *c; \ - Field(v, 1) = (value) last_ctx; \ - register_finalizer(&finalize_ ## T ## _closure, xstr(finalize_ ## T), \ - (Z3_context) *c, v); \ - T ## _inc_ref(last_ctx, *c); \ - return v; \ - } \ - \ - void ml2c_ ## T (value v, T * c) \ - { \ - *c = (T) Field(v, 0); \ - } \ - \ - value finalize_ ## T (value v) \ - { \ - Z3_context c; \ - c = (Z3_context) Field(v, 1); \ - T ## _dec_ref(c, (T) Field(v, 0)); \ - check_error_code(c); \ - return Val_unit; \ - } \ - "); - -#endif - -quote(c,"DEFINE_RC_OPS(Z3_params)"); DEFINE_CUST_TYPE(params); -quote(c,"DEFINE_RC_OPS(Z3_param_descrs)"); DEFINE_CUST_TYPE(param_descrs); -quote(c,"DEFINE_RC_OPS(Z3_model)"); DEFINE_CUST_TYPE(model); -quote(c,"DEFINE_RC_OPS(Z3_func_interp)"); DEFINE_CUST_TYPE(func_interp); -quote(c,"DEFINE_RC_OPS(Z3_func_entry)"); DEFINE_CUST_TYPE(func_entry); -quote(c,"DEFINE_RC_OPS(Z3_fixedpoint)"); DEFINE_CUST_TYPE(fixedpoint); -quote(c,"DEFINE_RC_OPS(Z3_ast_vector)"); DEFINE_CUST_TYPE(ast_vector); -quote(c,"DEFINE_RC_OPS(Z3_ast_map)"); DEFINE_CUST_TYPE(ast_map); -quote(c,"DEFINE_RC_OPS(Z3_goal)"); DEFINE_CUST_TYPE(goal); -quote(c,"DEFINE_RC_OPS(Z3_tactic)"); DEFINE_CUST_TYPE(tactic); -quote(c,"DEFINE_RC_OPS(Z3_probe)"); DEFINE_CUST_TYPE(probe); -quote(c,"DEFINE_RC_OPS(Z3_apply_result)"); DEFINE_CUST_TYPE(apply_result); -quote(c,"DEFINE_RC_OPS(Z3_solver)"); DEFINE_CUST_TYPE(solver); -quote(c,"DEFINE_RC_OPS(Z3_stats)"); DEFINE_CUST_TYPE(stats); - - -// possibly-NULL pointer types, translated to OCaml option types -quote(c,"\ -#define DEFINE_OPT_OPS(T) \ - void ml2c_ ## T ## _opt (value v, T* c) \ - { \ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; \ - camlidl_ctx _ctx = &_ctxs; \ - if (v != Val_int(0)) { \ - camlidl_ml2c_z3_ ## T(Field(v, 0), c, _ctx); \ - } else { \ - *c = NULL; \ - } \ - } \ - \ - value c2ml_ ## T ## _opt (T* c) \ - { \ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; \ - camlidl_ctx _ctx = &_ctxs; \ - value v; \ - value a; \ - if (*c) { \ - a = camlidl_c2ml_z3_ ## T(c, _ctx); \ - Begin_root(a) \ - v = caml_alloc_small(1, 0); \ - Field(v, 0) = a; \ - End_roots(); \ - } else { \ - v = Val_int(0); \ - } \ - return v; \ - } -"); - -#define DEFINE_OPT_TYPE(T) \ - typedef [mltype(xstr(T option)), \ - ml2c(ml2c_Z3_ ## T ## _opt), \ - c2ml(c2ml_Z3_ ## T ## _opt) \ - ] Z3_ ## T Z3_ ## T ## _opt - -quote(c,"DEFINE_OPT_OPS(Z3_ast)"); -DEFINE_OPT_TYPE(ast); - -quote(c,"DEFINE_OPT_OPS(Z3_sort)"); -DEFINE_OPT_TYPE(sort); - -quote(c,"DEFINE_OPT_OPS(Z3_func_interp)"); -DEFINE_OPT_TYPE(func_interp); - - -// ToDo: these unnecessarily appear in the API documentation -DEFINE_TYPE(Z3_constructor); -DEFINE_TYPE(Z3_constructor_list); - - -// shadow delete operations with nops -quote(ml," -let del_constructor _ _ = () -let del_constructor_list _ _ = () -let del_model _ _ = () -let del_context _ = () -let reset_memory () = () -"); - - -#else // MLAPIV3 - -// Provide custom error handler: -quote (c,"Z3_error_handler caml_z3_error_handler;"); -quote (c,"void caml_z3_error_handler(Z3_context c, Z3_error_code e) { static char buffer[128]; char * msg = Z3_get_error_msg_ex(c, e); if (strlen(msg) > 100) { failwith(\"Z3: error message is too big to fit in buffer\"); } else { sprintf(buffer, \"Z3: %s\", msg); failwith(buffer); } }"); - - -#define DEFINE_TYPE(T) typedef [abstract] void* T -#define DEFINE_VOID(T) typedef [abstract] void* T - -#define BEGIN_MLAPI_EXCLUDE -#define END_MLAPI_EXCLUDE - -#endif // MLAPIV3 - - - -#ifndef __in -#define __in [in] -#endif - -#ifndef __out -#define __out [out] -#endif - -#ifndef __out_opt -#define __out_opt [out,unique] -#endif - -#ifndef __ecount -#define __ecount(num_args) [NOT_SUPPORTED] -#endif - -#ifndef __in_ecount -#define __in_ecount(num_args) [in, size_is(num_args), length_is(num_args)] -#endif - -#ifndef __out_ecount -#define __out_ecount(num_args) [out, size_is(num_args), length_is(num_args)] -#endif - -#ifndef __inout_ecount -#define __inout_ecount(num_args) [in, out, size_is(num_args), length_is(num_args)] -#endif - -#ifndef __inout -#define __inout [in, out] -#endif - -#ifndef Z3_bool_opt -#define Z3_bool_opt void -#endif - - -#define Z3_API - -#ifdef MLAPIV3 - -#include "z3V3_api.idl" -#include "x3V3.mli" -#include "x3V3.ml" - -#else - -#include "z3_api.idl" -#include "x3.ml" - -quote(ml," -let _ = - Printexc.register_printer (function - | Error(c,e) -> Some (\"Z3 \"^(get_error_msg c e)) - | _ -> None - ) -"); - - -quote(mli," -(** - {2 {L Legacy V3 API}} -*) - -module V3 : sig -(** - {2 {L Legacy V3 API}} -*) -"); - -quote(ml," -module V3 = struct -"); - -#endif - -#ifdef MLAPIV3 - -quote(mlmli," -end -"); - -#endif diff --git a/src/api/ml/old/z3_stubs.c b/src/api/ml/old/z3_stubs.c deleted file mode 100644 index bad4338de..000000000 --- a/src/api/ml/old/z3_stubs.c +++ /dev/null @@ -1,19044 +0,0 @@ -/* File generated from z3.idl */ - -#include -#include -#include -#include -#include -#include -#include -#ifdef Custom_tag -#include -#include -#endif -#include - - -#include "z3.h" - -#define xstr(s) str(s) -#define str(s) #s - -void check_error_code (Z3_context c); -Z3_context last_ctx; - - - // caml_final_register is the implementation of Gc.finalize - value caml_final_register (value f, value v); - void register_finalizer(value** closure, char* name, Z3_context ctx, value v) - { - if (*closure == NULL) { - *closure = caml_named_value(name); - if (*closure == NULL) { - Z3_set_error(ctx, Z3_INTERNAL_FATAL); - return; - } - } - caml_final_register(**closure, v); - } - value c2ml_Z3_context (Z3_context* c) - { - static value* finalize_Z3_context_closure = NULL; - value v; - v = caml_alloc_small(1, Abstract_tag); - Field(v, 0) = (value) *c; - register_finalizer(&finalize_Z3_context_closure, "finalize_Z3_context", - (Z3_context) *c, v); - return v; - } - void ml2c_Z3_context (value v, Z3_context* c) - { - *c = (Z3_context) Field(v, 0); - last_ctx = *c; - } - value finalize_Z3_context (value v) - { - Z3_context c; - c = (Z3_context) Field(v, 0); - Z3_del_context(c); - return Val_unit; - } - -#define camlidl_ml2c_z3_Z3_context(v,c,ctx) ml2c_Z3_context(v,c) - -#define camlidl_c2ml_z3_Z3_context(c,ctx) c2ml_Z3_context(c) - -void camlidl_ml2c_z3_Z3_symbol(value _v1, Z3_symbol * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_symbol *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3_Z3_symbol(Z3_symbol * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_symbol) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_symbol *) Bp_val(_v1)) = *_c2; - return _v1; -} - - -typedef struct _Z3_ast_context { - Z3_ast ast; - Z3_context ctx; -} Z3_ast_context; -void ml2c_Z3_ast (value v, Z3_ast* c) -{ - *c = ((Z3_ast_context*) Data_custom_val(v))->ast; -} -static int compare_Z3_ast (value v1, value v2) -{ - Z3_ast_context* ac1; - Z3_ast_context* ac2; - unsigned id1, id2; - ac1 = Data_custom_val(v1); - ac2 = Data_custom_val(v2); - id1 = Z3_get_ast_id(ac1->ctx, ac1->ast); - check_error_code(ac1->ctx); - id2 = Z3_get_ast_id(ac2->ctx, ac2->ast); - check_error_code(ac2->ctx); - return id2 - id1; -} -static intnat hash_Z3_ast (value v) -{ - Z3_ast_context* ac; - unsigned hash; - ac = Data_custom_val(v); - hash = Z3_get_ast_hash(ac->ctx, ac->ast); - check_error_code(ac->ctx); - return hash; -} - - - value finalize_Z3_ast (value v) - { - Z3_ast_context* ac; - ac = Data_custom_val(v); - Z3_dec_ref(ac->ctx, ac->ast); - check_error_code(ac->ctx); - return Val_unit; - } - static struct custom_operations cops_Z3_ast = { - NULL, - custom_finalize_default, - compare_Z3_ast, - hash_Z3_ast, - custom_serialize_default, - custom_deserialize_default - }; - value c2ml_Z3_ast (Z3_ast* c) - { - static value* finalize_Z3_ast_closure = NULL; - value v; - Z3_ast_context* ac; - check_error_code(last_ctx); - v = caml_alloc_custom(&cops_Z3_ast, sizeof(Z3_ast_context), 0, 1); - ac = Data_custom_val(v); - ac->ast = *c; - ac->ctx = last_ctx; - register_finalizer(&finalize_Z3_ast_closure, "finalize_Z3_ast", - (Z3_context) *c, v); - Z3_inc_ref(last_ctx, *c); - return v; - } - -#define camlidl_ml2c_z3_Z3_ast(v,c,ctx) ml2c_Z3_ast(v,c) - -#define camlidl_c2ml_z3_Z3_ast(c,ctx) c2ml_Z3_ast(c) - -#define DEFINE_SUBAST_OPS(T) void ml2c_ ## T (value v, T * a) { ml2c_Z3_ast(v, (Z3_ast*) a); } value c2ml_ ## T (T * a) { return c2ml_Z3_ast((Z3_ast*) a); } -DEFINE_SUBAST_OPS(Z3_sort) -#define camlidl_ml2c_z3_Z3_sort(v,c,ctx) ml2c_Z3_sort(v,c) - -#define camlidl_c2ml_z3_Z3_sort(c,ctx) c2ml_Z3_sort(c) - -DEFINE_SUBAST_OPS(Z3_func_decl) -#define camlidl_ml2c_z3_Z3_func_decl(v,c,ctx) ml2c_Z3_func_decl(v,c) - -#define camlidl_c2ml_z3_Z3_func_decl(c,ctx) c2ml_Z3_func_decl(c) - -DEFINE_SUBAST_OPS(Z3_app) -#define camlidl_ml2c_z3_Z3_app(v,c,ctx) ml2c_Z3_app(v,c) - -#define camlidl_c2ml_z3_Z3_app(c,ctx) c2ml_Z3_app(c) - -DEFINE_SUBAST_OPS(Z3_pattern) -#define camlidl_ml2c_z3_Z3_pattern(v,c,ctx) ml2c_Z3_pattern(v,c) - -#define camlidl_c2ml_z3_Z3_pattern(c,ctx) c2ml_Z3_pattern(c) - - #define DEFINE_RC_OPS(T) value c2ml_ ## T (T * c) { static value* finalize_ ## T ## _closure = NULL; value v; check_error_code(last_ctx); v = caml_alloc_small(2, Abstract_tag); Field(v, 0) = (value) *c; Field(v, 1) = (value) last_ctx; register_finalizer(&finalize_ ## T ## _closure, xstr(finalize_ ## T), (Z3_context) *c, v); T ## _inc_ref(last_ctx, *c); return v; } void ml2c_ ## T (value v, T * c) { *c = (T) Field(v, 0); } value finalize_ ## T (value v) { Z3_context c; c = (Z3_context) Field(v, 1); T ## _dec_ref(c, (T) Field(v, 0)); check_error_code(c); return Val_unit; } -DEFINE_RC_OPS(Z3_params) -#define camlidl_ml2c_z3_Z3_params(v,c,ctx) ml2c_Z3_params(v,c) - -#define camlidl_c2ml_z3_Z3_params(c,ctx) c2ml_Z3_params(c) - -DEFINE_RC_OPS(Z3_param_descrs) -#define camlidl_ml2c_z3_Z3_param_descrs(v,c,ctx) ml2c_Z3_param_descrs(v,c) - -#define camlidl_c2ml_z3_Z3_param_descrs(c,ctx) c2ml_Z3_param_descrs(c) - -DEFINE_RC_OPS(Z3_model) -#define camlidl_ml2c_z3_Z3_model(v,c,ctx) ml2c_Z3_model(v,c) - -#define camlidl_c2ml_z3_Z3_model(c,ctx) c2ml_Z3_model(c) - -DEFINE_RC_OPS(Z3_func_interp) -#define camlidl_ml2c_z3_Z3_func_interp(v,c,ctx) ml2c_Z3_func_interp(v,c) - -#define camlidl_c2ml_z3_Z3_func_interp(c,ctx) c2ml_Z3_func_interp(c) - -DEFINE_RC_OPS(Z3_func_entry) -#define camlidl_ml2c_z3_Z3_func_entry(v,c,ctx) ml2c_Z3_func_entry(v,c) - -#define camlidl_c2ml_z3_Z3_func_entry(c,ctx) c2ml_Z3_func_entry(c) - -DEFINE_RC_OPS(Z3_fixedpoint) -#define camlidl_ml2c_z3_Z3_fixedpoint(v,c,ctx) ml2c_Z3_fixedpoint(v,c) - -#define camlidl_c2ml_z3_Z3_fixedpoint(c,ctx) c2ml_Z3_fixedpoint(c) - -DEFINE_RC_OPS(Z3_ast_vector) -#define camlidl_ml2c_z3_Z3_ast_vector(v,c,ctx) ml2c_Z3_ast_vector(v,c) - -#define camlidl_c2ml_z3_Z3_ast_vector(c,ctx) c2ml_Z3_ast_vector(c) - -DEFINE_RC_OPS(Z3_ast_map) -#define camlidl_ml2c_z3_Z3_ast_map(v,c,ctx) ml2c_Z3_ast_map(v,c) - -#define camlidl_c2ml_z3_Z3_ast_map(c,ctx) c2ml_Z3_ast_map(c) - -DEFINE_RC_OPS(Z3_goal) -#define camlidl_ml2c_z3_Z3_goal(v,c,ctx) ml2c_Z3_goal(v,c) - -#define camlidl_c2ml_z3_Z3_goal(c,ctx) c2ml_Z3_goal(c) - -DEFINE_RC_OPS(Z3_tactic) -#define camlidl_ml2c_z3_Z3_tactic(v,c,ctx) ml2c_Z3_tactic(v,c) - -#define camlidl_c2ml_z3_Z3_tactic(c,ctx) c2ml_Z3_tactic(c) - -DEFINE_RC_OPS(Z3_probe) -#define camlidl_ml2c_z3_Z3_probe(v,c,ctx) ml2c_Z3_probe(v,c) - -#define camlidl_c2ml_z3_Z3_probe(c,ctx) c2ml_Z3_probe(c) - -DEFINE_RC_OPS(Z3_apply_result) -#define camlidl_ml2c_z3_Z3_apply_result(v,c,ctx) ml2c_Z3_apply_result(v,c) - -#define camlidl_c2ml_z3_Z3_apply_result(c,ctx) c2ml_Z3_apply_result(c) - -DEFINE_RC_OPS(Z3_solver) -#define camlidl_ml2c_z3_Z3_solver(v,c,ctx) ml2c_Z3_solver(v,c) - -#define camlidl_c2ml_z3_Z3_solver(c,ctx) c2ml_Z3_solver(c) - -DEFINE_RC_OPS(Z3_stats) -#define camlidl_ml2c_z3_Z3_stats(v,c,ctx) ml2c_Z3_stats(v,c) - -#define camlidl_c2ml_z3_Z3_stats(c,ctx) c2ml_Z3_stats(c) - -#define DEFINE_OPT_OPS(T) void ml2c_ ## T ## _opt (value v, T* c) { struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; camlidl_ctx _ctx = &_ctxs; if (v != Val_int(0)) { camlidl_ml2c_z3_ ## T(Field(v, 0), c, _ctx); } else { *c = NULL; } } value c2ml_ ## T ## _opt (T* c) { struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; camlidl_ctx _ctx = &_ctxs; value v; value a; if (*c) { a = camlidl_c2ml_z3_ ## T(c, _ctx); Begin_root(a) v = caml_alloc_small(1, 0); Field(v, 0) = a; End_roots(); } else { v = Val_int(0); } return v; } - -DEFINE_OPT_OPS(Z3_ast) -#define camlidl_ml2c_z3_Z3_ast_opt(v,c,ctx) ml2c_Z3_ast_opt(v,c) - -#define camlidl_c2ml_z3_Z3_ast_opt(c,ctx) c2ml_Z3_ast_opt(c) - -DEFINE_OPT_OPS(Z3_sort) -#define camlidl_ml2c_z3_Z3_sort_opt(v,c,ctx) ml2c_Z3_sort_opt(v,c) - -#define camlidl_c2ml_z3_Z3_sort_opt(c,ctx) c2ml_Z3_sort_opt(c) - -DEFINE_OPT_OPS(Z3_func_interp) -#define camlidl_ml2c_z3_Z3_func_interp_opt(v,c,ctx) ml2c_Z3_func_interp_opt(v,c) - -#define camlidl_c2ml_z3_Z3_func_interp_opt(c,ctx) c2ml_Z3_func_interp_opt(c) - -void camlidl_ml2c_z3_Z3_constructor(value _v1, Z3_constructor * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_constructor *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3_Z3_constructor(Z3_constructor * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_constructor) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_constructor *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3_Z3_constructor_list(value _v1, Z3_constructor_list * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_constructor_list *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3_Z3_constructor_list(Z3_constructor_list * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_constructor_list) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_constructor_list *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3_Z3_string(value _v1, Z3_string * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_malloc_string(_v1, _ctx); -} - -value camlidl_c2ml_z3_Z3_string(Z3_string * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = copy_string((*_c2)); - return _v1; -} - -int camlidl_transl_table_z3_enum_1[3] = { - Z3_L_FALSE, - Z3_L_UNDEF, - Z3_L_TRUE, -}; - -void camlidl_ml2c_z3_Z3_lbool(value _v1, Z3_lbool * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_1[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_lbool(Z3_lbool * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_L_FALSE: _v1 = Val_int(0); break; - case Z3_L_UNDEF: _v1 = Val_int(1); break; - case Z3_L_TRUE: _v1 = Val_int(2); break; - default: invalid_argument("typedef Z3_lbool: bad enum value"); - } - return _v1; -} - -int camlidl_transl_table_z3_enum_2[2] = { - Z3_INT_SYMBOL, - Z3_STRING_SYMBOL, -}; - -void camlidl_ml2c_z3_Z3_symbol_kind(value _v1, Z3_symbol_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_2[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_symbol_kind(Z3_symbol_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_INT_SYMBOL: _v1 = Val_int(0); break; - case Z3_STRING_SYMBOL: _v1 = Val_int(1); break; - default: invalid_argument("typedef Z3_symbol_kind: bad enum value"); - } - return _v1; -} - -int camlidl_transl_table_z3_enum_3[7] = { - Z3_PARAMETER_INT, - Z3_PARAMETER_DOUBLE, - Z3_PARAMETER_RATIONAL, - Z3_PARAMETER_SYMBOL, - Z3_PARAMETER_SORT, - Z3_PARAMETER_AST, - Z3_PARAMETER_FUNC_DECL, -}; - -void camlidl_ml2c_z3_Z3_parameter_kind(value _v1, Z3_parameter_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_3[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_parameter_kind(Z3_parameter_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_3, 7, "typedef Z3_parameter_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3_enum_4[10] = { - Z3_UNINTERPRETED_SORT, - Z3_BOOL_SORT, - Z3_INT_SORT, - Z3_REAL_SORT, - Z3_BV_SORT, - Z3_ARRAY_SORT, - Z3_DATATYPE_SORT, - Z3_RELATION_SORT, - Z3_FINITE_DOMAIN_SORT, - Z3_UNKNOWN_SORT, -}; - -void camlidl_ml2c_z3_Z3_sort_kind(value _v1, Z3_sort_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_4[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_sort_kind(Z3_sort_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_4, 10, "typedef Z3_sort_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3_enum_5[7] = { - Z3_NUMERAL_AST, - Z3_APP_AST, - Z3_VAR_AST, - Z3_QUANTIFIER_AST, - Z3_SORT_AST, - Z3_FUNC_DECL_AST, - Z3_UNKNOWN_AST, -}; - -void camlidl_ml2c_z3_Z3_ast_kind(value _v1, Z3_ast_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_5[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_ast_kind(Z3_ast_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_5, 7, "typedef Z3_ast_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3_enum_6[152] = { - Z3_OP_TRUE, - Z3_OP_FALSE, - Z3_OP_EQ, - Z3_OP_DISTINCT, - Z3_OP_ITE, - Z3_OP_AND, - Z3_OP_OR, - Z3_OP_IFF, - Z3_OP_XOR, - Z3_OP_NOT, - Z3_OP_IMPLIES, - Z3_OP_OEQ, - Z3_OP_ANUM, - Z3_OP_AGNUM, - Z3_OP_LE, - Z3_OP_GE, - Z3_OP_LT, - Z3_OP_GT, - Z3_OP_ADD, - Z3_OP_SUB, - Z3_OP_UMINUS, - Z3_OP_MUL, - Z3_OP_DIV, - Z3_OP_IDIV, - Z3_OP_REM, - Z3_OP_MOD, - Z3_OP_TO_REAL, - Z3_OP_TO_INT, - Z3_OP_IS_INT, - Z3_OP_POWER, - Z3_OP_STORE, - Z3_OP_SELECT, - Z3_OP_CONST_ARRAY, - Z3_OP_ARRAY_MAP, - Z3_OP_ARRAY_DEFAULT, - Z3_OP_SET_UNION, - Z3_OP_SET_INTERSECT, - Z3_OP_SET_DIFFERENCE, - Z3_OP_SET_COMPLEMENT, - Z3_OP_SET_SUBSET, - Z3_OP_AS_ARRAY, - Z3_OP_BNUM, - Z3_OP_BIT1, - Z3_OP_BIT0, - Z3_OP_BNEG, - Z3_OP_BADD, - Z3_OP_BSUB, - Z3_OP_BMUL, - Z3_OP_BSDIV, - Z3_OP_BUDIV, - Z3_OP_BSREM, - Z3_OP_BUREM, - Z3_OP_BSMOD, - Z3_OP_BSDIV0, - Z3_OP_BUDIV0, - Z3_OP_BSREM0, - Z3_OP_BUREM0, - Z3_OP_BSMOD0, - Z3_OP_ULEQ, - Z3_OP_SLEQ, - Z3_OP_UGEQ, - Z3_OP_SGEQ, - Z3_OP_ULT, - Z3_OP_SLT, - Z3_OP_UGT, - Z3_OP_SGT, - Z3_OP_BAND, - Z3_OP_BOR, - Z3_OP_BNOT, - Z3_OP_BXOR, - Z3_OP_BNAND, - Z3_OP_BNOR, - Z3_OP_BXNOR, - Z3_OP_CONCAT, - Z3_OP_SIGN_EXT, - Z3_OP_ZERO_EXT, - Z3_OP_EXTRACT, - Z3_OP_REPEAT, - Z3_OP_BREDOR, - Z3_OP_BREDAND, - Z3_OP_BCOMP, - Z3_OP_BSHL, - Z3_OP_BLSHR, - Z3_OP_BASHR, - Z3_OP_ROTATE_LEFT, - Z3_OP_ROTATE_RIGHT, - Z3_OP_EXT_ROTATE_LEFT, - Z3_OP_EXT_ROTATE_RIGHT, - Z3_OP_INT2BV, - Z3_OP_BV2INT, - Z3_OP_CARRY, - Z3_OP_XOR3, - Z3_OP_PR_UNDEF, - Z3_OP_PR_TRUE, - Z3_OP_PR_ASSERTED, - Z3_OP_PR_GOAL, - Z3_OP_PR_MODUS_PONENS, - Z3_OP_PR_REFLEXIVITY, - Z3_OP_PR_SYMMETRY, - Z3_OP_PR_TRANSITIVITY, - Z3_OP_PR_TRANSITIVITY_STAR, - Z3_OP_PR_MONOTONICITY, - Z3_OP_PR_QUANT_INTRO, - Z3_OP_PR_DISTRIBUTIVITY, - Z3_OP_PR_AND_ELIM, - Z3_OP_PR_NOT_OR_ELIM, - Z3_OP_PR_REWRITE, - Z3_OP_PR_REWRITE_STAR, - Z3_OP_PR_PULL_QUANT, - Z3_OP_PR_PULL_QUANT_STAR, - Z3_OP_PR_PUSH_QUANT, - Z3_OP_PR_ELIM_UNUSED_VARS, - Z3_OP_PR_DER, - Z3_OP_PR_QUANT_INST, - Z3_OP_PR_HYPOTHESIS, - Z3_OP_PR_LEMMA, - Z3_OP_PR_UNIT_RESOLUTION, - Z3_OP_PR_IFF_TRUE, - Z3_OP_PR_IFF_FALSE, - Z3_OP_PR_COMMUTATIVITY, - Z3_OP_PR_DEF_AXIOM, - Z3_OP_PR_DEF_INTRO, - Z3_OP_PR_APPLY_DEF, - Z3_OP_PR_IFF_OEQ, - Z3_OP_PR_NNF_POS, - Z3_OP_PR_NNF_NEG, - Z3_OP_PR_NNF_STAR, - Z3_OP_PR_CNF_STAR, - Z3_OP_PR_SKOLEMIZE, - Z3_OP_PR_MODUS_PONENS_OEQ, - Z3_OP_PR_TH_LEMMA, - Z3_OP_PR_HYPER_RESOLVE, - Z3_OP_RA_STORE, - Z3_OP_RA_EMPTY, - Z3_OP_RA_IS_EMPTY, - Z3_OP_RA_JOIN, - Z3_OP_RA_UNION, - Z3_OP_RA_WIDEN, - Z3_OP_RA_PROJECT, - Z3_OP_RA_FILTER, - Z3_OP_RA_NEGATION_FILTER, - Z3_OP_RA_RENAME, - Z3_OP_RA_COMPLEMENT, - Z3_OP_RA_SELECT, - Z3_OP_RA_CLONE, - Z3_OP_FD_LT, - Z3_OP_LABEL, - Z3_OP_LABEL_LIT, - Z3_OP_DT_CONSTRUCTOR, - Z3_OP_DT_RECOGNISER, - Z3_OP_DT_ACCESSOR, - Z3_OP_UNINTERPRETED, -}; - -void camlidl_ml2c_z3_Z3_decl_kind(value _v1, Z3_decl_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_6[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_decl_kind(Z3_decl_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_6, 152, "typedef Z3_decl_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3_enum_7[7] = { - Z3_PK_UINT, - Z3_PK_BOOL, - Z3_PK_DOUBLE, - Z3_PK_SYMBOL, - Z3_PK_STRING, - Z3_PK_OTHER, - Z3_PK_INVALID, -}; - -void camlidl_ml2c_z3_Z3_param_kind(value _v1, Z3_param_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_7[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_param_kind(Z3_param_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_7, 7, "typedef Z3_param_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3_enum_8[4] = { - Z3_PRINT_SMTLIB_FULL, - Z3_PRINT_LOW_LEVEL, - Z3_PRINT_SMTLIB_COMPLIANT, - Z3_PRINT_SMTLIB2_COMPLIANT, -}; - -void camlidl_ml2c_z3_Z3_ast_print_mode(value _v1, Z3_ast_print_mode * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_8[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_ast_print_mode(Z3_ast_print_mode * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_PRINT_SMTLIB_FULL: _v1 = Val_int(0); break; - case Z3_PRINT_LOW_LEVEL: _v1 = Val_int(1); break; - case Z3_PRINT_SMTLIB_COMPLIANT: _v1 = Val_int(2); break; - case Z3_PRINT_SMTLIB2_COMPLIANT: _v1 = Val_int(3); break; - default: invalid_argument("typedef Z3_ast_print_mode: bad enum value"); - } - return _v1; -} - -int camlidl_transl_table_z3_enum_9[13] = { - Z3_OK, - Z3_SORT_ERROR, - Z3_IOB, - Z3_INVALID_ARG, - Z3_PARSER_ERROR, - Z3_NO_PARSER, - Z3_INVALID_PATTERN, - Z3_MEMOUT_FAIL, - Z3_FILE_ACCESS_ERROR, - Z3_INTERNAL_FATAL, - Z3_INVALID_USAGE, - Z3_DEC_REF_ERROR, - Z3_EXCEPTION, -}; - -void camlidl_ml2c_z3_Z3_error_code(value _v1, Z3_error_code * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_9[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_error_code(Z3_error_code * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3_enum_9, 13, "typedef Z3_error_code: bad enum value"); - return _v1; -} - - -/* All contexts share the same handler */ -static value caml_z3_error_handler = 0; - - -value camlidl_c2ml_z3_Z3_error_code(Z3_error_code * _c2, camlidl_ctx _ctx); -/* Error checking routine that raises OCaml Error exceptions */ -void check_error_code (Z3_context c) -{ - static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - value* exn_tag = NULL; - value ctx_err[2]; - Z3_error_code e; - e = Z3_get_error_code(c); - if (e != Z3_OK) { - ctx_err[0] = c2ml_Z3_context(&c); - ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs); - exn_tag = caml_named_value("Z3.Error"); - if (*exn_tag == 0) { - fprintf(stderr, "Z3.Error not found"); - exit(1); - } - caml_raise_with_args(*exn_tag, 2, ctx_err); - } -} -/* Disable default error handler, all error checking is done by check_error_code */ -void* error_handler_static = NULL; - -int camlidl_transl_table_z3_enum_10[4] = { - Z3_GOAL_PRECISE, - Z3_GOAL_UNDER, - Z3_GOAL_OVER, - Z3_GOAL_UNDER_OVER, -}; - -void camlidl_ml2c_z3_Z3_goal_prec(value _v1, Z3_goal_prec * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3_enum_10[Int_val(_v1)]; -} - -value camlidl_c2ml_z3_Z3_goal_prec(Z3_goal_prec * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_GOAL_PRECISE: _v1 = Val_int(0); break; - case Z3_GOAL_UNDER: _v1 = Val_int(1); break; - case Z3_GOAL_OVER: _v1 = Val_int(2); break; - case Z3_GOAL_UNDER_OVER: _v1 = Val_int(3); break; - default: invalid_argument("typedef Z3_goal_prec: bad enum value"); - } - return _v1; -} - - -value caml_z3_mk_context(value key_val_list) -{ - CAMLparam1( key_val_list ); - CAMLlocal4( item, vkey, vval, _vres ); - char * ckey; - char * cval; - Z3_config cfg; - Z3_context _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - cfg = Z3_mk_config(); - while (key_val_list != Val_emptylist) - { - item = Field(key_val_list, 0); - vkey = Field(item, 0); - vval = Field(item, 1); - ckey = camlidl_malloc_string(vkey, _ctx); - cval = camlidl_malloc_string(vval, _ctx); - Z3_set_param_value(cfg, ckey, cval); - key_val_list = Field(key_val_list, 1); - } - _res = Z3_mk_context_rc(cfg); - Z3_del_config(cfg); - _vres = camlidl_c2ml_z3_Z3_context(&_res, _ctx); - camlidl_free(_ctx); - Z3_set_error_handler(_res, error_handler_static); - CAMLreturn(_vres); -} - -value camlidl_z3_Z3_update_param_value( - value _v_c, - value _v_param_id, - value _v_param_value) -{ - Z3_context c; /*in*/ - Z3_string param_id; /*in*/ - Z3_string param_value; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_param_id, ¶m_id, _ctx); - camlidl_ml2c_z3_Z3_string(_v_param_value, ¶m_value, _ctx); - Z3_update_param_value(c, param_id, param_value); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_get_param_value( - value _v_c, - value _v_param_id) -{ - Z3_context c; /*in*/ - Z3_string param_id; /*in*/ - Z3_string *param_value; /*out*/ - Z3_string _c1; - value _v2; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_param_id, ¶m_id, _ctx); - param_value = &_c1; - Z3_get_param_value(c, param_id, param_value); - if (param_value == NULL) { - _vres = Val_int(0); - } else { - _v2 = camlidl_c2ml_z3_Z3_string(&*param_value, _ctx); - Begin_root(_v2) - _vres = camlidl_alloc_small(1, 0); - Field(_vres, 0) = _v2; - End_roots(); - } - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_interrupt( - value _v_c) -{ - Z3_context c; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - Z3_interrupt(c); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_mk_params( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_params _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_params(c); - _vres = camlidl_c2ml_z3_Z3_params(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_params_set_bool( - value _v_c, - value _v_p, - value _v_k, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_params p; /*in*/ - Z3_symbol k; /*in*/ - int v; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_k, &k, _ctx); - v = Int_val(_v_v); - Z3_params_set_bool(c, p, k, v); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_params_set_uint( - value _v_c, - value _v_p, - value _v_k, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_params p; /*in*/ - Z3_symbol k; /*in*/ - unsigned int v; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_k, &k, _ctx); - v = Int_val(_v_v); - Z3_params_set_uint(c, p, k, v); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_params_set_double( - value _v_c, - value _v_p, - value _v_k, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_params p; /*in*/ - Z3_symbol k; /*in*/ - double v; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_k, &k, _ctx); - v = Double_val(_v_v); - Z3_params_set_double(c, p, k, v); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_params_set_symbol( - value _v_c, - value _v_p, - value _v_k, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_params p; /*in*/ - Z3_symbol k; /*in*/ - Z3_symbol v; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_k, &k, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_v, &v, _ctx); - Z3_params_set_symbol(c, p, k, v); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_params_to_string( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_params p; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - _res = Z3_params_to_string(c, p); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_params_validate( - value _v_c, - value _v_p, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_params p; /*in*/ - Z3_param_descrs d; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_param_descrs(_v_d, &d, _ctx); - Z3_params_validate(c, p, d); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_param_descrs_get_kind( - value _v_c, - value _v_p, - value _v_n) -{ - Z3_context c; /*in*/ - Z3_param_descrs p; /*in*/ - Z3_symbol n; /*in*/ - Z3_param_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_param_descrs(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_n, &n, _ctx); - _res = Z3_param_descrs_get_kind(c, p, n); - _vres = camlidl_c2ml_z3_Z3_param_kind(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_param_descrs_size( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_param_descrs p; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_param_descrs(_v_p, &p, _ctx); - _res = Z3_param_descrs_size(c, p); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_param_descrs_get_name( - value _v_c, - value _v_p, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_param_descrs p; /*in*/ - unsigned int i; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_param_descrs(_v_p, &p, _ctx); - i = Int_val(_v_i); - _res = Z3_param_descrs_get_name(c, p, i); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_param_descrs_to_string( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_param_descrs p; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_param_descrs(_v_p, &p, _ctx); - _res = Z3_param_descrs_to_string(c, p); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_int_symbol( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - int i; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_mk_int_symbol(c, i); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_string_symbol( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_string s; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_s, &s, _ctx); - _res = Z3_mk_string_symbol(c, s); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_uninterpreted_sort( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_mk_uninterpreted_sort(c, s); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bool_sort( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_bool_sort(c); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_int_sort( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_int_sort(c); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_real_sort( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_real_sort(c); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bv_sort( - value _v_c, - value _v_sz) -{ - Z3_context c; /*in*/ - unsigned int sz; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - sz = Int_val(_v_sz); - _res = Z3_mk_bv_sort(c, sz); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_finite_domain_sort( - value _v_c, - value _v_name, - value _v_size) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - unsigned long long size; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - size = Int64_val(_v_size); - _res = Z3_mk_finite_domain_sort(c, name, size); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_array_sort( - value _v_c, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_sort range; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_array_sort(c, domain, range); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_tuple_sort( - value _v_c, - value _v_mk_tuple_name, - value _v_field_names, - value _v_field_sorts) -{ - Z3_context c; /*in*/ - Z3_symbol mk_tuple_name; /*in*/ - unsigned int num_fields; /*in*/ - Z3_symbol const *field_names; /*in*/ - Z3_sort const *field_sorts; /*in*/ - Z3_func_decl *mk_tuple_decl; /*out*/ - Z3_func_decl *proj_decl; /*out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - Z3_func_decl _c7; - mlsize_t _c8; - value _v9; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_mk_tuple_name, &mk_tuple_name, _ctx); - _c1 = Wosize_val(_v_field_names); - field_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_field_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &field_names[_c2], _ctx); - } - num_fields = _c1; - _c4 = Wosize_val(_v_field_sorts); - field_sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_field_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &field_sorts[_c5], _ctx); - } - num_fields = _c4; - mk_tuple_decl = &_c7; - proj_decl = camlidl_malloc(num_fields * sizeof(Z3_func_decl ), _ctx); - _res = Z3_mk_tuple_sort(c, mk_tuple_name, num_fields, field_names, field_sorts, mk_tuple_decl, proj_decl); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_c2ml_z3_Z3_func_decl(&*mk_tuple_decl, _ctx); - _vres[2] = camlidl_alloc(num_fields, 0); - Begin_root(_vres[2]) - for (_c8 = 0; _c8 < num_fields; _c8++) { - _v9 = camlidl_c2ml_z3_Z3_func_decl(&proj_decl[_c8], _ctx); - modify(&Field(_vres[2], _c8), _v9); - } - End_roots() - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_mk_enumeration_sort( - value _v_c, - value _v_name, - value _v_enum_names) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - unsigned int n; /*in*/ - Z3_symbol const *enum_names; /*in*/ - Z3_func_decl *enum_consts; /*out*/ - Z3_func_decl *enum_testers; /*out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - value _v5; - mlsize_t _c6; - value _v7; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - _c1 = Wosize_val(_v_enum_names); - enum_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_enum_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &enum_names[_c2], _ctx); - } - n = _c1; - enum_consts = camlidl_malloc(n * sizeof(Z3_func_decl ), _ctx); - enum_testers = camlidl_malloc(n * sizeof(Z3_func_decl ), _ctx); - _res = Z3_mk_enumeration_sort(c, name, n, enum_names, enum_consts, enum_testers); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_alloc(n, 0); - Begin_root(_vres[1]) - for (_c4 = 0; _c4 < n; _c4++) { - _v5 = camlidl_c2ml_z3_Z3_func_decl(&enum_consts[_c4], _ctx); - modify(&Field(_vres[1], _c4), _v5); - } - End_roots() - _vres[2] = camlidl_alloc(n, 0); - Begin_root(_vres[2]) - for (_c6 = 0; _c6 < n; _c6++) { - _v7 = camlidl_c2ml_z3_Z3_func_decl(&enum_testers[_c6], _ctx); - modify(&Field(_vres[2], _c6), _v7); - } - End_roots() - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_mk_list_sort( - value _v_c, - value _v_name, - value _v_elem_sort) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - Z3_sort elem_sort; /*in*/ - Z3_func_decl *nil_decl; /*out*/ - Z3_func_decl *is_nil_decl; /*out*/ - Z3_func_decl *cons_decl; /*out*/ - Z3_func_decl *is_cons_decl; /*out*/ - Z3_func_decl *head_decl; /*out*/ - Z3_func_decl *tail_decl; /*out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_func_decl _c1; - Z3_func_decl _c2; - Z3_func_decl _c3; - Z3_func_decl _c4; - Z3_func_decl _c5; - Z3_func_decl _c6; - value _vresult; - value _vres[7] = { 0, 0, 0, 0, 0, 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_elem_sort, &elem_sort, _ctx); - nil_decl = &_c1; - is_nil_decl = &_c2; - cons_decl = &_c3; - is_cons_decl = &_c4; - head_decl = &_c5; - tail_decl = &_c6; - _res = Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl); - Begin_roots_block(_vres, 7) - _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_c2ml_z3_Z3_func_decl(&*nil_decl, _ctx); - _vres[2] = camlidl_c2ml_z3_Z3_func_decl(&*is_nil_decl, _ctx); - _vres[3] = camlidl_c2ml_z3_Z3_func_decl(&*cons_decl, _ctx); - _vres[4] = camlidl_c2ml_z3_Z3_func_decl(&*is_cons_decl, _ctx); - _vres[5] = camlidl_c2ml_z3_Z3_func_decl(&*head_decl, _ctx); - _vres[6] = camlidl_c2ml_z3_Z3_func_decl(&*tail_decl, _ctx); - _vresult = camlidl_alloc_small(7, 0); - { mlsize_t _c7; - for (_c7 = 0; _c7 < 7; _c7++) Field(_vresult, _c7) = _vres[_c7]; - } - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_mk_constructor( - value _v_c, - value _v_name, - value _v_recognizer, - value _v_field_names, - value _v_sorts, - value _v_sort_refs) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - Z3_symbol recognizer; /*in*/ - unsigned int num_fields; /*in*/ - Z3_symbol const *field_names; /*in*/ - Z3_sort_opt const *sorts; /*in*/ - unsigned int *sort_refs; /*in*/ - Z3_constructor _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_recognizer, &recognizer, _ctx); - _c1 = Wosize_val(_v_field_names); - field_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_field_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &field_names[_c2], _ctx); - } - num_fields = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort_opt const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort_opt(_v6, &sorts[_c5], _ctx); - } - num_fields = _c4; - _c7 = Wosize_val(_v_sort_refs); - sort_refs = camlidl_malloc(_c7 * sizeof(unsigned int ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_sort_refs, _c8); - sort_refs[_c8] = Int_val(_v9); - } - num_fields = _c7; - _res = Z3_mk_constructor(c, name, recognizer, num_fields, field_names, sorts, sort_refs); - _vres = camlidl_c2ml_z3_Z3_constructor(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_constructor_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_constructor(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_del_constructor( - value _v_c, - value _v_constr) -{ - Z3_context c; /*in*/ - Z3_constructor constr; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_constructor(_v_constr, &constr, _ctx); - Z3_del_constructor(c, constr); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_mk_datatype( - value _v_c, - value _v_name, - value _v_constructors) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - unsigned int num_constructors; /*in*/ - Z3_constructor *constructors; /*in,out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - value _v5; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - _c1 = Wosize_val(_v_constructors); - constructors = camlidl_malloc(_c1 * sizeof(Z3_constructor ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_constructors, _c2); - camlidl_ml2c_z3_Z3_constructor(_v3, &constructors[_c2], _ctx); - } - num_constructors = _c1; - _res = Z3_mk_datatype(c, name, num_constructors, constructors); - Begin_roots_block(_vres, 2) - _vres[0] = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_alloc(num_constructors, 0); - Begin_root(_vres[1]) - for (_c4 = 0; _c4 < num_constructors; _c4++) { - _v5 = camlidl_c2ml_z3_Z3_constructor(&constructors[_c4], _ctx); - modify(&Field(_vres[1], _c4), _v5); - } - End_roots() - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_mk_constructor_list( - value _v_c, - value _v_constructors) -{ - Z3_context c; /*in*/ - unsigned int num_constructors; /*in*/ - Z3_constructor const *constructors; /*in*/ - Z3_constructor_list _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_constructors); - constructors = camlidl_malloc(_c1 * sizeof(Z3_constructor const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_constructors, _c2); - camlidl_ml2c_z3_Z3_constructor(_v3, &constructors[_c2], _ctx); - } - num_constructors = _c1; - _res = Z3_mk_constructor_list(c, num_constructors, constructors); - _vres = camlidl_c2ml_z3_Z3_constructor_list(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_del_constructor_list( - value _v_c, - value _v_clist) -{ - Z3_context c; /*in*/ - Z3_constructor_list clist; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_constructor_list(_v_clist, &clist, _ctx); - Z3_del_constructor_list(c, clist); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_mk_datatypes( - value _v_c, - value _v_sort_names, - value _v_constructor_lists) -{ - Z3_context c; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort *sorts; /*out*/ - Z3_constructor_list *constructor_lists; /*in,out*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - value _v8; - mlsize_t _c9; - value _v10; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_constructor_lists); - constructor_lists = camlidl_malloc(_c4 * sizeof(Z3_constructor_list ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_constructor_lists, _c5); - camlidl_ml2c_z3_Z3_constructor_list(_v6, &constructor_lists[_c5], _ctx); - } - num_sorts = _c4; - sorts = camlidl_malloc(num_sorts * sizeof(Z3_sort ), _ctx); - Z3_mk_datatypes(c, num_sorts, sort_names, sorts, constructor_lists); - Begin_roots_block(_vres, 2) - _vres[0] = camlidl_alloc(num_sorts, 0); - Begin_root(_vres[0]) - for (_c7 = 0; _c7 < num_sorts; _c7++) { - _v8 = camlidl_c2ml_z3_Z3_sort(&sorts[_c7], _ctx); - modify(&Field(_vres[0], _c7), _v8); - } - End_roots() - _vres[1] = camlidl_alloc(num_sorts, 0); - Begin_root(_vres[1]) - for (_c9 = 0; _c9 < num_sorts; _c9++) { - _v10 = camlidl_c2ml_z3_Z3_constructor_list(&constructor_lists[_c9], _ctx); - modify(&Field(_vres[1], _c9), _v10); - } - End_roots() - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_query_constructor( - value _v_c, - value _v_constr, - value _v_num_fields) -{ - Z3_context c; /*in*/ - Z3_constructor constr; /*in*/ - unsigned int num_fields; /*in*/ - Z3_func_decl *constructor; /*out*/ - Z3_func_decl *tester; /*out*/ - Z3_func_decl *accessors; /*out*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_func_decl _c1; - Z3_func_decl _c2; - mlsize_t _c3; - value _v4; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_constructor(_v_constr, &constr, _ctx); - num_fields = Int_val(_v_num_fields); - constructor = &_c1; - tester = &_c2; - accessors = camlidl_malloc(num_fields * sizeof(Z3_func_decl ), _ctx); - Z3_query_constructor(c, constr, num_fields, constructor, tester, accessors); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_c2ml_z3_Z3_func_decl(&*constructor, _ctx); - _vres[1] = camlidl_c2ml_z3_Z3_func_decl(&*tester, _ctx); - _vres[2] = camlidl_alloc(num_fields, 0); - Begin_root(_vres[2]) - for (_c3 = 0; _c3 < num_fields; _c3++) { - _v4 = camlidl_c2ml_z3_Z3_func_decl(&accessors[_c3], _ctx); - modify(&Field(_vres[2], _c3), _v4); - } - End_roots() - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_mk_func_decl( - value _v_c, - value _v_s, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - unsigned int domain_size; /*in*/ - Z3_sort const *domain; /*in*/ - Z3_sort range; /*in*/ - Z3_func_decl _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx); - _c1 = Wosize_val(_v_domain); - domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_domain, _c2); - camlidl_ml2c_z3_Z3_sort(_v3, &domain[_c2], _ctx); - } - domain_size = _c1; - camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_func_decl(c, s, domain_size, domain, range); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_app( - value _v_c, - value _v_d, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_app(c, d, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_const( - value _v_c, - value _v_s, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_const(c, s, ty); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_fresh_func_decl( - value _v_c, - value _v_prefix, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_string prefix; /*in*/ - unsigned int domain_size; /*in*/ - Z3_sort const *domain; /*in*/ - Z3_sort range; /*in*/ - Z3_func_decl _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_prefix, &prefix, _ctx); - _c1 = Wosize_val(_v_domain); - domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_domain, _c2); - camlidl_ml2c_z3_Z3_sort(_v3, &domain[_c2], _ctx); - } - domain_size = _c1; - camlidl_ml2c_z3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_fresh_func_decl(c, prefix, domain_size, domain, range); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_fresh_const( - value _v_c, - value _v_prefix, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_string prefix; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_prefix, &prefix, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_fresh_const(c, prefix, ty); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_true( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_true(c); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_false( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_false(c); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_eq( - value _v_c, - value _v_l, - value _v_r) -{ - Z3_context c; /*in*/ - Z3_ast l; /*in*/ - Z3_ast r; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_l, &l, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_r, &r, _ctx); - _res = Z3_mk_eq(c, l, r); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_distinct( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_distinct(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_not( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_mk_not(c, a); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_ite( - value _v_c, - value _v_t1, - value _v_t2, - value _v_t3) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast t3; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t3, &t3, _ctx); - _res = Z3_mk_ite(c, t1, t2, t3); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_iff( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_iff(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_implies( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_implies(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_xor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_xor(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_and( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_and(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_or( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_or(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_add( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_add(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_mul( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_mul(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_sub( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_sub(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_unary_minus( - value _v_c, - value _v_arg) -{ - Z3_context c; /*in*/ - Z3_ast arg; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg, &arg, _ctx); - _res = Z3_mk_unary_minus(c, arg); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_div( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_div(c, arg1, arg2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_mod( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_mod(c, arg1, arg2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_rem( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_rem(c, arg1, arg2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_power( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_power(c, arg1, arg2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_lt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_lt(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_le( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_le(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_gt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_gt(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_ge( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_ge(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_int2real( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_int2real(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_real2int( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_real2int(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_is_int( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_is_int(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvnot( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvnot(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvredand( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvredand(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvredor( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvredor(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvand( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvand(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvor(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvxor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvxor(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvnand( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvnand(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvnor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvnor(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvxnor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvxnor(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvneg( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvneg(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvadd( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvadd(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsub( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsub(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvmul( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvmul(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvudiv( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvudiv(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsdiv( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsdiv(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvurem( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvurem(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsrem( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsrem(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsmod( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsmod(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvult( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvult(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvslt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvslt(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvule( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvule(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsle( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsle(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvuge( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvuge(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsge( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsge(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvugt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvugt(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsgt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsgt(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_concat( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_concat(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_extract( - value _v_c, - value _v_high, - value _v_low, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int high; /*in*/ - unsigned int low; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - high = Int_val(_v_high); - low = Int_val(_v_low); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_extract(c, high, low, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_sign_ext( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_sign_ext(c, i, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_zero_ext( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_zero_ext(c, i, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_repeat( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_repeat(c, i, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvshl( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvshl(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvlshr( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvlshr(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvashr( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvashr(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_rotate_left( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_rotate_left(c, i, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_rotate_right( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_rotate_right(c, i, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_ext_rotate_left( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_ext_rotate_left(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_ext_rotate_right( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_ext_rotate_right(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_int2bv( - value _v_c, - value _v_n, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int n; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - n = Int_val(_v_n); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_int2bv(c, n, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bv2int( - value _v_c, - value _v_t1, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bv2int(c, t1, is_signed); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvadd_no_overflow( - value _v_c, - value _v_t1, - value _v_t2, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bvadd_no_overflow(c, t1, t2, is_signed); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvadd_no_underflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvadd_no_underflow(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsub_no_overflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsub_no_overflow(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsub_no_underflow( - value _v_c, - value _v_t1, - value _v_t2, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bvsub_no_underflow(c, t1, t2, is_signed); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvsdiv_no_overflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsdiv_no_overflow(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvneg_no_overflow( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvneg_no_overflow(c, t1); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvmul_no_overflow( - value _v_c, - value _v_t1, - value _v_t2, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bvmul_no_overflow(c, t1, t2, is_signed); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bvmul_no_underflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvmul_no_underflow(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_select( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_i, &i, _ctx); - _res = Z3_mk_select(c, a, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_store( - value _v_c, - value _v_a, - value _v_i, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast i; /*in*/ - Z3_ast v; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_i, &i, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx); - _res = Z3_mk_store(c, a, i, v); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_const_array( - value _v_c, - value _v_domain, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_ast v; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx); - _res = Z3_mk_const_array(c, domain, v); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_map( - value _v_c, - value _v_f, - value _v_n, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_func_decl f; /*in*/ - unsigned int n; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - Z3_ast _c1; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx); - n = Int_val(_v_n); - args = &_c1; - camlidl_ml2c_z3_Z3_ast(_v_args, &_c1, _ctx); - _res = Z3_mk_map(c, f, n, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_array_default( - value _v_c, - value _v_array) -{ - Z3_context c; /*in*/ - Z3_ast array; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_array, &array, _ctx); - _res = Z3_mk_array_default(c, array); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_sort( - value _v_c, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_sort ty; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_set_sort(c, ty); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_empty_set( - value _v_c, - value _v_domain) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx); - _res = Z3_mk_empty_set(c, domain); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_full_set( - value _v_c, - value _v_domain) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_domain, &domain, _ctx); - _res = Z3_mk_full_set(c, domain); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_add( - value _v_c, - value _v_set, - value _v_elem) -{ - Z3_context c; /*in*/ - Z3_ast set; /*in*/ - Z3_ast elem; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_set, &set, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_elem, &elem, _ctx); - _res = Z3_mk_set_add(c, set, elem); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_del( - value _v_c, - value _v_set, - value _v_elem) -{ - Z3_context c; /*in*/ - Z3_ast set; /*in*/ - Z3_ast elem; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_set, &set, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_elem, &elem, _ctx); - _res = Z3_mk_set_del(c, set, elem); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_union( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_set_union(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_intersect( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_set_intersect(c, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_difference( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_set_difference(c, arg1, arg2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_complement( - value _v_c, - value _v_arg) -{ - Z3_context c; /*in*/ - Z3_ast arg; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg, &arg, _ctx); - _res = Z3_mk_set_complement(c, arg); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_member( - value _v_c, - value _v_elem, - value _v_set) -{ - Z3_context c; /*in*/ - Z3_ast elem; /*in*/ - Z3_ast set; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_elem, &elem, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_set, &set, _ctx); - _res = Z3_mk_set_member(c, elem, set); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_set_subset( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_set_subset(c, arg1, arg2); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_numeral( - value _v_c, - value _v_numeral, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_string numeral; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_numeral, &numeral, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_numeral(c, numeral, ty); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_real( - value _v_c, - value _v_num, - value _v_den) -{ - Z3_context c; /*in*/ - int num; /*in*/ - int den; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - num = Int_val(_v_num); - den = Int_val(_v_den); - _res = Z3_mk_real(c, num, den); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_int( - value _v_c, - value _v_v, - value _v_ty) -{ - Z3_context c; /*in*/ - int v; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - v = Int_val(_v_v); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_int(c, v, ty); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_int64( - value _v_c, - value _v_v, - value _v_ty) -{ - Z3_context c; /*in*/ - long long v; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - v = Int64_val(_v_v); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_int64(c, v, ty); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_pattern( - value _v_c, - value _v_terms) -{ - Z3_context c; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_ast const *terms; /*in*/ - Z3_pattern _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_terms); - terms = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_terms, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &terms[_c2], _ctx); - } - num_patterns = _c1; - _res = Z3_mk_pattern(c, num_patterns, terms); - _vres = camlidl_c2ml_z3_Z3_pattern(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_bound( - value _v_c, - value _v_index, - value _v_ty) -{ - Z3_context c; /*in*/ - unsigned int index; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - index = Int_val(_v_index); - camlidl_ml2c_z3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_bound(c, index, ty); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_forall( - value _v_c, - value _v_weight, - value _v_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_decls = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_forall(c, weight, num_patterns, patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_forall_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_forall(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_mk_exists( - value _v_c, - value _v_weight, - value _v_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_decls = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_exists(c, weight, num_patterns, patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_exists_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_exists(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_mk_quantifier( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_decls = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier(c, is_forall, weight, num_patterns, patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_quantifier_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_quantifier(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); -} - -value camlidl_z3_Z3_mk_quantifier_ex( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_quantifier_id, - value _v_skolem_id, - value _v_patterns, - value _v_no_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - Z3_symbol quantifier_id; /*in*/ - Z3_symbol skolem_id; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_no_patterns; /*in*/ - Z3_ast const *no_patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - camlidl_ml2c_z3_Z3_symbol(_v_quantifier_id, &quantifier_id, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_skolem_id, &skolem_id, _ctx); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_no_patterns); - no_patterns = camlidl_malloc(_c4 * sizeof(Z3_ast const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_no_patterns, _c5); - camlidl_ml2c_z3_Z3_ast(_v6, &no_patterns[_c5], _ctx); - } - num_no_patterns = _c4; - _c7 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c7 * sizeof(Z3_sort const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_sorts, _c8); - camlidl_ml2c_z3_Z3_sort(_v9, &sorts[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c10 * sizeof(Z3_symbol const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decl_names, _c11); - camlidl_ml2c_z3_Z3_symbol(_v12, &decl_names[_c11], _ctx); - } - num_decls = _c10; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns, num_no_patterns, no_patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_quantifier_ex_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_quantifier_ex(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); -} - -value camlidl_z3_Z3_mk_forall_const( - value _v_c, - value _v_weight, - value _v_bound, - value _v_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_forall_const(c, weight, num_bound, bound, num_patterns, patterns, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_exists_const( - value _v_c, - value _v_weight, - value _v_bound, - value _v_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_exists_const(c, weight, num_bound, bound, num_patterns, patterns, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_quantifier_const( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_bound, - value _v_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier_const(c, is_forall, weight, num_bound, bound, num_patterns, patterns, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_quantifier_const_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_quantifier_const(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_mk_quantifier_const_ex( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_quantifier_id, - value _v_skolem_id, - value _v_bound, - value _v_patterns, - value _v_no_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - Z3_symbol quantifier_id; /*in*/ - Z3_symbol skolem_id; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_no_patterns; /*in*/ - Z3_ast const *no_patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - camlidl_ml2c_z3_Z3_symbol(_v_quantifier_id, &quantifier_id, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_skolem_id, &skolem_id, _ctx); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - _c7 = Wosize_val(_v_no_patterns); - no_patterns = camlidl_malloc(_c7 * sizeof(Z3_ast const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_no_patterns, _c8); - camlidl_ml2c_z3_Z3_ast(_v9, &no_patterns[_c8], _ctx); - } - num_no_patterns = _c7; - camlidl_ml2c_z3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier_const_ex(c, is_forall, weight, quantifier_id, skolem_id, num_bound, bound, num_patterns, patterns, num_no_patterns, no_patterns, body); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_quantifier_const_ex_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_mk_quantifier_const_ex(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]); -} - -value camlidl_z3_Z3_get_symbol_kind( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_symbol_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_get_symbol_kind(c, s); - _vres = camlidl_c2ml_z3_Z3_symbol_kind(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_symbol_int( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_get_symbol_int(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_symbol_string( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_get_symbol_string(c, s); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_sort_name( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_sort d; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_d, &d, _ctx); - _res = Z3_get_sort_name(c, d); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_sort_id( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_get_sort_id(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_sort_to_ast( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_sort_to_ast(c, s); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_eq_sort( - value _v_c, - value _v_s1, - value _v_s2) -{ - Z3_context c; /*in*/ - Z3_sort s1; /*in*/ - Z3_sort s2; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s1, &s1, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s2, &s2, _ctx); - _res = Z3_is_eq_sort(c, s1, s2); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_sort_kind( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_sort_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_sort_kind(c, t); - _vres = camlidl_c2ml_z3_Z3_sort_kind(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_bv_sort_size( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_bv_sort_size(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_finite_domain_sort_size( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned long long *r; /*out*/ - unsigned long long _c1; - value _v2; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - r = &_c1; - Z3_get_finite_domain_sort_size(c, s, r); - if (r == NULL) { - _vres = Val_int(0); - } else { - _v2 = copy_int64(*r); - Begin_root(_v2) - _vres = camlidl_alloc_small(1, 0); - Field(_vres, 0) = _v2; - End_roots(); - } - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_array_sort_domain( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_array_sort_domain(c, t); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_array_sort_range( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_array_sort_range(c, t); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_tuple_sort_mk_decl( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_tuple_sort_mk_decl(c, t); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_tuple_sort_num_fields( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_tuple_sort_num_fields(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_tuple_sort_field_decl( - value _v_c, - value _v_t, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - i = Int_val(_v_i); - _res = Z3_get_tuple_sort_field_decl(c, t, i); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_datatype_sort_num_constructors( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_datatype_sort_num_constructors(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_datatype_sort_constructor( - value _v_c, - value _v_t, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int idx; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_datatype_sort_constructor(c, t, idx); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_datatype_sort_recognizer( - value _v_c, - value _v_t, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int idx; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_datatype_sort_recognizer(c, t, idx); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_datatype_sort_constructor_accessor( - value _v_c, - value _v_t, - value _v_idx_c, - value _v_idx_a) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int idx_c; /*in*/ - unsigned int idx_a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_t, &t, _ctx); - idx_c = Int_val(_v_idx_c); - idx_a = Int_val(_v_idx_a); - _res = Z3_get_datatype_sort_constructor_accessor(c, t, idx_c, idx_a); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_relation_arity( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_get_relation_arity(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_relation_column( - value _v_c, - value _v_s, - value _v_col) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned int col; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - col = Int_val(_v_col); - _res = Z3_get_relation_column(c, s, col); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_decl_to_ast( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_decl f; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx); - _res = Z3_func_decl_to_ast(c, f); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_eq_func_decl( - value _v_c, - value _v_f1, - value _v_f2) -{ - Z3_context c; /*in*/ - Z3_func_decl f1; /*in*/ - Z3_func_decl f2; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f1, &f1, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f2, &f2, _ctx); - _res = Z3_is_eq_func_decl(c, f1, f2); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_func_decl_id( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_decl f; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx); - _res = Z3_get_func_decl_id(c, f); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_name( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_decl_name(c, d); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_kind( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_decl_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_decl_kind(c, d); - _vres = camlidl_c2ml_z3_Z3_decl_kind(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_domain_size( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_domain_size(c, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_arity( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_arity(c, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_domain( - value _v_c, - value _v_d, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - i = Int_val(_v_i); - _res = Z3_get_domain(c, d, i); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_range( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_range(c, d); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_num_parameters( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_decl_num_parameters(c, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_parameter_kind( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_parameter_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_parameter_kind(c, d, idx); - _vres = camlidl_c2ml_z3_Z3_parameter_kind(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_int_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_int_parameter(c, d, idx); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_double_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - double _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_double_parameter(c, d, idx); - _vres = copy_double(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_symbol_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_symbol_parameter(c, d, idx); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_sort_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_sort_parameter(c, d, idx); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_ast_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_ast_parameter(c, d, idx); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_func_decl_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_func_decl_parameter(c, d, idx); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_decl_rational_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_rational_parameter(c, d, idx); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_app_to_ast( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx); - _res = Z3_app_to_ast(c, a); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_app_decl( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx); - _res = Z3_get_app_decl(c, a); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_app_num_args( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx); - _res = Z3_get_app_num_args(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_app_arg( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_app(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_app_arg(c, a, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_eq_ast( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_is_eq_ast(c, t1, t2); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_ast_id( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_ast t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t, &t, _ctx); - _res = Z3_get_ast_id(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_ast_hash( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_ast_hash(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_sort( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_sort(c, a); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_well_sorted( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_ast t; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t, &t, _ctx); - _res = Z3_is_well_sorted(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_bool_value( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_lbool _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_bool_value(c, a); - _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_ast_kind( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_ast_kind(c, a); - _vres = camlidl_c2ml_z3_Z3_ast_kind(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_app( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_app(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_numeral_ast( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_numeral_ast(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_algebraic_number( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_algebraic_number(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_to_app( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_app _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_to_app(c, a); - _vres = camlidl_c2ml_z3_Z3_app(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_to_func_decl( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_to_func_decl(c, a); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_numeral_string( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_numeral_string(c, a); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_numeral_decimal_string( - value _v_c, - value _v_a, - value _v_precision) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int precision; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - precision = Int_val(_v_precision); - _res = Z3_get_numeral_decimal_string(c, a, precision); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_numerator( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_numerator(c, a); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_denominator( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_denominator(c, a); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_numeral_small( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - long long *num; /*out*/ - long long *den; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - long long _c1; - long long _c2; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - num = &_c1; - den = &_c2; - _res = Z3_get_numeral_small(c, a, num, den); - Begin_roots_block(_vres, 3) - _vres[0] = Val_int(_res); - _vres[1] = copy_int64(*num); - _vres[2] = copy_int64(*den); - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_get_numeral_int( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast v; /*in*/ - int *i; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - int _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx); - i = &_c1; - _res = Z3_get_numeral_int(c, v, i); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = Val_int(*i); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_get_numeral_int64( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast v; /*in*/ - long long *i; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - long long _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx); - i = &_c1; - _res = Z3_get_numeral_int64(c, v, i); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = copy_int64(*i); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_get_numeral_rational_int64( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast v; /*in*/ - long long *num; /*out*/ - long long *den; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - long long _c1; - long long _c2; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx); - num = &_c1; - den = &_c2; - _res = Z3_get_numeral_rational_int64(c, v, num, den); - Begin_roots_block(_vres, 3) - _vres[0] = Val_int(_res); - _vres[1] = copy_int64(*num); - _vres[2] = copy_int64(*den); - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -value camlidl_z3_Z3_get_algebraic_number_lower( - value _v_c, - value _v_a, - value _v_precision) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int precision; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - precision = Int_val(_v_precision); - _res = Z3_get_algebraic_number_lower(c, a, precision); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_algebraic_number_upper( - value _v_c, - value _v_a, - value _v_precision) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int precision; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - precision = Int_val(_v_precision); - _res = Z3_get_algebraic_number_upper(c, a, precision); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_pattern_to_ast( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx); - _res = Z3_pattern_to_ast(c, p); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_pattern_num_terms( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx); - _res = Z3_get_pattern_num_terms(c, p); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_pattern( - value _v_c, - value _v_p, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - unsigned int idx; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_pattern(c, p, idx); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_index_value( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_index_value(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_quantifier_forall( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_quantifier_forall(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_weight( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_weight(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_num_patterns( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_num_patterns(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_pattern_ast( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_pattern _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_pattern_ast(c, a, i); - _vres = camlidl_c2ml_z3_Z3_pattern(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_num_no_patterns( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_num_no_patterns(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_no_pattern_ast( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_no_pattern_ast(c, a, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_num_bound( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_num_bound(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_bound_name( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_bound_name(c, a, i); - _vres = camlidl_c2ml_z3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_bound_sort( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_bound_sort(c, a, i); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_quantifier_body( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_body(c, a); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_simplify( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_simplify(c, a); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_simplify_ex( - value _v_c, - value _v_a, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_params p; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - _res = Z3_simplify_ex(c, a, p); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_simplify_get_help( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_simplify_get_help(c); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_simplify_get_param_descrs( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_param_descrs _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_simplify_get_param_descrs(c); - _vres = camlidl_c2ml_z3_Z3_param_descrs(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_update_term( - value _v_c, - value _v_a, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_update_term(c, a, num_args, args); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_substitute( - value _v_c, - value _v_a, - value _v_from, - value _v_to) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_exprs; /*in*/ - Z3_ast const *from; /*in*/ - Z3_ast const *to; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _c1 = Wosize_val(_v_from); - from = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_from, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &from[_c2], _ctx); - } - num_exprs = _c1; - _c4 = Wosize_val(_v_to); - to = camlidl_malloc(_c4 * sizeof(Z3_ast const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_to, _c5); - camlidl_ml2c_z3_Z3_ast(_v6, &to[_c5], _ctx); - } - num_exprs = _c4; - _res = Z3_substitute(c, a, num_exprs, from, to); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_substitute_vars( - value _v_c, - value _v_a, - value _v_to) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_exprs; /*in*/ - Z3_ast const *to; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _c1 = Wosize_val(_v_to); - to = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_to, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &to[_c2], _ctx); - } - num_exprs = _c1; - _res = Z3_substitute_vars(c, a, num_exprs, to); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_translate( - value _v_source, - value _v_a, - value _v_target) -{ - Z3_context source; /*in*/ - Z3_ast a; /*in*/ - Z3_context target; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_source, &source, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3_Z3_context(_v_target, &target, _ctx); - _res = Z3_translate(source, a, target); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(source); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_eval( - value _v_c, - value _v_m, - value _v_t, - value _v_model_completion) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_ast t; /*in*/ - int model_completion; /*in*/ - Z3_ast *v; /*out*/ - Z3_ast _c1; - value _v2; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_t, &t, _ctx); - model_completion = Int_val(_v_model_completion); - v = &_c1; - Z3_model_eval(c, m, t, model_completion, v); - if (v == NULL) { - _vres = Val_int(0); - } else { - _v2 = camlidl_c2ml_z3_Z3_ast(&*v, _ctx); - Begin_root(_v2) - _vres = camlidl_alloc_small(1, 0); - Field(_vres, 0) = _v2; - End_roots(); - } - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_const_interp( - value _v_c, - value _v_m, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_func_decl a; /*in*/ - Z3_ast_opt _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_a, &a, _ctx); - _res = Z3_model_get_const_interp(c, m, a); - _vres = camlidl_c2ml_z3_Z3_ast_opt(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_func_interp( - value _v_c, - value _v_m, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_func_decl f; /*in*/ - Z3_func_interp_opt _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx); - _res = Z3_model_get_func_interp(c, m, f); - _vres = camlidl_c2ml_z3_Z3_func_interp_opt(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_num_consts( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - _res = Z3_model_get_num_consts(c, m); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_const_decl( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_model_get_const_decl(c, m, i); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_num_funcs( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - _res = Z3_model_get_num_funcs(c, m); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_func_decl( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_model_get_func_decl(c, m, i); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_num_sorts( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - _res = Z3_model_get_num_sorts(c, m); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_sort( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_model_get_sort(c, m, i); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_get_sort_universe( - value _v_c, - value _v_m, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_sort s; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_model_get_sort_universe(c, m, s); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_is_as_array( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_as_array(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_as_array_func_decl( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_as_array_func_decl(c, a); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_interp_get_num_entries( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_interp f; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_interp(_v_f, &f, _ctx); - _res = Z3_func_interp_get_num_entries(c, f); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_interp_get_entry( - value _v_c, - value _v_f, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_func_interp f; /*in*/ - unsigned int i; /*in*/ - Z3_func_entry _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_interp(_v_f, &f, _ctx); - i = Int_val(_v_i); - _res = Z3_func_interp_get_entry(c, f, i); - _vres = camlidl_c2ml_z3_Z3_func_entry(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_interp_get_else( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_interp f; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_interp(_v_f, &f, _ctx); - _res = Z3_func_interp_get_else(c, f); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_interp_get_arity( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_interp f; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_interp(_v_f, &f, _ctx); - _res = Z3_func_interp_get_arity(c, f); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_entry_get_value( - value _v_c, - value _v_e) -{ - Z3_context c; /*in*/ - Z3_func_entry e; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_entry(_v_e, &e, _ctx); - _res = Z3_func_entry_get_value(c, e); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_entry_get_num_args( - value _v_c, - value _v_e) -{ - Z3_context c; /*in*/ - Z3_func_entry e; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_entry(_v_e, &e, _ctx); - _res = Z3_func_entry_get_num_args(c, e); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_entry_get_arg( - value _v_c, - value _v_e, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_func_entry e; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_entry(_v_e, &e, _ctx); - i = Int_val(_v_i); - _res = Z3_func_entry_get_arg(c, e, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_open_log( - value _v_filename) -{ - Z3_string filename; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_string(_v_filename, &filename, _ctx); - _res = Z3_open_log(filename); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3_Z3_append_log( - value _v_string) -{ - Z3_string string; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_string(_v_string, &string, _ctx); - Z3_append_log(string); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3_Z3_close_log(value _unit) -{ - Z3_close_log(); - return Val_unit; -} - -value camlidl_z3_Z3_toggle_warning_messages( - value _v_enabled) -{ - int enabled; /*in*/ - enabled = Int_val(_v_enabled); - Z3_toggle_warning_messages(enabled); - return Val_unit; -} - -value camlidl_z3_Z3_set_ast_print_mode( - value _v_c, - value _v_mode) -{ - Z3_context c; /*in*/ - Z3_ast_print_mode mode; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_print_mode(_v_mode, &mode, _ctx); - Z3_set_ast_print_mode(c, mode); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_to_string( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_ast_to_string(c, a); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_pattern_to_string( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_pattern(_v_p, &p, _ctx); - _res = Z3_pattern_to_string(c, p); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_sort_to_string( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_sort_to_string(c, s); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_func_decl_to_string( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_func_decl_to_string(c, d); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_model_to_string( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - _res = Z3_model_to_string(c, m); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_benchmark_to_smtlib_string( - value _v_c, - value _v_name, - value _v_logic, - value _v_status, - value _v_attributes, - value _v_assumptions, - value _v_formula) -{ - Z3_context c; /*in*/ - Z3_string name; /*in*/ - Z3_string logic; /*in*/ - Z3_string status; /*in*/ - Z3_string attributes; /*in*/ - unsigned int num_assumptions; /*in*/ - Z3_ast const *assumptions; /*in*/ - Z3_ast formula; /*in*/ - Z3_string _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_name, &name, _ctx); - camlidl_ml2c_z3_Z3_string(_v_logic, &logic, _ctx); - camlidl_ml2c_z3_Z3_string(_v_status, &status, _ctx); - camlidl_ml2c_z3_Z3_string(_v_attributes, &attributes, _ctx); - _c1 = Wosize_val(_v_assumptions); - assumptions = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_assumptions, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &assumptions[_c2], _ctx); - } - num_assumptions = _c1; - camlidl_ml2c_z3_Z3_ast(_v_formula, &formula, _ctx); - _res = Z3_benchmark_to_smtlib_string(c, name, logic, status, attributes, num_assumptions, assumptions, formula); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_benchmark_to_smtlib_string_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_benchmark_to_smtlib_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); -} - -value camlidl_z3_Z3_parse_smtlib2_string( - value _v_c, - value _v_str, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string str; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_str, &str, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - _res = Z3_parse_smtlib2_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_parse_smtlib2_string_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_parse_smtlib2_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_parse_smtlib2_file( - value _v_c, - value _v_file_name, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string file_name; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_file_name, &file_name, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - _res = Z3_parse_smtlib2_file(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_parse_smtlib2_file_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_parse_smtlib2_file(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_parse_smtlib_string( - value _v_c, - value _v_str, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string str; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_str, &str, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_parse_smtlib_string_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_parse_smtlib_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_parse_smtlib_file( - value _v_c, - value _v_file_name, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string file_name; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_file_name, &file_name, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_parse_smtlib_file_bytecode(value * argv, int argn) -{ - return camlidl_z3_Z3_parse_smtlib_file(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3_Z3_get_smtlib_num_formulas( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_formulas(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_formula( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_formula(c, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_num_assumptions( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_assumptions(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_assumption( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_assumption(c, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_num_decls( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_decls(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_decl( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_decl(c, i); - _vres = camlidl_c2ml_z3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_num_sorts( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_sorts(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_sort( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_sort(c, i); - _vres = camlidl_c2ml_z3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_smtlib_error( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_error(c); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_set_error( - value _v_c, - value _v_e) -{ - Z3_context c; /*in*/ - Z3_error_code e; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_error_code(_v_e, &e, _ctx); - Z3_set_error(c, e); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_get_error_msg_ex( - value _v_c, - value _v_err) -{ - Z3_context c; /*in*/ - Z3_error_code err; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_error_code(_v_err, &err, _ctx); - _res = Z3_get_error_msg_ex(c, err); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_version(value _unit) -{ - unsigned int *major; /*out*/ - unsigned int *minor; /*out*/ - unsigned int *build_number; /*out*/ - unsigned int *revision_number; /*out*/ - unsigned int _c1; - unsigned int _c2; - unsigned int _c3; - unsigned int _c4; - value _vresult; - value _vres[4] = { 0, 0, 0, 0, }; - - major = &_c1; - minor = &_c2; - build_number = &_c3; - revision_number = &_c4; - Z3_get_version(major, minor, build_number, revision_number); - Begin_roots_block(_vres, 4) - _vres[0] = Val_int(*major); - _vres[1] = Val_int(*minor); - _vres[2] = Val_int(*build_number); - _vres[3] = Val_int(*revision_number); - _vresult = camlidl_alloc_small(4, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - Field(_vresult, 3) = _vres[3]; - End_roots() - return _vresult; -} - -value camlidl_z3_Z3_enable_trace( - value _v_tag) -{ - Z3_string tag; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_string(_v_tag, &tag, _ctx); - Z3_enable_trace(tag); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3_Z3_disable_trace( - value _v_tag) -{ - Z3_string tag; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_string(_v_tag, &tag, _ctx); - Z3_disable_trace(tag); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3_Z3_mk_fixedpoint( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_fixedpoint _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_fixedpoint(c); - _vres = camlidl_c2ml_z3_Z3_fixedpoint(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_add_rule( - value _v_c, - value _v_d, - value _v_rule, - value _v_name) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_ast rule; /*in*/ - Z3_symbol name; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_rule, &rule, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - Z3_fixedpoint_add_rule(c, d, rule, name); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_add_fact( - value _v_c, - value _v_d, - value _v_r, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_func_decl r; /*in*/ - unsigned int num_args; /*in*/ - unsigned int *args; /*in*/ - mlsize_t _c1; - mlsize_t _c2; - value _v3; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_r, &r, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(unsigned int ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - args[_c2] = Int_val(_v3); - } - num_args = _c1; - Z3_fixedpoint_add_fact(c, d, r, num_args, args); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_assert( - value _v_c, - value _v_d, - value _v_axiom) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_ast axiom; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_axiom, &axiom, _ctx); - Z3_fixedpoint_assert(c, d, axiom); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_query( - value _v_c, - value _v_d, - value _v_query) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_ast query; /*in*/ - Z3_lbool _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_query, &query, _ctx); - _res = Z3_fixedpoint_query(c, d, query); - _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_query_relations( - value _v_c, - value _v_d, - value _v_relations) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - unsigned int num_relations; /*in*/ - Z3_func_decl const *relations; /*in*/ - Z3_lbool _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - _c1 = Wosize_val(_v_relations); - relations = camlidl_malloc(_c1 * sizeof(Z3_func_decl const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_relations, _c2); - camlidl_ml2c_z3_Z3_func_decl(_v3, &relations[_c2], _ctx); - } - num_relations = _c1; - _res = Z3_fixedpoint_query_relations(c, d, num_relations, relations); - _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_get_answer( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - _res = Z3_fixedpoint_get_answer(c, d); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_get_reason_unknown( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - _res = Z3_fixedpoint_get_reason_unknown(c, d); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_update_rule( - value _v_c, - value _v_d, - value _v_a, - value _v_name) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_ast a; /*in*/ - Z3_symbol name; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_name, &name, _ctx); - Z3_fixedpoint_update_rule(c, d, a, name); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_get_num_levels( - value _v_c, - value _v_d, - value _v_pred) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_func_decl pred; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_pred, &pred, _ctx); - _res = Z3_fixedpoint_get_num_levels(c, d, pred); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_get_cover_delta( - value _v_c, - value _v_d, - value _v_level, - value _v_pred) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - int level; /*in*/ - Z3_func_decl pred; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - level = Int_val(_v_level); - camlidl_ml2c_z3_Z3_func_decl(_v_pred, &pred, _ctx); - _res = Z3_fixedpoint_get_cover_delta(c, d, level, pred); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_add_cover( - value _v_c, - value _v_d, - value _v_level, - value _v_pred, - value _v_property) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - int level; /*in*/ - Z3_func_decl pred; /*in*/ - Z3_ast property; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - level = Int_val(_v_level); - camlidl_ml2c_z3_Z3_func_decl(_v_pred, &pred, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_property, &property, _ctx); - Z3_fixedpoint_add_cover(c, d, level, pred, property); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_get_statistics( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_stats _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - _res = Z3_fixedpoint_get_statistics(c, d); - _vres = camlidl_c2ml_z3_Z3_stats(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_register_relation( - value _v_c, - value _v_d, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_func_decl f; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx); - Z3_fixedpoint_register_relation(c, d, f); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_set_predicate_representation( - value _v_c, - value _v_d, - value _v_f, - value _v_relation_kinds) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - Z3_func_decl f; /*in*/ - unsigned int num_relations; /*in*/ - Z3_symbol const *relation_kinds; /*in*/ - mlsize_t _c1; - mlsize_t _c2; - value _v3; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - camlidl_ml2c_z3_Z3_func_decl(_v_f, &f, _ctx); - _c1 = Wosize_val(_v_relation_kinds); - relation_kinds = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_relation_kinds, _c2); - camlidl_ml2c_z3_Z3_symbol(_v3, &relation_kinds[_c2], _ctx); - } - num_relations = _c1; - Z3_fixedpoint_set_predicate_representation(c, d, f, num_relations, relation_kinds); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_get_rules( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - _res = Z3_fixedpoint_get_rules(c, f); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_get_assertions( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - _res = Z3_fixedpoint_get_assertions(c, f); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_set_params( - value _v_c, - value _v_f, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_params p; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - Z3_fixedpoint_set_params(c, f, p); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_get_help( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - _res = Z3_fixedpoint_get_help(c, f); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_get_param_descrs( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_param_descrs _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - _res = Z3_fixedpoint_get_param_descrs(c, f); - _vres = camlidl_c2ml_z3_Z3_param_descrs(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_to_string( - value _v_c, - value _v_f, - value _v_queries) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - unsigned int num_queries; /*in*/ - Z3_ast *queries; /*in*/ - Z3_string _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - _c1 = Wosize_val(_v_queries); - queries = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_queries, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &queries[_c2], _ctx); - } - num_queries = _c1; - _res = Z3_fixedpoint_to_string(c, f, num_queries, queries); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_from_string( - value _v_c, - value _v_f, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_string s; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - camlidl_ml2c_z3_Z3_string(_v_s, &s, _ctx); - _res = Z3_fixedpoint_from_string(c, f, s); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_from_file( - value _v_c, - value _v_f, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_fixedpoint f; /*in*/ - Z3_string s; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_f, &f, _ctx); - camlidl_ml2c_z3_Z3_string(_v_s, &s, _ctx); - _res = Z3_fixedpoint_from_file(c, f, s); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_fixedpoint_push( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - Z3_fixedpoint_push(c, d); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_fixedpoint_pop( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_fixedpoint d; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_fixedpoint(_v_d, &d, _ctx); - Z3_fixedpoint_pop(c, d); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_mk_ast_vector( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_ast_vector(c); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_vector_size( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast_vector v; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - _res = Z3_ast_vector_size(c, v); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_vector_get( - value _v_c, - value _v_v, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast_vector v; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - i = Int_val(_v_i); - _res = Z3_ast_vector_get(c, v, i); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_vector_set( - value _v_c, - value _v_v, - value _v_i, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast_vector v; /*in*/ - unsigned int i; /*in*/ - Z3_ast a; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - Z3_ast_vector_set(c, v, i, a); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_vector_resize( - value _v_c, - value _v_v, - value _v_n) -{ - Z3_context c; /*in*/ - Z3_ast_vector v; /*in*/ - unsigned int n; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - n = Int_val(_v_n); - Z3_ast_vector_resize(c, v, n); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_vector_push( - value _v_c, - value _v_v, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast_vector v; /*in*/ - Z3_ast a; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - Z3_ast_vector_push(c, v, a); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_vector_translate( - value _v_s, - value _v_v, - value _v_t) -{ - Z3_context s; /*in*/ - Z3_ast_vector v; /*in*/ - Z3_context t; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_s, &s, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - camlidl_ml2c_z3_Z3_context(_v_t, &t, _ctx); - _res = Z3_ast_vector_translate(s, v, t); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(s); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_vector_to_string( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast_vector v; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_vector(_v_v, &v, _ctx); - _res = Z3_ast_vector_to_string(c, v); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_ast_map( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast_map _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_ast_map(c); - _vres = camlidl_c2ml_z3_Z3_ast_map(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_map_contains( - value _v_c, - value _v_m, - value _v_k) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - Z3_ast k; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_k, &k, _ctx); - _res = Z3_ast_map_contains(c, m, k); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_map_find( - value _v_c, - value _v_m, - value _v_k) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - Z3_ast k; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_k, &k, _ctx); - _res = Z3_ast_map_find(c, m, k); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_map_insert( - value _v_c, - value _v_m, - value _v_k, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - Z3_ast k; /*in*/ - Z3_ast v; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_k, &k, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_v, &v, _ctx); - Z3_ast_map_insert(c, m, k, v); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_map_erase( - value _v_c, - value _v_m, - value _v_k) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - Z3_ast k; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_k, &k, _ctx); - Z3_ast_map_erase(c, m, k); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_map_reset( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - Z3_ast_map_reset(c, m); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_ast_map_size( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - _res = Z3_ast_map_size(c, m); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_map_keys( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - _res = Z3_ast_map_keys(c, m); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_ast_map_to_string( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_ast_map m; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_ast_map(_v_m, &m, _ctx); - _res = Z3_ast_map_to_string(c, m); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_goal( - value _v_c, - value _v_models, - value _v_unsat_cores, - value _v_proofs) -{ - Z3_context c; /*in*/ - int models; /*in*/ - int unsat_cores; /*in*/ - int proofs; /*in*/ - Z3_goal _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - models = Int_val(_v_models); - unsat_cores = Int_val(_v_unsat_cores); - proofs = Int_val(_v_proofs); - _res = Z3_mk_goal(c, models, unsat_cores, proofs); - _vres = camlidl_c2ml_z3_Z3_goal(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_precision( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - Z3_goal_prec _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_precision(c, g); - _vres = camlidl_c2ml_z3_Z3_goal_prec(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_assert( - value _v_c, - value _v_g, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - Z3_ast a; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - Z3_goal_assert(c, g, a); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_goal_inconsistent( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_inconsistent(c, g); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_depth( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_depth(c, g); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_reset( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - Z3_goal_reset(c, g); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_goal_size( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_size(c, g); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_formula( - value _v_c, - value _v_g, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - unsigned int idx; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - idx = Int_val(_v_idx); - _res = Z3_goal_formula(c, g, idx); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_num_exprs( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_num_exprs(c, g); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_is_decided_sat( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_is_decided_sat(c, g); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_is_decided_unsat( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_is_decided_unsat(c, g); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_translate( - value _v_source, - value _v_g, - value _v_target) -{ - Z3_context source; /*in*/ - Z3_goal g; /*in*/ - Z3_context target; /*in*/ - Z3_goal _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_source, &source, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - camlidl_ml2c_z3_Z3_context(_v_target, &target, _ctx); - _res = Z3_goal_translate(source, g, target); - _vres = camlidl_c2ml_z3_Z3_goal(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(source); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_goal_to_string( - value _v_c, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_goal g; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_goal_to_string(c, g); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_tactic( - value _v_c, - value _v_name) -{ - Z3_context c; /*in*/ - Z3_string name; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_name, &name, _ctx); - _res = Z3_mk_tactic(c, name); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_probe( - value _v_c, - value _v_name) -{ - Z3_context c; /*in*/ - Z3_string name; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_name, &name, _ctx); - _res = Z3_mk_probe(c, name); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_and_then( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_tactic t1; /*in*/ - Z3_tactic t2; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t2, &t2, _ctx); - _res = Z3_tactic_and_then(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_or_else( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_tactic t1; /*in*/ - Z3_tactic t2; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t2, &t2, _ctx); - _res = Z3_tactic_or_else(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_par_or( - value _v_c, - value _v_ts) -{ - Z3_context c; /*in*/ - unsigned int num; /*in*/ - Z3_tactic const *ts; /*in*/ - Z3_tactic _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_ts); - ts = camlidl_malloc(_c1 * sizeof(Z3_tactic const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_ts, _c2); - camlidl_ml2c_z3_Z3_tactic(_v3, &ts[_c2], _ctx); - } - num = _c1; - _res = Z3_tactic_par_or(c, num, ts); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_par_and_then( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_tactic t1; /*in*/ - Z3_tactic t2; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t2, &t2, _ctx); - _res = Z3_tactic_par_and_then(c, t1, t2); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_try_for( - value _v_c, - value _v_t, - value _v_ms) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - unsigned int ms; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - ms = Int_val(_v_ms); - _res = Z3_tactic_try_for(c, t, ms); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_when( - value _v_c, - value _v_p, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_probe p; /*in*/ - Z3_tactic t; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - _res = Z3_tactic_when(c, p, t); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_cond( - value _v_c, - value _v_p, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_probe p; /*in*/ - Z3_tactic t1; /*in*/ - Z3_tactic t2; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t1, &t1, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t2, &t2, _ctx); - _res = Z3_tactic_cond(c, p, t1, t2); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_repeat( - value _v_c, - value _v_t, - value _v_max) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - unsigned int max; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - max = Int_val(_v_max); - _res = Z3_tactic_repeat(c, t, max); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_skip( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_tactic_skip(c); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_fail( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_tactic_fail(c); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_fail_if( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_probe p; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p, &p, _ctx); - _res = Z3_tactic_fail_if(c, p); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_fail_if_not_decided( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_tactic_fail_if_not_decided(c); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_using_params( - value _v_c, - value _v_t, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - Z3_params p; /*in*/ - Z3_tactic _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - _res = Z3_tactic_using_params(c, t, p); - _vres = camlidl_c2ml_z3_Z3_tactic(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_const( - value _v_x, - value _v_val) -{ - Z3_context x; /*in*/ - double val; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - val = Double_val(_v_val); - _res = Z3_probe_const(x, val); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_lt( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_lt(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_gt( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_gt(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_le( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_le(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_ge( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_ge(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_eq( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_eq(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_and( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_and(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_or( - value _v_x, - value _v_p1, - value _v_p2) -{ - Z3_context x; /*in*/ - Z3_probe p1; /*in*/ - Z3_probe p2; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p1, &p1, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p2, &p2, _ctx); - _res = Z3_probe_or(x, p1, p2); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_not( - value _v_x, - value _v_p) -{ - Z3_context x; /*in*/ - Z3_probe p; /*in*/ - Z3_probe _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_x, &x, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p, &p, _ctx); - _res = Z3_probe_not(x, p); - _vres = camlidl_c2ml_z3_Z3_probe(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(x); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_num_tactics( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_num_tactics(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_tactic_name( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_tactic_name(c, i); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_num_probes( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_num_probes(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_probe_name( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_probe_name(c, i); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_get_help( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - _res = Z3_tactic_get_help(c, t); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_get_param_descrs( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - Z3_param_descrs _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - _res = Z3_tactic_get_param_descrs(c, t); - _vres = camlidl_c2ml_z3_Z3_param_descrs(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_get_descr( - value _v_c, - value _v_name) -{ - Z3_context c; /*in*/ - Z3_string name; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_name, &name, _ctx); - _res = Z3_tactic_get_descr(c, name); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_get_descr( - value _v_c, - value _v_name) -{ - Z3_context c; /*in*/ - Z3_string name; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_string(_v_name, &name, _ctx); - _res = Z3_probe_get_descr(c, name); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_probe_apply( - value _v_c, - value _v_p, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_probe p; /*in*/ - Z3_goal g; /*in*/ - double _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_probe(_v_p, &p, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_probe_apply(c, p, g); - _vres = copy_double(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_apply( - value _v_c, - value _v_t, - value _v_g) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - Z3_goal g; /*in*/ - Z3_apply_result _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - _res = Z3_tactic_apply(c, t, g); - _vres = camlidl_c2ml_z3_Z3_apply_result(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_tactic_apply_ex( - value _v_c, - value _v_t, - value _v_g, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - Z3_goal g; /*in*/ - Z3_params p; /*in*/ - Z3_apply_result _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - camlidl_ml2c_z3_Z3_goal(_v_g, &g, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - _res = Z3_tactic_apply_ex(c, t, g, p); - _vres = camlidl_c2ml_z3_Z3_apply_result(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_apply_result_to_string( - value _v_c, - value _v_r) -{ - Z3_context c; /*in*/ - Z3_apply_result r; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_apply_result(_v_r, &r, _ctx); - _res = Z3_apply_result_to_string(c, r); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_apply_result_get_num_subgoals( - value _v_c, - value _v_r) -{ - Z3_context c; /*in*/ - Z3_apply_result r; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_apply_result(_v_r, &r, _ctx); - _res = Z3_apply_result_get_num_subgoals(c, r); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_apply_result_get_subgoal( - value _v_c, - value _v_r, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_apply_result r; /*in*/ - unsigned int i; /*in*/ - Z3_goal _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_apply_result(_v_r, &r, _ctx); - i = Int_val(_v_i); - _res = Z3_apply_result_get_subgoal(c, r, i); - _vres = camlidl_c2ml_z3_Z3_goal(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_apply_result_convert_model( - value _v_c, - value _v_r, - value _v_i, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_apply_result r; /*in*/ - unsigned int i; /*in*/ - Z3_model m; /*in*/ - Z3_model _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_apply_result(_v_r, &r, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3_Z3_model(_v_m, &m, _ctx); - _res = Z3_apply_result_convert_model(c, r, i, m); - _vres = camlidl_c2ml_z3_Z3_model(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_solver( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_solver _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_solver(c); - _vres = camlidl_c2ml_z3_Z3_solver(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_simple_solver( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_solver _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_simple_solver(c); - _vres = camlidl_c2ml_z3_Z3_solver(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_solver_for_logic( - value _v_c, - value _v_logic) -{ - Z3_context c; /*in*/ - Z3_symbol logic; /*in*/ - Z3_solver _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_symbol(_v_logic, &logic, _ctx); - _res = Z3_mk_solver_for_logic(c, logic); - _vres = camlidl_c2ml_z3_Z3_solver(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_mk_solver_from_tactic( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_tactic t; /*in*/ - Z3_solver _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_tactic(_v_t, &t, _ctx); - _res = Z3_mk_solver_from_tactic(c, t); - _vres = camlidl_c2ml_z3_Z3_solver(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_help( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_help(c, s); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_param_descrs( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_param_descrs _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_param_descrs(c, s); - _vres = camlidl_c2ml_z3_Z3_param_descrs(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_set_params( - value _v_c, - value _v_s, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_params p; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - camlidl_ml2c_z3_Z3_params(_v_p, &p, _ctx); - Z3_solver_set_params(c, s, p); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_solver_push( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - Z3_solver_push(c, s); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_solver_pop( - value _v_c, - value _v_s, - value _v_n) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - unsigned int n; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - n = Int_val(_v_n); - Z3_solver_pop(c, s, n); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_solver_reset( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - Z3_solver_reset(c, s); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_solver_get_num_scopes( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_num_scopes(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_assert( - value _v_c, - value _v_s, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_ast a; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - Z3_solver_assert(c, s, a); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_solver_assert_and_track( - value _v_c, - value _v_s, - value _v_a, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_ast a; /*in*/ - Z3_ast p; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3_Z3_ast(_v_p, &p, _ctx); - Z3_solver_assert_and_track(c, s, a, p); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return Val_unit; -} - -value camlidl_z3_Z3_solver_get_assertions( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_assertions(c, s); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_check( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_lbool _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_check(c, s); - _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_check_assumptions( - value _v_c, - value _v_s, - value _v_assumptions) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - unsigned int num_assumptions; /*in*/ - Z3_ast const *assumptions; /*in*/ - Z3_lbool _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _c1 = Wosize_val(_v_assumptions); - assumptions = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_assumptions, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &assumptions[_c2], _ctx); - } - num_assumptions = _c1; - _res = Z3_solver_check_assumptions(c, s, num_assumptions, assumptions); - _vres = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_model( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_model _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_model(c, s); - _vres = camlidl_c2ml_z3_Z3_model(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_proof( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_proof(c, s); - _vres = camlidl_c2ml_z3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_unsat_core( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_ast_vector _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_unsat_core(c, s); - _vres = camlidl_c2ml_z3_Z3_ast_vector(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_reason_unknown( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_reason_unknown(c, s); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_get_statistics( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_stats _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_get_statistics(c, s); - _vres = camlidl_c2ml_z3_Z3_stats(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_solver_to_string( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _res = Z3_solver_to_string(c, s); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_to_string( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - _res = Z3_stats_to_string(c, s); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_size( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - _res = Z3_stats_size(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_get_key( - value _v_c, - value _v_s, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - unsigned int idx; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - idx = Int_val(_v_idx); - _res = Z3_stats_get_key(c, s, idx); - _vres = camlidl_c2ml_z3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_is_uint( - value _v_c, - value _v_s, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - unsigned int idx; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - idx = Int_val(_v_idx); - _res = Z3_stats_is_uint(c, s, idx); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_is_double( - value _v_c, - value _v_s, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - unsigned int idx; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - idx = Int_val(_v_idx); - _res = Z3_stats_is_double(c, s, idx); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_get_uint_value( - value _v_c, - value _v_s, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - unsigned int idx; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - idx = Int_val(_v_idx); - _res = Z3_stats_get_uint_value(c, s, idx); - _vres = Val_int(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_stats_get_double_value( - value _v_c, - value _v_s, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_stats s; /*in*/ - unsigned int idx; /*in*/ - double _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_stats(_v_s, &s, _ctx); - idx = Int_val(_v_idx); - _res = Z3_stats_get_double_value(c, s, idx); - _vres = copy_double(_res); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3_Z3_get_implied_equalities( - value _v_c, - value _v_s, - value _v_terms) -{ - Z3_context c; /*in*/ - Z3_solver s; /*in*/ - unsigned int num_terms; /*in*/ - Z3_ast const *terms; /*in*/ - unsigned int *class_ids; /*out*/ - Z3_lbool _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - value _v5; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3_Z3_solver(_v_s, &s, _ctx); - _c1 = Wosize_val(_v_terms); - terms = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_terms, _c2); - camlidl_ml2c_z3_Z3_ast(_v3, &terms[_c2], _ctx); - } - num_terms = _c1; - class_ids = camlidl_malloc(num_terms * sizeof(unsigned int ), _ctx); - _res = Z3_get_implied_equalities(c, s, num_terms, terms, class_ids); - Begin_roots_block(_vres, 2) - _vres[0] = camlidl_c2ml_z3_Z3_lbool(&_res, _ctx); - _vres[1] = camlidl_alloc(num_terms, 0); - for (_c4 = 0; _c4 < num_terms; _c4++) { - _v5 = Val_int(class_ids[_c4]); - modify(&Field(_vres[1], _c4), _v5); - } - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -check_error_code(c); - /* end user-supplied deallocation sequence */ - return _vresult; -} - -void camlidl_ml2c_z3V3_Z3_symbol(value _v1, Z3_symbol * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_symbol *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_symbol(Z3_symbol * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_symbol) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_symbol *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_literals(value _v1, Z3_literals * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_literals *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_literals(Z3_literals * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_literals) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_literals *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_theory(value _v1, Z3_theory * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_theory *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_theory(Z3_theory * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_theory) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_theory *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_config(value _v1, Z3_config * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_config *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_config(Z3_config * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_config) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_config *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_context(value _v1, Z3_context * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_context *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_context(Z3_context * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_context) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_context *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_sort(value _v1, Z3_sort * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_sort *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_sort(Z3_sort * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_sort) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_sort *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_func_decl(value _v1, Z3_func_decl * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_func_decl *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_func_decl(Z3_func_decl * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_func_decl) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_func_decl *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_ast(value _v1, Z3_ast * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_ast *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_ast(Z3_ast * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_ast) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_ast *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_app(value _v1, Z3_app * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_app *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_app(Z3_app * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_app) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_app *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_pattern(value _v1, Z3_pattern * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_pattern *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_pattern(Z3_pattern * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_pattern) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_pattern *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_model(value _v1, Z3_model * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_model *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_model(Z3_model * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_model) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_model *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_constructor(value _v1, Z3_constructor * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_constructor *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_constructor(Z3_constructor * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_constructor) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_constructor *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_constructor_list(value _v1, Z3_constructor_list * _c2, camlidl_ctx _ctx) -{ - *_c2 = *((Z3_constructor_list *) Bp_val(_v1)); -} - -value camlidl_c2ml_z3V3_Z3_constructor_list(Z3_constructor_list * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_alloc((sizeof(Z3_constructor_list) + sizeof(value) - 1) / sizeof(value), Abstract_tag); - *((Z3_constructor_list *) Bp_val(_v1)) = *_c2; - return _v1; -} - -void camlidl_ml2c_z3V3_Z3_string(value _v1, Z3_string * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_malloc_string(_v1, _ctx); -} - -value camlidl_c2ml_z3V3_Z3_string(Z3_string * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = copy_string((*_c2)); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_1[3] = { - Z3_L_FALSE, - Z3_L_UNDEF, - Z3_L_TRUE, -}; - -void camlidl_ml2c_z3V3_Z3_lbool(value _v1, Z3_lbool * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_1[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_lbool(Z3_lbool * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_L_FALSE: _v1 = Val_int(0); break; - case Z3_L_UNDEF: _v1 = Val_int(1); break; - case Z3_L_TRUE: _v1 = Val_int(2); break; - default: invalid_argument("typedef Z3_lbool: bad enum value"); - } - return _v1; -} - -int camlidl_transl_table_z3V3_enum_2[2] = { - Z3_INT_SYMBOL, - Z3_STRING_SYMBOL, -}; - -void camlidl_ml2c_z3V3_Z3_symbol_kind(value _v1, Z3_symbol_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_2[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_symbol_kind(Z3_symbol_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_INT_SYMBOL: _v1 = Val_int(0); break; - case Z3_STRING_SYMBOL: _v1 = Val_int(1); break; - default: invalid_argument("typedef Z3_symbol_kind: bad enum value"); - } - return _v1; -} - -int camlidl_transl_table_z3V3_enum_3[7] = { - Z3_PARAMETER_INT, - Z3_PARAMETER_DOUBLE, - Z3_PARAMETER_RATIONAL, - Z3_PARAMETER_SYMBOL, - Z3_PARAMETER_SORT, - Z3_PARAMETER_AST, - Z3_PARAMETER_FUNC_DECL, -}; - -void camlidl_ml2c_z3V3_Z3_parameter_kind(value _v1, Z3_parameter_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_3[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_parameter_kind(Z3_parameter_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3V3_enum_3, 7, "typedef Z3_parameter_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_4[10] = { - Z3_UNINTERPRETED_SORT, - Z3_BOOL_SORT, - Z3_INT_SORT, - Z3_REAL_SORT, - Z3_BV_SORT, - Z3_ARRAY_SORT, - Z3_DATATYPE_SORT, - Z3_RELATION_SORT, - Z3_FINITE_DOMAIN_SORT, - Z3_UNKNOWN_SORT, -}; - -void camlidl_ml2c_z3V3_Z3_sort_kind(value _v1, Z3_sort_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_4[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_sort_kind(Z3_sort_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3V3_enum_4, 10, "typedef Z3_sort_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_5[7] = { - Z3_NUMERAL_AST, - Z3_APP_AST, - Z3_VAR_AST, - Z3_QUANTIFIER_AST, - Z3_SORT_AST, - Z3_FUNC_DECL_AST, - Z3_UNKNOWN_AST, -}; - -void camlidl_ml2c_z3V3_Z3_ast_kind(value _v1, Z3_ast_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_5[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_ast_kind(Z3_ast_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3V3_enum_5, 7, "typedef Z3_ast_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_6[152] = { - Z3_OP_TRUE, - Z3_OP_FALSE, - Z3_OP_EQ, - Z3_OP_DISTINCT, - Z3_OP_ITE, - Z3_OP_AND, - Z3_OP_OR, - Z3_OP_IFF, - Z3_OP_XOR, - Z3_OP_NOT, - Z3_OP_IMPLIES, - Z3_OP_OEQ, - Z3_OP_ANUM, - Z3_OP_AGNUM, - Z3_OP_LE, - Z3_OP_GE, - Z3_OP_LT, - Z3_OP_GT, - Z3_OP_ADD, - Z3_OP_SUB, - Z3_OP_UMINUS, - Z3_OP_MUL, - Z3_OP_DIV, - Z3_OP_IDIV, - Z3_OP_REM, - Z3_OP_MOD, - Z3_OP_TO_REAL, - Z3_OP_TO_INT, - Z3_OP_IS_INT, - Z3_OP_POWER, - Z3_OP_STORE, - Z3_OP_SELECT, - Z3_OP_CONST_ARRAY, - Z3_OP_ARRAY_MAP, - Z3_OP_ARRAY_DEFAULT, - Z3_OP_SET_UNION, - Z3_OP_SET_INTERSECT, - Z3_OP_SET_DIFFERENCE, - Z3_OP_SET_COMPLEMENT, - Z3_OP_SET_SUBSET, - Z3_OP_AS_ARRAY, - Z3_OP_BNUM, - Z3_OP_BIT1, - Z3_OP_BIT0, - Z3_OP_BNEG, - Z3_OP_BADD, - Z3_OP_BSUB, - Z3_OP_BMUL, - Z3_OP_BSDIV, - Z3_OP_BUDIV, - Z3_OP_BSREM, - Z3_OP_BUREM, - Z3_OP_BSMOD, - Z3_OP_BSDIV0, - Z3_OP_BUDIV0, - Z3_OP_BSREM0, - Z3_OP_BUREM0, - Z3_OP_BSMOD0, - Z3_OP_ULEQ, - Z3_OP_SLEQ, - Z3_OP_UGEQ, - Z3_OP_SGEQ, - Z3_OP_ULT, - Z3_OP_SLT, - Z3_OP_UGT, - Z3_OP_SGT, - Z3_OP_BAND, - Z3_OP_BOR, - Z3_OP_BNOT, - Z3_OP_BXOR, - Z3_OP_BNAND, - Z3_OP_BNOR, - Z3_OP_BXNOR, - Z3_OP_CONCAT, - Z3_OP_SIGN_EXT, - Z3_OP_ZERO_EXT, - Z3_OP_EXTRACT, - Z3_OP_REPEAT, - Z3_OP_BREDOR, - Z3_OP_BREDAND, - Z3_OP_BCOMP, - Z3_OP_BSHL, - Z3_OP_BLSHR, - Z3_OP_BASHR, - Z3_OP_ROTATE_LEFT, - Z3_OP_ROTATE_RIGHT, - Z3_OP_EXT_ROTATE_LEFT, - Z3_OP_EXT_ROTATE_RIGHT, - Z3_OP_INT2BV, - Z3_OP_BV2INT, - Z3_OP_CARRY, - Z3_OP_XOR3, - Z3_OP_PR_UNDEF, - Z3_OP_PR_TRUE, - Z3_OP_PR_ASSERTED, - Z3_OP_PR_GOAL, - Z3_OP_PR_MODUS_PONENS, - Z3_OP_PR_REFLEXIVITY, - Z3_OP_PR_SYMMETRY, - Z3_OP_PR_TRANSITIVITY, - Z3_OP_PR_TRANSITIVITY_STAR, - Z3_OP_PR_MONOTONICITY, - Z3_OP_PR_QUANT_INTRO, - Z3_OP_PR_DISTRIBUTIVITY, - Z3_OP_PR_AND_ELIM, - Z3_OP_PR_NOT_OR_ELIM, - Z3_OP_PR_REWRITE, - Z3_OP_PR_REWRITE_STAR, - Z3_OP_PR_PULL_QUANT, - Z3_OP_PR_PULL_QUANT_STAR, - Z3_OP_PR_PUSH_QUANT, - Z3_OP_PR_ELIM_UNUSED_VARS, - Z3_OP_PR_DER, - Z3_OP_PR_QUANT_INST, - Z3_OP_PR_HYPOTHESIS, - Z3_OP_PR_LEMMA, - Z3_OP_PR_UNIT_RESOLUTION, - Z3_OP_PR_IFF_TRUE, - Z3_OP_PR_IFF_FALSE, - Z3_OP_PR_COMMUTATIVITY, - Z3_OP_PR_DEF_AXIOM, - Z3_OP_PR_DEF_INTRO, - Z3_OP_PR_APPLY_DEF, - Z3_OP_PR_IFF_OEQ, - Z3_OP_PR_NNF_POS, - Z3_OP_PR_NNF_NEG, - Z3_OP_PR_NNF_STAR, - Z3_OP_PR_CNF_STAR, - Z3_OP_PR_SKOLEMIZE, - Z3_OP_PR_MODUS_PONENS_OEQ, - Z3_OP_PR_TH_LEMMA, - Z3_OP_PR_HYPER_RESOLVE, - Z3_OP_RA_STORE, - Z3_OP_RA_EMPTY, - Z3_OP_RA_IS_EMPTY, - Z3_OP_RA_JOIN, - Z3_OP_RA_UNION, - Z3_OP_RA_WIDEN, - Z3_OP_RA_PROJECT, - Z3_OP_RA_FILTER, - Z3_OP_RA_NEGATION_FILTER, - Z3_OP_RA_RENAME, - Z3_OP_RA_COMPLEMENT, - Z3_OP_RA_SELECT, - Z3_OP_RA_CLONE, - Z3_OP_FD_LT, - Z3_OP_LABEL, - Z3_OP_LABEL_LIT, - Z3_OP_DT_CONSTRUCTOR, - Z3_OP_DT_RECOGNISER, - Z3_OP_DT_ACCESSOR, - Z3_OP_UNINTERPRETED, -}; - -void camlidl_ml2c_z3V3_Z3_decl_kind(value _v1, Z3_decl_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_6[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_decl_kind(Z3_decl_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3V3_enum_6, 152, "typedef Z3_decl_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_7[7] = { - Z3_PK_UINT, - Z3_PK_BOOL, - Z3_PK_DOUBLE, - Z3_PK_SYMBOL, - Z3_PK_STRING, - Z3_PK_OTHER, - Z3_PK_INVALID, -}; - -void camlidl_ml2c_z3V3_Z3_param_kind(value _v1, Z3_param_kind * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_7[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_param_kind(Z3_param_kind * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3V3_enum_7, 7, "typedef Z3_param_kind: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_8[8] = { - Z3_NO_FAILURE, - Z3_UNKNOWN, - Z3_TIMEOUT, - Z3_MEMOUT_WATERMARK, - Z3_CANCELED, - Z3_NUM_CONFLICTS, - Z3_THEORY, - Z3_QUANTIFIERS, -}; - -void camlidl_ml2c_z3V3_Z3_search_failure(value _v1, Z3_search_failure * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_8[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_search_failure(Z3_search_failure * _c2, camlidl_ctx _ctx) -{ -value _v1; - _v1 = camlidl_find_enum((*_c2), camlidl_transl_table_z3V3_enum_8, 8, "typedef Z3_search_failure: bad enum value"); - return _v1; -} - -int camlidl_transl_table_z3V3_enum_9[4] = { - Z3_PRINT_SMTLIB_FULL, - Z3_PRINT_LOW_LEVEL, - Z3_PRINT_SMTLIB_COMPLIANT, - Z3_PRINT_SMTLIB2_COMPLIANT, -}; - -void camlidl_ml2c_z3V3_Z3_ast_print_mode(value _v1, Z3_ast_print_mode * _c2, camlidl_ctx _ctx) -{ - (*_c2) = camlidl_transl_table_z3V3_enum_9[Int_val(_v1)]; -} - -value camlidl_c2ml_z3V3_Z3_ast_print_mode(Z3_ast_print_mode * _c2, camlidl_ctx _ctx) -{ -value _v1; - switch((*_c2)) { - case Z3_PRINT_SMTLIB_FULL: _v1 = Val_int(0); break; - case Z3_PRINT_LOW_LEVEL: _v1 = Val_int(1); break; - case Z3_PRINT_SMTLIB_COMPLIANT: _v1 = Val_int(2); break; - case Z3_PRINT_SMTLIB2_COMPLIANT: _v1 = Val_int(3); break; - default: invalid_argument("typedef Z3_ast_print_mode: bad enum value"); - } - return _v1; -} - -value camlidl_z3V3_Z3_global_param_set( - value _v_param_id, - value _v_param_value) -{ - Z3_string param_id; /*in*/ - Z3_string param_value; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_string(_v_param_id, ¶m_id, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_param_value, ¶m_value, _ctx); - Z3_global_param_set(param_id, param_value); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_global_param_reset_all(value _unit) -{ - Z3_global_param_reset_all(); - return Val_unit; -} - -value camlidl_z3V3_Z3_global_param_get( - value _v_param_id) -{ - Z3_string param_id; /*in*/ - Z3_string *param_value; /*out*/ - Z3_string _c1; - value _v2; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_string(_v_param_id, ¶m_id, _ctx); - param_value = &_c1; - Z3_global_param_get(param_id, param_value); - if (param_value == NULL) { - _vres = Val_int(0); - } else { - _v2 = camlidl_c2ml_z3V3_Z3_string(&*param_value, _ctx); - Begin_root(_v2) - _vres = camlidl_alloc_small(1, 0); - Field(_vres, 0) = _v2; - End_roots(); - } - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_config(value _unit) -{ - Z3_config _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - _res = Z3_mk_config(); - _vres = camlidl_c2ml_z3V3_Z3_config(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_del_config( - value _v_c) -{ - Z3_config c; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_config(_v_c, &c, _ctx); - Z3_del_config(c); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_set_param_value( - value _v_c, - value _v_param_id, - value _v_param_value) -{ - Z3_config c; /*in*/ - Z3_string param_id; /*in*/ - Z3_string param_value; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_config(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_param_id, ¶m_id, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_param_value, ¶m_value, _ctx); - Z3_set_param_value(c, param_id, param_value); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_mk_context( - value _v_c) -{ - Z3_config c; /*in*/ - Z3_context _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_config(_v_c, &c, _ctx); - _res = Z3_mk_context(c); - _vres = camlidl_c2ml_z3V3_Z3_context(&_res, _ctx); - camlidl_free(_ctx); - /* begin user-supplied deallocation sequence */ -Z3_set_error_handler(_res, (void*)caml_z3_error_handler); - /* end user-supplied deallocation sequence */ - return _vres; -} - -value camlidl_z3V3_Z3_del_context( - value _v_c) -{ - Z3_context c; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - Z3_del_context(c); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_update_param_value( - value _v_c, - value _v_param_id, - value _v_param_value) -{ - Z3_context c; /*in*/ - Z3_string param_id; /*in*/ - Z3_string param_value; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_param_id, ¶m_id, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_param_value, ¶m_value, _ctx); - Z3_update_param_value(c, param_id, param_value); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_get_param_value( - value _v_c, - value _v_param_id) -{ - Z3_context c; /*in*/ - Z3_string param_id; /*in*/ - Z3_string *param_value; /*out*/ - Z3_string _c1; - value _v2; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_param_id, ¶m_id, _ctx); - param_value = &_c1; - Z3_get_param_value(c, param_id, param_value); - if (param_value == NULL) { - _vres = Val_int(0); - } else { - _v2 = camlidl_c2ml_z3V3_Z3_string(&*param_value, _ctx); - Begin_root(_v2) - _vres = camlidl_alloc_small(1, 0); - Field(_vres, 0) = _v2; - End_roots(); - } - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_int_symbol( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - int i; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_mk_int_symbol(c, i); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_string_symbol( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_string s; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_s, &s, _ctx); - _res = Z3_mk_string_symbol(c, s); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_uninterpreted_sort( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_mk_uninterpreted_sort(c, s); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bool_sort( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_bool_sort(c); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_int_sort( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_int_sort(c); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_real_sort( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_real_sort(c); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bv_sort( - value _v_c, - value _v_sz) -{ - Z3_context c; /*in*/ - unsigned int sz; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - sz = Int_val(_v_sz); - _res = Z3_mk_bv_sort(c, sz); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_finite_domain_sort( - value _v_c, - value _v_name, - value _v_size) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - unsigned long long size; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_name, &name, _ctx); - size = Int64_val(_v_size); - _res = Z3_mk_finite_domain_sort(c, name, size); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_array_sort( - value _v_c, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_sort range; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_domain, &domain, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_array_sort(c, domain, range); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_tuple_sort( - value _v_c, - value _v_mk_tuple_name, - value _v_field_names, - value _v_field_sorts) -{ - Z3_context c; /*in*/ - Z3_symbol mk_tuple_name; /*in*/ - unsigned int num_fields; /*in*/ - Z3_symbol const *field_names; /*in*/ - Z3_sort const *field_sorts; /*in*/ - Z3_func_decl *mk_tuple_decl; /*out*/ - Z3_func_decl *proj_decl; /*out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - Z3_func_decl _c7; - mlsize_t _c8; - value _v9; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_mk_tuple_name, &mk_tuple_name, _ctx); - _c1 = Wosize_val(_v_field_names); - field_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_field_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &field_names[_c2], _ctx); - } - num_fields = _c1; - _c4 = Wosize_val(_v_field_sorts); - field_sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_field_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &field_sorts[_c5], _ctx); - } - num_fields = _c4; - mk_tuple_decl = &_c7; - proj_decl = camlidl_malloc(num_fields * sizeof(Z3_func_decl ), _ctx); - _res = Z3_mk_tuple_sort(c, mk_tuple_name, num_fields, field_names, field_sorts, mk_tuple_decl, proj_decl); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_c2ml_z3V3_Z3_func_decl(&*mk_tuple_decl, _ctx); - _vres[2] = camlidl_alloc(num_fields, 0); - Begin_root(_vres[2]) - for (_c8 = 0; _c8 < num_fields; _c8++) { - _v9 = camlidl_c2ml_z3V3_Z3_func_decl(&proj_decl[_c8], _ctx); - modify(&Field(_vres[2], _c8), _v9); - } - End_roots() - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_mk_enumeration_sort( - value _v_c, - value _v_name, - value _v_enum_names) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - unsigned int n; /*in*/ - Z3_symbol const *enum_names; /*in*/ - Z3_func_decl *enum_consts; /*out*/ - Z3_func_decl *enum_testers; /*out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - value _v5; - mlsize_t _c6; - value _v7; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_name, &name, _ctx); - _c1 = Wosize_val(_v_enum_names); - enum_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_enum_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &enum_names[_c2], _ctx); - } - n = _c1; - enum_consts = camlidl_malloc(n * sizeof(Z3_func_decl ), _ctx); - enum_testers = camlidl_malloc(n * sizeof(Z3_func_decl ), _ctx); - _res = Z3_mk_enumeration_sort(c, name, n, enum_names, enum_consts, enum_testers); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_alloc(n, 0); - Begin_root(_vres[1]) - for (_c4 = 0; _c4 < n; _c4++) { - _v5 = camlidl_c2ml_z3V3_Z3_func_decl(&enum_consts[_c4], _ctx); - modify(&Field(_vres[1], _c4), _v5); - } - End_roots() - _vres[2] = camlidl_alloc(n, 0); - Begin_root(_vres[2]) - for (_c6 = 0; _c6 < n; _c6++) { - _v7 = camlidl_c2ml_z3V3_Z3_func_decl(&enum_testers[_c6], _ctx); - modify(&Field(_vres[2], _c6), _v7); - } - End_roots() - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_mk_list_sort( - value _v_c, - value _v_name, - value _v_elem_sort) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - Z3_sort elem_sort; /*in*/ - Z3_func_decl *nil_decl; /*out*/ - Z3_func_decl *is_nil_decl; /*out*/ - Z3_func_decl *cons_decl; /*out*/ - Z3_func_decl *is_cons_decl; /*out*/ - Z3_func_decl *head_decl; /*out*/ - Z3_func_decl *tail_decl; /*out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_func_decl _c1; - Z3_func_decl _c2; - Z3_func_decl _c3; - Z3_func_decl _c4; - Z3_func_decl _c5; - Z3_func_decl _c6; - value _vresult; - value _vres[7] = { 0, 0, 0, 0, 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_name, &name, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_elem_sort, &elem_sort, _ctx); - nil_decl = &_c1; - is_nil_decl = &_c2; - cons_decl = &_c3; - is_cons_decl = &_c4; - head_decl = &_c5; - tail_decl = &_c6; - _res = Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl); - Begin_roots_block(_vres, 7) - _vres[0] = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_c2ml_z3V3_Z3_func_decl(&*nil_decl, _ctx); - _vres[2] = camlidl_c2ml_z3V3_Z3_func_decl(&*is_nil_decl, _ctx); - _vres[3] = camlidl_c2ml_z3V3_Z3_func_decl(&*cons_decl, _ctx); - _vres[4] = camlidl_c2ml_z3V3_Z3_func_decl(&*is_cons_decl, _ctx); - _vres[5] = camlidl_c2ml_z3V3_Z3_func_decl(&*head_decl, _ctx); - _vres[6] = camlidl_c2ml_z3V3_Z3_func_decl(&*tail_decl, _ctx); - _vresult = camlidl_alloc_small(7, 0); - { mlsize_t _c7; - for (_c7 = 0; _c7 < 7; _c7++) Field(_vresult, _c7) = _vres[_c7]; - } - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_mk_constructor( - value _v_c, - value _v_name, - value _v_recognizer, - value _v_field_names, - value _v_sorts, - value _v_sort_refs) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - Z3_symbol recognizer; /*in*/ - unsigned int num_fields; /*in*/ - Z3_symbol const *field_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int *sort_refs; /*in*/ - Z3_constructor _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_name, &name, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_recognizer, &recognizer, _ctx); - _c1 = Wosize_val(_v_field_names); - field_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_field_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &field_names[_c2], _ctx); - } - num_fields = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_fields = _c4; - _c7 = Wosize_val(_v_sort_refs); - sort_refs = camlidl_malloc(_c7 * sizeof(unsigned int ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_sort_refs, _c8); - sort_refs[_c8] = Int_val(_v9); - } - num_fields = _c7; - _res = Z3_mk_constructor(c, name, recognizer, num_fields, field_names, sorts, sort_refs); - _vres = camlidl_c2ml_z3V3_Z3_constructor(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_constructor_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_constructor(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_del_constructor( - value _v_c, - value _v_constr) -{ - Z3_context c; /*in*/ - Z3_constructor constr; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_constructor(_v_constr, &constr, _ctx); - Z3_del_constructor(c, constr); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_mk_datatype( - value _v_c, - value _v_name, - value _v_constructors) -{ - Z3_context c; /*in*/ - Z3_symbol name; /*in*/ - unsigned int num_constructors; /*in*/ - Z3_constructor *constructors; /*in,out*/ - Z3_sort _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - value _v5; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_name, &name, _ctx); - _c1 = Wosize_val(_v_constructors); - constructors = camlidl_malloc(_c1 * sizeof(Z3_constructor ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_constructors, _c2); - camlidl_ml2c_z3V3_Z3_constructor(_v3, &constructors[_c2], _ctx); - } - num_constructors = _c1; - _res = Z3_mk_datatype(c, name, num_constructors, constructors); - Begin_roots_block(_vres, 2) - _vres[0] = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - _vres[1] = camlidl_alloc(num_constructors, 0); - Begin_root(_vres[1]) - for (_c4 = 0; _c4 < num_constructors; _c4++) { - _v5 = camlidl_c2ml_z3V3_Z3_constructor(&constructors[_c4], _ctx); - modify(&Field(_vres[1], _c4), _v5); - } - End_roots() - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_mk_constructor_list( - value _v_c, - value _v_constructors) -{ - Z3_context c; /*in*/ - unsigned int num_constructors; /*in*/ - Z3_constructor const *constructors; /*in*/ - Z3_constructor_list _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_constructors); - constructors = camlidl_malloc(_c1 * sizeof(Z3_constructor const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_constructors, _c2); - camlidl_ml2c_z3V3_Z3_constructor(_v3, &constructors[_c2], _ctx); - } - num_constructors = _c1; - _res = Z3_mk_constructor_list(c, num_constructors, constructors); - _vres = camlidl_c2ml_z3V3_Z3_constructor_list(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_del_constructor_list( - value _v_c, - value _v_clist) -{ - Z3_context c; /*in*/ - Z3_constructor_list clist; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_constructor_list(_v_clist, &clist, _ctx); - Z3_del_constructor_list(c, clist); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_mk_datatypes( - value _v_c, - value _v_sort_names, - value _v_constructor_lists) -{ - Z3_context c; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort *sorts; /*out*/ - Z3_constructor_list *constructor_lists; /*in,out*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - value _v8; - mlsize_t _c9; - value _v10; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_constructor_lists); - constructor_lists = camlidl_malloc(_c4 * sizeof(Z3_constructor_list ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_constructor_lists, _c5); - camlidl_ml2c_z3V3_Z3_constructor_list(_v6, &constructor_lists[_c5], _ctx); - } - num_sorts = _c4; - sorts = camlidl_malloc(num_sorts * sizeof(Z3_sort ), _ctx); - Z3_mk_datatypes(c, num_sorts, sort_names, sorts, constructor_lists); - Begin_roots_block(_vres, 2) - _vres[0] = camlidl_alloc(num_sorts, 0); - Begin_root(_vres[0]) - for (_c7 = 0; _c7 < num_sorts; _c7++) { - _v8 = camlidl_c2ml_z3V3_Z3_sort(&sorts[_c7], _ctx); - modify(&Field(_vres[0], _c7), _v8); - } - End_roots() - _vres[1] = camlidl_alloc(num_sorts, 0); - Begin_root(_vres[1]) - for (_c9 = 0; _c9 < num_sorts; _c9++) { - _v10 = camlidl_c2ml_z3V3_Z3_constructor_list(&constructor_lists[_c9], _ctx); - modify(&Field(_vres[1], _c9), _v10); - } - End_roots() - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_query_constructor( - value _v_c, - value _v_constr, - value _v_num_fields) -{ - Z3_context c; /*in*/ - Z3_constructor constr; /*in*/ - unsigned int num_fields; /*in*/ - Z3_func_decl *constructor; /*out*/ - Z3_func_decl *tester; /*out*/ - Z3_func_decl *accessors; /*out*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_func_decl _c1; - Z3_func_decl _c2; - mlsize_t _c3; - value _v4; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_constructor(_v_constr, &constr, _ctx); - num_fields = Int_val(_v_num_fields); - constructor = &_c1; - tester = &_c2; - accessors = camlidl_malloc(num_fields * sizeof(Z3_func_decl ), _ctx); - Z3_query_constructor(c, constr, num_fields, constructor, tester, accessors); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_c2ml_z3V3_Z3_func_decl(&*constructor, _ctx); - _vres[1] = camlidl_c2ml_z3V3_Z3_func_decl(&*tester, _ctx); - _vres[2] = camlidl_alloc(num_fields, 0); - Begin_root(_vres[2]) - for (_c3 = 0; _c3 < num_fields; _c3++) { - _v4 = camlidl_c2ml_z3V3_Z3_func_decl(&accessors[_c3], _ctx); - modify(&Field(_vres[2], _c3), _v4); - } - End_roots() - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_mk_func_decl( - value _v_c, - value _v_s, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - unsigned int domain_size; /*in*/ - Z3_sort const *domain; /*in*/ - Z3_sort range; /*in*/ - Z3_func_decl _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _c1 = Wosize_val(_v_domain); - domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_domain, _c2); - camlidl_ml2c_z3V3_Z3_sort(_v3, &domain[_c2], _ctx); - } - domain_size = _c1; - camlidl_ml2c_z3V3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_func_decl(c, s, domain_size, domain, range); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_app( - value _v_c, - value _v_d, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_app(c, d, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_const( - value _v_c, - value _v_s, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_const(c, s, ty); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_fresh_func_decl( - value _v_c, - value _v_prefix, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_string prefix; /*in*/ - unsigned int domain_size; /*in*/ - Z3_sort const *domain; /*in*/ - Z3_sort range; /*in*/ - Z3_func_decl _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_prefix, &prefix, _ctx); - _c1 = Wosize_val(_v_domain); - domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_domain, _c2); - camlidl_ml2c_z3V3_Z3_sort(_v3, &domain[_c2], _ctx); - } - domain_size = _c1; - camlidl_ml2c_z3V3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_fresh_func_decl(c, prefix, domain_size, domain, range); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_fresh_const( - value _v_c, - value _v_prefix, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_string prefix; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_prefix, &prefix, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_fresh_const(c, prefix, ty); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_true( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_true(c); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_false( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_mk_false(c); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_eq( - value _v_c, - value _v_l, - value _v_r) -{ - Z3_context c; /*in*/ - Z3_ast l; /*in*/ - Z3_ast r; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_l, &l, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_r, &r, _ctx); - _res = Z3_mk_eq(c, l, r); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_distinct( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_distinct(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_not( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_mk_not(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_ite( - value _v_c, - value _v_t1, - value _v_t2, - value _v_t3) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast t3; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t3, &t3, _ctx); - _res = Z3_mk_ite(c, t1, t2, t3); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_iff( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_iff(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_implies( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_implies(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_xor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_xor(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_and( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_and(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_or( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_or(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_add( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_add(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_mul( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_mul(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_sub( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_sub(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_unary_minus( - value _v_c, - value _v_arg) -{ - Z3_context c; /*in*/ - Z3_ast arg; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg, &arg, _ctx); - _res = Z3_mk_unary_minus(c, arg); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_div( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_div(c, arg1, arg2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_mod( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_mod(c, arg1, arg2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_rem( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_rem(c, arg1, arg2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_power( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_power(c, arg1, arg2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_lt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_lt(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_le( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_le(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_gt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_gt(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_ge( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_ge(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_int2real( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_int2real(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_real2int( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_real2int(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_is_int( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_is_int(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvnot( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvnot(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvredand( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvredand(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvredor( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvredor(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvand( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvand(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvor(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvxor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvxor(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvnand( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvnand(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvnor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvnor(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvxnor( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvxnor(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvneg( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvneg(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvadd( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvadd(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsub( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsub(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvmul( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvmul(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvudiv( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvudiv(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsdiv( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsdiv(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvurem( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvurem(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsrem( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsrem(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsmod( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsmod(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvult( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvult(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvslt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvslt(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvule( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvule(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsle( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsle(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvuge( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvuge(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsge( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsge(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvugt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvugt(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsgt( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsgt(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_concat( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_concat(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_extract( - value _v_c, - value _v_high, - value _v_low, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int high; /*in*/ - unsigned int low; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - high = Int_val(_v_high); - low = Int_val(_v_low); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_extract(c, high, low, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_sign_ext( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_sign_ext(c, i, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_zero_ext( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_zero_ext(c, i, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_repeat( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_repeat(c, i, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvshl( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvshl(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvlshr( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvlshr(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvashr( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvashr(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_rotate_left( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_rotate_left(c, i, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_rotate_right( - value _v_c, - value _v_i, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_rotate_right(c, i, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_ext_rotate_left( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_ext_rotate_left(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_ext_rotate_right( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_ext_rotate_right(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_int2bv( - value _v_c, - value _v_n, - value _v_t1) -{ - Z3_context c; /*in*/ - unsigned int n; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - n = Int_val(_v_n); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_int2bv(c, n, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bv2int( - value _v_c, - value _v_t1, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bv2int(c, t1, is_signed); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvadd_no_overflow( - value _v_c, - value _v_t1, - value _v_t2, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bvadd_no_overflow(c, t1, t2, is_signed); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvadd_no_underflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvadd_no_underflow(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsub_no_overflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsub_no_overflow(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsub_no_underflow( - value _v_c, - value _v_t1, - value _v_t2, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bvsub_no_underflow(c, t1, t2, is_signed); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvsdiv_no_overflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvsdiv_no_overflow(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvneg_no_overflow( - value _v_c, - value _v_t1) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - _res = Z3_mk_bvneg_no_overflow(c, t1); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvmul_no_overflow( - value _v_c, - value _v_t1, - value _v_t2, - value _v_is_signed) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int is_signed; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - is_signed = Int_val(_v_is_signed); - _res = Z3_mk_bvmul_no_overflow(c, t1, t2, is_signed); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bvmul_no_underflow( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_mk_bvmul_no_underflow(c, t1, t2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_select( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_i, &i, _ctx); - _res = Z3_mk_select(c, a, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_store( - value _v_c, - value _v_a, - value _v_i, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast i; /*in*/ - Z3_ast v; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_i, &i, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - _res = Z3_mk_store(c, a, i, v); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_const_array( - value _v_c, - value _v_domain, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_ast v; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_domain, &domain, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - _res = Z3_mk_const_array(c, domain, v); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_map( - value _v_c, - value _v_f, - value _v_n, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_func_decl f; /*in*/ - unsigned int n; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - Z3_ast _c1; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_f, &f, _ctx); - n = Int_val(_v_n); - args = &_c1; - camlidl_ml2c_z3V3_Z3_ast(_v_args, &_c1, _ctx); - _res = Z3_mk_map(c, f, n, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_array_default( - value _v_c, - value _v_array) -{ - Z3_context c; /*in*/ - Z3_ast array; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_array, &array, _ctx); - _res = Z3_mk_array_default(c, array); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_sort( - value _v_c, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_sort ty; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_set_sort(c, ty); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_empty_set( - value _v_c, - value _v_domain) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_domain, &domain, _ctx); - _res = Z3_mk_empty_set(c, domain); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_full_set( - value _v_c, - value _v_domain) -{ - Z3_context c; /*in*/ - Z3_sort domain; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_domain, &domain, _ctx); - _res = Z3_mk_full_set(c, domain); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_add( - value _v_c, - value _v_set, - value _v_elem) -{ - Z3_context c; /*in*/ - Z3_ast set; /*in*/ - Z3_ast elem; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_set, &set, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_elem, &elem, _ctx); - _res = Z3_mk_set_add(c, set, elem); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_del( - value _v_c, - value _v_set, - value _v_elem) -{ - Z3_context c; /*in*/ - Z3_ast set; /*in*/ - Z3_ast elem; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_set, &set, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_elem, &elem, _ctx); - _res = Z3_mk_set_del(c, set, elem); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_union( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_set_union(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_intersect( - value _v_c, - value _v_args) -{ - Z3_context c; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_mk_set_intersect(c, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_difference( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_set_difference(c, arg1, arg2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_complement( - value _v_c, - value _v_arg) -{ - Z3_context c; /*in*/ - Z3_ast arg; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg, &arg, _ctx); - _res = Z3_mk_set_complement(c, arg); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_member( - value _v_c, - value _v_elem, - value _v_set) -{ - Z3_context c; /*in*/ - Z3_ast elem; /*in*/ - Z3_ast set; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_elem, &elem, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_set, &set, _ctx); - _res = Z3_mk_set_member(c, elem, set); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_set_subset( - value _v_c, - value _v_arg1, - value _v_arg2) -{ - Z3_context c; /*in*/ - Z3_ast arg1; /*in*/ - Z3_ast arg2; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg1, &arg1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_arg2, &arg2, _ctx); - _res = Z3_mk_set_subset(c, arg1, arg2); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_numeral( - value _v_c, - value _v_numeral, - value _v_ty) -{ - Z3_context c; /*in*/ - Z3_string numeral; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_numeral, &numeral, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_numeral(c, numeral, ty); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_real( - value _v_c, - value _v_num, - value _v_den) -{ - Z3_context c; /*in*/ - int num; /*in*/ - int den; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - num = Int_val(_v_num); - den = Int_val(_v_den); - _res = Z3_mk_real(c, num, den); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_int( - value _v_c, - value _v_v, - value _v_ty) -{ - Z3_context c; /*in*/ - int v; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - v = Int_val(_v_v); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_int(c, v, ty); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_int64( - value _v_c, - value _v_v, - value _v_ty) -{ - Z3_context c; /*in*/ - long long v; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - v = Int64_val(_v_v); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_int64(c, v, ty); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_pattern( - value _v_c, - value _v_terms) -{ - Z3_context c; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_ast const *terms; /*in*/ - Z3_pattern _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_terms); - terms = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_terms, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &terms[_c2], _ctx); - } - num_patterns = _c1; - _res = Z3_mk_pattern(c, num_patterns, terms); - _vres = camlidl_c2ml_z3V3_Z3_pattern(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_bound( - value _v_c, - value _v_index, - value _v_ty) -{ - Z3_context c; /*in*/ - unsigned int index; /*in*/ - Z3_sort ty; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - index = Int_val(_v_index); - camlidl_ml2c_z3V3_Z3_sort(_v_ty, &ty, _ctx); - _res = Z3_mk_bound(c, index, ty); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_forall( - value _v_c, - value _v_weight, - value _v_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3V3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_decls = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_forall(c, weight, num_patterns, patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_forall_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_forall(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_mk_exists( - value _v_c, - value _v_weight, - value _v_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3V3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_decls = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_exists(c, weight, num_patterns, patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_exists_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_exists(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_mk_quantifier( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3V3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_decls = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier(c, is_forall, weight, num_patterns, patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_quantifier_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_quantifier(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); -} - -value camlidl_z3V3_Z3_mk_quantifier_ex( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_quantifier_id, - value _v_skolem_id, - value _v_patterns, - value _v_no_patterns, - value _v_sorts, - value _v_decl_names, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - Z3_symbol quantifier_id; /*in*/ - Z3_symbol skolem_id; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_no_patterns; /*in*/ - Z3_ast const *no_patterns; /*in*/ - unsigned int num_decls; /*in*/ - Z3_sort const *sorts; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - camlidl_ml2c_z3V3_Z3_symbol(_v_quantifier_id, &quantifier_id, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_skolem_id, &skolem_id, _ctx); - _c1 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c1 * sizeof(Z3_pattern const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_patterns, _c2); - camlidl_ml2c_z3V3_Z3_pattern(_v3, &patterns[_c2], _ctx); - } - num_patterns = _c1; - _c4 = Wosize_val(_v_no_patterns); - no_patterns = camlidl_malloc(_c4 * sizeof(Z3_ast const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_no_patterns, _c5); - camlidl_ml2c_z3V3_Z3_ast(_v6, &no_patterns[_c5], _ctx); - } - num_no_patterns = _c4; - _c7 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c7 * sizeof(Z3_sort const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_sorts, _c8); - camlidl_ml2c_z3V3_Z3_sort(_v9, &sorts[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c10 * sizeof(Z3_symbol const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decl_names, _c11); - camlidl_ml2c_z3V3_Z3_symbol(_v12, &decl_names[_c11], _ctx); - } - num_decls = _c10; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns, num_no_patterns, no_patterns, num_decls, sorts, decl_names, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_quantifier_ex_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_quantifier_ex(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]); -} - -value camlidl_z3V3_Z3_mk_forall_const( - value _v_c, - value _v_weight, - value _v_bound, - value _v_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3V3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3V3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_forall_const(c, weight, num_bound, bound, num_patterns, patterns, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_exists_const( - value _v_c, - value _v_weight, - value _v_bound, - value _v_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3V3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3V3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_exists_const(c, weight, num_bound, bound, num_patterns, patterns, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_quantifier_const( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_bound, - value _v_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3V3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3V3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier_const(c, is_forall, weight, num_bound, bound, num_patterns, patterns, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_quantifier_const_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_quantifier_const(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_mk_quantifier_const_ex( - value _v_c, - value _v_is_forall, - value _v_weight, - value _v_quantifier_id, - value _v_skolem_id, - value _v_bound, - value _v_patterns, - value _v_no_patterns, - value _v_body) -{ - Z3_context c; /*in*/ - int is_forall; /*in*/ - unsigned int weight; /*in*/ - Z3_symbol quantifier_id; /*in*/ - Z3_symbol skolem_id; /*in*/ - unsigned int num_bound; /*in*/ - Z3_app const *bound; /*in*/ - unsigned int num_patterns; /*in*/ - Z3_pattern const *patterns; /*in*/ - unsigned int num_no_patterns; /*in*/ - Z3_ast const *no_patterns; /*in*/ - Z3_ast body; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - is_forall = Int_val(_v_is_forall); - weight = Int_val(_v_weight); - camlidl_ml2c_z3V3_Z3_symbol(_v_quantifier_id, &quantifier_id, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_skolem_id, &skolem_id, _ctx); - _c1 = Wosize_val(_v_bound); - bound = camlidl_malloc(_c1 * sizeof(Z3_app const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_bound, _c2); - camlidl_ml2c_z3V3_Z3_app(_v3, &bound[_c2], _ctx); - } - num_bound = _c1; - _c4 = Wosize_val(_v_patterns); - patterns = camlidl_malloc(_c4 * sizeof(Z3_pattern const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_patterns, _c5); - camlidl_ml2c_z3V3_Z3_pattern(_v6, &patterns[_c5], _ctx); - } - num_patterns = _c4; - _c7 = Wosize_val(_v_no_patterns); - no_patterns = camlidl_malloc(_c7 * sizeof(Z3_ast const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_no_patterns, _c8); - camlidl_ml2c_z3V3_Z3_ast(_v9, &no_patterns[_c8], _ctx); - } - num_no_patterns = _c7; - camlidl_ml2c_z3V3_Z3_ast(_v_body, &body, _ctx); - _res = Z3_mk_quantifier_const_ex(c, is_forall, weight, quantifier_id, skolem_id, num_bound, bound, num_patterns, patterns, num_no_patterns, no_patterns, body); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_quantifier_const_ex_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_mk_quantifier_const_ex(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]); -} - -value camlidl_z3V3_Z3_get_symbol_kind( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_symbol_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_get_symbol_kind(c, s); - _vres = camlidl_c2ml_z3V3_Z3_symbol_kind(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_symbol_int( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_get_symbol_int(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_symbol_string( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_get_symbol_string(c, s); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_sort_name( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_sort d; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_d, &d, _ctx); - _res = Z3_get_sort_name(c, d); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_sort_id( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_get_sort_id(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_sort_to_ast( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_sort_to_ast(c, s); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_eq_sort( - value _v_c, - value _v_s1, - value _v_s2) -{ - Z3_context c; /*in*/ - Z3_sort s1; /*in*/ - Z3_sort s2; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s1, &s1, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s2, &s2, _ctx); - _res = Z3_is_eq_sort(c, s1, s2); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_sort_kind( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_sort_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_sort_kind(c, t); - _vres = camlidl_c2ml_z3V3_Z3_sort_kind(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_bv_sort_size( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_bv_sort_size(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_finite_domain_sort_size( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned long long *r; /*out*/ - unsigned long long _c1; - value _v2; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - r = &_c1; - Z3_get_finite_domain_sort_size(c, s, r); - if (r == NULL) { - _vres = Val_int(0); - } else { - _v2 = copy_int64(*r); - Begin_root(_v2) - _vres = camlidl_alloc_small(1, 0); - Field(_vres, 0) = _v2; - End_roots(); - } - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_array_sort_domain( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_array_sort_domain(c, t); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_array_sort_range( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_array_sort_range(c, t); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_tuple_sort_mk_decl( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_tuple_sort_mk_decl(c, t); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_tuple_sort_num_fields( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_tuple_sort_num_fields(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_tuple_sort_field_decl( - value _v_c, - value _v_t, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - i = Int_val(_v_i); - _res = Z3_get_tuple_sort_field_decl(c, t, i); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_datatype_sort_num_constructors( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - _res = Z3_get_datatype_sort_num_constructors(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_datatype_sort_constructor( - value _v_c, - value _v_t, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int idx; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_datatype_sort_constructor(c, t, idx); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_datatype_sort_recognizer( - value _v_c, - value _v_t, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int idx; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_datatype_sort_recognizer(c, t, idx); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_datatype_sort_constructor_accessor( - value _v_c, - value _v_t, - value _v_idx_c, - value _v_idx_a) -{ - Z3_context c; /*in*/ - Z3_sort t; /*in*/ - unsigned int idx_c; /*in*/ - unsigned int idx_a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_t, &t, _ctx); - idx_c = Int_val(_v_idx_c); - idx_a = Int_val(_v_idx_a); - _res = Z3_get_datatype_sort_constructor_accessor(c, t, idx_c, idx_a); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_relation_arity( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_get_relation_arity(c, s); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_relation_column( - value _v_c, - value _v_s, - value _v_col) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - unsigned int col; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - col = Int_val(_v_col); - _res = Z3_get_relation_column(c, s, col); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_func_decl_to_ast( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_decl f; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_f, &f, _ctx); - _res = Z3_func_decl_to_ast(c, f); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_eq_func_decl( - value _v_c, - value _v_f1, - value _v_f2) -{ - Z3_context c; /*in*/ - Z3_func_decl f1; /*in*/ - Z3_func_decl f2; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_f1, &f1, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_f2, &f2, _ctx); - _res = Z3_is_eq_func_decl(c, f1, f2); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_func_decl_id( - value _v_c, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_func_decl f; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_f, &f, _ctx); - _res = Z3_get_func_decl_id(c, f); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_name( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_decl_name(c, d); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_kind( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_decl_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_decl_kind(c, d); - _vres = camlidl_c2ml_z3V3_Z3_decl_kind(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_domain_size( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_domain_size(c, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_arity( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_arity(c, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_domain( - value _v_c, - value _v_d, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - i = Int_val(_v_i); - _res = Z3_get_domain(c, d, i); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_range( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_range(c, d); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_num_parameters( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_get_decl_num_parameters(c, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_parameter_kind( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_parameter_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_parameter_kind(c, d, idx); - _vres = camlidl_c2ml_z3V3_Z3_parameter_kind(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_int_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_int_parameter(c, d, idx); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_double_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - double _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_double_parameter(c, d, idx); - _vres = copy_double(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_symbol_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_symbol_parameter(c, d, idx); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_sort_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_sort_parameter(c, d, idx); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_ast_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_ast_parameter(c, d, idx); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_func_decl_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_func_decl_parameter(c, d, idx); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_decl_rational_parameter( - value _v_c, - value _v_d, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int idx; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_decl_rational_parameter(c, d, idx); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_app_to_ast( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_app(_v_a, &a, _ctx); - _res = Z3_app_to_ast(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_app_decl( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_app(_v_a, &a, _ctx); - _res = Z3_get_app_decl(c, a); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_app_num_args( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_app(_v_a, &a, _ctx); - _res = Z3_get_app_num_args(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_app_arg( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_app a; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_app(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_app_arg(c, a, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_eq_ast( - value _v_c, - value _v_t1, - value _v_t2) -{ - Z3_context c; /*in*/ - Z3_ast t1; /*in*/ - Z3_ast t2; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t1, &t1, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t2, &t2, _ctx); - _res = Z3_is_eq_ast(c, t1, t2); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_ast_id( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_ast t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t, &t, _ctx); - _res = Z3_get_ast_id(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_ast_hash( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_ast_hash(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_sort( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_sort(c, a); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_well_sorted( - value _v_c, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_ast t; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t, &t, _ctx); - _res = Z3_is_well_sorted(c, t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_bool_value( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_lbool _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_bool_value(c, a); - _vres = camlidl_c2ml_z3V3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_ast_kind( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast_kind _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_ast_kind(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast_kind(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_app( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_app(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_numeral_ast( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_numeral_ast(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_algebraic_number( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_algebraic_number(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_to_app( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_app _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_to_app(c, a); - _vres = camlidl_c2ml_z3V3_Z3_app(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_to_func_decl( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_to_func_decl(c, a); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_numeral_string( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_numeral_string(c, a); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_numeral_decimal_string( - value _v_c, - value _v_a, - value _v_precision) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int precision; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - precision = Int_val(_v_precision); - _res = Z3_get_numeral_decimal_string(c, a, precision); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_numerator( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_numerator(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_denominator( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_denominator(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_numeral_small( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - long long *num; /*out*/ - long long *den; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - long long _c1; - long long _c2; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - num = &_c1; - den = &_c2; - _res = Z3_get_numeral_small(c, a, num, den); - Begin_roots_block(_vres, 3) - _vres[0] = Val_int(_res); - _vres[1] = copy_int64(*num); - _vres[2] = copy_int64(*den); - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_get_numeral_int( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast v; /*in*/ - int *i; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - int _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - i = &_c1; - _res = Z3_get_numeral_int(c, v, i); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = Val_int(*i); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_get_numeral_int64( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast v; /*in*/ - long long *i; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - long long _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - i = &_c1; - _res = Z3_get_numeral_int64(c, v, i); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = copy_int64(*i); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_get_numeral_rational_int64( - value _v_c, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_ast v; /*in*/ - long long *num; /*out*/ - long long *den; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - long long _c1; - long long _c2; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - num = &_c1; - den = &_c2; - _res = Z3_get_numeral_rational_int64(c, v, num, den); - Begin_roots_block(_vres, 3) - _vres[0] = Val_int(_res); - _vres[1] = copy_int64(*num); - _vres[2] = copy_int64(*den); - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_get_algebraic_number_lower( - value _v_c, - value _v_a, - value _v_precision) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int precision; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - precision = Int_val(_v_precision); - _res = Z3_get_algebraic_number_lower(c, a, precision); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_algebraic_number_upper( - value _v_c, - value _v_a, - value _v_precision) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int precision; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - precision = Int_val(_v_precision); - _res = Z3_get_algebraic_number_upper(c, a, precision); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_pattern_to_ast( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_pattern(_v_p, &p, _ctx); - _res = Z3_pattern_to_ast(c, p); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_pattern_num_terms( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_pattern(_v_p, &p, _ctx); - _res = Z3_get_pattern_num_terms(c, p); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_pattern( - value _v_c, - value _v_p, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - unsigned int idx; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_pattern(_v_p, &p, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_pattern(c, p, idx); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_index_value( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_index_value(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_is_quantifier_forall( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_is_quantifier_forall(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_weight( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_weight(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_num_patterns( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_num_patterns(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_pattern_ast( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_pattern _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_pattern_ast(c, a, i); - _vres = camlidl_c2ml_z3V3_Z3_pattern(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_num_no_patterns( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_num_no_patterns(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_no_pattern_ast( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_no_pattern_ast(c, a, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_num_bound( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_num_bound(c, a); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_bound_name( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_bound_name(c, a, i); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_bound_sort( - value _v_c, - value _v_a, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - i = Int_val(_v_i); - _res = Z3_get_quantifier_bound_sort(c, a, i); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_quantifier_body( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_get_quantifier_body(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_simplify( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_simplify(c, a); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_update_term( - value _v_c, - value _v_a, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - _res = Z3_update_term(c, a, num_args, args); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_substitute( - value _v_c, - value _v_a, - value _v_from, - value _v_to) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_exprs; /*in*/ - Z3_ast const *from; /*in*/ - Z3_ast const *to; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _c1 = Wosize_val(_v_from); - from = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_from, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &from[_c2], _ctx); - } - num_exprs = _c1; - _c4 = Wosize_val(_v_to); - to = camlidl_malloc(_c4 * sizeof(Z3_ast const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_to, _c5); - camlidl_ml2c_z3V3_Z3_ast(_v6, &to[_c5], _ctx); - } - num_exprs = _c4; - _res = Z3_substitute(c, a, num_exprs, from, to); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_substitute_vars( - value _v_c, - value _v_a, - value _v_to) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_exprs; /*in*/ - Z3_ast const *to; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _c1 = Wosize_val(_v_to); - to = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_to, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &to[_c2], _ctx); - } - num_exprs = _c1; - _res = Z3_substitute_vars(c, a, num_exprs, to); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_open_log( - value _v_filename) -{ - Z3_string filename; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_string(_v_filename, &filename, _ctx); - _res = Z3_open_log(filename); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_append_log( - value _v_string) -{ - Z3_string string; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_string(_v_string, &string, _ctx); - Z3_append_log(string); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_close_log(value _unit) -{ - Z3_close_log(); - return Val_unit; -} - -value camlidl_z3V3_Z3_toggle_warning_messages( - value _v_enabled) -{ - int enabled; /*in*/ - enabled = Int_val(_v_enabled); - Z3_toggle_warning_messages(enabled); - return Val_unit; -} - -value camlidl_z3V3_Z3_set_ast_print_mode( - value _v_c, - value _v_mode) -{ - Z3_context c; /*in*/ - Z3_ast_print_mode mode; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast_print_mode(_v_mode, &mode, _ctx); - Z3_set_ast_print_mode(c, mode); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_ast_to_string( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - _res = Z3_ast_to_string(c, a); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_pattern_to_string( - value _v_c, - value _v_p) -{ - Z3_context c; /*in*/ - Z3_pattern p; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_pattern(_v_p, &p, _ctx); - _res = Z3_pattern_to_string(c, p); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_sort_to_string( - value _v_c, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_sort s; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_sort_to_string(c, s); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_func_decl_to_string( - value _v_c, - value _v_d) -{ - Z3_context c; /*in*/ - Z3_func_decl d; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_func_decl_to_string(c, d); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_model_to_string( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - _res = Z3_model_to_string(c, m); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_benchmark_to_smtlib_string( - value _v_c, - value _v_name, - value _v_logic, - value _v_status, - value _v_attributes, - value _v_assumptions, - value _v_formula) -{ - Z3_context c; /*in*/ - Z3_string name; /*in*/ - Z3_string logic; /*in*/ - Z3_string status; /*in*/ - Z3_string attributes; /*in*/ - unsigned int num_assumptions; /*in*/ - Z3_ast const *assumptions; /*in*/ - Z3_ast formula; /*in*/ - Z3_string _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_name, &name, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_logic, &logic, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_status, &status, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_attributes, &attributes, _ctx); - _c1 = Wosize_val(_v_assumptions); - assumptions = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_assumptions, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &assumptions[_c2], _ctx); - } - num_assumptions = _c1; - camlidl_ml2c_z3V3_Z3_ast(_v_formula, &formula, _ctx); - _res = Z3_benchmark_to_smtlib_string(c, name, logic, status, attributes, num_assumptions, assumptions, formula); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_benchmark_to_smtlib_string_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_benchmark_to_smtlib_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); -} - -value camlidl_z3V3_Z3_parse_smtlib2_string( - value _v_c, - value _v_str, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string str; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_str, &str, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3V3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - _res = Z3_parse_smtlib2_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_parse_smtlib2_string_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_parse_smtlib2_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_parse_smtlib2_file( - value _v_c, - value _v_file_name, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string file_name; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - Z3_ast _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_file_name, &file_name, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3V3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - _res = Z3_parse_smtlib2_file(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_parse_smtlib2_file_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_parse_smtlib2_file(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_parse_smtlib_string( - value _v_c, - value _v_str, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string str; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_str, &str, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3V3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_parse_smtlib_string_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_parse_smtlib_string(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_parse_smtlib_file( - value _v_c, - value _v_file_name, - value _v_sort_names, - value _v_sorts, - value _v_decl_names, - value _v_decls) -{ - Z3_context c; /*in*/ - Z3_string file_name; /*in*/ - unsigned int num_sorts; /*in*/ - Z3_symbol const *sort_names; /*in*/ - Z3_sort const *sorts; /*in*/ - unsigned int num_decls; /*in*/ - Z3_symbol const *decl_names; /*in*/ - Z3_func_decl const *decls; /*in*/ - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - mlsize_t _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - mlsize_t _c11; - value _v12; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_file_name, &file_name, _ctx); - _c1 = Wosize_val(_v_sort_names); - sort_names = camlidl_malloc(_c1 * sizeof(Z3_symbol const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_sort_names, _c2); - camlidl_ml2c_z3V3_Z3_symbol(_v3, &sort_names[_c2], _ctx); - } - num_sorts = _c1; - _c4 = Wosize_val(_v_sorts); - sorts = camlidl_malloc(_c4 * sizeof(Z3_sort const ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_sorts, _c5); - camlidl_ml2c_z3V3_Z3_sort(_v6, &sorts[_c5], _ctx); - } - num_sorts = _c4; - _c7 = Wosize_val(_v_decl_names); - decl_names = camlidl_malloc(_c7 * sizeof(Z3_symbol const ), _ctx); - for (_c8 = 0; _c8 < _c7; _c8++) { - _v9 = Field(_v_decl_names, _c8); - camlidl_ml2c_z3V3_Z3_symbol(_v9, &decl_names[_c8], _ctx); - } - num_decls = _c7; - _c10 = Wosize_val(_v_decls); - decls = camlidl_malloc(_c10 * sizeof(Z3_func_decl const ), _ctx); - for (_c11 = 0; _c11 < _c10; _c11++) { - _v12 = Field(_v_decls, _c11); - camlidl_ml2c_z3V3_Z3_func_decl(_v12, &decls[_c11], _ctx); - } - num_decls = _c10; - Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_parse_smtlib_file_bytecode(value * argv, int argn) -{ - return camlidl_z3V3_Z3_parse_smtlib_file(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); -} - -value camlidl_z3V3_Z3_get_smtlib_num_formulas( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_formulas(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_formula( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_formula(c, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_num_assumptions( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_assumptions(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_assumption( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_assumption(c, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_num_decls( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_decls(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_decl( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_decl(c, i); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_num_sorts( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_num_sorts(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_sort( - value _v_c, - value _v_i) -{ - Z3_context c; /*in*/ - unsigned int i; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - i = Int_val(_v_i); - _res = Z3_get_smtlib_sort(c, i); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_smtlib_error( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_smtlib_error(c); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_version(value _unit) -{ - unsigned int *major; /*out*/ - unsigned int *minor; /*out*/ - unsigned int *build_number; /*out*/ - unsigned int *revision_number; /*out*/ - unsigned int _c1; - unsigned int _c2; - unsigned int _c3; - unsigned int _c4; - value _vresult; - value _vres[4] = { 0, 0, 0, 0, }; - - major = &_c1; - minor = &_c2; - build_number = &_c3; - revision_number = &_c4; - Z3_get_version(major, minor, build_number, revision_number); - Begin_roots_block(_vres, 4) - _vres[0] = Val_int(*major); - _vres[1] = Val_int(*minor); - _vres[2] = Val_int(*build_number); - _vres[3] = Val_int(*revision_number); - _vresult = camlidl_alloc_small(4, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - Field(_vresult, 3) = _vres[3]; - End_roots() - return _vresult; -} - -value camlidl_z3V3_Z3_enable_trace( - value _v_tag) -{ - Z3_string tag; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_string(_v_tag, &tag, _ctx); - Z3_enable_trace(tag); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_disable_trace( - value _v_tag) -{ - Z3_string tag; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_string(_v_tag, &tag, _ctx); - Z3_disable_trace(tag); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_reset_memory(value _unit) -{ - Z3_reset_memory(); - return Val_unit; -} - -value camlidl_z3V3_Z3_theory_mk_sort( - value _v_c, - value _v_t, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_theory t; /*in*/ - Z3_symbol s; /*in*/ - Z3_sort _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _res = Z3_theory_mk_sort(c, t, s); - _vres = camlidl_c2ml_z3V3_Z3_sort(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_mk_value( - value _v_c, - value _v_t, - value _v_n, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_theory t; /*in*/ - Z3_symbol n; /*in*/ - Z3_sort s; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_n, &n, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_theory_mk_value(c, t, n, s); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_mk_constant( - value _v_c, - value _v_t, - value _v_n, - value _v_s) -{ - Z3_context c; /*in*/ - Z3_theory t; /*in*/ - Z3_symbol n; /*in*/ - Z3_sort s; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_n, &n, _ctx); - camlidl_ml2c_z3V3_Z3_sort(_v_s, &s, _ctx); - _res = Z3_theory_mk_constant(c, t, n, s); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_mk_func_decl( - value _v_c, - value _v_t, - value _v_n, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_theory t; /*in*/ - Z3_symbol n; /*in*/ - unsigned int domain_size; /*in*/ - Z3_sort const *domain; /*in*/ - Z3_sort range; /*in*/ - Z3_func_decl _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_n, &n, _ctx); - _c1 = Wosize_val(_v_domain); - domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_domain, _c2); - camlidl_ml2c_z3V3_Z3_sort(_v3, &domain[_c2], _ctx); - } - domain_size = _c1; - camlidl_ml2c_z3V3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_theory_mk_func_decl(c, t, n, domain_size, domain, range); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_context( - value _v_t) -{ - Z3_theory t; /*in*/ - Z3_context _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - _res = Z3_theory_get_context(t); - _vres = camlidl_c2ml_z3V3_Z3_context(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_assert_axiom( - value _v_t, - value _v_ax) -{ - Z3_theory t; /*in*/ - Z3_ast ax; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_ax, &ax, _ctx); - Z3_theory_assert_axiom(t, ax); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_theory_assume_eq( - value _v_t, - value _v_lhs, - value _v_rhs) -{ - Z3_theory t; /*in*/ - Z3_ast lhs; /*in*/ - Z3_ast rhs; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_lhs, &lhs, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_rhs, &rhs, _ctx); - Z3_theory_assume_eq(t, lhs, rhs); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_theory_enable_axiom_simplification( - value _v_t, - value _v_flag) -{ - Z3_theory t; /*in*/ - int flag; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - flag = Int_val(_v_flag); - Z3_theory_enable_axiom_simplification(t, flag); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_theory_get_eqc_root( - value _v_t, - value _v_n) -{ - Z3_theory t; /*in*/ - Z3_ast n; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_n, &n, _ctx); - _res = Z3_theory_get_eqc_root(t, n); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_eqc_next( - value _v_t, - value _v_n) -{ - Z3_theory t; /*in*/ - Z3_ast n; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_n, &n, _ctx); - _res = Z3_theory_get_eqc_next(t, n); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_num_parents( - value _v_t, - value _v_n) -{ - Z3_theory t; /*in*/ - Z3_ast n; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_n, &n, _ctx); - _res = Z3_theory_get_num_parents(t, n); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_parent( - value _v_t, - value _v_n, - value _v_i) -{ - Z3_theory t; /*in*/ - Z3_ast n; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_n, &n, _ctx); - i = Int_val(_v_i); - _res = Z3_theory_get_parent(t, n, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_is_value( - value _v_t, - value _v_n) -{ - Z3_theory t; /*in*/ - Z3_ast n; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_n, &n, _ctx); - _res = Z3_theory_is_value(t, n); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_is_decl( - value _v_t, - value _v_d) -{ - Z3_theory t; /*in*/ - Z3_func_decl d; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _res = Z3_theory_is_decl(t, d); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_num_elems( - value _v_t) -{ - Z3_theory t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - _res = Z3_theory_get_num_elems(t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_elem( - value _v_t, - value _v_i) -{ - Z3_theory t; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - i = Int_val(_v_i); - _res = Z3_theory_get_elem(t, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_num_apps( - value _v_t) -{ - Z3_theory t; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - _res = Z3_theory_get_num_apps(t); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_theory_get_app( - value _v_t, - value _v_i) -{ - Z3_theory t; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_theory(_v_t, &t, _ctx); - i = Int_val(_v_i); - _res = Z3_theory_get_app(t, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_injective_function( - value _v_c, - value _v_s, - value _v_domain, - value _v_range) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - unsigned int domain_size; /*in*/ - Z3_sort const *domain; /*in*/ - Z3_sort range; /*in*/ - Z3_func_decl _res; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - _c1 = Wosize_val(_v_domain); - domain = camlidl_malloc(_c1 * sizeof(Z3_sort const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_domain, _c2); - camlidl_ml2c_z3V3_Z3_sort(_v3, &domain[_c2], _ctx); - } - domain_size = _c1; - camlidl_ml2c_z3V3_Z3_sort(_v_range, &range, _ctx); - _res = Z3_mk_injective_function(c, s, domain_size, domain, range); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_set_logic( - value _v_c, - value _v_logic) -{ - Z3_context c; /*in*/ - Z3_string logic; /*in*/ - int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_string(_v_logic, &logic, _ctx); - _res = Z3_set_logic(c, logic); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_push( - value _v_c) -{ - Z3_context c; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - Z3_push(c); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_pop( - value _v_c, - value _v_num_scopes) -{ - Z3_context c; /*in*/ - unsigned int num_scopes; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - num_scopes = Int_val(_v_num_scopes); - Z3_pop(c, num_scopes); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_get_num_scopes( - value _v_c) -{ - Z3_context c; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_num_scopes(c); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_persist_ast( - value _v_c, - value _v_a, - value _v_num_scopes) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - unsigned int num_scopes; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - num_scopes = Int_val(_v_num_scopes); - Z3_persist_ast(c, a, num_scopes); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_assert_cnstr( - value _v_c, - value _v_a) -{ - Z3_context c; /*in*/ - Z3_ast a; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_a, &a, _ctx); - Z3_assert_cnstr(c, a); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_check_and_get_model( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_model *m; /*out*/ - Z3_lbool _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_model _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - m = &_c1; - _res = Z3_check_and_get_model(c, m); - Begin_roots_block(_vres, 2) - _vres[0] = camlidl_c2ml_z3V3_Z3_lbool(&_res, _ctx); - _vres[1] = camlidl_c2ml_z3V3_Z3_model(&*m, _ctx); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_check( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_lbool _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_check(c); - _vres = camlidl_c2ml_z3V3_Z3_lbool(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_check_assumptions( - value _v_c, - value _v_assumptions, - value _v_core_size, - value _v_core) -{ - Z3_context c; /*in*/ - unsigned int num_assumptions; /*in*/ - Z3_ast const *assumptions; /*in*/ - Z3_model *m; /*out*/ - Z3_ast *proof; /*out*/ - unsigned int *core_size; /*in,out*/ - Z3_ast *core; /*in,out*/ - Z3_lbool _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - unsigned int _c4; - mlsize_t _c5; - mlsize_t _c6; - value _v7; - Z3_model _c8; - Z3_ast _c9; - mlsize_t _c10; - value _v11; - value _vresult; - value _vres[5] = { 0, 0, 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _c1 = Wosize_val(_v_assumptions); - assumptions = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_assumptions, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &assumptions[_c2], _ctx); - } - num_assumptions = _c1; - core_size = &_c4; - _c4 = Int_val(_v_core_size); - _c5 = Wosize_val(_v_core); - core = camlidl_malloc(_c5 * sizeof(Z3_ast ), _ctx); - for (_c6 = 0; _c6 < _c5; _c6++) { - _v7 = Field(_v_core, _c6); - camlidl_ml2c_z3V3_Z3_ast(_v7, &core[_c6], _ctx); - } - num_assumptions = _c5; - m = &_c8; - proof = &_c9; - _res = Z3_check_assumptions(c, num_assumptions, assumptions, m, proof, core_size, core); - Begin_roots_block(_vres, 5) - _vres[0] = camlidl_c2ml_z3V3_Z3_lbool(&_res, _ctx); - _vres[1] = camlidl_c2ml_z3V3_Z3_model(&*m, _ctx); - _vres[2] = camlidl_c2ml_z3V3_Z3_ast(&*proof, _ctx); - _vres[3] = Val_int(*core_size); - _vres[4] = camlidl_alloc(num_assumptions, 0); - Begin_root(_vres[4]) - for (_c10 = 0; _c10 < num_assumptions; _c10++) { - _v11 = camlidl_c2ml_z3V3_Z3_ast(&core[_c10], _ctx); - modify(&Field(_vres[4], _c10), _v11); - } - End_roots() - _vresult = camlidl_alloc_small(5, 0); - { mlsize_t _c12; - for (_c12 = 0; _c12 < 5; _c12++) Field(_vresult, _c12) = _vres[_c12]; - } - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_del_model( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - Z3_del_model(c, m); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_soft_check_cancel( - value _v_c) -{ - Z3_context c; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - Z3_soft_check_cancel(c); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_get_search_failure( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_search_failure _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_search_failure(c); - _vres = camlidl_c2ml_z3V3_Z3_search_failure(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_mk_label( - value _v_c, - value _v_s, - value _v_is_pos, - value _v_f) -{ - Z3_context c; /*in*/ - Z3_symbol s; /*in*/ - int is_pos; /*in*/ - Z3_ast f; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_symbol(_v_s, &s, _ctx); - is_pos = Int_val(_v_is_pos); - camlidl_ml2c_z3V3_Z3_ast(_v_f, &f, _ctx); - _res = Z3_mk_label(c, s, is_pos, f); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_relevant_labels( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_literals _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_relevant_labels(c); - _vres = camlidl_c2ml_z3V3_Z3_literals(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_relevant_literals( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_literals _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_relevant_literals(c); - _vres = camlidl_c2ml_z3V3_Z3_literals(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_guessed_literals( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_literals _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_guessed_literals(c); - _vres = camlidl_c2ml_z3V3_Z3_literals(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_del_literals( - value _v_c, - value _v_lbls) -{ - Z3_context c; /*in*/ - Z3_literals lbls; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_literals(_v_lbls, &lbls, _ctx); - Z3_del_literals(c, lbls); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_get_num_literals( - value _v_c, - value _v_lbls) -{ - Z3_context c; /*in*/ - Z3_literals lbls; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_literals(_v_lbls, &lbls, _ctx); - _res = Z3_get_num_literals(c, lbls); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_label_symbol( - value _v_c, - value _v_lbls, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_literals lbls; /*in*/ - unsigned int idx; /*in*/ - Z3_symbol _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_literals(_v_lbls, &lbls, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_label_symbol(c, lbls, idx); - _vres = camlidl_c2ml_z3V3_Z3_symbol(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_literal( - value _v_c, - value _v_lbls, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_literals lbls; /*in*/ - unsigned int idx; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_literals(_v_lbls, &lbls, _ctx); - idx = Int_val(_v_idx); - _res = Z3_get_literal(c, lbls, idx); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_disable_literal( - value _v_c, - value _v_lbls, - value _v_idx) -{ - Z3_context c; /*in*/ - Z3_literals lbls; /*in*/ - unsigned int idx; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_literals(_v_lbls, &lbls, _ctx); - idx = Int_val(_v_idx); - Z3_disable_literal(c, lbls, idx); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_block_literals( - value _v_c, - value _v_lbls) -{ - Z3_context c; /*in*/ - Z3_literals lbls; /*in*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_literals(_v_lbls, &lbls, _ctx); - Z3_block_literals(c, lbls); - camlidl_free(_ctx); - return Val_unit; -} - -value camlidl_z3V3_Z3_get_model_num_constants( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - _res = Z3_get_model_num_constants(c, m); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_constant( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_get_model_constant(c, m, i); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_num_funcs( - value _v_c, - value _v_m) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - _res = Z3_get_model_num_funcs(c, m); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_func_decl( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - Z3_func_decl _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_get_model_func_decl(c, m, i); - _vres = camlidl_c2ml_z3V3_Z3_func_decl(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_eval_func_decl( - value _v_c, - value _v_m, - value _v_decl) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_func_decl decl; /*in*/ - Z3_ast *v; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_ast _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_decl, &decl, _ctx); - v = &_c1; - _res = Z3_eval_func_decl(c, m, decl, v); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = camlidl_c2ml_z3V3_Z3_ast(&*v, _ctx); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_is_array_value( - value _v_c, - value _v_m, - value _v_v) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_ast v; /*in*/ - unsigned int *num_entries; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - unsigned int _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - num_entries = &_c1; - _res = Z3_is_array_value(c, m, v, num_entries); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = Val_int(*num_entries); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_get_array_value( - value _v_c, - value _v_m, - value _v_v, - value _v_indices, - value _v_values) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_ast v; /*in*/ - unsigned int num_entries; /*in*/ - Z3_ast *indices; /*in,out*/ - Z3_ast *values; /*in,out*/ - Z3_ast *else_value; /*out*/ - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - mlsize_t _c4; - mlsize_t _c5; - value _v6; - Z3_ast _c7; - mlsize_t _c8; - value _v9; - mlsize_t _c10; - value _v11; - value _vresult; - value _vres[3] = { 0, 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_v, &v, _ctx); - _c1 = Wosize_val(_v_indices); - indices = camlidl_malloc(_c1 * sizeof(Z3_ast ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_indices, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &indices[_c2], _ctx); - } - num_entries = _c1; - _c4 = Wosize_val(_v_values); - values = camlidl_malloc(_c4 * sizeof(Z3_ast ), _ctx); - for (_c5 = 0; _c5 < _c4; _c5++) { - _v6 = Field(_v_values, _c5); - camlidl_ml2c_z3V3_Z3_ast(_v6, &values[_c5], _ctx); - } - num_entries = _c4; - else_value = &_c7; - Z3_get_array_value(c, m, v, num_entries, indices, values, else_value); - Begin_roots_block(_vres, 3) - _vres[0] = camlidl_alloc(num_entries, 0); - Begin_root(_vres[0]) - for (_c8 = 0; _c8 < num_entries; _c8++) { - _v9 = camlidl_c2ml_z3V3_Z3_ast(&indices[_c8], _ctx); - modify(&Field(_vres[0], _c8), _v9); - } - End_roots() - _vres[1] = camlidl_alloc(num_entries, 0); - Begin_root(_vres[1]) - for (_c10 = 0; _c10 < num_entries; _c10++) { - _v11 = camlidl_c2ml_z3V3_Z3_ast(&values[_c10], _ctx); - modify(&Field(_vres[1], _c10), _v11); - } - End_roots() - _vres[2] = camlidl_c2ml_z3V3_Z3_ast(&*else_value, _ctx); - _vresult = camlidl_alloc_small(3, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - Field(_vresult, 2) = _vres[2]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_get_model_func_else( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_get_model_func_else(c, m, i); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_func_num_entries( - value _v_c, - value _v_m, - value _v_i) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - _res = Z3_get_model_func_num_entries(c, m, i); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_func_entry_num_args( - value _v_c, - value _v_m, - value _v_i, - value _v_j) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - unsigned int j; /*in*/ - unsigned int _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - j = Int_val(_v_j); - _res = Z3_get_model_func_entry_num_args(c, m, i, j); - _vres = Val_int(_res); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_func_entry_arg( - value _v_c, - value _v_m, - value _v_i, - value _v_j, - value _v_k) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - unsigned int j; /*in*/ - unsigned int k; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - j = Int_val(_v_j); - k = Int_val(_v_k); - _res = Z3_get_model_func_entry_arg(c, m, i, j, k); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_model_func_entry_value( - value _v_c, - value _v_m, - value _v_i, - value _v_j) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - unsigned int i; /*in*/ - unsigned int j; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - i = Int_val(_v_i); - j = Int_val(_v_j); - _res = Z3_get_model_func_entry_value(c, m, i, j); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_eval( - value _v_c, - value _v_m, - value _v_t) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_ast t; /*in*/ - Z3_ast *v; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - Z3_ast _c1; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3V3_Z3_ast(_v_t, &t, _ctx); - v = &_c1; - _res = Z3_eval(c, m, t, v); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = camlidl_c2ml_z3V3_Z3_ast(&*v, _ctx); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_eval_decl( - value _v_c, - value _v_m, - value _v_d, - value _v_args) -{ - Z3_context c; /*in*/ - Z3_model m; /*in*/ - Z3_func_decl d; /*in*/ - unsigned int num_args; /*in*/ - Z3_ast const *args; /*in*/ - Z3_ast *v; /*out*/ - int _res; - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - mlsize_t _c1; - mlsize_t _c2; - value _v3; - Z3_ast _c4; - value _vresult; - value _vres[2] = { 0, 0, }; - - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - camlidl_ml2c_z3V3_Z3_model(_v_m, &m, _ctx); - camlidl_ml2c_z3V3_Z3_func_decl(_v_d, &d, _ctx); - _c1 = Wosize_val(_v_args); - args = camlidl_malloc(_c1 * sizeof(Z3_ast const ), _ctx); - for (_c2 = 0; _c2 < _c1; _c2++) { - _v3 = Field(_v_args, _c2); - camlidl_ml2c_z3V3_Z3_ast(_v3, &args[_c2], _ctx); - } - num_args = _c1; - v = &_c4; - _res = Z3_eval_decl(c, m, d, num_args, args, v); - Begin_roots_block(_vres, 2) - _vres[0] = Val_int(_res); - _vres[1] = camlidl_c2ml_z3V3_Z3_ast(&*v, _ctx); - _vresult = camlidl_alloc_small(2, 0); - Field(_vresult, 0) = _vres[0]; - Field(_vresult, 1) = _vres[1]; - End_roots() - camlidl_free(_ctx); - return _vresult; -} - -value camlidl_z3V3_Z3_context_to_string( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_context_to_string(c); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_statistics_to_string( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_string _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_statistics_to_string(c); - _vres = camlidl_c2ml_z3V3_Z3_string(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - -value camlidl_z3V3_Z3_get_context_assignment( - value _v_c) -{ - Z3_context c; /*in*/ - Z3_ast _res; - value _vres; - - struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; - camlidl_ctx _ctx = &_ctxs; - camlidl_ml2c_z3V3_Z3_context(_v_c, &c, _ctx); - _res = Z3_get_context_assignment(c); - _vres = camlidl_c2ml_z3V3_Z3_ast(&_res, _ctx); - camlidl_free(_ctx); - return _vres; -} - diff --git a/src/api/ml/old/z3_theory_stubs.c b/src/api/ml/old/z3_theory_stubs.c deleted file mode 100644 index a48b94553..000000000 --- a/src/api/ml/old/z3_theory_stubs.c +++ /dev/null @@ -1,339 +0,0 @@ -/*++ -Copyright (c) Microsoft Corporation - -Module Name: - - z3_theory_stubs.c - -Abstract: - - OCaml C bindings for callbacks between OCaml and C for - theory plugins. - The API for theory plugins require associating a set of - callbacks as C function pointers. - We use the following strategy: - - - store in the user_ext_data blob that theory constructors allow - a record of callback functions. - - - define catch-all static callback functions that access the - ML record with the callbacks. It then invokes these through user-registered - application functions that apply the callback stored in the record to the - actual parameters. - It is tempting to avoid this user-registered callback and directly access - the record of callback functions and apply the proper field. - However, the layout of records appears to be opaque, or at least we assume it is - so, from the C runtime. - -Author: - - -Revision History: ---*/ - -#include -#include -#include -#include -#include -#include -#include -#ifdef Custom_tag -#include -#include -#endif - -#include "z3.h" - -#define ML_SIZE(_ty) ((sizeof(_ty) + sizeof(value) - 1)/ sizeof(value)) - -static value mk_func_decl(Z3_func_decl f) { - value _f = alloc(ML_SIZE(Z3_func_decl), Abstract_tag); - *((Z3_func_decl*) Bp_val(_f)) = f; - return _f; -} - -static value Val_ast(Z3_ast a) { - value _a = alloc(ML_SIZE(Z3_ast), Abstract_tag); - *((Z3_ast*) Bp_val(_a)) = a; - return _a; -} - - -static value Val_ast_array(unsigned int sz, Z3_ast const args[]) { - value res; - Z3_ast* args1; - unsigned int i; - args1 = malloc((sz+1)*sizeof(Z3_ast)); - for (i = 0; i < sz; ++i) { - args1[i] = args[i]; - } - args1[sz] = 0; - res = alloc_array((value (*)(char const*))Val_ast, (const char**)args1); - free(args1); - return res; -} - -// ------------------ -// get_theory_callbacks -// - -value get_theory_callbacks(value th) -{ - Z3_theory _th = *((Z3_theory*) Bp_val(th)); - return (value) Z3_theory_get_ext_data(_th); -} - -// ------------------ -// delete_theory -// -static void delete_callback_static(Z3_theory th) -{ - CAMLparam0(); - CAMLlocal1(f); - value user_data = (value) Z3_theory_get_ext_data(th); - f = *(caml_named_value("apply_delete")) ; - callback(f, user_data); - remove_global_root(&user_data); - CAMLreturn0; -} - -#define SET_CALLBACK(_cb_name) \ - value set_ ## _cb_name ## _callback_register(value th) \ - { \ - CAMLparam1(th); \ - Z3_theory _th = *((Z3_theory*) Bp_val(th)); \ - Z3_set_ ## _cb_name ## _callback(_th, _cb_name ## _callback_static); \ - CAMLreturn(Val_unit); \ - } \ - -SET_CALLBACK(delete); - - -// ------------------ -// mk_theory -// - -value mk_theory_register(value context, value name, value user_data) -{ - CAMLparam3(context, name, user_data); - Z3_context _context = *((Z3_context *) Bp_val(context)); - value _th; - Z3_theory th; - register_global_root(&user_data); - th = Z3_mk_theory(_context, String_val(name), (void*)user_data); - // jjb: test th == NULL ? - Z3_set_delete_callback(th, delete_callback_static); - _th = alloc(ML_SIZE(Z3_context), Abstract_tag); - *((Z3_theory*) Bp_val(_th)) = th; - CAMLreturn(_th); -} - - -// ------------------- -// reduce_app_callback - -static Z3_bool reduce_app_callback_static(Z3_theory th, Z3_func_decl f, unsigned num_args, Z3_ast const args[], Z3_ast* r) { - CAMLparam0(); - CAMLlocal4(cb, _r, _v, _args); - value user_data; - Z3_bool result; - - _args = Val_ast_array(num_args, args); - - user_data = (value) Z3_theory_get_ext_data(th); - - cb = *(caml_named_value("apply_reduce_app")); - _r = callback3(cb, user_data, mk_func_decl(f), _args); - - cb = *(caml_named_value("is_some")); - _v = callback(cb, _r); - result = 0 != Bool_val(_v); - - if (result && r) { - cb = *(caml_named_value("get_some")); - _v = callback(cb, _r); - *r = *((Z3_ast*) Bp_val(_v)); - } - - CAMLreturn (result); -} - -SET_CALLBACK(reduce_app); - -// ------------------- -// reduce_eq_callback - -static Z3_bool reduce_eq_callback_static(Z3_theory th, Z3_ast a, Z3_ast b, Z3_ast * r) -{ - CAMLparam0(); - CAMLlocal5(cb, _r, _a, _b, _v); - value user_data; - Z3_bool result; - - _a = Val_ast(a); - _b = Val_ast(b); - - user_data = (value) Z3_theory_get_ext_data(th); - - cb = *(caml_named_value("apply_reduce_eq")); - _r = callback3(cb, user_data, _a, _b); - - cb = *(caml_named_value("is_some")); - _v = callback(cb, _r); - result = 0 != Bool_val(_v); - - if (result && r) { - cb = *(caml_named_value("get_some")); - _v = callback(cb, _r); - *r = *((Z3_ast*) Bp_val(_v)); - } - - CAMLreturn (result); -} - -SET_CALLBACK(reduce_eq); - - -// ------------------- -// reduce_distinct - -static Z3_bool reduce_distinct_callback_static(Z3_theory th, unsigned n, Z3_ast const args[], Z3_ast * r) -{ - CAMLparam0(); - CAMLlocal4(cb, _r, _args, _v); - value user_data; - Z3_bool result; - - _args = Val_ast_array(n, args); - - user_data = (value) Z3_theory_get_ext_data(th); - - cb = *(caml_named_value("apply_reduce_distinct")); - _r = callback2(cb, user_data, _args); - - cb = *(caml_named_value("is_some")); - _v = callback(cb, _r); - result = 0 != Bool_val(_v); - - if (result && r) { - cb = *(caml_named_value("get_some")); - _v = callback(cb, _r); - *r = *((Z3_ast*) Bp_val(_v)); - } - - CAMLreturn (result); -} - -SET_CALLBACK(reduce_distinct); - -// ------------------- -// new_app - -#define AST_CALLBACK(_cb_name) \ -static void _cb_name##_callback_static(Z3_theory th, Z3_ast a) \ -{ \ - CAMLparam0(); \ - CAMLlocal3(cb, _a, user_data); \ - _a = Val_ast(a); \ - user_data = (value) Z3_theory_get_ext_data(th); \ - cb = *(caml_named_value("apply_" #_cb_name)); \ - callback2(cb, user_data, _a); \ - CAMLreturn0; \ -} \ - -AST_CALLBACK(new_app); -SET_CALLBACK(new_app); - -// ------------------- -// new_elem - -AST_CALLBACK(new_elem); -SET_CALLBACK(new_elem); - -// ------------------- -// init_search - -#define TH_CALLBACK(_cb_name) \ -static void _cb_name##_callback_static(Z3_theory th) \ -{ \ - CAMLparam0(); \ - CAMLlocal2(cb, user_data); \ - user_data = (value) Z3_theory_get_ext_data(th); \ - cb = *(caml_named_value("apply_" #_cb_name)); \ - callback(cb, user_data); \ - CAMLreturn0; \ -} \ - -TH_CALLBACK(init_search); -SET_CALLBACK(init_search); - -// ------------------- -// push - -TH_CALLBACK(push); -SET_CALLBACK(push); - -TH_CALLBACK(pop); -SET_CALLBACK(pop); - -TH_CALLBACK(restart); -SET_CALLBACK(restart); - -TH_CALLBACK(reset); -SET_CALLBACK(reset); - - -#define FC_CALLBACK(_cb_name) \ - static Z3_bool _cb_name##_callback_static(Z3_theory th) \ - { \ - CAMLparam0(); \ - CAMLlocal3(cb, r, user_data); \ - user_data = (value) Z3_theory_get_ext_data(th); \ - cb = *(caml_named_value("apply_" #_cb_name)); \ - r = callback(cb, user_data); \ - CAMLreturn (Bool_val(r) != 0); \ - } \ - -FC_CALLBACK(final_check); -SET_CALLBACK(final_check); - -#define AST_AST_CALLBACK(_cb_name) \ - static void _cb_name##_callback_static(Z3_theory th, Z3_ast a, Z3_ast b) \ - { \ - CAMLparam0(); \ - CAMLlocal4(cb, _a, _b, user_data); \ - _a = Val_ast(a); \ - _b = Val_ast(b); \ - user_data = (value) Z3_theory_get_ext_data(th); \ - cb = *(caml_named_value("apply_" #_cb_name)); \ - callback3(cb, user_data, _a, _b); \ - CAMLreturn0; \ - } \ - -AST_AST_CALLBACK(new_eq); -SET_CALLBACK(new_eq); - -AST_AST_CALLBACK(new_diseq); -SET_CALLBACK(new_diseq); - -#define AST_BOOL_CALLBACK(_cb_name) \ - static void _cb_name##_callback_static(Z3_theory th, Z3_ast a, Z3_bool b) \ - { \ - CAMLparam0(); \ - CAMLlocal4(cb, _a, _b, user_data); \ - _a = Val_ast(a); \ - _b = Val_bool(b); \ - user_data = (value) Z3_theory_get_ext_data(th); \ - cb = *(caml_named_value("apply_" #_cb_name)); \ - callback3(cb, user_data, _a, _b); \ - CAMLreturn0; \ - } \ - - -AST_BOOL_CALLBACK(new_assignment); -SET_CALLBACK(new_assignment); - -AST_CALLBACK(new_relevant); -SET_CALLBACK(new_relevant); - From b92bdaeebe9cedb3191d2c5e30abf95dcee72e82 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 18:51:47 +0000 Subject: [PATCH 506/507] ML API readme fixes Signed-off-by: Christoph M. Wintersteiger --- examples/ml/README | 2 -- src/api/ml/README | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/ml/README b/examples/ml/README index b7aa187fa..562e9fe46 100644 --- a/examples/ml/README +++ b/examples/ml/README @@ -1,5 +1,3 @@ -### This is work-in-progress. - Small example using the Z3 ML bindings. To build the example execute make examples diff --git a/src/api/ml/README b/src/api/ml/README index f697e5ff4..ffdd3e709 100644 --- a/src/api/ml/README +++ b/src/api/ml/README @@ -1,6 +1,5 @@ -This directory is work in progress. - -We are currently working on a brand new ML API. +This is the new ML API introduced with Z3 4.4. For the legacy bindings, please +refer to previous releases of Z3. On Windows, there are no less than four different ports of OCaml. The Z3 build system assumes that either the win32 or the win64 port is installed. This means From e1d469fcbf79609d6240e79b23a9b4e4f7f732c8 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Sat, 24 Jan 2015 19:12:55 +0000 Subject: [PATCH 507/507] Update release notes Signed-off-by: Christoph M. Wintersteiger --- RELEASE_NOTES | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index f8cac4c8b..bfadb8f75 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -9,14 +9,17 @@ Version 4.4 See also: Froehlich, Biere, Wintersteiger, Hamadi: Stochastic Local Search for Satisfiability Modulo Theories, AAAI 2015. +- Upgrade: This release includes a brand new OCaml/ML API that is much better integrated with the build system, and hopefully also easier to use than the previous one. + - Fixed various bugs reported by Marc Brockschmidt, Venkatesh-Prasad Ranganath, Enric Carbonell, Morgan Deters, Tom Ball, Malte Schwerhoff, and Codeplex users rsas, clockish, Heizmann. + Version 4.3.2 ============= - Added preliminary support for the theory of floating point numbers (tactics qffpa, qffpabv, and logics QF_FPA, QF_FPABV). -- Added the interpolation features of iZ3, which are now integrated into the Z3. +- Added the interpolation features of iZ3, which are now integrated into Z3. - Fixed a multitude of bugs and inconsistencies that were reported to us either in person, by email, or on Codeplex. Of those that we do have records of, we would like to express our gratitude to: Vladimir Klebanov, Konrad Jamrozik, Nuno Lopes, Carsten Ruetz, Esteban Pavese, Tomer Weiss, Ilya Mironov, Gabriele Paganelli, Levent Erkok, Fabian Emmes, David Cok, Etienne Kneuss, Arlen Cox, Matt Lewis, Carsten Otto, Paul Jackson, David Monniaux, Markus Rabe, Martin Pluecker, Jasmin Blanchette, Jules Villard, Andrew Gacek, George Karpenkov, Joerg Pfaehler, and Pablo Aledo